--- title: 'Design notes: Homage system' name: design-notes description: Visual tokens, palette families, and component rules for albersdown. output: rmarkdown::html_vignette: toc: yes toc_depth: 2 df_print: kable params: family: red preset: study base_size: 13 content_width: 80 style: minimal vignette: | %\VignetteIndexEntry{Design notes: Homage system} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} css: albers.css resource_files: - albers.css - albers.js includes: in_header: |- --- ```{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 ) set.seed(123) oldopt <- options(pillar.sigfig = 7, width = 80) `%||%` <- function(a, b) if (is.null(a)) b else a library(ggplot2) if (requireNamespace("ggplot2", quietly = TRUE) && requireNamespace("albersdown", quietly = TRUE)) { oldtheme <- ggplot2::theme_set(albersdown::theme_albers( family = params$family, preset = params$preset, base_size = params$base_size )) } ``` ```{r albers-family, echo=FALSE, results='asis'} cat(sprintf('', params$family)) ``` ```{r albers-preset, echo=FALSE, results='asis'} cat(sprintf('', params$preset)) ``` ```{r albers-style, echo=FALSE, results='asis'} style_class <- switch( tolower(params$style %||% "balanced"), minimal = "style-minimal", assertive = "style-assertive", balanced = "" ) if (nzchar(style_class)) { cat(sprintf('', style_class)) } ``` ```{r content-width, echo=FALSE, results='asis'} cat(sprintf('', params$content_width)) ``` ## What's new in this release {#whats-new} - Token-driven design system (`inst/tokens/albers-tokens.yml`) now controls families, presets, and dark calibrations. - Deterministic composition blocks (`.albers-composition`) add a signature visual motif. - Semantic callout variants (`callout-note`, `callout-insight`, `callout-warning`, `callout-experiment`) are available. - Contrast validation now checks family/preset combinations against AA thresholds. ### Semantic callouts {#semantic-callouts}
Use callout-note for neutral guidance.
Use callout-insight for interpretation and design intent.
Use callout-warning when a choice has clear tradeoffs.
Use callout-experiment for exploratory or provisional guidance.
### Typography and syntax tone {#typography-syntax} ```{r syntax-demo} fit <- lm(mpg ~ wt + hp, data = mtcars) coef(summary(fit)) ``` ### Contrast guardrail example {#contrast-guardrails} ```{r contrast-example} contrast_ratio <- function(fg, bg) { to_rgb <- function(x) as.numeric(grDevices::col2rgb(x)) / 255 to_lin <- function(u) ifelse(u <= 0.03928, u / 12.92, ((u + 0.055) / 1.055)^2.4) luma <- function(x) { rgb <- to_rgb(x); lin <- to_lin(rgb) 0.2126 * lin[1] + 0.7152 * lin[2] + 0.0722 * lin[3] } l1 <- luma(fg); l2 <- luma(bg) if (l1 < l2) { tmp <- l1; l1 <- l2; l2 <- tmp } (l1 + 0.05) / (l2 + 0.05) } ratio_structural <- contrast_ratio("#C22B23", "#e6e9ed") ratio_adobe <- contrast_ratio("#C22B23", "#ece9e7") stopifnot(ratio_structural >= 4.5, ratio_adobe >= 4.5) data.frame( context = c("structural bg", "adobe bg"), ratio = c(ratio_structural, ratio_adobe) ) ``` ## Overview {.overview} - One family per page (A900/A700/A500/A300 → roles) - Links + focus use AA tones; anchors reveal a typographic dash on hover - Callouts and tables use quiet A300 tints; code blocks use a structural left ribbon ## Palette families and roles {#palettes} Families available: red, lapis, ochre, teal, green, violet. Each has four tones: - A900: links and focus in light mode; strongest contrast - A700: highlights (one series per plot); nav active marker - A500: borders, dash anchors, code ribbons, structural rules - A300: tints for callouts and table stripe; links/focus in dark mode ## Image-derived palettes {#image-palettes} The original Homage families favor a single hue family per plot or page. When you want a different aesthetic (pulled from the grid image), use the image-derived palettes and scales. They mirror the API and are fully opt-in. Sequential (image-based) ```{r img-seq, fig.height=3.2} mtcars |> ggplot(aes(wt, mpg, colour = hp)) + geom_point(size = 2.2) + labs(title = "Image-derived sequential (lapis)") + albersdown::scale_color_albers_img( "lapis", discrete = FALSE, breaks = c(100, 150, 200, 250, 300) ) + ggplot2::guides( colour = ggplot2::guide_colorbar( title.position = "top", barheight = grid::unit(70, "pt"), barwidth = grid::unit(10, "pt") ) ) + ggplot2::theme(legend.position = "right") ``` Diverging (image-based) ```{r img-div, fig.height=3.2} df <- transform(datasets::faithful, centered = waiting - mean(waiting)) ggplot(df, aes(eruptions, centered, colour = centered)) + geom_point(alpha = 0.9) + labs(title = "Image-derived diverging (red <-> teal)") + albersdown::scale_color_albers_img_red_teal(neutral = "#e5e7eb") ``` Notes - The `*_img` scales are opt-in and don’t change existing defaults. - `neutral` can be set to `"#e5e7eb"` (site border token) for visual coherence with pages. - Prefer the original single-family scales for a quieter, unified look; reach for the image-derived or diverging scales to emphasize contrasts. ## Links, anchors, and rhythm {#links-anchors} Links and focus rings always meet AA. Move the cursor over H2/H3 to reveal the structural dash anchor. Style modes - `style: minimal` (default): lighter rules and quieter dash language. - `style: balanced`: the calibrated middle ground. - `style: assertive`: stronger edges and more emphatic structural marks. ## Callouts and code blocks {#callouts-code} > TIP: Callouts use an A500 border and a subtle A300 tint (≈8–10%). Keep them short and purposeful. ```r # a small, readable function foo <- function(x) if (length(x) == 0) NA_real_ else mean(x) foo(c(1, 2, 3)) ``` The code fence stays flat: no drop shadow, with an A500 left ribbon and a compact copy control. ## Tables {#tables} Base HTML tables pick up a quiet A300 zebra stripe and thin borders. ```{r} knitr::kable(head(mtcars[, 1:5]), format = "html") ``` ## Plots: one highlight, others neutral {#plots} ```{r} mtcars$grp <- ifelse(mtcars$cyl == 6, "highlight", "other") mtcars$grp <- factor(mtcars$grp, levels = c("other", "highlight")) ggplot(mtcars, aes(wt, mpg, color = grp)) + geom_point(size = 2.2) + albersdown::scale_color_albers_highlight( family = params$family, tone = "A700", highlight = "highlight", other_name = "other" ) + labs(title = "One highlighted series; others neutral", subtitle = "A700 draws the eye; gray recedes", x = "Weight (1000 lbs)", y = "MPG") ``` ## See also {#see-also} - Getting started: `articles/getting-started.html` - pkgdown template docs: `reference/index.html` - Palette and roles: `#palettes` ```{r cleanup, include=FALSE} options(oldopt) if (exists("oldtheme")) ggplot2::theme_set(oldtheme) ```