/* ===========================================================================
   presets.css — brand skins, for the catalog only
   ---------------------------------------------------------------------------
   These are NOT part of the library contract. They exist to prove one claim:
   every section here is design-agnostic. Switch the preset in the catalog
   toolbar and all 30+ sections re-skin — different type, colour, weight, case,
   rhythm and shape — with zero changes to any section's own CSS.

   If a section fails to follow a preset, that section has hardcoded something
   it shouldn't have. The switcher is the test suite.

   A preset that only repaints and re-letters is a weak test, because the page
   underneath stays the same page. The ones below also move the measure, the
   gutter, the whole type scale rather than the hero step alone, the section
   rhythm, and how far a reveal travels — the axes that actually decide what a
   page feels like. Litmus is the extreme of that idea and is not a brand at
   all: it exists to make anything hardcoded impossible to miss.

   Font stacks lean on faces that ship with macOS so the presets read as truly
   different offline, with web-safe fallbacks behind each one. In a real client
   project you'd swap these for the brand's licensed faces.
   ========================================================================= */

/* --- Editorial ------------------------------------------------------------
   Traditional publishing. High-contrast serif display, warm paper stock,
   hairline rules, square corners, restrained accent. */
[data-vb-preset="editorial"] {
	--vb-color-ink:            #1a1714;
	--vb-color-ink-soft:       #4a443d;
	--vb-color-mute:           #6f6759;
	--vb-color-paper:          #fbf9f5;
	--vb-color-paper-muted:    #f2eee6;
	--vb-color-paper-sunk:     #e7e1d5;
	--vb-color-rule:           #ddd6c8;
	--vb-color-accent:         #7a2e1e;
	--vb-color-accent-hover:   #5e2216;
	--vb-color-accent-contrast:#fbf9f5;
	--vb-color-accent-soft:    #f2e4de;
	/* Its own dark world, not the shared slate: the ground is the brand's own
	   ink brown taken to near-black, so the warmth survives the flip. */
	--vb-color-ink-on-dark:         #f7f3ec;
	--vb-color-ink-soft-on-dark:    #cec5b6;
	--vb-color-mute-on-dark:        #9a9082;
	--vb-color-paper-on-dark:       #17130f;
	--vb-color-paper-muted-on-dark: #211c17;
	--vb-color-paper-sunk-on-dark:  #2c2620;
	--vb-color-rule-on-dark:        #3a332b;
	--vb-color-accent-soft-on-dark: #3a201a;
	--vb-color-accent-on-dark:          #e8927a;
	--vb-color-accent-on-dark-hover:    #f0ab96;
	--vb-color-accent-on-dark-contrast: #14121f;

	--vb-font-display: 'Iowan Old Style', 'Palatino Linotype', Palatino, Georgia, serif;
	--vb-font-sans:    'Charter', Georgia, 'Times New Roman', serif;

	--vb-fs-display-1: clamp(2.5rem, 4.5vw + 0.5rem, 5rem);
	--vb-lh-display-1: 1.06;
	--vb-ls-display-1: -0.015em;
	--vb-weight-display: 400;
	--vb-weight-heading: 600;
	--vb-ls-eyebrow:   0.24em;

	--vb-radius-sm: 0; --vb-radius-card: 0; --vb-radius-lg: 0; --vb-radius-pill: 0;
	--vb-shadow-card: none;
	--vb-shadow-card-hover: none;
	--vb-shadow-pop: 0 20px 50px -30px rgb(26 23 20 / 0.4);
}

/* --- Brutalist ------------------------------------------------------------
   Loud, structural, unapologetic. Grotesque display at max weight, hard
   offset shadows, zero radius, high-voltage accent on near-black. */
[data-vb-preset="brutalist"] {
	--vb-color-ink:            #0a0a0a;
	--vb-color-ink-soft:       #2e2e2e;
	--vb-color-mute:           #575757;
	--vb-color-paper:          #f2f2ef;
	--vb-color-paper-muted:    #e4e4de;
	--vb-color-paper-sunk:     #d7d7d1;
	--vb-color-rule:           #0a0a0a;
	--vb-color-accent:         #1f38ff;
	--vb-color-accent-hover:   #0a1fd6;
	--vb-color-accent-contrast:#ffffff;
	--vb-color-accent-soft:    #dfe3ff;
	/* True black, and rule-on-dark is the ink again — the light side sets
	   rule to #0a0a0a for hard full-strength hairlines, and losing that on
	   the flip would soften the one thing this preset is about. */
	--vb-color-ink-on-dark:         #f2f2ef;
	--vb-color-ink-soft-on-dark:    #c9c9c5;
	--vb-color-mute-on-dark:        #949490;
	--vb-color-paper-on-dark:       #0a0a0a;
	--vb-color-paper-muted-on-dark: #191919;
	--vb-color-paper-sunk-on-dark:  #262626;
	--vb-color-rule-on-dark:        #f2f2ef;
	--vb-color-accent-soft-on-dark: #161d52;
	--vb-color-accent-on-dark:          #8fa0ff;
	--vb-color-accent-on-dark-hover:    #b0bcff;
	--vb-color-accent-on-dark-contrast: #14121f;

	--vb-font-display: 'Helvetica Neue', Helvetica, Arial, sans-serif;
	--vb-font-sans:    'Helvetica Neue', Helvetica, Arial, sans-serif;

	--vb-fs-display-1: clamp(3rem, 7vw, 7.5rem);
	--vb-lh-display-1: 0.9;
	--vb-ls-display-1: -0.045em;
	--vb-weight-display: 800;
	--vb-weight-heading: 700;
	--vb-weight-eyebrow: 700;
	--vb-case-display: uppercase;
	--vb-ls-eyebrow:   0.1em;

	--vb-radius-sm: 0; --vb-radius-card: 0; --vb-radius-lg: 0; --vb-radius-pill: 0;
	--vb-border-hair: 2px;
	--vb-shadow-card:       6px 6px 0 0 var(--vb-color-ink);
	--vb-shadow-card-hover: 10px 10px 0 0 var(--vb-color-accent);
	--vb-shadow-pop:        12px 12px 0 0 var(--vb-color-ink);
	--vb-dur-base: 120ms;
	--vb-ease-out-soft: cubic-bezier(0.2, 0, 0, 1);
}

/* --- Luxe -----------------------------------------------------------------
   Quiet, expensive, generous. Light-weight display, near-monochrome palette,
   huge whitespace, soft radii, shadows you barely notice. */
[data-vb-preset="luxe"] {
	--vb-color-ink:            #232220;
	--vb-color-ink-soft:       #6b6862;
	--vb-color-mute:           #6f6b62;
	--vb-color-paper:          #f7f6f3;
	--vb-color-paper-muted:    #efedE8;
	--vb-color-paper-sunk:     #e4e1da;
	--vb-color-rule:           #dedbd3;
	--vb-color-accent:         #786a4f;
	--vb-color-accent-hover:   #63583f;
	--vb-color-accent-contrast:#fdfcfa;
	--vb-color-accent-soft:    #eee9df;
	/* Warm charcoal rather than black. This preset is 300-weight and airy;
	   a hard black ground makes thin type look broken rather than expensive. */
	--vb-color-ink-on-dark:         #f4f2ee;
	--vb-color-ink-soft-on-dark:    #c5c1b8;
	--vb-color-mute-on-dark:        #938e83;
	--vb-color-paper-on-dark:       #1b1a17;
	--vb-color-paper-muted-on-dark: #242320;
	--vb-color-paper-sunk-on-dark:  #2f2d29;
	--vb-color-rule-on-dark:        #3b3833;
	--vb-color-accent-soft-on-dark: #2e2921;
	--vb-color-accent-on-dark:          #cbb98f;
	--vb-color-accent-on-dark-hover:    #ddceab;
	--vb-color-accent-on-dark-contrast: #14121f;

	--vb-font-display: 'Optima', 'Avenir Next', 'Gill Sans', system-ui, sans-serif;
	--vb-font-sans:    'Avenir Next', Avenir, system-ui, sans-serif;

	--vb-fs-display-1: clamp(2.25rem, 4vw + 0.5rem, 4.5rem);
	--vb-lh-display-1: 1.15;
	--vb-ls-display-1: 0.005em;
	--vb-weight-display: 300;
	--vb-weight-heading: 400;
	--vb-weight-body:    300;
	--vb-weight-strong:  500;
	--vb-ls-eyebrow:   0.3em;
	--vb-fs-eyebrow:   0.625rem;

	--vb-space-section:    clamp(6rem, 11vw, 11rem);
	--vb-space-section-sm: clamp(4rem, 7vw, 6.5rem);
	--vb-space-section-lg: clamp(8rem, 16vw, 15rem);
	--vb-lh-body: 1.85;

	--vb-radius-sm: 0.125rem; --vb-radius-card: 0.25rem; --vb-radius-lg: 0.5rem;
	--vb-shadow-card:       0 2px 24px -12px rgb(35 34 32 / 0.14);
	--vb-shadow-card-hover: 0 8px 40px -16px rgb(35 34 32 / 0.2);
	--vb-dur-base: 480ms;
	--vb-dur-slow: 900ms;
}

/* --- Tech -----------------------------------------------------------------
   Dark-native product surface. Tight grotesque, monospace eyebrows, electric
   accent, low-contrast panels lifted by hairline borders. */
[data-vb-preset="tech"] {
	--vb-color-ink:            #f0f2f5;
	--vb-color-ink-soft:       #a7adba;
	--vb-color-mute:           #8b93a1;
	--vb-color-paper:          #08090c;
	--vb-color-paper-muted:    #101218;
	--vb-color-paper-sunk:     #171a22;
	--vb-color-rule:           #23262f;
	--vb-color-accent:         #4ade80;
	--vb-color-accent-hover:   #22c55e;
	--vb-color-accent-contrast:#05140b;
	--vb-color-accent-soft:    #0e2318;

	--vb-font-display: 'SF Pro Display', system-ui, -apple-system, sans-serif;
	--vb-font-sans:    system-ui, -apple-system, 'Segoe UI', sans-serif;

	--vb-fs-display-1: clamp(2.5rem, 4.5vw + 0.5rem, 4.75rem);
	--vb-lh-display-1: 1.05;
	--vb-ls-display-1: -0.035em;
	--vb-weight-display: 620;
	--vb-weight-heading: 560;
	--vb-ls-eyebrow:   0.14em;

	--vb-radius-sm: 0.25rem; --vb-radius-card: 0.625rem; --vb-radius-lg: 1rem;
	--vb-shadow-card:       0 1px 0 0 rgb(255 255 255 / 0.05) inset, 0 12px 32px -18px rgb(0 0 0 / 0.9);
	--vb-shadow-card-hover: 0 1px 0 0 rgb(255 255 255 / 0.08) inset, 0 20px 48px -20px rgb(0 0 0 / 1);
	--vb-shadow-pop:        0 32px 80px -32px rgb(0 0 0 / 1);

	/* Tech is dark at rest, so its "dark surface" is the light one. Every
	   other preset inherits the shared *-on-dark set from tokens.css; this is
	   what declaring your own looks like. It used to need a two-class selector
	   to out-specify the literals baked into .vb-invert — now it is an ordinary
	   preset declaration like any other. */
	--vb-color-ink-on-dark:         #08090c;
	--vb-color-ink-soft-on-dark:    #3f4653;
	--vb-color-mute-on-dark:        #616875;
	--vb-color-paper-on-dark:       #f0f2f5;
	--vb-color-paper-muted-on-dark: #e2e5ea;
	--vb-color-paper-sunk-on-dark:  #d3d7de;
	--vb-color-rule-on-dark:        #c3c8d1;
	--vb-color-accent-soft-on-dark: #d6f5e2;
	--vb-color-accent-on-dark:          #137a39;
	--vb-color-accent-on-dark-hover:    #0f5f2d;
	--vb-color-accent-on-dark-contrast: #ffffff;
}

/* --- Organic --------------------------------------------------------------
   Warm, human, hand-made. Humanist sans, clay and moss palette, oversized
   soft radii, gentle depth. */
[data-vb-preset="organic"] {
	--vb-color-ink:            #2b2521;
	--vb-color-ink-soft:       #5e544c;
	--vb-color-mute:           #7d7062;
	--vb-color-paper:          #fdf8f2;
	--vb-color-paper-muted:    #f4ebdf;
	--vb-color-paper-sunk:     #e8dac8;
	--vb-color-rule:           #e0d2bf;
	--vb-color-accent:         #4f6b45;
	--vb-color-accent-hover:   #3d5435;
	--vb-color-accent-contrast:#fdf8f2;
	--vb-color-accent-soft:    #e3ebdd;
	/* The one that most needed it. A warm cream brand landing on the shared
	   cool slate stopped being this brand the moment a section went dark, so
	   the ground here is the cream's own hue driven down instead. */
	--vb-color-ink-on-dark:         #fbf5ec;
	--vb-color-ink-soft-on-dark:    #d3c7b8;
	--vb-color-mute-on-dark:        #a09283;
	--vb-color-paper-on-dark:       #1a1512;
	--vb-color-paper-muted-on-dark: #241d18;
	--vb-color-paper-sunk-on-dark:  #2f2620;
	--vb-color-rule-on-dark:        #3c3229;
	--vb-color-accent-soft-on-dark: #1f2b1b;
	--vb-color-accent-on-dark:          #a3c294;
	--vb-color-accent-on-dark-hover:    #bcd4b0;
	--vb-color-accent-on-dark-contrast: #14121f;

	--vb-font-display: 'Palatino Linotype', Palatino, 'Book Antiqua', Georgia, serif;
	--vb-font-sans:    'Optima', 'Gill Sans', 'Trebuchet MS', system-ui, sans-serif;

	--vb-fs-display-1: clamp(2.5rem, 4.5vw + 0.5rem, 4.75rem);
	--vb-lh-display-1: 1.1;
	--vb-ls-display-1: -0.01em;
	--vb-weight-display: 500;
	--vb-weight-heading: 600;
	--vb-case-eyebrow: lowercase;
	--vb-ls-eyebrow:   0.12em;
	--vb-fs-eyebrow:   0.8125rem;

	--vb-radius-sm: 0.75rem; --vb-radius-card: 1.5rem; --vb-radius-lg: 2.5rem;
	--vb-shadow-card:       0 2px 4px rgb(43 37 33 / 0.04), 0 12px 32px -16px rgb(43 37 33 / 0.22);
	--vb-shadow-card-hover: 0 2px 6px rgb(43 37 33 / 0.06), 0 22px 48px -18px rgb(43 37 33 / 0.3);
	--vb-dur-base: 400ms;
}

/* --- Swiss ----------------------------------------------------------------
   International Style. Helvetica at every size, a signal-red accent, small
   dense type, generous outer margin — and NO depth at all: a card is a hairline
   rectangle, and hover darkens the rule instead of lifting the box. It is the
   preset that catches a section leaning on box-shadow to make its hierarchy. */
[data-vb-preset="swiss"] {
	--vb-color-ink:            #111111;
	--vb-color-ink-soft:       #3d3d3d;
	--vb-color-mute:           #5c5c5c;
	--vb-color-paper:          #ffffff;
	--vb-color-paper-muted:    #f0f0ef;
	--vb-color-paper-sunk:     #e2e2e0;
	--vb-color-rule:           #111111;
	--vb-color-accent:         #d81e05;
	--vb-color-accent-hover:   #a81704;
	--vb-color-accent-contrast:#ffffff;
	--vb-color-accent-soft:    #fbe6e2;
	--vb-color-accent-on-dark:          #ff6a4d;
	--vb-color-accent-on-dark-hover:    #ff8f78;
	--vb-color-accent-on-dark-contrast: #14121f;

	/* Its dark surface is ink, not slate, and the rules stay hard white. */
	--vb-color-ink-on-dark:         #ffffff;
	--vb-color-ink-soft-on-dark:    #c9c9c7;
	--vb-color-mute-on-dark:        #9a9a97;
	--vb-color-paper-on-dark:       #111111;
	--vb-color-paper-muted-on-dark: #1c1c1b;
	--vb-color-paper-sunk-on-dark:  #262625;
	--vb-color-rule-on-dark:        #ffffff;
	--vb-color-accent-soft-on-dark: #3a120c;

	--vb-font-display: 'Helvetica Neue', Helvetica, Arial, sans-serif;
	--vb-font-sans:    'Helvetica Neue', Helvetica, Arial, sans-serif;
	--vb-font-mono:    'SF Mono', Menlo, Consolas, monospace;

	/* The whole scale, not just the hero. Swiss sets display type large and
	   everything under it small — the gap between the two is the style. */
	--vb-fs-display-1: clamp(2.25rem, 4vw + 0.5rem, 4.25rem);
	--vb-lh-display-1: 0.98;
	--vb-ls-display-1: -0.025em;
	--vb-fs-display-2: clamp(1.75rem, 2.4vw + 0.5rem, 2.75rem);
	--vb-lh-display-2: 1;
	--vb-ls-display-2: -0.02em;
	--vb-fs-h1: clamp(1.5rem, 1.6vw + 0.75rem, 2.125rem);
	--vb-lh-h1: 1.1;   --vb-ls-h1: -0.015em;
	--vb-fs-h2: clamp(1.25rem, 1vw + 0.75rem, 1.5rem);
	--vb-lh-h2: 1.15;  --vb-ls-h2: -0.01em;
	--vb-fs-h3: 1.0625rem;
	--vb-lh-h3: 1.25;  --vb-ls-h3: -0.005em;
	--vb-fs-lead: clamp(1rem, 0.4vw + 0.9rem, 1.1875rem);
	--vb-lh-lead: 1.45;
	--vb-fs-body: 0.9375rem;  --vb-lh-body: 1.55;
	--vb-fs-small: 0.8125rem; --vb-lh-small: 1.45;
	--vb-fs-eyebrow: 0.6875rem;
	--vb-ls-eyebrow: 0.06em;
	--vb-weight-display: 700;
	--vb-weight-heading: 700;
	--vb-weight-strong:  700;
	--vb-weight-eyebrow: 700;

	/* Wide field, deep margin. The column is where the style lives. */
	--vb-max-content: 88rem;
	--vb-max-wide:    104rem;
	--vb-max-narrow:  44rem;
	--vb-max-prose:   58ch;
	--vb-gutter:           clamp(1.5rem, 5vw, 4.5rem);
	--vb-space-section:    clamp(3.5rem, 6vw, 6rem);
	--vb-space-section-sm: clamp(2.25rem, 4vw, 3.75rem);
	--vb-space-section-lg: clamp(5rem, 9vw, 8.5rem);

	--vb-radius-sm: 0; --vb-radius-card: 0; --vb-radius-lg: 0;
	--vb-radius-pill: 0; --vb-radius-btn: 0;
	--vb-border-hair: 1px;
	--vb-shadow-card:       none;
	--vb-shadow-card-hover: 0 0 0 1px var(--vb-color-ink);
	--vb-shadow-pop:        0 0 0 1px var(--vb-color-ink);

	--vb-ease-out-soft: cubic-bezier(0.33, 0, 0.15, 1);
	--vb-ease-in-out:   cubic-bezier(0.5, 0, 0.5, 1);
	--vb-dur-fast: 100ms;
	--vb-dur-base: 180ms;
	--vb-dur-slow: 320ms;
	--vb-motion-distance: 10px;
	--vb-motion-step:     40ms;
}

/* --- Terminal -------------------------------------------------------------
   Phosphor. One monospaced face doing display, body and label alike, amber on
   near-black, hard corners, depth expressed as a 1px ring, and motion quantised
   with steps() so nothing eases. The only preset that exercises --vb-font-mono,
   and the honest test of whether a layout survives a monospaced body. */
[data-vb-preset="terminal"] {
	--vb-color-ink:            #d7d3c7;
	--vb-color-ink-soft:       #a9a496;
	--vb-color-mute:           #857f70;
	--vb-color-paper:          #0a0a08;
	--vb-color-paper-muted:    #121210;
	--vb-color-paper-sunk:     #1a1a16;
	--vb-color-rule:           #2f2e27;
	--vb-color-accent:         #ffb000;
	--vb-color-accent-hover:   #ffc94d;
	--vb-color-accent-contrast:#0a0a08;
	--vb-color-accent-soft:    #2a1d00;

	/* Dark at rest, so .vb-invert has to hand it a paper world — the same move
	   Tech makes, and the reason the whole palette is restated rather than the
	   accent alone. */
	--vb-color-ink-on-dark:         #12120e;
	--vb-color-ink-soft-on-dark:    #3c3a31;
	--vb-color-mute-on-dark:        #5d5a4e;
	--vb-color-paper-on-dark:       #e8e5d8;
	--vb-color-paper-muted-on-dark: #dcd8c8;
	--vb-color-paper-sunk-on-dark:  #ccc8b6;
	--vb-color-rule-on-dark:        #b4af9c;
	--vb-color-accent-soft-on-dark: #f2e4bd;
	--vb-color-accent-on-dark:          #8a5a00;
	--vb-color-accent-on-dark-hover:    #6d4700;
	--vb-color-accent-on-dark-contrast: #ffffff;

	--vb-font-display: 'SF Mono', ui-monospace, Menlo, Consolas, monospace;
	--vb-font-sans:    'SF Mono', ui-monospace, Menlo, Consolas, monospace;
	--vb-font-mono:    'SF Mono', ui-monospace, Menlo, Consolas, monospace;

	/* Monospace runs wide, so the display steps are smaller than any other
	   preset's and the body gets extra leading to stay readable. */
	--vb-fs-display-1: clamp(1.75rem, 3vw + 0.5rem, 3.25rem);
	--vb-lh-display-1: 1.15;
	--vb-ls-display-1: -0.02em;
	--vb-fs-display-2: clamp(1.5rem, 2vw + 0.5rem, 2.25rem);
	--vb-lh-display-2: 1.2;
	--vb-ls-display-2: -0.015em;
	--vb-fs-h1: clamp(1.375rem, 1.4vw + 0.75rem, 1.75rem);
	--vb-lh-h1: 1.25;  --vb-ls-h1: -0.01em;
	--vb-fs-h2: clamp(1.125rem, 0.8vw + 0.75rem, 1.375rem);
	--vb-lh-h2: 1.3;   --vb-ls-h2: 0em;
	--vb-fs-h3: 1rem;
	--vb-lh-h3: 1.4;   --vb-ls-h3: 0em;
	--vb-fs-lead: clamp(1rem, 0.3vw + 0.9rem, 1.125rem);
	--vb-lh-lead: 1.65;
	--vb-fs-body: 0.875rem;  --vb-lh-body: 1.75;
	--vb-fs-small: 0.75rem;  --vb-lh-small: 1.6;
	--vb-fs-eyebrow: 0.6875rem;
	--vb-ls-eyebrow: 0.14em;
	--vb-weight-display: 500;
	--vb-weight-heading: 500;
	--vb-weight-strong:  700;
	--vb-weight-eyebrow: 400;
	--vb-case-display: uppercase;

	--vb-max-content: 72rem;
	--vb-max-wide:    84rem;
	--vb-max-narrow:  42rem;
	--vb-max-prose:   58ch;
	--vb-gutter:           clamp(1rem, 3vw, 2rem);
	--vb-space-section:    clamp(3rem, 6vw, 5.5rem);
	--vb-space-section-sm: clamp(2rem, 4vw, 3.5rem);
	--vb-space-section-lg: clamp(4.5rem, 9vw, 8rem);

	--vb-radius-sm: 0; --vb-radius-card: 0; --vb-radius-lg: 0;
	--vb-radius-pill: 0; --vb-radius-btn: 0;
	--vb-border-hair: 1px;
	--vb-shadow-card:       0 0 0 1px var(--vb-color-rule);
	--vb-shadow-card-hover: 0 0 0 1px var(--vb-color-accent);
	--vb-shadow-pop:        0 0 0 1px var(--vb-color-accent), 0 0 48px -12px rgb(255 176 0 / 0.45);

	/* Quantised. A steps() timing function is legal anywhere an ease is, and
	   every transition in the library reads its curve from these two tokens. */
	--vb-ease-out-soft: steps(5, end);
	--vb-ease-in-out:   steps(5, end);
	--vb-dur-fast: 60ms;
	--vb-dur-base: 110ms;
	--vb-dur-slow: 180ms;
	--vb-motion-distance: 6px;
	--vb-motion-step:     30ms;
}

/* --- Civic ----------------------------------------------------------------
   Institutional: university, bank, ministry, hospital. Transitional serif over
   a plain sans, navy on white, small type and COMPRESSED rhythm — half of Luxe's
   vertical space. Luxe proves the library survives generosity; this is the only
   preset that proves it survives density. Square buttons under rounded cards,
   which is what --vb-radius-btn exists for. */
[data-vb-preset="civic"] {
	--vb-color-ink:            #16203a;
	--vb-color-ink-soft:       #3c4763;
	--vb-color-mute:           #5b6580;
	--vb-color-paper:          #ffffff;
	--vb-color-paper-muted:    #f3f5f9;
	--vb-color-paper-sunk:     #e6eaf2;
	--vb-color-rule:           #ccd4e2;
	--vb-color-accent:         #1a4f9c;
	--vb-color-accent-hover:   #123c7c;
	--vb-color-accent-contrast:#ffffff;
	--vb-color-accent-soft:    #e5edf9;

	--vb-color-ink-on-dark:         #f2f5fa;
	--vb-color-ink-soft-on-dark:    #bcc6da;
	--vb-color-mute-on-dark:        #8e9ab4;
	--vb-color-paper-on-dark:       #101a2e;
	--vb-color-paper-muted-on-dark: #172341;
	--vb-color-paper-sunk-on-dark:  #1f2d4f;
	--vb-color-rule-on-dark:        #2c3c63;
	--vb-color-accent-soft-on-dark: #17264a;
	--vb-color-accent-on-dark:          #8ab4f8;
	--vb-color-accent-on-dark-hover:    #adc9fb;
	--vb-color-accent-on-dark-contrast: #0b1424;

	--vb-font-display: 'Charter', 'Iowan Old Style', Georgia, 'Times New Roman', serif;
	--vb-font-sans:    'Helvetica Neue', system-ui, -apple-system, sans-serif;
	--vb-font-mono:    Menlo, Consolas, monospace;

	/* Deliberately small display. An institution states, it doesn't shout, and
	   nothing else in the library tests a hero that stays under 3.25rem. */
	--vb-fs-display-1: clamp(1.875rem, 2.6vw + 0.75rem, 3.125rem);
	--vb-lh-display-1: 1.14;
	--vb-ls-display-1: -0.012em;
	--vb-fs-display-2: clamp(1.625rem, 1.8vw + 0.75rem, 2.375rem);
	--vb-lh-display-2: 1.18;
	--vb-ls-display-2: -0.01em;
	--vb-fs-h1: clamp(1.375rem, 1.2vw + 0.75rem, 1.875rem);
	--vb-lh-h1: 1.22;  --vb-ls-h1: -0.008em;
	--vb-fs-h2: clamp(1.1875rem, 0.7vw + 0.85rem, 1.4375rem);
	--vb-lh-h2: 1.28;  --vb-ls-h2: -0.004em;
	--vb-fs-h3: 1.0625rem;
	--vb-lh-h3: 1.4;   --vb-ls-h3: 0em;
	--vb-fs-lead: clamp(1.0625rem, 0.3vw + 0.95rem, 1.1875rem);
	--vb-lh-lead: 1.55;
	--vb-fs-body: 0.9375rem;  --vb-lh-body: 1.65;
	--vb-fs-small: 0.8125rem; --vb-lh-small: 1.5;
	--vb-fs-eyebrow: 0.6875rem;
	--vb-ls-eyebrow: 0.1em;
	--vb-weight-display: 600;
	--vb-weight-heading: 600;
	--vb-weight-strong:  700;
	--vb-weight-eyebrow: 700;

	--vb-max-content: 74rem;
	--vb-max-wide:    86rem;
	--vb-max-narrow:  40rem;
	--vb-max-prose:   74ch;
	--vb-gutter:           clamp(1rem, 2.5vw, 1.75rem);
	--vb-space-section:    clamp(2.75rem, 5vw, 4.5rem);
	--vb-space-section-sm: clamp(1.75rem, 3.5vw, 3rem);
	--vb-space-section-lg: clamp(4rem, 7vw, 6.5rem);

	--vb-radius-sm: 0.125rem; --vb-radius-card: 0.25rem; --vb-radius-lg: 0.375rem;
	--vb-radius-btn: 0.125rem;
	--vb-border-hair: 1px;
	--vb-shadow-card:       0 1px 2px rgb(22 32 58 / 0.06);
	--vb-shadow-card-hover: 0 2px 6px rgb(22 32 58 / 0.1);
	--vb-shadow-pop:        0 10px 30px -18px rgb(22 32 58 / 0.4);

	--vb-ease-out-soft: cubic-bezier(0.25, 0.1, 0.25, 1);
	--vb-dur-fast: 100ms;
	--vb-dur-base: 170ms;
	--vb-dur-slow: 300ms;
	--vb-motion-distance: 8px;
	--vb-motion-step:     35ms;
}

/* --- Litmus ---------------------------------------------------------------
   NOT A BRAND. A hostile preset whose only job is to make a hardcoded value
   scream: faces nobody would choose, four-pixel borders, 0.45em tracking,
   crushed section rhythm against an enormous large step, 120rem measure, a
   half-rem gutter, offset shadows in the accent, and reveals that travel 96px
   over 1.4s. Anything that looks unchanged under Litmus is not reading its
   tokens. The palette is garish on purpose but still passes WCAG, so a real
   failure in tools/contrast.py stays a real failure. */
[data-vb-preset="litmus"] {
	--vb-color-ink:            #000000;
	--vb-color-ink-soft:       #1a1a1a;
	--vb-color-mute:           #3d3d3d;
	--vb-color-paper:          #fdf500;
	--vb-color-paper-muted:    #00e5ff;
	--vb-color-paper-sunk:     #ff9ee0;
	--vb-color-rule:           #000000;
	--vb-color-accent:         #7c00ff;
	--vb-color-accent-hover:   #5c00c0;
	--vb-color-accent-contrast:#ffffff;
	--vb-color-accent-soft:    #d9c2ff;

	--vb-color-ink-on-dark:         #fdf500;
	--vb-color-ink-soft-on-dark:    #ffd6f4;
	--vb-color-mute-on-dark:        #9ef0ff;
	--vb-color-paper-on-dark:       #12002b;
	--vb-color-paper-muted-on-dark: #24004f;
	--vb-color-paper-sunk-on-dark:  #350073;
	--vb-color-rule-on-dark:        #fdf500;
	--vb-color-accent-soft-on-dark: #3c0080;
	--vb-color-accent-on-dark:          #00ffc8;
	--vb-color-accent-on-dark-hover:    #6bffdd;
	--vb-color-accent-on-dark-contrast: #12002b;

	/* Faces chosen to be unmistakable. If any text on screen still looks like
	   the neutral sans, that text has its font hardcoded. */
	--vb-font-display: 'Papyrus', 'Bradley Hand', fantasy;
	--vb-font-sans:    'Courier New', Courier, monospace;
	--vb-font-mono:    'Comic Sans MS', 'Chalkboard', cursive;

	--vb-fs-display-1: clamp(3rem, 9vw, 8.5rem);
	--vb-lh-display-1: 0.82;
	--vb-ls-display-1: -0.05em;
	--vb-fs-display-2: clamp(2.25rem, 5vw, 5rem);
	--vb-lh-display-2: 0.9;
	--vb-ls-display-2: -0.04em;
	--vb-fs-h1: clamp(2rem, 3vw + 0.75rem, 3.5rem);
	--vb-lh-h1: 0.95;  --vb-ls-h1: 0.02em;
	--vb-fs-h2: clamp(1.75rem, 2vw + 0.75rem, 2.5rem);
	--vb-lh-h2: 1;     --vb-ls-h2: 0.04em;
	--vb-fs-h3: 1.5rem;
	--vb-lh-h3: 1.05;  --vb-ls-h3: 0.06em;
	--vb-fs-lead: 1.5rem;      --vb-lh-lead: 1.9;
	--vb-fs-body: 1.1875rem;   --vb-lh-body: 2.1;
	--vb-fs-small: 1.0625rem;  --vb-lh-small: 1.9;
	--vb-fs-eyebrow: 0.9375rem;
	--vb-lh-eyebrow: 1.4;
	--vb-ls-eyebrow: 0.45em;
	--vb-weight-display: 900;
	--vb-weight-heading: 800;
	--vb-weight-body:    500;
	--vb-weight-strong:  900;
	--vb-weight-eyebrow: 900;
	--vb-case-display: uppercase;
	--vb-case-eyebrow: uppercase;

	--vb-max-content: 120rem;
	--vb-max-wide:    140rem;
	--vb-max-narrow:  68rem;
	--vb-max-prose:   110ch;
	--vb-gutter:           0.5rem;
	--vb-space-section:    clamp(1rem, 2vw, 1.75rem);
	--vb-space-section-sm: 0.75rem;
	--vb-space-section-lg: clamp(8rem, 18vw, 16rem);

	--vb-radius-sm: 1.25rem; --vb-radius-card: 3rem; --vb-radius-lg: 5rem;
	--vb-radius-btn: 0;
	--vb-border-hair: 4px;
	--vb-shadow-card:       14px 14px 0 0 var(--vb-color-accent);
	--vb-shadow-card-hover: 24px 24px 0 0 var(--vb-color-ink);
	--vb-shadow-pop:        0 0 0 6px var(--vb-color-ink);

	--vb-ease-out-soft: cubic-bezier(0.68, -0.6, 0.32, 1.6);
	--vb-ease-in-out:   cubic-bezier(0.87, 0, 0.13, 1);
	--vb-dur-fast: 300ms;
	--vb-dur-base: 700ms;
	--vb-dur-slow: 1400ms;
	--vb-motion-distance: 96px;
	--vb-motion-step:     180ms;
}

/* --- Bauhaus --------------------------------------------------------------
   Dessau: geometric sans, warm paper stock, black rule, and primary colour
   used as composition rather than as emphasis — a red circle, a blue bar and
   a yellow quadrant sharing one canvas, none of them "the accent".

   This preset is why --vb-color-chroma-* exists. Before the sequence it could
   only be red on off-white, because one chromatic slot cannot hold three hues
   that mean nothing individually. It is the working test for that axis: if a
   grid of tiles under this preset comes out all red, the section is reaching
   for the accent where it should be cycling. */
[data-vb-preset="bauhaus"] {
	--vb-color-ink:            #16161a;
	--vb-color-ink-soft:       #3a3a40;
	--vb-color-mute:           #6a6a72;
	--vb-color-paper:          #f2ede3;
	--vb-color-paper-muted:    #e6dfd1;
	--vb-color-paper-sunk:     #d8cfbd;
	--vb-color-rule:           #16161a;
	--vb-color-accent:         #c8241b;
	--vb-color-accent-hover:   #a81c14;
	--vb-color-accent-contrast:#f2ede3;
	--vb-color-accent-soft:    #f2d9d5;

	--vb-color-ink-on-dark:         #f2ede3;
	--vb-color-ink-soft-on-dark:    #c9c3b7;
	--vb-color-mute-on-dark:        #8e8880;
	--vb-color-paper-on-dark:       #16161a;
	--vb-color-paper-muted-on-dark: #202027;
	--vb-color-paper-sunk-on-dark:  #2c2c34;
	--vb-color-rule-on-dark:        #f2ede3;
	--vb-color-accent-soft-on-dark: #3d1512;
	--vb-color-accent-on-dark:          #ff5a4a;
	--vb-color-accent-on-dark-hover:    #ff8577;
	--vb-color-accent-on-dark-contrast: #16161a;

	/* The three primaries, as a sequence rather than as roles. Red is also the
	   accent — an action on this page is red — but blue and yellow mean
	   nothing at all, which is exactly what the sequence is for. Yellow takes
	   ink for its contrast: dark text on yellow is the legible pairing, and
	   the whole point of shipping -contrast per stop is that it does not have
	   to be the same answer for all three. */
	--vb-color-chroma-1:          #c8241b;
	--vb-color-chroma-1-ink:      #c8241b;
	--vb-color-chroma-1-soft:     #f2d9d5;
	--vb-color-chroma-1-contrast: #f2ede3;
	--vb-color-chroma-2:          #1a4fa0;
	--vb-color-chroma-2-ink:      #1a4fa0;
	--vb-color-chroma-2-soft:     #d6e0f0;
	--vb-color-chroma-2-contrast: #f2ede3;
	/* Yellow is where this preset deliberately declines the field/mark split.
	   The mark would normally be the hue taken down to where a 1.5px stroke
	   survives on cream (#7d5900 clears 3:1); that value reads as brown, and a
	   brown Bauhaus is not Bauhaus. So the mark IS the field here — #f2b705 on
	   cream, 1.6:1 — and the two exceptions that creates are named explicitly
	   in tools/contrast.py rather than the check being softened for everyone.
	   This is a chosen trade, not an oversight: the preset exists to show the
	   aesthetic, and any client brand built on it should take the darker mark.
	   The dark world needs no exception — yellow on near-black is 12:1. */
	--vb-color-chroma-3:          #f2b705;
	--vb-color-chroma-3-ink:      #f2b705;
	--vb-color-chroma-3-soft:     #faedcb;
	--vb-color-chroma-3-contrast: #16161a;

	--vb-color-chroma-1-on-dark:          #ff5a4a;
	--vb-color-chroma-1-ink-on-dark:      #ff8577;
	--vb-color-chroma-1-soft-on-dark:     #3d1512;
	--vb-color-chroma-1-contrast-on-dark: #16161a;
	--vb-color-chroma-2-on-dark:          #6f9fe0;
	--vb-color-chroma-2-ink-on-dark:      #9dbdec;
	--vb-color-chroma-2-soft-on-dark:     #14243d;
	--vb-color-chroma-2-contrast-on-dark: #16161a;
	/* On dark the split reverses: yellow is now the brightest thing available,
	   so the field and the mark converge and only the tint has to move. */
	--vb-color-chroma-3-on-dark:          #ffcf3d;
	--vb-color-chroma-3-ink-on-dark:      #ffcf3d;
	--vb-color-chroma-3-soft-on-dark:     #3a2e08;
	--vb-color-chroma-3-contrast-on-dark: #16161a;

	--vb-font-display: 'Futura', 'Century Gothic', 'Avenir Next', system-ui, sans-serif;
	--vb-font-sans:    'Futura', 'Century Gothic', 'Avenir Next', system-ui, sans-serif;

	--vb-fs-display-1: clamp(3rem, 7.5vw, 8rem);
	--vb-lh-display-1: 0.88;
	--vb-ls-display-1: -0.04em;
	--vb-fs-display-2: clamp(2.25rem, 4.5vw, 4.5rem);
	--vb-lh-display-2: 0.95;
	--vb-weight-display: 700;
	--vb-weight-heading: 600;
	--vb-weight-eyebrow: 700;
	--vb-case-display: uppercase;
	--vb-case-eyebrow: uppercase;
	--vb-ls-eyebrow:   0.16em;

	--vb-radius-sm: 0; --vb-radius-card: 0; --vb-radius-lg: 0;
	--vb-radius-pill: 999px;
	--vb-radius-btn:  0;
	--vb-border-hair: 2px;
	--vb-shadow-card: none;
	--vb-shadow-card-hover: none;
	--vb-shadow-pop: none;

	--vb-dur-base: 200ms;
	--vb-ease-out-soft: cubic-bezier(0.2, 0, 0, 1);
	--vb-motion-distance: 40px;
}

/* --- Spectrum -------------------------------------------------------------
   The saturated gradient site: a ground that transitions rather than sits, a
   headline filled with the same ramp, vivid stops used as a family.

   This preset is why --vb-surface-image and --vb-color-ramp exist. Before
   them a ground could only be one flat colour, because grounds are painted
   background-color and a gradient has nowhere to live. It is the working test
   for that axis: any ground that stays flat under this preset is painting a
   colour without its image beside it. */
[data-vb-preset="spectrum"] {
	--vb-color-ink:            #f6f2ff;
	--vb-color-ink-soft:       #bfb4dd;
	--vb-color-mute:           #8b81ab;
	--vb-color-paper:          #0a0616;
	--vb-color-paper-muted:    #140c28;
	--vb-color-paper-sunk:     #1e1339;
	--vb-color-rule:           #33254f;
	--vb-color-accent:         #ff3d81;
	--vb-color-accent-hover:   #ff6b9e;
	--vb-color-accent-contrast:#0a0616;
	--vb-color-accent-soft:    #35102a;

	/* Dark-native, so the "on-dark" world is this brand's light one. */
	--vb-color-ink-on-dark:         #12081f;
	--vb-color-ink-soft-on-dark:    #3d2b57;
	--vb-color-mute-on-dark:        #6f5f8b;
	--vb-color-paper-on-dark:       #fdf7ff;
	--vb-color-paper-muted-on-dark: #f4e9fb;
	--vb-color-paper-sunk-on-dark:  #e7d7f4;
	--vb-color-rule-on-dark:        #d8c4ea;
	--vb-color-accent-soft-on-dark: #ffe0ec;
	--vb-color-accent-on-dark:          #c2185b;
	--vb-color-accent-on-dark-hover:    #9c134a;
	--vb-color-accent-on-dark-contrast: #fdf7ff;

	/* The ramp, and the ground it paints. --vb-surface-image is set once here
	   and every ground in the library carries it: the body over the full page
	   height, and each banded section over its own box. */
	--vb-color-ramp: linear-gradient(135deg, #ff3d81 0%, #a742ff 45%, #2fd1ff 100%);
	--vb-surface-image:
		radial-gradient(120% 85% at 12% -10%, rgb(167 66 255 / 0.42) 0%, transparent 62%),
		radial-gradient(110% 80% at 92% 8%, rgb(255 61 129 / 0.34) 0%, transparent 58%),
		radial-gradient(140% 110% at 50% 108%, rgb(47 209 255 / 0.22) 0%, transparent 60%);
	--vb-panel-image:
		linear-gradient(160deg, rgb(255 61 129 / 0.14) 0%, rgb(47 209 255 / 0.07) 100%);

	/* Three stops of the same ramp, so repeated items can walk it. */
	--vb-color-chroma-1:          #ff3d81;
	--vb-color-chroma-1-soft:     #35102a;
	--vb-color-chroma-1-contrast: #0a0616;
	--vb-color-chroma-2:          #a742ff;
	--vb-color-chroma-2-soft:     #241040;
	--vb-color-chroma-2-contrast: #0a0616;
	--vb-color-chroma-3:          #2fd1ff;
	--vb-color-chroma-3-soft:     #06263a;
	--vb-color-chroma-3-contrast: #0a0616;

	/* Dark-native, so this brand's "on-dark" world is the light one — the
	   stops darken rather than lighten, and the ground image is dropped
	   because those washes were mixed for near-black, not for white. */
	--vb-color-chroma-1-on-dark:          #c2185b;
	--vb-color-chroma-1-soft-on-dark:     #ffe0ec;
	--vb-color-chroma-1-contrast-on-dark: #fdf7ff;
	--vb-color-chroma-2-on-dark:          #6a1fb0;
	--vb-color-chroma-2-soft-on-dark:     #efe0fb;
	--vb-color-chroma-2-contrast-on-dark: #fdf7ff;
	--vb-color-chroma-3-on-dark:          #0071a3;
	--vb-color-chroma-3-soft-on-dark:     #d9f2fb;
	--vb-color-chroma-3-contrast-on-dark: #fdf7ff;

	--vb-font-display: 'Avenir Next', 'Helvetica Neue', system-ui, sans-serif;
	--vb-font-sans:    'Avenir Next', 'Helvetica Neue', system-ui, sans-serif;

	--vb-fs-display-1: clamp(3rem, 8vw, 8.5rem);
	--vb-lh-display-1: 0.92;
	--vb-ls-display-1: -0.045em;
	--vb-fs-display-2: clamp(2.25rem, 5vw, 5rem);
	--vb-lh-display-2: 0.98;
	--vb-weight-display: 800;
	--vb-weight-heading: 700;
	--vb-ls-eyebrow:   0.2em;

	--vb-radius-sm: 0.5rem; --vb-radius-card: 1.5rem; --vb-radius-lg: 2.5rem;
	--vb-border-hair: 1px;
	--vb-shadow-card:       0 20px 60px -30px rgb(255 61 129 / 0.55);
	--vb-shadow-card-hover: 0 30px 80px -30px rgb(255 61 129 / 0.7);
	--vb-shadow-pop:        0 40px 100px -40px rgb(255 61 129 / 0.6);

	--vb-dur-base: 420ms;
	--vb-dur-slow: 800ms;
	--vb-motion-distance: 48px;
}

/* Spectrum's ramp and ground washes hardcode their stops rather than deriving
   them from roles, so unlike a role-built ramp they do not re-resolve when the
   surface flips. Restated here for the light world — the one case the comment
   in tokens.css warns about. */
[data-vb-preset="spectrum"] .vb-invert,
html[data-vb-preset="spectrum"].vb-invert-page,
[data-vb-preset="spectrum"] [data-vb-surface="dark"],
[data-vb-preset="spectrum"] [data-vb-surface="dark-surface"],
html[data-vb-preset="spectrum"][data-vb-surface="dark"],
html[data-vb-preset="spectrum"][data-vb-surface="dark-surface"] {
	--vb-color-ramp: linear-gradient(135deg, #c2185b 0%, #6a1fb0 45%, #0071a3 100%);
	--vb-surface-image:
		radial-gradient(120% 85% at 12% -10%, rgb(106 31 176 / 0.10) 0%, transparent 62%),
		radial-gradient(110% 80% at 92% 8%, rgb(194 24 91 / 0.09) 0%, transparent 58%);
	--vb-panel-image: none;
}

/* --- Risograph ------------------------------------------------------------
   Duplicator printing: a handful of soy-ink spot colours laid down one pass at
   a time on uncoated stock, slightly out of register, with the paper's own
   grain showing through everything. Register entry e05.

   It is here because it stresses three things nothing else does.

   TEXTURE, NOT GRADIENT. Spectrum proved --vb-surface-image can hold a
   gradient. A gradient has no intrinsic size, so it simply fills whatever box
   it is given and every ground looks the same. Grain is the opposite: the SVG
   below carries width/height, so it TILES at its own size, and a card and the
   page get the same grain rather than the card getting a shrunken copy of the
   page's. That is the case that would have justified a --vb-surface-image-size
   token, and it turns out not to need one — an intrinsically-sized SVG plus
   the default background-repeat does it. Anything that comes out smooth under
   this preset is painting a colour with no image beside it, which a stretched
   gradient hides and a tiling texture cannot.

   THREE SPOT INKS, AND ONLY TWO OF THEM NEED THE SPLIT. Riso ink is what the
   chromatic sequence is for — pink, blue and green here mean nothing
   individually, they are just which drum was loaded. Fluorescent pink and
   green are unusable as marks on cream (2.7:1) and perfect as fields, so they
   take a darker mark. Blue is dark enough to do both jobs, so its -ink is the
   field. Bauhaus makes the case for overruling the contrast tool; this preset
   is the case where the tool is simply right, and where the answer differs
   per stop rather than per brand.

   ROUND BUTTONS ON SQUARE CARDS. Every other zero-radius preset zeroes the
   button too. Riso stickers are round and riso cards are cut square, so this
   is the first preset to actually use the --vb-radius-btn decoupling, and the
   first test that a section reads it rather than reaching for --vb-radius-pill.
   The condensed display face is likewise the only one in the library — a
   section that assumes display type is as wide as Helvetica will show it. */
[data-vb-preset="risograph"] {
	--vb-color-ink:            #1a1a18;  /* riso "black" is never true black */
	--vb-color-ink-soft:       #46433c;
	/* Darker than the palette needs on paper (5.97:1 where 4.5 would do) and
	   that headroom is deliberate. The grain below darkens every ground it
	   paints — the page renders #e9e6dc rather than the declared #f5f1e6, a
	   card #e6dfd5 rather than #ece7d8 — and tools/contrast.py scores the
	   DECLARED colour, because it reads hex out of CSS and cannot rasterise an
	   feTurbulence. At the first-choice #6b665c this preset passed the checker
	   at 4.72:1 and rendered at 4.32:1 on a card, which is a real failure the
	   tool cannot see. Measured off the actual PNG, not reasoned about.

	   The rule that follows for any brand declaring --vb-surface-image: the
	   checker's number is an upper bound, and the palette has to hold against
	   the composite. Carrying a step of headroom is the cheap way to do that. */
	--vb-color-mute:           #605b52;
	--vb-color-paper:          #f5f1e6;  /* uncoated stock */
	--vb-color-paper-muted:    #ece7d8;
	--vb-color-paper-sunk:     #ded8c6;
	--vb-color-rule:           #cec7b2;
	--vb-color-accent:         #c2186f;
	--vb-color-accent-hover:   #a3125d;
	--vb-color-accent-contrast:#f5f1e6;  /* the paper showing through, not white */
	--vb-color-accent-soft:    #ffdcef;

	--vb-color-ink-on-dark:         #f5f1e6;
	--vb-color-ink-soft-on-dark:    #c9c3b3;
	/* Same headroom, same reason, and the dark side needs MORE of it. The grain
	   is mid-grey, so it darkens a light ground and LIGHTENS a dark one — a
	   card inside a dark-surface band renders #332e2a against a declared
	   #1e1c17. At #8e887a that card measured 3.80:1 while the checker read
	   5.27:1, the worst gap in either world. */
	--vb-color-mute-on-dark:        #a09a8c;
	--vb-color-paper-on-dark:       #141310;
	--vb-color-paper-muted-on-dark: #1e1c17;
	--vb-color-paper-sunk-on-dark:  #2a2721;
	--vb-color-rule-on-dark:        #3b372e;
	--vb-color-accent-soft-on-dark: #3d0f28;
	--vb-color-accent-on-dark:          #ff6cc0;
	--vb-color-accent-on-dark-hover:    #ff8ccd;
	--vb-color-accent-on-dark-contrast: #141310;

	/* The three drums. Pink and green are fields that cannot be marks; blue is
	   dark enough to be both, so its -ink is left pointing at the field. */
	--vb-color-chroma-1:          #ff48b0;  /* fluorescent pink */
	--vb-color-chroma-1-ink:      #c2186f;
	--vb-color-chroma-1-soft:     #ffdcef;
	--vb-color-chroma-1-contrast: #1a1a18;
	/* Nudged one step off the true ink (#0078bf) so the knockout clears 4.5:1.
	   Knockout on a riso field is unprinted paper, i.e. this preset's cream —
	   not white — and cream on the true blue lands at 4.19. Half a percent of
	   fidelity buys a legible label, which is the opposite call to the Bauhaus
	   yellow because nothing about riso blue depends on it being that exact
	   blue. */
	--vb-color-chroma-2:          #0072b5;  /* blue */
	--vb-color-chroma-2-ink:      #0072b5;
	--vb-color-chroma-2-soft:     #d4e9f7;
	--vb-color-chroma-2-contrast: #f5f1e6;
	--vb-color-chroma-3:          #00a95c;  /* green */
	--vb-color-chroma-3-ink:      #008146;
	--vb-color-chroma-3-soft:     #d3f0e0;
	--vb-color-chroma-3-contrast: #1a1a18;

	--vb-color-chroma-1-on-dark:          #ff6cc0;
	--vb-color-chroma-1-ink-on-dark:      #ff8ccd;
	--vb-color-chroma-1-soft-on-dark:     #3d0f28;
	--vb-color-chroma-1-contrast-on-dark: #141310;
	--vb-color-chroma-2-on-dark:          #4fb3e8;
	--vb-color-chroma-2-ink-on-dark:      #7ecbf1;
	--vb-color-chroma-2-soft-on-dark:     #0d2a3d;
	--vb-color-chroma-2-contrast-on-dark: #141310;
	--vb-color-chroma-3-on-dark:          #35d489;
	--vb-color-chroma-3-ink-on-dark:      #6ee3ab;
	--vb-color-chroma-3-soft-on-dark:     #0b3324;
	--vb-color-chroma-3-contrast-on-dark: #141310;

	/* Overprint: two drums crossing where they overlap. */
	--vb-color-ramp: linear-gradient(120deg, #ff48b0 0%, #7a3fa8 48%, #0078bf 100%);

	/* The paper's grain, tiling at its own size on every ground. The panel pass
	   is finer so a card reads as a second impression rather than a crop of the
	   first.

	   type='turbulence' rather than 'fractalNoise', and the choice was measured
	   rather than picked: over this cream, turbulence at 0.45 opacity renders a
	   pixel stdev of 8.1 while dropping the ground only 12 levels, where
	   fractalNoise needs 0.80 opacity to reach 7.8 and costs 23. Grain that has
	   to be hunted for cannot fail visibly, and grain that darkens the paper is
	   spending contrast the palette was checked at — see the note below.

	   stitchTiles='stitch' is what keeps the seams invisible where the tile
	   repeats. Without it every 180px there is a visible ruled line. */
	--vb-surface-image:
		url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='180' height='180'%3E%3Cfilter id='r'%3E%3CfeTurbulence type='turbulence' baseFrequency='0.75' numOctaves='4' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='180' height='180' filter='url(%23r)' opacity='0.45'/%3E%3C/svg%3E");
	--vb-panel-image:
		url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='r'%3E%3CfeTurbulence type='turbulence' baseFrequency='1.05' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='120' height='120' filter='url(%23r)' opacity='0.34'/%3E%3C/svg%3E");

	/* The grain is INK, so it multiplies into the paper rather than sitting on
	   it — it can darken the stock and never lighten it. Numerically this lands
	   where plain compositing did (a 12-level shift, stdev 8.3 measured on a
	   render), so it costs nothing; it is here because it is what the press
	   does, and because it makes the offset plates below behave correctly when
	   they cross. The dark world screens instead — see the block after this
	   preset for why. */
	--vb-surface-blend: multiply;
	--vb-panel-blend:   multiply;

	/* And the same for elements: anything a section marks .vb-overprint now
	   crosses like a second pass on the drum instead of covering what is under
	   it. This is the half a brand cannot deliver alone — the section has to
	   say which two things overlap. */
	--vb-blend-ink: multiply;

	/* The only condensed display face in the library. */
	--vb-font-display: 'Avenir Next Condensed', 'HelveticaNeue-CondensedBold', 'Arial Narrow', system-ui, sans-serif;
	--vb-font-sans:    'Avenir Next', Avenir, 'Helvetica Neue', system-ui, sans-serif;

	--vb-fs-display-1: clamp(3rem, 8vw, 8rem);
	--vb-lh-display-1: 0.94;
	--vb-ls-display-1: -0.02em;
	--vb-fs-display-2: clamp(2.25rem, 5vw, 4.75rem);
	--vb-lh-display-2: 0.98;
	--vb-weight-display: 700;
	--vb-weight-heading: 600;
	--vb-weight-eyebrow: 700;
	--vb-case-eyebrow: uppercase;
	--vb-ls-eyebrow:   0.14em;

	/* Zine density. */
	--vb-space-section:    clamp(3rem, 6vw, 5.5rem);
	--vb-space-section-sm: clamp(2rem, 4vw, 3.5rem);
	--vb-space-section-lg: clamp(4.5rem, 9vw, 8rem);

	/* Square cuts, round stickers — the pairing --vb-radius-btn exists for. */
	--vb-radius-sm: 0; --vb-radius-card: 0; --vb-radius-lg: 0;
	--vb-radius-pill: 999px;
	--vb-radius-btn:  999px;
	--vb-border-hair: 1.5px;

	/* Misregistration: a second drum landing a few millimetres off, hard-edged
	   because a duplicator has no blur to give. */
	--vb-shadow-card:       5px 5px 0 0 rgb(0 114 181 / 0.32);
	--vb-shadow-card-hover: 8px 8px 0 0 rgb(255 72 176 / 0.42);
	--vb-shadow-pop:        10px 10px 0 0 rgb(26 26 24 / 0.22);

	--vb-dur-fast: 120ms;
	--vb-dur-base: 200ms;
	--vb-ease-out-soft: cubic-bezier(0.2, 0, 0, 1);
	--vb-motion-distance: 18px;
	--vb-motion-step:     50ms;
}

/* Risograph's dark world inverts the press. Multiplying a near-black ground by
   a grey texture leaves it near-black — measured, the grain collapses from a
   stdev of 8.3 to 1.56 and is simply gone — which is physically honest (you
   cannot print dark ink onto dark paper and see it) and useless as a surface.
   So on dark the same texture screens instead: it is no longer ink on paper,
   it is the tooth of the stock catching light, which is what you actually see
   on a dark sheet. Same tokens, opposite operation, and the sections know
   nothing about either. */
[data-vb-preset="risograph"] .vb-invert,
html[data-vb-preset="risograph"].vb-invert-page,
[data-vb-preset="risograph"] [data-vb-surface="dark"],
[data-vb-preset="risograph"] [data-vb-surface="dark-surface"],
html[data-vb-preset="risograph"][data-vb-surface="dark"],
html[data-vb-preset="risograph"][data-vb-surface="dark-surface"] {
	--vb-surface-blend: screen;
	--vb-panel-blend:   screen;
	--vb-blend-ink:     screen;
}
