---
title: 'Theme Lab: Tune Family, Preset, and Rhythm'
name: theme-lab
description: Interactive controls for palette family, preset, style intensity, and
  content width.
output:
  rmarkdown::html_vignette:
    toc: yes
    toc_depth: 2
    css: albers.css
    includes:
      in_header: albers-header.html
params:
  family: red
  preset: homage
  base_size: 13
  content_width: 80
  style: minimal
resource_files:
- albers.css
- albers.js
- albers-header.html

vignette: |
  %\VignetteIndexEntry{Theme Lab: Tune Family, Preset, and Rhythm}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(
  collapse = TRUE, comment = "#>", fig.align = "center", fig.retina = 2,
  out.width = "100%", fig.width = 7, fig.asp = 0.618, message = FALSE, warning = FALSE
)
library(ggplot2)
if (requireNamespace("ragg", quietly = TRUE)) knitr::opts_chunk$set(dev = "ragg_png")
if (
  requireNamespace("systemfonts", quietly = TRUE) &&
  requireNamespace("albersdown", quietly = TRUE) &&
  "albers_register_fonts" %in% getNamespaceExports("albersdown")
) {
  albersdown::albers_register_fonts()
}
if (requireNamespace("ggplot2", quietly = TRUE) && requireNamespace("albersdown", quietly = TRUE)) {
  if (requireNamespace("ggplot2", quietly = TRUE) && requireNamespace("albersdown", quietly = TRUE)) ggplot2::theme_set(albersdown::theme_albers(family = params$family, preset = params$preset))
}
```

```{r albers-classes, echo=FALSE, results='asis'}
cat(sprintf(
  paste0(
    '<script>document.addEventListener("DOMContentLoaded",function(){',
    'document.body.classList.remove("palette-red","palette-lapis","palette-ochre","palette-teal","palette-green","palette-violet","preset-homage","preset-interaction","preset-study","preset-structural","preset-adobe","preset-midnight");',
    'document.body.classList.add("palette-%s","preset-%s");',
    '});</script>'
  ),
  params$family,
  params$preset
))
```



```{r albers-style, echo=FALSE, results='asis'}
cat(sprintf(
  paste0(
    '<script>document.addEventListener("DOMContentLoaded",function(){',
    'if(!document.body.classList.contains("style-minimal") && !document.body.classList.contains("style-assertive") && "%s"!=="balanced") document.body.classList.add("style-%s");',
    '});</script>'
  ),
  params$style,
  params$style
))
cat(sprintf('<style>:root{--content:%sch}</style>', params$content_width))
```

## What Is This Page For?

Use this page to choose a visual direction before you retrofit or create vignettes.
You can tune one parameter at a time and immediately see the effect on hierarchy,
contrast, and page rhythm.

<div class="callout callout-insight">
Start with <strong>family</strong> and <strong>preset</strong>, then tune <strong>style</strong>, then adjust content width.
That order gives the fastest path to a coherent page.
</div>

## How Do You Use It?

1. Pick a family for color character (the four chips show its tones).
2. Pick a direction: warm **homage** or cool **interaction**.
3. Toggle style intensity to set structural emphasis (marker + rule weight).
4. Adjust content width to match prose density.

<div class="theme-lab" data-albers-lab>
<div class="theme-lab__panel">
  <div class="theme-lab__controls">
  <div>
  <label for="albers-family">Family</label>
  <select id="albers-family" data-albers-control="family">
  <option value="red">red</option>
  <option value="lapis">lapis</option>
  <option value="ochre">ochre</option>
  <option value="teal">teal</option>
  <option value="green">green</option>
  <option value="violet">violet</option>
  </select>
  </div>
  <div>
  <label for="albers-preset">Direction</label>
  <select id="albers-preset" data-albers-control="preset">
  <option value="homage">homage (warm)</option>
  <option value="interaction">interaction (cool)</option>
  </select>
  </div>
  <div>
  <label for="albers-style">Style</label>
  <select id="albers-style" data-albers-control="style">
  <option value="minimal">minimal</option>
  <option value="balanced">balanced</option>
  <option value="assertive">assertive</option>
  </select>
  </div>
  <div>
  <label for="albers-width">Content width (ch)</label>
  <input id="albers-width" data-albers-control="width" type="number" min="60" max="100" value="80" />
  </div>
  </div>
</div>

<div class="theme-lab__preview">
  <div class="theme-lab__chips">
  <span class="albers-chip">A900</span>
  <span class="albers-chip">A700</span>
  <span class="albers-chip">A500</span>
  <span class="albers-chip">A300</span>
  </div>
  <p data-albers-lab-summary>family=red | preset=homage | style=minimal | width=80ch</p>
  <div class="albers-composition albers-composition--dense" data-seed="theme-lab" data-density="8" aria-hidden="true"></div>
</div>
</div>

## What Does Each Control Change?

- `family`: accent hue and contrast character for links, rules, the nested-square
  marker, and plot palettes (the four chips above show the active family's tones).
- `preset` (direction): warm **homage** (cream ground, serif body, light code) vs
  cool **interaction** (grey ground, grotesk, dark code).
- `style`: structural weight (`minimal`, `balanced`, `assertive`).
- `content_width`: reading measure in `ch` units.

## Can You Validate The Palette Quickly?

```{r palette-check}
pal <- albersdown::albers_palette(params$family)
stopifnot(
  identical(names(pal), c("A900", "A700", "A500", "A300")),
  all(nzchar(unname(pal)))
)
knitr::kable(data.frame(tone = names(pal), hex = unname(pal)), format = "html")
```

## Copy Into YAML

```yaml
params:
  family: red
  preset: homage
  base_size: 13
  content_width: 80
  style: minimal
```

## Example Plot

```{r example-plot}
mtcars$grp <- factor(mtcars$cyl)
stopifnot(length(levels(mtcars$grp)) >= 3)

ggplot(mtcars, aes(wt, mpg, colour = grp)) +
  geom_point(size = 2.2) +
  labs(
    title = "Theme Lab preview",
    subtitle = "Tune family + preset + style, then copy YAML"
  )
```
