/* Semantic alias layer — maps OKLCH ladder steps + literal foundations onto
 * v4-canonical semantic roles. Consumed by components.css and any external
 * consumer of the runtime CSS contract.
 *
 * AUTHORED, not generated (v1). Future work: the OKLCH token generator
 * (scripts/generate-tokens.ts) could emit this from brand/profile.json once
 * the semantic-alias schema lands in the brand profile. For now the mappings
 * here are the v4 Button Catalog reference canonical bindings.
 *
 * Layer order: load AFTER tokens.generated.css (the OKLCH ladders) and
 * BEFORE primitives.css + components.css.
 */

:root {
  /* ── Radii ──────────────────────────────────────────────────────────── */
  /* v4 reference colors_and_type.css §Radii. Used by Button + Tile shape
     selectors (rectangular = --radius-sm; pill stays 9999px literal). */
  --event-calendar-control-size: 2.5rem;
  --event-calendar-day-min-block-size: 5.25rem;
  --event-calendar-marker-size: 0.25rem;
  --event-calendar-measure: 70rem;
  --event-calendar-panel-inline-size: 23rem;
  --event-calendar-tl-time-size: 3.5rem;
  --event-calendar-add-size: 3rem;
  /* v5 (ADR 153) — masthead band shared by the month header and the reader
     dateline so the reader separator lands on the dow-row line by construction;
     tracks the variant's numeral size. add-size-lg is the taller footer action
     when the day is empty (primary). */
  --event-calendar-masthead-block-size: calc(var(--event-calendar-numeral-size) * var(--lh-tight));
  --event-calendar-add-size-lg: var(--ctrl-block-h-xl);
  /* v5 variants (ADR 154) — default type scale (re-pointed per [data-variant])
     and per-variant geometry. */
  --event-calendar-month-size: var(--text-4xl);
  --event-calendar-numeral-size: var(--text-5xl);
  --event-calendar-measure-compact: 22rem;
  --event-calendar-measure-full: 90rem;
  --event-calendar-day-block-compact: 3.5rem;
  --event-calendar-day-block-full: 6.5rem;
  --event-calendar-panel-inline-full: 27rem;
  /* Mobile bottom-sheet geometry (ADR 155). root = the sheet-mode card height;
     open-top = gap above the open sheet; peek = the collapsed sheet's visible lip. */
  --event-calendar-sheet-root: 38rem;
  --event-calendar-sheet-root-compact: 38rem;
  --event-calendar-sheet-open-top: 4.5rem;
  --event-calendar-sheet-peek: 7.5rem;

  /* golf-marker + golf-hole-sign component geometry (rescued, ADR 149/150) */
  --golf-hole-sign-badge-font-size: 5em;
  --golf-hole-sign-data-font-size: 0.25em;
  --golf-hole-sign-data-gap: 0.25em;
  --golf-hole-sign-enter-delay-data: 380ms;
  --golf-hole-sign-enter-delay-length: 420ms;
  --golf-hole-sign-enter-delay-number: 240ms;
  --golf-hole-sign-enter-duration: 600ms;
  --golf-hole-sign-enter-ease: cubic-bezier(0.25, 0.46, 0.45, 0.94);
  --golf-hole-sign-enter-translate: 40px;
  --golf-hole-sign-font-size: var(--text-md);
  --golf-hole-sign-font-size-lg: var(--text-lg);
  --golf-hole-sign-font-size-sm: var(--text-sm);
  --golf-hole-sign-font-var: var(--font-wght-barlow-regular);
  --golf-hole-sign-length-font-size: 1.5em;
  --golf-hole-sign-line-height: 1;
  --golf-hole-sign-par-font-size: 1.75em;
  --golf-hole-sign-tee-dot-font-size: 1.33em;
  --golf-hole-sign-tee-dot-gap: 0.33em;
  --golf-hole-sign-tee-dot-size: 0.5em;
  --golf-hole-sign-value-padding-inline: 0.066em;
  --golf-marker-min-inline-size: 3.25rem;
  --golf-marker-min-inline-size-sm: 2.5rem;
  --golf-marker-min-inline-size-lg: 4.25rem;
  --golf-marker-fairway-min-inline-size: 2.75rem;
  --golf-marker-rule-inline-size: min(15rem, 42vw);
  --golf-marker-unit-offset-block-end: 0.1em;
  /* corner-label — folded-corner flag geometry (compose the global scale) */
  --corner-label-size-sm: var(--space-6);  /* 32px triangle leg */
  --corner-label-size-md: var(--space-7);  /* 48px */
  --corner-label-size-lg: var(--space-8);  /* 64px */
  --corner-label-icon-sm: var(--text-sm);  /* 13px */
  --corner-label-icon-md: var(--text-md);  /* 16px */
  --corner-label-icon-lg: var(--text-lg);  /* 18px */
  --radius-none: 0;
  --radius-sm:   2px;   /* default for buttons / inputs / dense controls */
  --radius-md:   4px;   /* cards, panels, soft surfaces */
  --radius-lg:   8px;   /* hero containers, large cards */
  --radius-xl:   16px;  /* sheets, dialogs, attached-button container hosts */
  --radius-full: 9999px;

  /* Deprecated backwards-compat alias — legacy `--radius` (no suffix) points at -lg.
     New code must pick an explicit suffix. */
  --radius: var(--radius-lg);

  /* ── Keyboard inset (ADR-139) ───────────────────────────────────────── */
  /* --kb-inset: on-screen-keyboard overlap at the viewport bottom, px >= 0.
   * Native path resolves it here via env(); the polyfill (<KeyboardInset/>)
   * overrides with an inline value on :root. --kb-open: 0 | 1 (both paths). */
  --kb-inset: env(keyboard-inset-height, 0px);
  --kb-open: 0;

  /* ── Spacing (4-grid) ───────────────────────────────────────────────── */
  --space-0:  0;
  --space-1:  4px;
  --space-2:  8px;
  --space-3:  12px;
  --space-4:  16px;
  --space-5:  24px;
  --space-6:  32px;
  --space-7:  48px;
  --space-8:  64px;
  --space-9:  96px;
  --space-10: 128px;
  /* Marketing / expanded-surface stops from the brand spacing scale (added
     2026-05-19): value-named so they extend the ladder without renumbering the
     indexed --space-N stops that components already consume. */
  --space-56: 56px;
  --space-80: 80px;

  /* ── Breakpoints (canonical viewport/container boundaries) ──────────── */
  /* CSS custom properties cannot parametrize @media/@container conditions,
     so these tokens are the *documented source of truth*: every width-based
     @media/@container in the runtime CSS must use one of these literal
     values (min-width: N) or the band edge below it (max-width: N - 1).
     Enforced by scripts/check-breakpoints.sh. Rationale + per-breakpoint
     layout guidance: ui/07-responsive-rulecards.md. */
  --bp-sm:  390px;   /* supported floor — no horizontal scroll above this */
  --bp-md:  768px;   /* tablet — multi-column form/page layouts switch on */
  --bp-lg:  960px;   /* desktop — docs shells, rails, two-up grids */
  --bp-xl:  1200px;  /* wide — persistent side rails, pattern shell */
  --bp-max: 1584px;  /* content cap — nothing scales past this */

  /* ── Foundational composition geometry ─────────────────────────────── */
  /* Page and FormLayout switch intrinsically from their own available
     inline size. These aliases make the layout intent explicit without
     changing the global breakpoint or relational spacing scales. */
  --page-measure-wide: 70rem;
  --page-split-aside-min: 17.5rem;
  --page-sidebar-min: 13.75rem;
  --page-layout-threshold: var(--bp-md);
  /* Page gap ladder, per density — ADR 155 amendment 3. Each density is its own
     four-rung ladder (heading / content / body / region) and every adjacent rung
     is exactly 2x the rung below it. Density scales the family PROPORTIONALLY;
     it never remaps one rung onto a raw step that collapses the ratio, which is
     what produced the three defects this replaces: compact region 16 == body 16,
     expanded content 16 == body 16, and gigantic body 16 -> content 24 = 1.5x,
     inside the ambiguity band amendment 2 rejected. Asserted by
     scripts/check-relational-ladder.sh.

       compact / unattributed    4 /  8 / 16 / 32
       comfortable               4 /  8 / 16 / 32
       expanded                  8 / 16 / 32 / 64
       gigantic                 12 / 24 / 48 / 96

     Compact declares the unattributed values on purpose. primitives.css already
     declares `:root, [data-density="compact"]` as one block — the app-root
     default IS compact — so a page ladder tighter than the unattributed one
     would put compact below the baseline it is defined to equal. The ladder is
     therefore expressed upward, on expanded and gigantic. */
  --page-heading-gap-compact: var(--space-1);
  --page-content-gap-compact: var(--space-2);
  --page-region-gap-compact: var(--space-6);
  --page-heading-gap-comfortable: var(--space-1);
  --page-content-gap-comfortable: var(--space-2);
  --page-region-gap-comfortable: var(--space-6);
  --page-heading-gap-expanded: var(--space-2);
  --page-content-gap-expanded: var(--space-4);
  --page-body-gap-expanded: var(--space-6);
  --page-region-gap-expanded: var(--space-8);
  --page-heading-gap-gigantic: var(--space-3);
  --page-content-gap-gigantic: var(--space-5);
  --page-body-gap-gigantic: var(--space-7);
  --page-region-gap-gigantic: var(--space-9);

  /* ── Aspect ratios ──────────────────────────────────────────────────── */
  /* Numeric primitives describe the exact geometry; semantic aliases map
     product/role intent; component aliases keep backward-compatible names.
     Consumers (AspectRatio presets, Tile data-ratio) must read these instead
     of inlining literals. Custom CSS ratio strings remain the escape hatch. */
  --ratio-1x1:  1 / 1;
  --ratio-3x4:  3 / 4;
  --ratio-4x3:  4 / 3;
  --ratio-16x9: 16 / 9;
  --ratio-21x9: 21 / 9;
  --ratio-5x1:  5 / 1;

  --ratio-square:    var(--ratio-1x1);
  --ratio-portrait:  var(--ratio-3x4);
  --ratio-standard:  var(--ratio-4x3);
  --ratio-video:     var(--ratio-16x9);
  --ratio-ultrawide: var(--ratio-21x9);
  --ratio-wordmark:  var(--ratio-5x1);

  --ratio-aspect-ratio-default: var(--ratio-video);   /* AspectRatio default preset */
  --ratio-tile-wide:            var(--ratio-video);    /* Tile data-ratio="wide" (16/9) */
  --ratio-tile-standard:        var(--ratio-standard); /* Tile data-ratio="standard" (4/3) */

  /* ── Vertical stack roles ─────────────────────────────────────────────── */
  /* The ONLY legal gaps between stacked text/content. Pick by RELATIONSHIP,
     not by component — see the decision table in DESIGN.md. Component gap
     tokens may exist for readability, but they must alias a role, never a
     length: `--tc-stack-gap: var(--stack-gap-related)` yes, `14px` no.
     Enforced by stylelint and scripts/check-stack-gaps.sh. */
  --stack-gap-micro:   2px;            /* value ↔ unit, digit ↔ caption — fused pairs.
                                          A literal because the 4-grid has no 2px step;
                                          do not invent a --space-0-5 primitive for it. */
  --stack-gap-heading: var(--space-1); /* eyebrow ↔ title ↔ description — one voice     */
  --stack-gap-content: var(--space-2); /* header block ↔ body/control — group boundary  */
  --stack-gap-related: var(--space-4); /* sibling items inside a block (fields, rows)   */
  --stack-gap-section: var(--space-6); /* between content blocks — hard boundary        */
  --stack-gap-major:   var(--space-8); /* between composed sections that each carry their
                                          own content boundary. The sixth rung exists because
                                          five rungs at a 2x floor support five nesting levels,
                                          and FormLayout nests six: heading 4 / fields 16 /
                                          heading-block-to-body 32 / section-to-section 64.
                                          See ADR 155 amendment 4 (DR-010).                  */

  /* ── Action groups (ui/08-action-rulecards.md, decision 132) ─────────── */
  /* Gaps and margins for commit clusters and action areas. Values mapped
     from the action spec by VALUE (8/16/48/32/24px), not by foreign index. */
  --action-gap:                  var(--space-2);   /* within the commit cluster */
  --action-subgroup-gap:         var(--space-4);   /* separated utility/danger zone */
  --action-area-margin:          var(--stack-gap-major); /* form content → action area.
                                    The actions row is a PEER of form sections, so it takes
                                    the section boundary. At --space-7 (48px) it sat under 2x
                                    the 32px heading-block-to-body boundary inside the section
                                    it follows — measured on /preview/form-layout. ADR 155 am.4. */
  --action-area-margin-dense:    var(--space-6);
  --action-area-margin-compact:  var(--space-5);
  --action-bar-full-bleed-safe-area-padding-block-end: env(safe-area-inset-bottom, 0px);

  /* ── Field widths (ui/06-form-rulecards.md UI-FORM-016, decision 133) ── */
  /* Semantic widths express expected data length (postal=short, email=long). */
  --field-w-short:  8rem;
  --field-w-medium: 16rem;
  --field-w-long:   24rem;
  --field-w-full:   100%;

  --search-box-inline-size: 28rem;
  --search-box-panel-max-block-size: 22rem;

  /* -- Spacing geometry aliases --------------------------------------- */
  /* Component-scoped aliases that preserve existing geometry while removing
     raw spacing/layout literals from runtime component CSS. These names are
     intentionally tied to the owning surface or component role rather than
     to numeric values, so future value changes remain centralized here. */
  --alert-close-optical-margin: -2px -2px 0 0;
  --badge-gap: 6px;
  --button-gap: 8px;
  --button-group-padding: 3px;
  --button-group-sm-hit-target-outset-block: -4px;
  --button-icon-leading-nudge-inline: -2px;
  --button-icon-trailing-nudge-inline: -2px;
  --button-sm-hit-target-outset: -4px;
  --drag-handle-hit-target-outset: -6px; /* expands the 32px drag handle to the 44px touch floor */
  --scroll-affordance-border-inset: 1px; /* tracks the scroll viewport's hairline border so edge fades stop short of it and never tint the border line */
  --scroll-affordance-extent: var(--space-6); /* how far a scroll-edge fade reaches into the viewport */
  --selection-hit-target-outset: calc((var(--ctrl-block-h-md) - 18px) / -2); /* touch hit area expands compact selection marks to the md control target */
  --editable-text-size-coarse: var(--text-md); /* prevents viewport zoom while preserving desktop density */
  --calendar-grid-gap: 2px;
  --calendar-cell-size-sm: 2rem;
  --calendar-cell-size-md: 2.25rem;
  --calendar-cell-size-lg: 2.625rem;
  --calendar-panel-inline-size: 18.25rem;
  --calendar-panel-padding-block: calc(var(--space-6) + var(--space-1));
  --calendar-panel-padding-inline: calc(var(--space-4) + var(--space-1));
  --calendar-caption-control-size: 2.75rem;
  --calendar-range-months-gap: var(--space-5);
  --date-picker-popover-gap: var(--space-3);
  --date-picker-popover-max-inline-size: calc(100vw - var(--space-4));
  --date-picker-popover-max-block-size: calc(100vh - var(--space-4));
  --date-picker-time-border: var(--border-subtle);
  --date-picker-time-padding-block-start: var(--space-3);
  --date-picker-time-grid-gap: var(--space-3);
  --date-picker-time-label-gap: var(--space-2);
  --card-demo-media-min-block-size: 7rem;
  --card-measure: 28rem;
  --catalog-example-viewport-min-block-size: 6rem;
  --chart-gap: 2px;
  --checkbox-content-gap: 3px;
  --checkbox-gap: 12px;
  --checkbox-group-gap: 8px;
  --checkbox-group-horizontal-gap: 12px 24px;
  --checkbox-group-items-gap: 8px;
  --checkbox-group-items-margin-block-start: var(--tabs-pill-bg-top);
  --checkbox-min-block-size: 24px;
  --component-view-workbench-copy-measure: 66ch;
  --component-view-workbench-link-min-block-size: 2.75rem;
  --container-measure-lg: 72rem;
  --container-measure-md: 56rem;
  --container-measure-sm: 40rem;
  --container-measure-xl: 88rem;
  /* Brand-source compatibility aliases used by promoted site chrome. */
  --container-sm: var(--container-measure-sm);
  --container-xl: var(--container-measure-xl);
  --clay-700: var(--clay-11);
  --data-table-page-size-min-inline-size: 5rem;
  /* The skeleton bar is the body cell's text line box, so a loading row is
     exactly as tall as the row it stands in for and content lands without a
     jump. A generic 1em bar is shorter than the line box it replaces. */
  --data-table-skeleton-block-size: calc(var(--text-sm) * var(--lh-snug));
  --date-picker-range-arrow-pill-size: 2.25rem;
  --date-picker-range-months-gap: 1px;
  --date-picker-range-times-gap: 1px;
  --dialog-content-gap: 16px;
  --dialog-footer-gap: 8px;
  --chart-term-gap: 2px;
  --docs-search-dropdown-max-block-size: 22rem;
  --docs-header-search-max-inline-size: 22rem;
  --docs-shell-inline-size: min(100%, 1280px);
  --drawer-content-gap: 16px;
  --empty-state-description-measure: 30rem;
  --empty-state-measure: 34rem;
  --error-summary-padding: 20px 24px;
  --error-summary-title-margin: 0 0 8px;
  --field-min-inline-size: 140px;
  --field-required-gap: var(--calendar-grid-gap);
  --hole-chart-legend-gap: 10px;
  --input-icon-interactive-edge-offset: 4px;
  --kbd-min-inline-size: 1.75rem;
  --kbd-padding: 0.125rem 0.45rem;
  --kbd-sm-min-inline-size: 1.5rem;
  --kbd-sm-padding: 0.0625rem 0.375rem;
  --marquee-wrap-gap: 8px;
  --dialog-header-gap: 6px;
  --marquee-tile-compact-gap: 6px;
  --measure-prose: 65ch;
  --menu-list-gap: 2px;
  --motion-table-min-inline-size: 48rem;
  --oklch-picker-controls-gap: 4px;
  --oklch-picker-fields-gap: 8px;
  --oklch-picker-fixed-gap: 8px;
  --oklch-picker-fixed-option-gap: 8px;
  --oklch-picker-fixed-option-padding: 8px 10px;
  --oklch-picker-gap: 12px;
  --oklch-picker-header-gap: 12px;
  --oklch-picker-title-gap: 4px;
  --oklch-picker-value-row-gap: 4px;
  --pattern-controls-copy-gap: 2px;
  --pattern-controls-ui-min-inline-size: min(32rem, 100%);
  --pattern-family-rail-min-block-size: 2.75rem;
  --pattern-grid-min-block-size: 18rem;
  --pattern-index-status-min-block-size: 2.75rem;
  --page-transition-demo-copy-measure: 42rem;
  --page-transition-demo-min-block-size: 22rem;
  --pattern-presets-padding: 2px;
  --pattern-search-input-min-block-size: 2.75rem;
  --preloader-block-size: 4px;
  --preloader-inline-size: min(100%, 28.75rem);
  --preloader-three-d-stage-inline-size: min(clamp(13.75rem, 60vw, 28.75rem), 86vw);
  --preview-hero-copy-measure: 76ch;
  --preview-matrix-cell-preview-min-block-size: 4rem;
  --preview-matrix-controls-min-inline-size: 16rem;
  --preview-matrix-header-inner-measure: 80rem;
  --preview-matrix-subheader-measure: 80rem;
  --preview-section-header-measure: 82ch;
  --preview-shell-inline-size: min(100%, 1280px);
  --split-button-menu-item-gap: 1px;
  --split-button-menu-min-inline-size: 13.75rem;
  --progress-circular-lg-size: 72px;
  --progress-circular-md-size: 56px;
  --progress-circular-sm-size: 40px;
  --progress-lg-block-size: 8px;
  --progress-measure: 28rem;
  --progress-sm-block-size: 4px;
  --progress-track-block-size: 6px;
  --radio-card-min-block-size: 64px;
  --radio-card-padding: 0 24px;
  --radio-card-sm-padding-inline: 18px;
  --resizable-panel-min-block-size: 8.75rem;
  --resizable-panel-min-inline-size: 13.75rem;
  --radio-gap: 12px;
  --radio-content-gap: 3px;
  --radio-group-card-gap: 10px;
  --range-column-gap: 12px;
  --radio-group-gap: var(--dialog-footer-gap);
  --radio-group-items-gap: var(--marquee-wrap-gap);
  --radio-min-block-size: 24px;
  --range-tooltip-bottom: calc(100% + 10px);
  --range-tooltip-padding: 3px 8px;
  --select-clear-indicator-padding: 0 4px;
  --select-count-font-size: var(--text-xs);
  --select-group-heading-padding: 8px 12px 4px;
  --select-indicators-padding-inline: 2px var(--space-4);
  --select-menu-list-padding: 4px 4px;
  --select-multi-value-gap: 4px;
  --select-multi-value-padding: 2px 4px 2px 8px;
  --select-no-options-padding: 10px 12px;
  --select-option-padding: 8px 12px;
  --signature-line-inset-block-end: 34px;
  --sr-only-offset: -1px;
  --sr-only-size: 1px;
  --statistic-value-row-gap: 0.14em;
  --stepper-padding-block-end: 2px;
  --switch-content-gap: 3px;
  --switch-control-padding-inline: 3px;
  --switch-gap: 12px;
  --switch-min-block-size: 24px;
  --switch-thumb-left: 3px;
  --system-hero-copy-measure: 78ch;
  --system-mermaid-caption-caption-measure: 82ch;
  --system-mermaid-frame-min-block-size: 18rem;
  --system-mermaid-frame-min-block-size-expanded: 22rem;
  --system-mermaid-svg-min-inline-size: min(52rem, 100%);
  --system-shell-inline-size: min(100%, 1280px);
  --tab-padding: 10px 16px;
  --tab-pill-padding: 0 14px;
  --tabs-indicator-bottom: -1px;
  --tabs-pill-bg-bottom: 4px;
  --tabs-pill-bg-top: 4px;
  --tabs-pill-bottom: 5px;
  --tabs-pill-sm-bg-bottom: 3px;
  --tabs-pill-gap: 2px;
  --tabs-pill-lg-bg-top: 4px;
  --tabs-pill-lg-gap: 2px;
  --docs-brand-gap: 2px;
  --tabs-pill-padding: 4px;
  --tabs-pill-sm-tab-padding: 0 10px;
  --tabs-pill-lg-tab-padding: 0 18px;
  --tabs-pill-sm-padding: 3px;
  --tabs-pill-lg-padding: 5px;
  --tabs-pill-top: 5px;
  --tabs-pill-sm-bg-top: 3px;
  --theme-band-inner-measure: 72rem;
  --tile-wide-lg-gap: 14px;
  --time-picker-meridiem-min-inline-size: 2.5rem;
  --time-picker-step-block-size: 1.25rem;
  --time-picker-step-inline-size: 1.5rem;
  --time-picker-value-inline-size: 2.25ch;
  --tournament-card-measure-lg: 40rem;
  --tournament-card-measure-md: 34rem;
  --tournament-card-measure-sm: 28rem;
  --tournament-card-qr-min-inline-size: 7rem;
  --tournament-card-qr-size: 6rem;
  --toast-margin: 3px 0 0;
  --tooltip-content-padding: 6px 10px;
  --tournament-card-measure-sm: 28rem;
  --tournament-card-measure-md: 34rem;
  --tournament-card-measure-lg: 40rem;
  --tournament-card-qr-min-inline-size: 7rem;
  --tournament-card-qr-size: 6rem;
  --typography-code-01-padding: 2px 6px;
  --viewport-block-full: 100vh;
  --viewport-block-full-dynamic: 100dvh;
  /* Runtime keyboard inset published by KeyboardInset; native resolves env(), polyfill overrides inline. */
  --kb-inset: env(keyboard-inset-height, 0px);
  --kb-open: 0;
  --visual-drift-proposal-copy-p-measure: 72ch;
  --visual-drift-review-copy-measure: 82ch;
  --visual-drift-screenshot-bar-block-size: 8px;
  --visual-drift-screenshot-bar-inline-size: 1.75rem;
  --visual-drift-screenshot-chrome-gap: 6px;
  --visual-drift-screenshot-chrome-span-block-size: 8px;
  --visual-drift-screenshot-chrome-span-inline-size: 8px;
  --visual-drift-screenshot-row-data-tone-after-visu-after-inline-size: 2.5rem;
  --visual-drift-screenshot-row-min-block-size: 2.5rem;
  --weather-strip-divider-inset-comfortable: 45px;
  --weather-strip-divider-inset-compact: 32px;
  --weather-tile-gap: 0.55em;

  /* ── Type scale (modular: minor third for body, 1.33 for display) ───── */
  --text-2xs:  11px;   /* micro — badges, markers, kbd */
  --text-xs:   12px;
  --text-sm:   13px;   /* button sm font-size */
  --text-base: 15px;   /* body default; a hair smaller for density */
  --text-md:   16px;
  --text-lg:   18px;
  --text-xl:   22px;
  --text-2xl:  28px;
  --text-3xl:  36px;
  --text-4xl:  48px;
  --text-5xl:  64px;
  --text-6xl:  88px;

  /* ── Fluid display sizes (ADR 140) ──────────────────────────────────────
     Display/hero roles only. The core --text-* steps above stay fixed; these
     two fluid aliases let display-01/02 scale between a mobile-safe floor and
     the fixed step as ceiling, so a hero title does not overflow a ~390px
     viewport (display-01 is otherwise a flat 88px at every width). The rem
     floors keep the minimum honouring user zoom (WCAG 1.4.4); the vw term
     drives the curve; the --text-6xl/5xl step is the ceiling. Body, controls,
     headings, and spacing stay fixed — adaptive sizing is owned by the
     discrete density modes, not the viewport. */
  --text-display-1: clamp(2.5rem, 7vw, var(--text-6xl));  /* 40px floor → 88px ceiling */
  --text-display-2: clamp(2rem, 5vw, var(--text-5xl));    /* 32px floor → 64px ceiling */

  /* ── Type families ──────────────────────────────────────────────────── */
  --font-sans:    "Silka", "Silka Fallback", "Barlow", system-ui, -apple-system, "Segoe UI", Helvetica, Arial, sans-serif;
  --font-ui:      var(--nxt-barlow-family, "Barlow"), "Silka", system-ui, sans-serif;
  --font-display: "Nextcaddy Clear", "Nextcaddy Clear Fallback", "Silka", Georgia, serif;
  --font-serif:   "Nextcaddy Clear", "Nextcaddy Clear Fallback", Georgia, "Times New Roman", serif;
  /* Editorial display family (self-hosted via fonts.generated.css). Exposed as a
     token so the brand's "editorial display-only" family is reachable through the
     token API instead of being loaded but unreferenced. */
  --font-editorial: "Cormorant Garamond", Georgia, serif;
  --font-mono:    "JetBrains Mono", ui-monospace, "SF Mono", Menlo, Consolas, monospace;

  /* Backwards-compat alias — legacy `--font-sans-stack` and `--font-mono-stack`
     point at the canonical names. */
  --font-sans-stack: var(--font-sans);
  --font-mono-stack: var(--font-mono);

  /* ── Barlow GX weight channel (ADR 137, BRAND-TYPE-001/002) ─────────────
     Barlow GX is variable with wght 22–188 (≡ CSS 100–900) and wdth 300–500.
     The @font-face declares `font-weight: 22 188`, so CSS font-weight ≥ 200
     clamps to 188 (max boldness). Never apply font-weight to Barlow text —
     consume these tokens via font-variation-settings. Each token emits BOTH
     axes: an fvs declaration that omits wdth resets it to its default.
     Scale anchored at the brand-standard regular = 90, step 21 (the linear
     slope of the 100–900 → 22–188 mapping). */
  --font-wdth-barlow: 426;            /* brand standard width */
  --font-wght-barlow-light:    "wght" 63,  "wdth" var(--font-wdth-barlow);
  --font-wght-barlow-regular:  "wght" 90,  "wdth" var(--font-wdth-barlow);
  --font-wght-barlow-medium:   "wght" 111, "wdth" var(--font-wdth-barlow);
  --font-wght-barlow-semibold: "wght" 132, "wdth" var(--font-wdth-barlow);
  --font-wght-barlow-bold:     "wght" 153, "wdth" var(--font-wdth-barlow);

  /* Component-tuned Barlow display values (ADR 137 legacy retirement, DENSITY v3 C2).
     Values copied verbatim from the component blocks; do not re-tune here. */
  --font-var-weather-temp:    "wght" 108, "wdth" 457;
  --font-var-weather-range:   "wght" 111, "wdth" 457;
  --font-var-weather-min:     "wght" 111, "wdth" 457;
  --font-var-datetile-label:  "wght" 50, "wdth" 426;
  --font-var-datetile-day:    "wght" 100, "wdth" 426;
  --font-var-time-readout:    "wght" 100, "wdth" 426;
  --font-var-datepicker-summary: "wght" 70, "wdth" 426;  /* 64px range-summary day numeral (datepicker v3) */
  --font-var-time-ghost:      "wght" 40, "wdth" 426;     /* 15px spinner ghost neighbors (datepicker v3) */
  --font-var-time-colon:      "wght" 60, "wdth" 426;     /* 32px spinner colon (datepicker v3) */

  /* ── Type weights ───────────────────────────────────────────────────── */
  --weight-light:    300;
  --weight-regular:  400;
  --weight-medium:   500;
  --weight-semibold: 600;
  --weight-bold:     700;

  /* ── Line heights ───────────────────────────────────────────────────── */
  --lh-none:    1;      /* single-line UI labels — tabs, menu items, ticks, chips */
  --lh-display: 0.9;    /* digit-only readouts (Barlow) — clock, date tile, weather */
  --lh-tight:   1.05;
  --lh-snug:    1.2;
  --lh-heading: 1.3;    /* multi-line titles — fills the 1.2 -> 1.45 gap */
  --lh-normal:  1.45;
  --lh-relaxed: 1.6;

  /* ── Tracking ───────────────────────────────────────────────────────── */
  --track-tight:  -0.02em;
  --track-snug:   -0.01em;
  --track-normal: 0;
  --track-wide:   0.04em;
  --track-caps:   0.08em;
  --track-caps-x: 0.10em;  /* tile labels */

  /* ── Motion — easings (Apple-style spring approximations) ───────────── */
  --ease-smooth: cubic-bezier(0.32, 0.72, 0, 1);    /* default UI */
  --ease-snap:   cubic-bezier(0.2,  0,    0.38, 0.9); /* snap-on hover bg / state flips */
  --ease-snappy: cubic-bezier(0.2,  0.9,  0.1,  1);  /* menus, chevrons (slightly slower than snap) */
  --ease-bouncy: cubic-bezier(0.5,  1.6,  0.4,  1);  /* toggles, sheets */
  --ease-enter:  cubic-bezier(0.16, 1,    0.3,  1);  /* content entering */
  --ease-exit:   cubic-bezier(0.7,  0,    0.84, 0);  /* content leaving */

  /* Legacy aliases (kept for existing components) */
  --ease-standard:   var(--ease-smooth);
  --ease-emphasized: var(--ease-enter);
  --ease-decelerate: var(--ease-enter);
  --ease-accelerate: var(--ease-exit);
  --ease-spring:     var(--ease-bouncy);
  --ease-out:        var(--ease-smooth);
  --ease-in-out:     var(--ease-smooth);

  /* ── Motion — durations (Apple's tight ladder + snap) ───────────────── */
  --dur-snap:       70ms;   /* hover bg flips, small state changes — instant-feel */
  --dur-instant:    100ms;
  --dur-fast:       200ms;
  --dur-quick:      250ms;
  --dur-base:       350ms;
  --dur-moderate:   450ms;
  --dur-slow:       550ms;
  --dur-deliberate: 750ms;

  /* ── Motion — component roles ──────────────────────────────────────────
     Indicator travel: the single highlight (pill / underline) that slides to
     the active sibling. One language shared by Tabs, Menu, and any future
     selection surface so the gesture feels identical everywhere. */
  --motion-indicator-duration: var(--dur-quick);   /* 250ms */
  --motion-indicator-ease:     var(--ease-smooth); /* cubic-bezier(0.32,0.72,0,1) */

  /* Selection indicators are the painted active mark; motion tokens above
     govern travel, these aliases govern colour, shape, and elevation. */
  --selection-indicator-duration: var(--motion-indicator-duration);
  --selection-indicator-ease:     var(--motion-indicator-ease);
  --selection-indicator-bg:       var(--neutral-fill);
  --selection-indicator-muted-bg: var(--neutral-soft-bg);
  --selection-indicator-surface:  var(--bg-canvas);
  --selection-indicator-border:   var(--border-subtle);
  --selection-indicator-radius:   var(--radius-sm);
  --selection-indicator-shadow:   var(--elevation-raised);

  /* Elevation roles: semantic shadow tiers consumed through app/src/lib/elevation.ts. */
  --shadow-color: 30 10% 15%;
  --elevation-flat: none;
  --elevation-raised: 0px 0.5px 0.6px hsl(var(--shadow-color) / 0.07), 0px 1px 1.1px -1.8px hsl(var(--shadow-color) / 0.06);
  --elevation-elevated: 0px 0.5px 0.6px hsl(var(--shadow-color) / 0.05), 0px 1.5px 1.7px -0.9px hsl(var(--shadow-color) / 0.05), 0px 3.4px 3.8px -1.8px hsl(var(--shadow-color) / 0.05);
  --elevation-floating: 0px 0.5px 0.6px hsl(var(--shadow-color) / 0.04), 0px 2px 2.3px -0.6px hsl(var(--shadow-color) / 0.04), 0px 4.3px 4.8px -1.2px hsl(var(--shadow-color) / 0.04), 0px 9.1px 10.2px -1.8px hsl(var(--shadow-color) / 0.04);
  --elevation-overlay: 0px 0.5px 0.6px hsl(var(--shadow-color) / 0.04), 0px 3.2px 3.6px -0.4px hsl(var(--shadow-color) / 0.04), 0px 6px 6.8px -0.8px hsl(var(--shadow-color) / 0.04), 0px 9.9px 11.1px -1.2px hsl(var(--shadow-color) / 0.04), 0px 15.8px 17.8px -1.5px hsl(var(--shadow-color) / 0.04), 0px 24.7px 27.8px -1.8px hsl(var(--shadow-color) / 0.04);
  --elevation-modal: 0px 0.5px 0.6px hsl(var(--shadow-color) / 0.04), 0px 5px 5.6px -0.3px hsl(var(--shadow-color) / 0.04), 0px 9.1px 10.2px -0.6px hsl(var(--shadow-color) / 0.04), 0px 13.9px 15.6px -0.9px hsl(var(--shadow-color) / 0.04), 0px 20.5px 23.1px -1.2px hsl(var(--shadow-color) / 0.04), 0px 30.4px 34.2px -1.5px hsl(var(--shadow-color) / 0.04), 0px 44.3px 49.8px -1.8px hsl(var(--shadow-color) / 0.04);

  /* Chart entrance + donut interaction. Bars/segments grow once from rest on
     --ease-enter with per-index stagger; donut hover re-weights on --ease-smooth.
     Durations resolve through the brand --dur-* ladder (nearest rung) so chart
     motion honours prefers-reduced-motion + brand calibration like every other
     component. The per-index stagger/delay offsets below are entrance
     choreography, not durations, so they stay as literal ms (no ladder rung). */
  --motion-chart-bar-duration:           var(--dur-slow);       /* growBar / growUp (was 600ms) */
  --motion-chart-seg-duration:           var(--dur-deliberate); /* donut drawSeg (was 760ms) */
  --motion-chart-label-duration:         var(--dur-moderate);   /* bar labels slideFadeIn (was 400ms) */
  --motion-chart-center-duration:        var(--dur-moderate);   /* donut center value + eyebrow (was 480ms) */
  --motion-chart-legend-duration:        var(--dur-base);       /* donut legend rows (was 380ms) */
  --motion-chart-ease:                   var(--ease-enter);
  --motion-chart-hover-stroke-duration:  var(--dur-fast);      /* segment grow on hover (was 220ms) */
  --motion-chart-hover-opacity-duration: var(--dur-fast);      /* sibling dim (was 200ms) */
  --motion-chart-hover-row-duration:     var(--dur-fast);      /* legend row tint/dim (was 180ms) */
  --motion-chart-hover-ease:             var(--ease-smooth);
  --motion-chart-stagger-bar:            100ms;
  --motion-chart-stagger-seg:            110ms;
  --motion-chart-stagger-legend:          70ms;
  --motion-chart-delay-bar:              200ms;
  --motion-chart-delay-label:            100ms;
  --motion-chart-delay-seg:              140ms;
  --motion-chart-delay-center:           560ms;
  --motion-chart-delay-eyebrow:          660ms;
  --motion-chart-delay-legend:           340ms;

  /* ── Color — semantic surface (light mode resolves via OKLCH inversion) */
  --bg-canvas:  var(--neutral-1);     /* page background */
  --bg-surface: var(--neutral-1);     /* default card / panel */
  --bg-raised:  var(--neutral-1);     /* modal / elevated surface */
  --bg-sunken:  var(--neutral-2);     /* inset / muted surface */
  --bg-inverse: var(--neutral-12);    /* dark-on-light surface */

  /* ── Color — semantic foreground ───────────────────────────────────── */
  --fg-primary:    var(--neutral-12); /* body text, headings */
  --fg-secondary:  var(--neutral-11); /* secondary text */
  --fg-tertiary:   var(--neutral-9);  /* muted text, captions */
  --fg-muted:      var(--neutral-7);  /* placeholder, hint text */
  --fg-inverse:    var(--neutral-1);  /* text on dark-fill */
  --fg-on-accent:  var(--neutral-12); /* text on lime fill — dark, not white */
  /* Reduced-emphasis content / hairline overlay on an inverse (dark) surface.
   * Derived from --fg-inverse so they track the theme; used by tournament-card
   * (date label + mobile-bold progress track) where the DS has no alpha-inverse. */
  --fg-on-inverse-muted: color-mix(in oklch, var(--fg-inverse) 82%, transparent);
  --overlay-on-inverse:  color-mix(in oklch, var(--fg-inverse) 15%, transparent);

  /* eyebrow role — single quiet sentence-case voice (matches card eyebrow).
     Hierarchy comes from ink, not from uppercase ornament. The mono/caps/tracked
     treatment is NOT this role: it stays reserved for data-grid labels (calendar
     weekdays, table headers), which are not eyebrows. */
  --eyebrow-font: var(--font-sans);
  --eyebrow-size: var(--text-sm);
  --eyebrow-weight: var(--weight-medium);
  --eyebrow-tracking: var(--track-normal);
  --eyebrow-fg: var(--fg-tertiary);

  /* ── Color — semantic border ───────────────────────────────────────── */
  --border-subtle:  var(--neutral-3); /* hairline divider, card border */
  --border-default: var(--neutral-5); /* default control border */
  --border-strong:  var(--neutral-11);/* emphasized border, outline emphasis button */
  --border-width-strong: 1.5px; /* reinforced control and state border */

  /* ── Color — accent (lime, accent-1 family) ─────────────────────────── */
  /* THE LIME FIX: --accent points at step-3 (electric lime, oklch(0.91 0.2 119))
     not step-9 (olive). The OKLCH generator places step-9 mid-darkness which
     is correct for peri/danger but wrong for accent-1 (lime's brand peak sits
     at L≈0.91 with high chroma). */
  --accent:           var(--accent-1-3);  /* electric lime — primary brand fill */
  --accent-hover:     var(--accent-1-4);  /* slightly darker bright lime */
  --accent-press:     var(--accent-1-5);  /* deeper still */
  --accent-soft-bg:   var(--accent-1-2);  /* very light lime tint — soft emphasis bg */
  --accent-soft-fg:   var(--accent-1-11); /* leaf — text on soft */
  --accent-fg:        var(--neutral-12);  /* DARK text on lime fill */
  --accent-bold-bg:   var(--accent-1-9);  /* dark lime in light / bright lime in dark — bold/inverted card fill */
  --accent-outline:   var(--accent-1-11); /* leaf — outline emphasis border + text */

  /* ── Color — secondary accent (peri / accent-2) ────────────────────── */
  --secondary:          var(--accent-2-9);   /* periwinkle */
  --secondary-hover:    var(--accent-2-10);
  --secondary-press:    var(--accent-2-11);
  --secondary-soft-bg:  var(--accent-2-2);
  --secondary-soft-fg:  var(--accent-2-12);
  --secondary-fg:       var(--neutral-1);    /* white text on peri */
  --secondary-outline:  var(--accent-2-9);

  /* ── Color — status (danger / semantic-error) ──────────────────────── */
  --danger:          var(--semantic-error-9);
  --danger-hover:    var(--semantic-error-10);
  --danger-press:    var(--semantic-error-11);
  --danger-soft-bg:  var(--semantic-error-2);
  --danger-soft-fg:  var(--semantic-error-11);
  --danger-fg:       var(--neutral-1);
  --danger-outline:  var(--semantic-error-9);

  /* ── Color — focus ring (intentionally tied to peri-mid) ───────────── */
  /* The focus ring color is the same across every intent and emphasis;
     this is the v4 reference convention. Bound to accent-2-7 raw because
     no semantic alias would name it more clearly. */
  --focus-ring: var(--accent-2-7);
  /* Atomic geometry for the doubled accessibility ring and shared cursor.
     These are focus roles, not spacing or border aliases: changing either
     intentionally affects the measured 2px gap + 2px indicator stroke. */
  --focus-ring-width: 2px;
  --focus-ring-gap: 2px;
  --focus-ring-shadow: 0 0 0 3px var(--focus-ring);
  --focus-ring-gap-color: var(--bg-canvas);
  --focus-ring-shadow-gap:
    0 0 0 var(--focus-ring-gap) var(--focus-ring-gap-color, var(--bg-canvas)),
    0 0 0 calc(var(--focus-ring-gap) + var(--focus-ring-width)) var(--focus-ring);

  /* ── Color — neutral fill (Button intent=neutral solid) ────────────── */
  --neutral-fill:      var(--neutral-12); /* near-black solid CTA */
  --neutral-fill-fg:   var(--neutral-1);
  --neutral-fill-hover:var(--neutral-11);
  --neutral-soft-bg:   var(--neutral-3);
  --neutral-soft-fg:   var(--neutral-11);
  --pressed-soft-bg:   var(--neutral-4); /* one step past --neutral-soft-bg for press feedback */

  /* Repeated element roles from the visual-drift review. These are recipes
     for shared parts, not public component APIs. */
  --control-frame-border-width: 1px;
  --control-frame-radius:       var(--radius-sm);
  --control-frame-focus-shadow: var(--focus-ring-shadow-gap);
  --control-frame-disabled-opacity: 0.38;
  --control-frame-muted-fill:       var(--neutral-7);
  --control-frame-muted-hover-fill: var(--neutral-8);

  --nav-item-block-size:     var(--ctrl-block-h-sm);
  --nav-item-padding-inline: var(--space-3);
  --nav-item-gap:            var(--space-2);
  --nav-item-radius:         var(--radius-sm);
  --nav-item-fg:             var(--fg-secondary);
  --nav-item-fg-hover:       var(--fg-primary);
  --nav-item-fg-active:      var(--neutral-fill-fg);
  --nav-item-bg-hover:       var(--neutral-soft-bg);
  --nav-item-bg-active:      var(--neutral-fill);
  --nav-item-focus-shadow:   var(--focus-ring-shadow-gap);

  --surface-frame-bg:           var(--bg-surface);
  --surface-frame-fg:           var(--fg-primary);
  --surface-frame-muted-bg:     var(--bg-sunken);
  --surface-frame-border:       var(--border-default);
  --surface-frame-border-hover: var(--border-strong);
  --surface-frame-radius:       var(--radius-sm);
  --surface-frame-padding:      var(--space-4);
  --surface-frame-gap:          var(--space-4);
  --surface-frame-title-gap:    var(--space-2);
  --surface-frame-shadow:       none;
  --shadow-md:                  var(--elevation-floating);
  --surface-frame-focus-shadow: var(--focus-ring-shadow-gap);
  --surface-frame-media-radius: calc(var(--surface-frame-radius) - 2px);

  /* Avatar surface: distinct from page canvas, more visible than --neutral-soft-bg
   * (which is too close to bg-canvas for a circular sleeve to read at 24-72px sizes).
   * Maps to neutral-4 for ~12% lightness drop from canvas in light mode — clearly
   * distinct without dominating the initials. Dark mode inverts automatically via
   * the OKLCH ladder (neutral-4 becomes the corresponding dark step). */
  --avatar-bg:         var(--neutral-4);
  --avatar-fg:         var(--neutral-12);

  /* Media edge outline: pure black/white only, never tinted neutrals. */
  --image-outline: 1px solid rgba(0, 0, 0, 0.10);

  /* ── Color — status (warning + success + info) ──────────────────────── */
  /* Bound to their own mode-aware ladders (semantic-success = green hue 130,
     semantic-warning = amber hue 80) so success / warning / accent read as
     three distinct intents instead of collapsing to lime. Mirrors the danger
     mapping onto semantic-error; soft pairs use step-2 bg / step-11 fg. */
  --warning:         var(--semantic-warning-9);  /* amber fill — warning emphasis */
  --warning-fg:      var(--neutral-1);
  --warning-soft-bg: var(--semantic-warning-2);
  --warning-soft-fg: var(--semantic-warning-11);
  --success:         var(--semantic-success-9);  /* green fill — success emphasis */
  --success-fg:      var(--neutral-1);
  --success-soft-bg: var(--semantic-success-2);
  --success-soft-fg: var(--semantic-success-11);
  --info:            var(--accent-2-9);          /* peri family */
  --info-fg:         var(--neutral-1);
  --info-soft-bg:    var(--accent-2-2);
  --info-soft-fg:    var(--accent-2-12);

  /* ── Color — domain · golf ──────────────────────────────────────────────
     Golf-domain semantic palettes ported from the brand color reference
     (brand/reference-materials/domain-golf-color-png.md; source values in
     _incoming "domain colors.zip"). These are FIXED brand foundations, not
     theme-studio re-skinnable aliases — every swatch is a contrast-tuned
     bg/fg pair drawn from golf scoring/marker convention, so they carry
     literal oklch values rather than mapping onto the OKLCH ladders. The
     `golf` prefix groups them as a domain namespace alongside the generic
     semantic roles above and is exempted as a foundation prefix in
     check-theme-studio-token-parity.sh. Contrast ratios noted per pair are
     from the source (AA = 4.5:1 normal / 3:1 large; AAA = 7:1).

     Score + Strokes are theme-independent (identical in light/dark); only
     Tees re-tune for dark mode (overrides in the dark block below).

     ── Score comparison — bright result chips (under / par / over par) ──── */
  --golf-score-par-bg:   oklch(100% 0 0);             /* #FFFFFF */
  --golf-score-par-fg:   oklch(58.77% 0.140 146.7);   /* #389247 — 3.91:1 large */
  --golf-score-under-bg: var(--golf-strokes-inv-birdie-bg); /* white-over-red inverted birdie */
  --golf-score-under-fg: var(--golf-strokes-inv-birdie-fg); /* 3.24:1, large text only */
  --golf-score-over-bg:  oklch(75.96% 0.135 242.7);   /* #5ABAFF */
  --golf-score-over-fg:  oklch(25.00% 0.030 256.27);  /* #182230 — 7.54:1 AAA */

  /* Score comparison · Partial (in-progress) — under/over take the light
     birdie/bogey scheme so a running total reads softer than a final result. */
  --golf-score-partial-par-bg:   var(--golf-score-par-bg);
  --golf-score-partial-par-fg:   var(--golf-score-par-fg);     /* green on white, 3.91 large */
  --golf-score-partial-under-bg: var(--golf-strokes-birdie-bg);
  --golf-score-partial-under-fg: var(--golf-strokes-birdie-fg); /* red on white, 4.60 AA */
  --golf-score-partial-over-bg:  var(--golf-strokes-bogey-bg);
  --golf-score-partial-over-fg:  var(--golf-strokes-bogey-fg);  /* blue on white, 4.60 AA */

  /* Strokes — light bg + coloured text, harmonised at 4.60:1 AA (eagle →
     birdie → par → bogey → double bogey). */
  --golf-strokes-eagle-bg:        oklch(93.00% 0.170 101.5);  /* #FFEB4E */
  --golf-strokes-eagle-fg:        oklch(51.75% 0.106 87.0);   /* #826301 — 4.60:1 AA */
  --golf-strokes-birdie-bg:       oklch(100% 0 0);            /* #FFFFFF */
  --golf-strokes-birdie-fg:       oklch(59.24% 0.240 24.9);   /* #EB0028 — 4.60:1 AA */
  --golf-strokes-par-bg:          oklch(100% 0 0);            /* #FFFFFF */
  --golf-strokes-par-fg:          oklch(54.59% 0.164 146.7);  /* #00882D — 4.60:1 AA */
  --golf-strokes-bogey-bg:        oklch(100% 0 0);            /* #FFFFFF */
  --golf-strokes-bogey-fg:        oklch(56.69% 0.187 255.3);  /* #0374E1 — 4.60:1 AA */
  --golf-strokes-double-bogey-bg: oklch(98% 0 0);             /* #F8F8F8 */
  --golf-strokes-double-bogey-fg: oklch(13.00% 0 0);          /* #070707 — 18.99:1 AAA anchor */

  /* Strokes · inverted — solid colour + near-white text (vivid). Eagle + par
     reuse their light versions; birdie/bogey are deliberately contrast-
     sacrificed for the vivid inverted look (large text only). */
  --golf-strokes-inv-eagle-bg:        var(--golf-strokes-eagle-bg);
  --golf-strokes-inv-eagle-fg:        var(--golf-strokes-eagle-fg);  /* 4.60:1 AA */
  --golf-strokes-inv-par-bg:          var(--golf-strokes-par-bg);
  --golf-strokes-inv-par-fg:          var(--golf-strokes-par-fg);    /* 3.91:1 large */
  --golf-strokes-inv-birdie-bg:       oklch(65.72% 0.207 24.9);      /* #F64C4C */
  --golf-strokes-inv-birdie-fg:       oklch(98% 0.014 24.9);         /* near-white — 3.24:1 large only */
  --golf-strokes-inv-bogey-bg:        var(--golf-score-over-bg);     /* #5ABAFF */
  --golf-strokes-inv-bogey-fg:        oklch(98% 0.014 242.7);        /* near-white — 2.00:1, decorative */
  --golf-strokes-inv-double-bogey-bg: oklch(54.90% 0 0);            /* #717171 */
  --golf-strokes-inv-double-bogey-fg: oklch(98% 0 0);               /* #F8F8F8 — 4.60:1 AA */

  /* Tees (light) — 9 golf tee-marker categories, keyed by the brand Spanish
     colour codes: BL blanco/white · AM amarillo/yellow · DO dorado/gold ·
     NA naranja/orange · RO rojo/red · RS rosa/pink · AZ azul/blue ·
     VE verde/green · NE negro/black. Each pairs a marker bg with an AA/AAA
     text fg. Dark-mode bg/fg re-tunes live in the dark block below. */
  --golf-tee-bl-bg: oklch(100.00% 0 0);
  --golf-tee-bl-fg: oklch(13.00% 0 0);          /* 20.12:1 AAA */
  --golf-tee-am-bg: oklch(92.75% 0.170 101.6);
  --golf-tee-am-fg: oklch(13.00% 0.040 101.6);  /* 16.39:1 AAA */
  --golf-tee-do-bg: oklch(84.17% 0.171 90.7);
  --golf-tee-do-fg: oklch(13.00% 0.040 90.7);   /* 12.33:1 AAA */
  --golf-tee-na-bg: oklch(75.72% 0.167 55.0);
  --golf-tee-na-fg: oklch(13.00% 0.040 55.0);   /* 8.87:1 AAA */
  --golf-tee-ro-bg: oklch(65.72% 0.207 24.9);
  --golf-tee-ro-fg: oklch(13.00% 0.040 24.9);   /* 5.83:1 AA */
  --golf-tee-rs-bg: oklch(76.64% 0.184 341.8);
  --golf-tee-rs-fg: oklch(13.00% 0.040 341.8);  /* 8.84:1 AAA */
  --golf-tee-az-bg: oklch(75.96% 0.135 242.7);
  --golf-tee-az-fg: oklch(13.00% 0.040 242.7);  /* 9.46:1 AAA */
  --golf-tee-ve-bg: oklch(72.67% 0.176 146.6);
  --golf-tee-ve-fg: oklch(13.00% 0.040 146.6);  /* 8.84:1 AAA */
  --golf-tee-ne-bg: oklch(0.00% 0 0);
  --golf-tee-ne-fg: oklch(98.50% 0 0);          /* 20.11:1 AAA */

  /* ── Overlays — Dialog / Popover / Tooltip surfaces ─────────────────────
   * Overlay panels sit on top of the page; the scrim dims the underlying
   * canvas. Border + radius are uniform across overlay types so a Dialog,
   * Popover, and Tooltip read as the same surface family. */
  --overlay-bg:      var(--bg-raised);
  --overlay-fg:      var(--fg-primary);
  --overlay-border:  var(--border-subtle);
  --overlay-radius:  8px;
  --overlay-scrim:   color-mix(in oklch, var(--neutral-12) 55%, transparent);
  /* Overlay-family exceptions: curated stacks for transient surfaces whose
   * perceived depth intentionally differs from the canonical elevation rungs. */
  --overlay-shadow:  var(--elevation-overlay);
  --tooltip-shadow:  var(--elevation-elevated);
  --overlay-panel-bg:      var(--overlay-bg);
  --overlay-panel-fg:      var(--overlay-fg);
  --overlay-panel-border:  var(--overlay-border);
  --overlay-panel-radius:  var(--overlay-radius);
  --overlay-panel-shadow:  var(--overlay-shadow);
  --overlay-panel-padding: var(--space-4);
  --z-overlay:             50;
  --z-overlay-panel:       51;
  --z-tooltip:             60;
  /* Dialog and drawer now share the same overlay-panel surface recipe. Scrim
   * stays a modal-specific backdrop token because anchored overlays have none. */
  --dialog-radius:   var(--overlay-panel-radius);
  --dialog-shadow:   var(--elevation-modal);
  --dialog-scrim:    color-mix(in oklch, var(--neutral-12) 28%, transparent);

  /* ── Form controls — input bg / border / fg ─────────────────────────── */
  --field-frame-bg:           var(--bg-surface);
  --field-frame-bg-disabled:  var(--bg-sunken);
  --field-frame-bg-readonly:  var(--bg-sunken);
  --field-frame-fg:           var(--fg-primary);
  --field-frame-fg-disabled:  var(--fg-muted);
  --field-frame-placeholder:  var(--fg-tertiary);
  --field-frame-border:           var(--control-frame-muted-fill);
  --field-frame-border-hover:     var(--border-strong);
  --field-frame-border-focus:     var(--neutral-fill); /* near-black focus border per neutral intent */
  --field-frame-border-invalid:   var(--danger);
  --field-frame-border-warning:   var(--warning);
  --field-frame-border-success:   var(--success);
  --field-frame-border-disabled:  var(--border-subtle);
  --field-frame-border-width:     var(--control-frame-border-width);
  --field-frame-radius:           var(--control-frame-radius);
  --field-frame-focus-shadow:     var(--control-frame-focus-shadow);

  --input-bg:           var(--field-frame-bg);
  --input-bg-disabled:  var(--field-frame-bg-disabled);
  --input-bg-readonly:  var(--field-frame-bg-readonly);
  --input-fg:           var(--field-frame-fg);
  --input-fg-disabled:  var(--field-frame-fg-disabled);
  --input-placeholder:  var(--field-frame-placeholder);

  --input-border:           var(--field-frame-border);
  --input-border-hover:     var(--field-frame-border-hover);
  --input-border-focus:     var(--field-frame-border-focus);
  --input-border-invalid:   var(--field-frame-border-invalid);
  --input-border-warning:   var(--field-frame-border-warning);
  --input-border-success:   var(--field-frame-border-success);
  --input-border-disabled:  var(--field-frame-border-disabled);
  --input-border-width:     var(--field-frame-border-width);

  /* Soft halo around inputs on focus-within. Derived from --input-border-focus
   * via color-mix so the alpha tracks the canonical token. Distinct from the
   * --focus-ring (doubled 2+4px outset ring) used by Button + Tile — inputs
   * use this softer 3px solid halo per the v4 reference. */
  --input-focus-ring:       var(--field-frame-focus-shadow);

  /* field inner rhythm — decoupled from button ctrl-inline-pad */
  --field-inline-pad-sm: var(--space-3);
  --field-inline-pad-md: var(--space-4);
  --field-inline-pad-lg: var(--space-5);

  /* ── Input affix slot (prefix / suffix wrappers around an input) ─────── */
  --input-affix-bg:         var(--bg-sunken);
  --input-affix-fg:         var(--fg-secondary);
  --input-affix-pad-x:      var(--space-3);

  /* ── Input icon (decorative or interactive icons inside an input) ────── */
  --input-icon-size:        16px;
  --input-icon-pad-extra:   24px;
  --input-icon-fg:          var(--fg-tertiary);
  --input-icon-fg-ok:       var(--success);
  --input-icon-fg-error:    var(--danger);

  /* ── Form fields — labels / descriptions / messages ─────────────────── */
  --field-label-fg:        var(--fg-primary);
  --field-label-required:  var(--danger);
  --field-description-fg:  var(--fg-secondary);
  --field-counter-fg:      var(--fg-tertiary);
  --field-counter-invalid: var(--danger);

  --field-message-error-fg:    var(--danger);
  --field-message-warning-fg:  var(--warning-soft-fg);
  --field-message-success-fg:  var(--success-soft-fg);
  --field-message-info-fg:     var(--info-soft-fg);

  /* ── Compatibility aliases — app and generated theme scopes ─────────── */
  --background:          var(--bg-canvas);
  --foreground:          var(--fg-primary);
  --primary:             var(--neutral-fill);
  --primary-foreground:  var(--neutral-fill-fg);
  --muted:               var(--neutral-soft-bg);
  --muted-foreground:    var(--fg-secondary);
  --border:              var(--border-default);
  --ring:                var(--focus-ring);

  /* T3 consistency remediation: component geometry tokens (cluster memos
     M-035..M-042; computed values preserved exactly). */
  --hairline-size: var(--control-frame-border-width); /* M-035 */
  --marquee-tile-icon-size: 20px; /* M-037 */
  --menu-item-icon-size: 16px; /* M-037 */
  --tabs-pill-icon-size-sm: 12px; /* M-037 */
  --tabs-pill-icon-size-md: 14px; /* M-037 */
  --tabs-pill-icon-size-lg: 16px; /* M-037 */
  --statistic-delta-icon-size: 12px; /* M-037 */
  --spinner-size-md: 20px; /* M-037 */
  --autocomplete-spinner-size: 14px; /* M-037 */
  --badge-dot-size: 6px; /* M-038 */
  --range-tick-size: 4px; /* M-038 */
  --time-marker-size: 8px; /* M-038 */
  --time-pivot-size: 10px; /* M-038 */
  --oklch-picker-fixed-swatch-size: 18px; /* M-038 */
  --oklch-picker-thumb-size: 18px; /* M-038 */
  --oklch-picker-swatch-block-size: 28px; /* M-038 */
  --select-swatch-size: 18px; /* M-038 */
  --select-count-block-size: 18px; /* M-038 */
  --stepper-marker-size: 28px; /* M-038 */
  --ctrl-hit-min-compact: 24px; /* M-039 */
  --toast-action-min-size: 32px; /* M-039 */
  --pagination-item-size-sm: 30px; /* M-039 */
  --select-multi-remove-size: 16px; /* M-039 */
  --input-otp-slot-block-size-sm: 40px; /* M-040 */
  --input-otp-slot-block-size-md: 48px; /* M-040 */
  --input-otp-slot-block-size-lg: 56px; /* M-040 */
  --tabs-pill-block-size-sm: 24px; /* M-040 */
  --tabs-pill-block-size-md: 28px; /* M-040 */
  --oklch-picker-plane-block-size: 112px; /* M-041 */
  --signature-stage-min-block-size: 132px; /* M-041 */
  --file-input-dropzone-min-block-size: 148px; /* M-041 */
  --weather-tile-solo-block-size-lg: 180px; /* M-041 */
  --tabs-indicator-thickness: 2px; /* M-042 */
}

/* The OKLCH ladder already inverts steps under [data-color-scheme="dark"] —
   so the semantic aliases above pick up the right values automatically. We
   only need to override aliases where the mapping itself differs by mode
   (none currently, but the block exists as the extension point). */
[data-color-scheme="dark"] {
  /* Dark surfaces separate through color and border, never depth shadows. */
  --elevation-flat: none;
  --elevation-raised: none;
  --elevation-elevated: none;
  --elevation-floating: none;
  --elevation-overlay: none;
  --elevation-modal: none;
  --selection-indicator-shadow: none;
  --overlay-shadow: none;
  --tooltip-shadow: none;
  --overlay-panel-shadow: none;
  --dialog-shadow: none;
  --shadow-md: none;

  --image-outline: 1px solid rgba(255, 255, 255, 0.10);

  /* Golf Tees — dark-theme re-tune (Score + Strokes are theme-independent and
     inherit their light values). Marker backgrounds drop in lightness while
     foregrounds keep the AA/AAA pairing noted per code. */
  --golf-tee-bl-bg: oklch(48.55% 0 0);
  --golf-tee-bl-fg: oklch(98.50% 0 0);          /* 6.12:1 AA */
  --golf-tee-am-bg: oklch(74.65% 0.135 101.4);
  --golf-tee-am-fg: oklch(13.00% 0.040 101.4);  /* 9.00:1 AAA */
  --golf-tee-do-bg: oklch(68.05% 0.138 91.1);
  --golf-tee-do-fg: oklch(13.00% 0.040 91.1);   /* 6.97:1 AA */
  --golf-tee-na-bg: oklch(61.18% 0.133 55.4);
  --golf-tee-na-fg: oklch(13.00% 0.040 55.4);   /* 5.14:1 AA */
  --golf-tee-ro-bg: oklch(53.15% 0.164 24.6);
  --golf-tee-ro-fg: oklch(98.50% 0.005 24.6);   /* 5.45:1 AA */
  --golf-tee-rs-bg: oklch(61.89% 0.146 341.5);
  --golf-tee-rs-fg: oklch(13.00% 0.040 341.5);  /* 5.12:1 AA */
  --golf-tee-az-bg: oklch(56.14% 0.110 243.4);
  --golf-tee-az-fg: oklch(13.00% 0.033 243.4);  /* 4.39:1 — large/bold only */
  --golf-tee-ve-bg: oklch(58.77% 0.140 146.7);
  --golf-tee-ve-fg: oklch(13.00% 0.040 146.7);  /* 5.12:1 AA */
  --golf-tee-ne-bg: oklch(0.00% 0 0);
  --golf-tee-ne-fg: oklch(98.50% 0 0);          /* 20.11:1 AAA */

}
