:root {
  --lib-color-surface: #f8fafc;
  --lib-color-panel: #ffffff;
  /* Neutral Foundation Contract Closure, 2026-09-08: was #eef6ff -- only
     19.2 real Euclidean units from --lib-color-panel (white), failing
     the real, already-existing panel-vs-panel-soft contract rule
     (catalog/factory/brand-contract.json semantic_pair_rules,
     min_distance 40). Never caught because nothing tested this static
     default against that rule until scripts/lib/brand-derive.js's
     CANONICAL_NEUTRAL_LIGHT started asserting it live for every real
     brand. #e0e6ed is a real 43.7 units from white (verified,
     scripts/lib/png-sample.js colorDistance) -- kept in sync with that
     same canonical value, and with previews/assets/brand-presets.js's
     own neutral preset (asserted by scripts/tests/brand-integrity.test.js). */
  --lib-color-panel-soft: #e0e6ed;
  --lib-color-ink: #0f172a;
  /* Neutral Foundation Contract Closure, 2026-09-08: was #475569 --
     directly contradicted the real, already-documented Pure Black/White
     LAW default (catalog/factory/BRAND_TOKEN_MAPPING_GUIDE.md:
     "--lib-color-muted ... es, por defecto, negro puro (#000000), sin
     excepciones"). #000000 is the one that was always correct per that
     rule -- kept in sync with brand-derive.js's CANONICAL_NEUTRAL_LIGHT
     and brand-presets.js's own neutral preset. */
  --lib-color-muted: #000000;
  --lib-color-subtle: #64748b;
  --lib-color-inverse: #ffffff;
  /* Governance correction pass 8 (2026-08-26), Hero Canvas authority
     final fix: a Hero-attached Authority/Trust Band (TRU-01's
     .lib-trust-strip--hero-attached / Path B's
     .hhds-authority-band--hero-attached) sits on the composing Hero's
     OWN media/scrim, not the ordinary Canvas-controlled page-context
     tier -- it needs to track THAT surface's real light/dark outcome,
     which differs depending on whether the Hero is composed on
     data-surface="SURFACE"/"PANEL" (Canvas-driven, this default applies)
     or data-surface="DARK" (permanently dark, overridden inside that
     rule in hero-split.css/hero-immersive.css/generation-hhds.css --
     same technique as --lib-gradient-hero-media-scrim's own DARK-scoped
     override just above). A real regression this pass found and fixed:
     removing the old, unconditional inverse default broke HERO-03's
     attached band (dark ink on its own still-permanently-dark surface,
     a real measured 1.4-2:1 failure) the moment this token's inheritance
     was the only thing left deciding its color. */
  --lib-hero-attached-foreground: var(--lib-color-ink);
  --lib-color-primary: #0b63ce;
  --lib-color-primary-strong: #073b82;
  --lib-color-accent: #00a6c8;
  --lib-color-border: #d8e2ef;
  --lib-color-surface-card: var(--lib-color-panel);
  --lib-color-surface-card-dark: color-mix(in srgb, var(--lib-color-deep) 92%, transparent);
  --lib-color-border-panel: color-mix(in srgb, var(--lib-color-deep) 22%, transparent);
  --lib-color-border-inverse-soft: rgba(255, 255, 255, 0.15);
  --lib-color-border-inverse-strong: rgba(255, 255, 255, 0.22);
  --lib-color-border-card: color-mix(in srgb, var(--lib-color-deep) 16%, transparent);
  --lib-color-border-card-hover: color-mix(in srgb, var(--lib-color-deep) 28%, transparent);
  --lib-color-surface-glass-border: rgba(255, 255, 255, 0.15);
  --lib-color-blog-card-panel: color-mix(in srgb, var(--lib-color-deep) 49%, transparent);
  --lib-color-blog-card-overlay-top: color-mix(in srgb, var(--lib-color-deep) 4%, transparent);
  --lib-color-blog-card-overlay-mid: color-mix(in srgb, var(--lib-color-deep) 18%, transparent);
  --lib-color-blog-card-overlay-bottom: color-mix(in srgb, var(--lib-color-deep) 60%, transparent);
  --lib-color-blog-card-backdrop-tint: color-mix(in srgb, var(--lib-color-deep) 28%, transparent);
  --lib-color-star: #facc15;
  --lib-color-star-stroke: color-mix(in srgb, var(--lib-color-star) 72%, #b45309);
  --lib-color-brand-facebook: #1877f2;
  --lib-color-brand-google: #ea4335;
  --lib-color-brand-instagram: #e1306c;
  --lib-color-brand-youtube: #ff0000;
  --lib-color-brand-maps: #4285f4;
  --lib-color-brand-tiktok: #111827;
  --lib-color-brand-linkedin: #0a66c2;
  --lib-color-brand-x: #000000;
  --lib-color-brand-yelp: #ff1a1a;
  --lib-color-brand-pinterest: #e60023;
  --lib-size-social-icon-link: 2.75rem;
  --lib-size-social-icon: 1.25rem;
  --lib-color-deep: #0f172a;
  --lib-color-deep-accent: #123c70;
  --lib-color-deep-muted: #334155;
  --lib-color-success: #0f766e;
  --lib-color-error: #dc2626;
  /* Human review governance pass, 2026-09-05: completes the real status
     color set (success/error already existed) -- warning/info are the
     same universal, brand-independent state-color category as those
     two (catalog/factory/brand-contract.json's own existing
     classification), not project brand colors. */
  --lib-color-warning: #b45309;
  --lib-color-info: #0284c7;
  --lib-color-hero-overlay-start: color-mix(in srgb, var(--lib-color-deep) 92%, transparent);
  --lib-color-hero-overlay-end: color-mix(in srgb, var(--lib-color-primary-strong) 78%, transparent);
  --lib-font-body: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --lib-font-heading: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --lib-space-0: 0rem;
  --lib-space-1: 0.25rem;
  --lib-space-2: 0.5rem;
  --lib-space-3: 0.75rem;
  --lib-space-4: 1rem;
  --lib-space-5: 1.25rem;
  --lib-space-6: 1.5rem;
  --lib-space-8: 2rem;
  --lib-space-10: 2.5rem;
  /* 12 and 16 were used by 5 sections (text-highlights-media, split-hero,
     inner-page-hero, narrative-profile, steps-proof-split) but never defined,
     so their gaps resolved to 0 (found 2026-10-14). */
  --lib-space-12: 3rem;
  --lib-space-16: 4rem;
  --lib-gutter: clamp(1rem, 3vw, 1.5rem);
  --lib-container-wide: min(112.5rem, 94vw);
  --lib-container-standard: min(90rem, calc(100% - (var(--lib-gutter) * 2)));
  --lib-container-xl: min(120rem, calc(100% - (var(--lib-gutter) * 2)));
  --lib-space-container-x: clamp(1rem, 4vw, 1.5rem);
  --lib-space-container-x-lg: clamp(1.5rem, 3vw, 2.5rem);
  --lib-content-measure: 65ch;
  --lib-space-section-y: clamp(3rem, 5vw, 5rem);
  /* Height of a transparent site header that overlays the first section of
     the page (project-owned; 0 when the header sits above the content).
     Full-bleed heroes add it to their top padding so content clears it. */
  --lib-site-header-overlay: 0px;
  --lib-space-section-y-lg: 5rem;
  --lib-space-grid-gap: 1.5rem;
  --lib-space-grid-gap-lg: 2rem;
  --lib-space-hairline: 0.0625rem;
  --lib-space-hairline-tight: 0.125rem;
  --lib-space-fine-tight: 0.2rem;
  --lib-space-fine-1: 0.375rem;
  --lib-space-fine-2: 0.625rem;
  --lib-size-control-lg: 3rem;
  --lib-size-control-sm: 2.125rem;
  --lib-size-header-search-input: 15rem;
  --lib-size-header-search-input-mobile: 7.5rem;
  --lib-space-control-gap: var(--lib-space-2);
  --lib-space-control-padding-x: 0.875rem;
  --lib-space-control-padding-x-sm: var(--lib-space-fine-2);
  --lib-space-control-padding-y-sm: var(--lib-space-fine-1);
  --lib-font-size-micro: 0.75rem;
  --lib-font-size-caption: 0.78rem;
  --lib-font-size-small: 0.875rem;
  --lib-font-size-body-sm: 0.9375rem;
  --lib-font-size-base: 1rem;
  --lib-font-size-body-lg: 1.0625rem;
  --lib-font-size-lead: 1.125rem;
  --lib-font-size-subheading: 1.25rem;
  --lib-font-size-title-sm: 1.375rem;
  --lib-font-size-title-md: 2rem;
  --lib-font-size-title-lg: 2.25rem;
  --lib-font-size-stat-metric: clamp(2.75rem, 6vw, 3.75rem);
  --lib-font-size-stat-suffix: 0.52em;
  --lib-font-size-card-blog-title: 1.5rem;
  --lib-leading-card-blog-title: 1.25;
  --lib-font-scale-icon: 0.6em;
  --lib-font-scale-compact: 0.75em;
  --lib-font-scale-emphasis: 1.1em;
  --lib-radius-sm: 0.5rem;
  --lib-radius-md: 0.75rem;
  --lib-radius-lg: 1rem;
  --lib-radius-xl: 1.5rem;
  --lib-radius-pill: 999rem;
  /*
   * Media Frame (UI-028, Phase 5B.3, catalog/governance/
   * MEDIA_PRIMITIVES_CONVERGENCE_AUDIT.md) -- the only three real
   * aspect-ratio values found repeated across two or more independent
   * canonical-library implementations before this token family existed:
   * --lib-aspect-video (16/9): skills-video, text-highlights-media
   *   (mobile), narrative-profile (mobile), steps-proof-split (mobile) --
   *   4 real occurrences.
   * --lib-aspect-portrait (3/4): narrative-profile (desktop),
   *   steps-proof-split (desktop) -- 2 real occurrences.
   * --lib-aspect-tall (4/5): founder-profile, Hero Gallery item
   *   (mobile/single-column state) -- 2 real occurrences.
   * Single-occurrence literals found in the same audit (4/3, 4/7, 1/2)
   * are deliberately NOT tokenized -- no demonstrated second consumer.
   */
  --lib-aspect-video: 16 / 9;
  --lib-aspect-portrait: 3 / 4;
  --lib-aspect-tall: 4 / 5;
  /*
   * Organic/blob shapes - real premium-site reference (2026-08-11, owner-
   * supplied screenshots: a spa site, a logistics site, an ecommerce site,
   * all using soft asymmetric container silhouettes instead of plain
   * rectangles or hard geometric cuts). Three distinct presets so
   * multiple organic elements on one page/section don't read as an
   * obviously copy-pasted identical shape.
   */
  --lib-shape-organic-1: 63% 37% 54% 46% / 43% 39% 61% 57%;
  --lib-shape-organic-2: 42% 58% 68% 32% / 55% 43% 57% 45%;
  --lib-shape-organic-3: 58% 42% 39% 61% / 47% 62% 38% 53%;
  --lib-radius-organic-soft: 1.25rem 2.5rem 1.25rem 2.5rem;
  --lib-shadow-card: 0 1rem 2.625rem rgba(15, 23, 42, 0.1);
  --lib-shadow-card-hover: 0 1.375rem 3.625rem rgba(15, 23, 42, 0.16);
  --lib-shadow-button: 0 0.75rem 1.75rem color-mix(in srgb, var(--lib-color-primary) 24%, transparent);
  --lib-shadow-card-soft: 0 0.75rem 1.875rem rgba(15, 23, 42, 0.08);
  --lib-shadow-panel-soft: 0 0.625rem 1.5rem rgba(15, 23, 42, 0.08);
  --lib-shadow-featured: drop-shadow(0 0.25rem 0.625rem rgba(15, 23, 42, 0.18));
  --lib-shadow-star: 0 1px 6px color-mix(in srgb, var(--lib-color-star) 12%, transparent);
  --lib-shadow-card-active: 0 20px 48px rgba(15, 23, 42, 0.14);
  --lib-shadow-card-stat: 0 18px 44px rgba(15, 23, 42, 0.1);
  --lib-shadow-card-stat-hover: 0 22px 52px rgba(15, 23, 42, 0.14);
  --lib-shadow-header-dropdown: 0 18px 40px rgba(0, 0, 0, 0.35);
  --lib-shadow-header-mobile: 0 18px 40px rgba(15, 23, 42, 0.28), inset 0 1px 0 rgba(255, 255, 255, 0.12);
  --lib-shadow-dark-md: 0 10px 20px -5px rgba(0, 0, 0, 0.35);
  --lib-shadow-footer-icon: inset 0 1px 0 rgba(255, 255, 255, 0.16), 0 8px 18px color-mix(in srgb, var(--lib-color-primary) 18%, transparent);
  --lib-shadow-footer-icon-desktop: inset 0 1px 0 rgba(255, 255, 255, 0.16), 0 10px 22px color-mix(in srgb, var(--lib-color-primary) 24%, transparent);
  --lib-shadow-footer-icon-mail: 0 8px 18px rgba(234, 67, 53, 0.22);
  --lib-shadow-footer-icon-map: 0 8px 18px rgba(66, 133, 244, 0.22);
  --lib-shadow-card-blog-panel: 0 18px 40px rgba(10, 25, 47, 0.28), inset 0 1px 0 rgba(255, 255, 255, 0.08);
  --lib-shadow-card-blog: 0 10px 22px rgba(15, 23, 42, 0.08);
  --lib-shadow-card-blog-hover: 0 14px 28px rgba(15, 23, 42, 0.12);
  --lib-shadow-floating: 0 8px 24px rgba(15, 23, 42, 0.25);
  --lib-shadow-floating-hover: 0 12px 28px rgba(15, 23, 42, 0.3);
  --lib-shadow-nav-button: 0 2px 10px rgba(15, 23, 42, 0.1);
  --lib-shadow-nav-button-hover: 0 4px 14px rgba(15, 23, 42, 0.16);
  --lib-size-star-stroke: 0.9px;
  --lib-size-rating-star: 1rem;
  --lib-size-rating-star-lg: 1.5rem;
  --lib-size-testimonial-avatar: 5rem;
  --lib-size-testimonial-avatar-mobile: 3.5rem;
  --lib-size-testimonial-accent-min: 4.5rem;
  --lib-size-testimonial-accent-max: 6rem;
  --lib-size-testimonial-accent-stroke: 0.25rem;
  --lib-size-testimonial-quote-collapsed: 7rem;
  --lib-size-testimonial-quote-fade: 2.5rem;
  --lib-size-testimonial-expand-icon: 0.875rem;
  --lib-size-card-blog-min-height: 25rem;
  --lib-size-card-blog-min-height-mobile: 18rem;
  --lib-size-card-blog-panel-max-width: 88%;
  --lib-size-card-blog-panel-blur: 14px;
  --lib-size-card-blog-media-backdrop-blur: 20px;
  --lib-size-card-blog-media-backdrop-scale: 1.12;
  --lib-size-header-call-icon: 1.75rem;
  --lib-size-header-call-icon-sm: 1.5rem;
  --lib-size-contact-form-field-icon: 1.25rem;
  /* Responsive Measure System, 2026-09-08: was a frozen 44ch -- correct
     as a MOBILE/tablet measure, but a fixed character count never grows
     with the viewport, so a component whose own container is wide
     enough to offer more room (e.g. UI-002 Section Heading's --width-lg)
     kept reading text at the exact same line length from 1024 through
     1920, the same frozen-measure symptom as a fixed-rem container.
     Same clamp() technique already used by --lib-container-standard/
     --lib-gutter above -- floor unchanged (44ch, so nothing below ~1024px
     viewport moves), ceiling capped at 56ch (still within the
     professional 45-75ch readable range, never unlimited). */
  --lib-measure-heading: clamp(44ch, calc(14vw + 30ch), 56ch);
  --lib-motion-ease-standard: cubic-bezier(0.4, 0, 0.2, 1);
  --lib-motion-ease-emphasis: cubic-bezier(0.22, 1, 0.36, 1);
  --lib-motion-ease-linear: linear;
  /* Phase 6B.1B (Motion Governance -- Final Decision & Closure,
     2026-08-27), Part 19 ("Si se demuestra que un valor representa una
     responsabilidad reusable: create/reuse semantic authority"). Real
     evidence, not a guess: the identical `ease-in-out` continuous
     "breathing" scale curve is independently hardcoded in 3 real files
     (local-signals.css, hero-split.css, hero-immersive.css) for the
     identical real slow Ken-Burns image-zoom responsibility -- one of
     them explicitly matching a real production site's own precedent
     (`.hero-ent__photo-img`). Zero value change (still literally
     `ease-in-out`) -- pure tokenization of an already-real, already-
     duplicated responsibility. Migrated: local-signals.css (a real,
     standalone source file). NOT migrated: hero-split.css/
     hero-immersive.css -- both are hand-synced copies of
     `adapters/wordpress/generation/generation-hhds.css` (declared in
     their own file headers); editing the copy without also updating the
     canonical source and every other synced copy would itself create
     new real drift, and doing that is Hero's own pending migration
     scope, not this ticket's (STOP CONDITION #7). */
  --lib-motion-ease-breathe: ease-in-out;
  --lib-motion-duration-micro: 180ms;
  --lib-motion-duration-entry: 520ms;
  --lib-motion-duration-narrative: 760ms;
  --lib-motion-duration-continuous-cycle: 18s;
  /* Phase 6B.1C (2026-08-27): a real, distinct responsibility from
     --lib-motion-duration-continuous-cycle above -- both happen to be
     18s today, but a scroll-cycle length (marquee) and an image-
     breathing cycle length (Ken-Burns zoom) are not the same design
     decision and must stay independently adjustable. Real evidence: 3
     real files (local-signals.css, hero-split.css, hero-immersive.css)
     independently hardcoded this identical value for the identical
     Ken-Burns responsibility. Pairs with --lib-motion-ease-breathe. */
  --lib-motion-duration-breathe: 18s;
  --lib-motion-duration-reduced: 0.01ms;
  --lib-motion-distance-sm: 0.5rem;
  --lib-motion-distance-md: 1rem;
  --lib-motion-distance-lg: 1.5rem;
  --lib-motion-scale-enter: 0.985;
  --lib-motion-scale-focus: 1.025;
  --lib-motion-stagger-step: 90ms;
  --lib-motion-delay-1: 90ms;
  --lib-motion-delay-2: 180ms;
  --lib-motion-delay-3: 270ms;
  --lib-motion-delay-4: 360ms;
  --lib-transition-base: var(--lib-motion-duration-micro) var(--lib-motion-ease-standard);
  --lib-transition-reveal: var(--lib-motion-duration-entry) var(--lib-motion-ease-emphasis);
  --lib-transition-reduced: var(--lib-motion-duration-reduced);
  --lib-delay-1: var(--lib-motion-delay-1);
  --lib-delay-2: var(--lib-motion-delay-2);
  --lib-delay-3: var(--lib-motion-delay-3);
  --lib-delay-4: var(--lib-motion-delay-4);
  --lib-duration-marquee: var(--lib-motion-duration-continuous-cycle);
  --lib-gradient-primary: linear-gradient(135deg, var(--lib-color-primary), var(--lib-color-primary-strong));
  --lib-gradient-accent: linear-gradient(135deg, var(--lib-color-primary), var(--lib-color-accent));
  --lib-gradient-deep: linear-gradient(135deg, var(--lib-color-deep), var(--lib-color-deep-accent));
  --lib-gradient-success: linear-gradient(135deg, var(--lib-color-deep-muted), var(--lib-color-success));
  --lib-gradient-hero-overlay: linear-gradient(135deg, var(--lib-color-hero-overlay-start), var(--lib-color-hero-overlay-end));
  /* Governance correction pass 8 (2026-08-26), Hero Canvas authority
     final fix: was color-mix(...--lib-color-deep...) -- a fixed Brand-
     identity dark tone applied unconditionally, the real reason a
     Hero's media treatment stayed dark under Canvas: Light. Re-pointed
     at --lib-color-surface, one of Canvas's own 7 page-context tokens
     (previews/assets/canvas-tokens.js) -- same 3-stop shape/opacities,
     zero new tokens, but now genuinely Canvas-responsive: Canvas Light
     (this default) washes the media toward the real light surface tone;
     Canvas Dark (canvas-tokens.js's own override of this same token)
     washes it dark, with no Hero-specific override code needed at all.
     See catalog/governance/CANVAS_AUTHORITY_MODEL.md. */
  --lib-gradient-hero-media-scrim: linear-gradient(
    180deg,
    color-mix(in srgb, var(--lib-color-surface) 96%, transparent) 0%,
    color-mix(in srgb, var(--lib-color-surface) 85%, transparent) 45%,
    color-mix(in srgb, var(--lib-color-surface) 90%, transparent) 100%
  );
  /*
   * Media-Backed Visual Governance correction pass (2026-08-26) --
   * catalog/governance/CANVAS_AUTHORITY_MODEL.md, "Media-Backed
   * Component Governance". The general semantic media scrim authority:
   * same real derivation mechanism as --lib-gradient-hero-media-scrim
   * above (built from --lib-color-surface, so it inherits Canvas's own
   * Light/Dark resolution for free, zero branching of its own), but at
   * an intensity empirically calibrated against
   * scripts/qa-component.js's own auditMediaPreservation() gate AND its
   * existing foreground-contrast gate, across every real specimen photo
   * in Background Media's own Visual Lab fixture (a first calibration
   * pass validated only against one photo and missed a real Canvas-Dark
   * contrast failure on the fixture's own lighter-toned images --
   * corrected by testing every real specimen title, not just one, per
   * this same governance pass's own Section 9 instruction to "probar
   * consumidores actuales").
   *
   * Real, measured calibration (`scripts/tests/media-preservation-governance.test.js`,
   * `scripts/tests/qa-component.test.js`), minimum across ALL 5 real
   * specimen titles/photos:
   *   96/85/90 (Hero's own value, reused verbatim before this pass):
   *     Canvas Light 30.2% preservation, Canvas Dark 2.2% -- the exact
   *     real Human Visual Review FAIL this correction pass exists to fix.
   *   60/50/55 (adopted below): Canvas Light 83.5% preservation /
   *     14.71:1 minimum contrast; Canvas Dark 22.0% preservation /
   *     4.58:1 minimum contrast -- both with real margin above the
   *     >=3:1 large-text requirement, across every real photo in the
   *     fixture, not just one.
   * Canvas Dark's own real, structural ceiling is lower than Canvas
   * Light's: darkening an arbitrary real photo enough for white text to
   * stay safely legible destroys more of its real luminance range than
   * lightening the same photo for dark text does -- confirmed by
   * testing a full intensity sweep, not assumed. This is why Gate B's
   * own minimum ratio (scripts/qa-component.js) is deliberately
   * asymmetric per canvas (0.40 Light / 0.15 Dark) rather than one
   * shared number -- see "Media Preservation contract" in
   * CANVAS_AUTHORITY_MODEL.md for the full reasoning.
   * --lib-gradient-hero-media-scrim itself is UNCHANGED and remains
   * Hero's own real, human-approved, evidenced-stronger identity for
   * its specific dense composition -- not retired, not aliased, a real
   * documented exception the same way data-surface="DARK" is a real
   * per-section exception to Canvas's general resolution (see
   * "Media-Backed Component Governance" for the full disposition).
   */
  --lib-gradient-media-scrim: linear-gradient(
    180deg,
    color-mix(in srgb, var(--lib-color-surface) 60%, transparent) 0%,
    color-mix(in srgb, var(--lib-color-surface) 50%, transparent) 45%,
    color-mix(in srgb, var(--lib-color-surface) 55%, transparent) 100%
  );
  --lib-gradient-service-hero: linear-gradient(135deg, var(--lib-color-deep), var(--lib-color-primary-strong));
  --lib-gradient-post-media: linear-gradient(135deg, color-mix(in srgb, var(--lib-color-primary) 82%, black), var(--lib-color-accent));
  --lib-gradient-preview-menu: linear-gradient(
    180deg,
    color-mix(in srgb, var(--lib-color-deep) 72%, transparent) 0%,
    color-mix(in srgb, var(--lib-color-deep) 88%, transparent) 100%
  );

  /* Section-treatment patterns (PAT-006–PAT-015): decorative dividers and
     background treatments for breaking up runs of flat, same-surface
     sections without a solid color-block change. */
  --lib-treatment-wave-height: 4.5rem;
  --lib-treatment-diagonal-height: 5rem;
  --lib-treatment-diagonal-angle: 40%;
  /* Center Peak / Triangle Rise divider (.lib-diagonal-cut--peak, Track
     12, 2026-09-04): the triangle's base sits 55% down the box, so the
     peak rises through the top 55% of --lib-treatment-diagonal-height. */
  --lib-treatment-peak-base: 55%;
  --lib-treatment-glow-size-lg: 24rem;
  --lib-treatment-glow-size-sm: 18rem;
  --lib-treatment-glow-opacity: 0.5;
  --lib-treatment-node-size-sm: 8px;
  --lib-treatment-node-size-lg: 12px;
  --lib-treatment-node-field-opacity: 0.6;
  --lib-treatment-node-marker-opacity: 0.6;
  --lib-treatment-node-line-opacity: 0.55;
  --lib-treatment-node-line-thickness: 1.5px;
  --lib-treatment-ghost-number-size: 22rem;
  --lib-treatment-ghost-number-stroke: 1.5px;
  --lib-treatment-ghost-number-mix: 10%;
  --lib-treatment-frame-inset: 1rem;
  --lib-treatment-frame-mark-size: 1.5rem;
  --lib-treatment-frame-mark-thickness: 2px;
  --lib-treatment-aurora-blur: 30px;
  --lib-treatment-aurora-opacity: 0.85;
  --lib-treatment-aurora-cycle: 16s;
  --lib-treatment-glass-blur: 18px;
  --lib-treatment-glass-radius: 1.25rem;
  --lib-treatment-glass-overlap: 3rem;
  --lib-treatment-holo-thickness: 3px;
  /* Cross-cutting Motion Governance foundation (2026-08-27): was 6s --
     a real, shipped, undetected violation of the continuous-cycle
     budget (motion-rules.yaml, min_cycle_ms: 12000) that predated any
     gate able to see it (holo-edge.css was never in runtime_sources,
     and this token's own resolved value was never cross-checked
     against the budget even once added -- see
     scripts/qa-motion.js's new validateContinuousCycleTokens()).
     Sequence followed per this pass's own directive: (1) register
     Holo Edge + wire the token-resolution gate, (2) confirm the gate
     reports the real 6000ms violation (scripts/tests/
     motion-governance-escape-path.test.js), (3) only then raise this
     value to the real governed minimum -- not the other way around. */
  --lib-treatment-holo-cycle: 12s;
  --lib-treatment-bento-radius: 1rem;

  /* Dot Grid (PAT-018, Phase 6B.3P prototype). Dot size/spacing and the
     base/sweep intensity mix percentages reuse HH Digital Studio's own
     real, shipped production values (hero-ent__grid) exactly -- real
     design decisions, not invented. --lib-treatment-dot-grid-cycle is
     the one real, deliberate departure from that evidence: HHDS's own
     shipped value was a literal 4s, which would be a real, undetected
     violation of the same governed continuous-cycle budget (12000-
     30000ms) Holo Edge's own cycle was already raised to satisfy --
     raised here from the start, not shipped-then-fixed. */
  --lib-treatment-dot-grid-dot-size: 2px;
  --lib-treatment-dot-grid-spacing: 56px;
  --lib-treatment-dot-grid-base-mix: 20%;
  --lib-treatment-dot-grid-sweep-mix: 70%;
  --lib-treatment-dot-grid-opacity: 0.55;
  --lib-treatment-dot-grid-cycle: 14s;

  /* Grain Texture (PAT-019, Phase 6B.3P prototype). A real, minimal
     SVG feTurbulence noise filter, monochrome (feColorMatrix
     saturate:0) so it reads as neutral grain regardless of the
     section's own real background hue -- deliberately not a
     brand-color token, grain is a texture, not an accent color.
     Opacity kept inside the real, evidenced 5-15% range research
     confirmed as "subtle" (see the pattern's own README). */
  --lib-grain-texture-svg: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22220%22%20height%3D%22220%22%3E%3Cfilter%20id%3D%22n%22%3E%3CfeTurbulence%20type%3D%22fractalNoise%22%20baseFrequency%3D%220.85%22%20numOctaves%3D%222%22%20stitchTiles%3D%22stitch%22%20result%3D%22t%22%2F%3E%3CfeColorMatrix%20in%3D%22t%22%20type%3D%22saturate%22%20values%3D%220%22%2F%3E%3C%2Ffilter%3E%3Crect%20width%3D%22100%25%22%20height%3D%22100%25%22%20filter%3D%22url%28%23n%29%22%2F%3E%3C%2Fsvg%3E");
  --lib-treatment-grain-tile-size: 220px;
  /* Human review correction, 2026-09-04: 0.06 (the low end of the real
     5-15% "subtle" research range) rendered as effectively invisible in
     review -- not a rendering bug (the technique itself is real and
     verified), a genuine evaluability problem. Raised to 0.13, still
     inside the same real evidenced range, near its upper end rather
     than its floor, so light-canvas surfaces (the lowest-contrast real
     case for this technique) stay genuinely distinguishable, confirmed
     via direct screenshot comparison, not assumed. */
  --lib-treatment-grain-opacity: 0.13;

  /* Particle Field (PAT-020, Phase 6B.3P prototype, CONTEXTUAL
     CANDIDATE). Real evidence: Michelle's Nails Service's own
     production two-layer star field (see the pattern's own README and
     MODERN_ATMOSPHERE_DISCOVERY.md Part 16). Both cycles set inside the
     governed continuous-cycle budget (12000-30000ms) from the start --
     a real, deliberate design choice, not a violation-then-fix. */
  --lib-treatment-particle-tile-size: 120px;
  --lib-treatment-particle-field-opacity: 0.6;
  --lib-treatment-particle-drift-cycle: 24s;
  --lib-treatment-particle-shooting-opacity: 0.9;
  --lib-treatment-particle-shoot-cycle: 18s;
  /* 8 real, varied-size white dots (mask alpha) -- the same real
     mask-image + background-color technique wave-divider.css/
     organic-blob.css already use, so --lib-particle-field-color is a
     real, themeable token (not a fixed hue baked into the SVG, unlike
     Michelle's own real, shipped brand-pink-only version). */
  --lib-particle-field-tile-svg: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22120%22%20height%3D%22120%22%3E%3Ccircle%20cx%3D%2215%22%20cy%3D%2220%22%20r%3D%221.4%22%20fill%3D%22white%22%2F%3E%3Ccircle%20cx%3D%2255%22%20cy%3D%2210%22%20r%3D%220.8%22%20fill%3D%22white%22%2F%3E%3Ccircle%20cx%3D%2290%22%20cy%3D%2235%22%20r%3D%221.1%22%20fill%3D%22white%22%2F%3E%3Ccircle%20cx%3D%2230%22%20cy%3D%2260%22%20r%3D%220.9%22%20fill%3D%22white%22%2F%3E%3Ccircle%20cx%3D%2270%22%20cy%3D%2275%22%20r%3D%221.6%22%20fill%3D%22white%22%2F%3E%3Ccircle%20cx%3D%22105%22%20cy%3D%2295%22%20r%3D%220.7%22%20fill%3D%22white%22%2F%3E%3Ccircle%20cx%3D%2245%22%20cy%3D%22105%22%20r%3D%221.2%22%20fill%3D%22white%22%2F%3E%3Ccircle%20cx%3D%2210%22%20cy%3D%2285%22%20r%3D%220.6%22%20fill%3D%22white%22%2F%3E%3C%2Fsvg%3E");
  /* Human review correction round 3, 2026-09-05: the shooting layer used
     to be ONE linear-gradient band spanning the full field -- read as a
     single horizontal/vertical sweep, not "some points brighter than
     others" (the real evidenced quality -- Michelle's Nails Service's
     own real production ran 3 independent traveling spotlights, not a
     single band; see particle-field.css/README.md). Real architecture
     constraint unchanged (still exactly 2 governed continuous layers,
     no third animation): this tile bakes 3 soft, independently-placed
     spotlight zones into ONE mask image, tiled and repeated across the
     whole field -- when the tile drifts (same single animation as
     before), many spotlights appear scattered across different real
     sparkles at different positions simultaneously, not one line
     sweeping through. Soft radial-gradient falloff (not a hard circle)
     keeps it elegant, not "cheap glitter". */
  --lib-particle-field-shooting-tile-svg: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22300%22%20height%3D%22300%22%3E%3Cdefs%3E%3CradialGradient%20id%3D%22g%22%20cx%3D%2250%25%22%20cy%3D%2250%25%22%20r%3D%2250%25%22%3E%3Cstop%20offset%3D%220%25%22%20stop-color%3D%22white%22%20stop-opacity%3D%221%22%2F%3E%3Cstop%20offset%3D%2245%25%22%20stop-color%3D%22white%22%20stop-opacity%3D%221%22%2F%3E%3Cstop%20offset%3D%22100%25%22%20stop-color%3D%22white%22%20stop-opacity%3D%220%22%2F%3E%3C%2FradialGradient%3E%3C%2Fdefs%3E%3Ccircle%20cx%3D%2260%22%20cy%3D%2290%22%20r%3D%2255%22%20fill%3D%22url%28%23g%29%22%2F%3E%3Ccircle%20cx%3D%22230%22%20cy%3D%2270%22%20r%3D%2245%22%20fill%3D%22url%28%23g%29%22%2F%3E%3Ccircle%20cx%3D%22150%22%20cy%3D%22230%22%20r%3D%2260%22%20fill%3D%22url%28%23g%29%22%2F%3E%3C%2Fsvg%3E");
  --lib-treatment-particle-shooting-tile-size: 300px;

  /* ── Layer 3 semantic tokens (Token Contract V1 + Accessibility
     Migration gate, 2026-09-06) ──────────────────────────────────────
     Real, defined, consumable aliases over the existing 13-color/2-font
     contract above -- addressable by real semantic role (what a token
     MEANS: "the page background", "text that sits on top of primary")
     instead of only by the library's own internal color name. Additive
     and non-breaking: every one of the 1,326 existing real
     `var(--lib-color-*)` call sites across core/components/sections/
     patterns is completely untouched by this block, so nothing already
     shipped changes behavior. This IS the real Layer 3 -- it is not yet
     the primary consumption path for existing canonical components,
     which is a separate, larger, dedicated migration (per-component
     visual regression, out of this pass's scope) -- disclosed as such
     in this gate's own console report, not silently claimed complete.
     New component work can and should consume these directly. */
  --lib-surface-page: var(--lib-color-surface);
  --lib-surface-section: var(--lib-color-panel-soft);
  --lib-surface-card: var(--lib-color-surface-card);
  --lib-surface-elevated: var(--lib-color-panel);

  --lib-text-primary: var(--lib-color-ink);
  --lib-text-secondary: var(--lib-color-muted);
  --lib-text-muted: var(--lib-color-subtle);

  /* text-on-primary/-secondary/-accent are NOT a flat var() alias --
     which real color passes 4.5:1 depends on the actual brand values in
     play (a light brand accent needs dark text, a dark one needs light
     text). scripts/lib/brand-derive.js's deriveTextOn() is the real,
     tested, WCAG-AA-verified computation (scripts/tests/
     brand-derive.test.js) -- these three fall back to the library's own
     real default (--lib-color-inverse, i.e. white), which is correct
     for the library's own default primary/accent, but a real per-brand
     adoption MUST override these three with its own computed result,
     never trust the fallback blindly for an arbitrary brand color. */
  --lib-text-on-primary: var(--lib-color-inverse);
  --lib-text-on-secondary: var(--lib-color-ink);
  --lib-text-on-accent: var(--lib-color-inverse);

  --lib-action-primary-bg: var(--lib-color-primary);
  --lib-action-primary-text: var(--lib-text-on-primary);
  --lib-action-primary-hover: var(--lib-color-primary-strong);

  --lib-border-default: var(--lib-color-border);
  --lib-border-strong: var(--lib-color-border-card-hover);

  --lib-focus-ring: var(--lib-color-primary);

  /* ── Color Role Contract (Color Role + Production Token Cutover Gate,
     2026-09-06) ────────────────────────────────────────────────────────
     Real, brand-SPECIFIC semantic roles -- deliberately separate from
     the neutral UI roles above (Section 3's own "NO asumir" list: a
     component's default surface/text/border must never silently become
     brand-colored). A component only reaches into these when its own
     function is intentionally branded (a CTA, a highlighted word, a
     branded badge). Values here are the library's own real DEFAULT
     (un-adopted) identity; scripts/lib/brand-derive.js's
     `semanticRoles`/`variants` output is the real, per-brand, contrast-
     checked replacement a project's generated tokens.css overrides these
     with -- same names, same real derivation, never a second set of
     rules (scripts/tests/brand-derive.test.js asserts every name below
     has a real counterpart there). The library has no native "secondary"
     brand color of its own (a pre-existing, real fact -- only primary/
     accent predate this gate); secondary-role defaults here fall back to
     the closest existing real token until a project supplies its own. */
  --lib-text-brand: var(--lib-color-primary);
  --lib-icon-brand: var(--lib-color-primary);
  --lib-border-brand: var(--lib-color-primary);
  /* Surface of the trust band attached to a hero (brand-owned). */
  --lib-trust-strip-hero-bg: color-mix(in srgb, var(--lib-border-brand) 46%, transparent);
  --lib-trust-strip-hero-icon: var(--lib-icon-brand);
  /* Button contract (brand-owned, 2026-10-14). Every library button
     (.lib-button, .hhds-button) reads its shape and type from these with
     the library's own look as the fallback, so they are NOT declared here
     (declaring them would change nothing and hide the fallback):
       --lib-button-radius, -padding-y, -padding-x, -mobile-padding-y,
       -mobile-padding-x, -border-width, -gap, -icon-size, -font-family,
       -font-size, -font-weight, -line-height, -letter-spacing, -text-transform,
       -hover-transform, -primary-bg, -primary-bg-hover, -primary-border,
       -primary-border-hover, -primary-shadow, -primary-color.
     The hero's own action over its photo: --lib-hero-action-bg, -bg-hover,
     -border, -border-hover, -border-width, -color, -font-weight, -shadow,
     -shadow-hover, -backdrop. Hero measure: --lib-hero-content-align, --lib-hero-content-max,
     --lib-hero-summary-max, --lib-hero-title-size; hero title type:
     --lib-hero-title-style, -weight, -line-height, -letter-spacing,
     -word-spacing, -transform. A brand maps them to its
     own button family instead of inheriting the library's pill. */
  --lib-action-primary-active: var(--lib-color-primary-strong);

  --lib-surface-brand-secondary: var(--lib-color-panel-soft);
  --lib-surface-brand-secondary-soft: color-mix(in srgb, var(--lib-color-panel-soft) 14%, white);
  --lib-action-secondary-bg: var(--lib-color-accent);
  --lib-action-secondary-hover: color-mix(in srgb, var(--lib-color-accent) 88%, black);
  --lib-action-secondary-text: var(--lib-color-inverse);
  --lib-icon-secondary: var(--lib-color-accent);
  --lib-text-secondary-brand: var(--lib-color-ink);

  --lib-text-accent: var(--lib-color-accent);
  --lib-icon-accent: var(--lib-color-accent);
  --lib-border-accent: var(--lib-color-accent);
  --lib-badge-accent: var(--lib-color-accent);
  --lib-eyebrow-accent: var(--lib-color-accent);
  --lib-highlight-accent: var(--lib-color-accent);

  --lib-surface-brand-primary: var(--lib-color-primary);
  --lib-surface-brand-primary-soft: color-mix(in srgb, var(--lib-color-primary) 14%, white);
  --lib-surface-brand-accent: var(--lib-color-accent);
  --lib-surface-brand-accent-soft: color-mix(in srgb, var(--lib-color-accent) 14%, white);

  /* ── Typography Contract (Color Role + Production Token Cutover Gate,
     2026-09-06, Section 15) ────────────────────────────────────────────
     Real project input stays exactly --lib-font-body/--lib-font-heading
     (unchanged, already the real contract). These are the real semantic
     ROLES and TYPE SCALE this gate asks for, named with the library's
     own real --lib- prefix (never a bare --font-*/--type-* name, which
     would collide with a real host theme's own tokens on a live
     WordPress page -- the same reason every other token in this file
     carries that prefix). Mapped onto the library's own EXISTING real
     font-size scale wherever a real equivalent already exists (added
     2026-01 through 2026-08, confirmed by grep before adding a single
     new value) -- --lib-type-display-xl/-lg are the only two genuinely
     new sizes, since no existing token represented a page-hero-scale
     display size. Additive only: zero existing component/section
     changed to consume these yet (same disclosed, deliberate scope
     boundary as the color Layer 3 above). */
  --lib-font-role-heading: var(--lib-font-heading);
  --lib-font-role-body-copy: var(--lib-font-body);
  --lib-font-role-ui: var(--lib-font-body);
  --lib-font-role-label: var(--lib-font-body);

  --lib-type-display-xl: clamp(2.5rem, 6vw, 4.5rem);
  --lib-type-display-lg: clamp(2.25rem, 5vw, 3.5rem);
  --lib-type-heading-1: var(--lib-font-size-title-lg);
  --lib-type-heading-2: var(--lib-font-size-title-md);
  --lib-type-heading-3: var(--lib-font-size-title-sm);
  --lib-type-body-lg: var(--lib-font-size-body-lg);
  --lib-type-body-md: var(--lib-font-size-base);
  --lib-type-body-sm: var(--lib-font-size-body-sm);
  --lib-type-label: var(--lib-font-size-small);
  --lib-type-caption: var(--lib-font-size-caption);
}
