:root{
  --background:0 0% 100%; --foreground:222 47% 11%;
  --card:0 0% 100%; --card-foreground:222 47% 11%;
  --popover:0 0% 100%; --popover-foreground:222 47% 11%;
  --primary:243 75% 59%; --primary-foreground:0 0% 100%; --primary-ink:243 75% 47%;
  --secondary:222 18% 95%; --secondary-foreground:222 47% 11%;
  /* Secondary copy must also pass when it sits on muted or lightly tinted surfaces. The previous
     47% lightness passed on white (4.72:1) but fell below 4.5:1 on --muted and --primary/5. */
  --muted:210 40% 96%; --muted-foreground:215 16% 39%;
  /* AAA reading surface (AX §8.1): --reading-secondary is the canonical secondary-text token for core
     operator reading surfaces. Verified 2026-07-02 (WCAG relative luminance): light 215 16% 35% on
     white = 7.35 (the previous light --muted-foreground computed 4.72 — AA, not AAA); dark 215 20% 70% on
     222 47% 7% = 8.73 (dark --muted-foreground 215 20% 65% already computes 7.47). Gate-enforced ≥ 7:1. */
  --reading-secondary:215 16% 35%;
  --accent:210 40% 96%; --accent-foreground:222 47% 11%;
  --destructive:0 72% 51%; --destructive-foreground:0 0% 100%; --destructive-ink:0 72% 44%;
  /* On-color pairs verified 2026-07-02 (WCAG relative luminance): destructive+white 4.80 (pass);
     white on success was 2.30 and white on info 2.85 (both FAIL AA) — success/info now pair with the
     near-black foreground: success 7.79, info 6.28, warning 8.37 (all pass in both themes). */
  --success:142 71% 45%; --success-foreground:222 47% 11%; --success-ink:142 71% 27%;
  --warning:38 92% 50%; --warning-foreground:222 47% 11%; --warning-ink:38 92% 28%;
  --info:199 89% 48%; --info-foreground:222 47% 11%; --info-ink:199 89% 31%;
  --border:214 32% 91%; --input:214 32% 91%; --ring:239 84% 67%;
  /* Semantic tint triad (INTAKE-2026-019). A status banner, callout or soft badge needs a tinted
     ground, an edge, and text that works ON that tint — the -ink roles are tuned for near-white and
     near-black grounds, not tinted ones. Verified 2026-08-17 (WCAG relative luminance), on-surface
     against BOTH its tint and --background so a callout survives if the tint fails to paint:
     destructive 6.85/8.40 · success 6.58/7.19 · warning 6.44/7.16 · info 8.47/10.25 · primary 9.29/11.40.
     The -border roles are decorative separation, not component identification, so 1.4.11's 3:1 does
     not apply; they compute 1.21-1.52 on --background where the incumbent --border computes 1.24.
     Where a border is the SOLE state signal, use the fill or -ink role, which does meet contrast. */
  --destructive-surface:0 93% 94%; --destructive-border:0 93% 89%; --destructive-on-surface:0 70% 35%;
  --success-surface:141 84% 93%; --success-border:141 79% 85%; --success-on-surface:143 64% 24%;
  --warning-surface:48 96% 89%; --warning-border:45 93% 63%; --warning-on-surface:23 83% 31%;
  --info-surface:214 95% 93%; --info-border:213 97% 87%; --info-on-surface:224 64% 33%;
  --primary-surface:226 100% 94%; --primary-border:228 96% 89%; --primary-on-surface:244 47% 34%;
  --ai:262 83% 58%; --ai-foreground:0 0% 100%; --ai-ink:262 83% 45%;
  --suite:239 84% 67%; --suite-ink:239 84% 45%; /* default = HDPulseAI indigo */
  --radius:0.5rem; --control:2.75rem; --row-py:0.45rem;
  /* Semantic foundation scales. These roles are the cross-stack contract; components consume the role,
     not a one-off number. The JSON token source carries the same names for platform generation. */
  --space-1:0.25rem; --space-2:0.5rem; --space-3:0.75rem; --space-4:1rem;
  --space-5:1.25rem; --space-6:1.5rem; --space-8:2rem; --space-10:2.5rem; --space-12:3rem;
  --text-xs:0.75rem; --text-sm:0.875rem; --text-base:1rem; --text-lg:1.125rem;
  --text-xl:1.25rem; --text-2xl:1.5rem; --text-3xl:1.875rem;
  --leading-tight:1.25; --leading-normal:1.5; --leading-relaxed:1.625;
  --target-min:2.75rem; --content-reading:44rem; --content-wide:80rem;
  --layer-base:0; --layer-sticky:20; --layer-nav:30; --layer-overlay:50; --layer-toast:60;
  /* Fill/graphic tokens retain the family palette. Their paired -ink roles are for small text on
     background, card, muted, and 10-15% semantic tints; each pair is independently theme-safe. */
  --status-new:221 83% 53%; --status-new-ink:221 83% 42%;
  --status-open:262 83% 58%; --status-open-ink:262 83% 45%;
  --status-pending:38 92% 50%; --status-pending-ink:38 92% 28%;
  --status-resolved:142 71% 45%; --status-resolved-ink:142 71% 27%;
  --status-closed:215 16% 47%; --status-closed-ink:215 16% 35%;
  --priority-low:142 71% 45%; --priority-low-ink:142 71% 27%;
  --priority-medium:38 92% 50%; --priority-medium-ink:38 92% 28%;
  --priority-high:25 95% 53%; --priority-high-ink:25 95% 32%;
  --priority-urgent:0 72% 51%; --priority-urgent-ink:0 72% 44%;
  --sla-ok:142 71% 45%; --sla-warn:38 92% 50%; --sla-breach:0 72% 51%;
  --font-sans:Inter,-apple-system,'Segoe UI',Roboto,Helvetica,Arial,sans-serif;
  --font-mono:'JetBrains Mono','SFMono-Regular',Consolas,monospace;
  /* Motion tokens — the durations/easings tokens/tailwind.preset.ts + components/lib/motion.ts use,
     exposed here for vanilla apps. Entrances use ease-out; movement uses the emphasized curve. */
  --motion-duration-fast:120ms; --motion-duration-base:200ms; --motion-duration-slow:250ms;
  --motion-duration-pop:300ms; --motion-duration-draw:500ms; --motion-duration-sweep:700ms;
  --motion-ease-out:ease-out; --motion-ease-emphasized:cubic-bezier(.2,0,0,1);
  /* Elevation shadows — tokenized so the dark theme can override them (fixed light-theme shadow colors
     are near-invisible on dark backgrounds). Light values match the tokens/tailwind.preset.ts boxShadow
     fallbacks exactly. */
  --shadow-1:0 1px 2px 0 hsl(222 47% 11% / 0.06);
  --shadow-2:0 4px 12px -2px hsl(222 47% 11% / 0.10);
  --shadow-3:0 12px 32px -4px hsl(222 47% 11% / 0.16);
}
[data-theme="dark"],.dark{
  --background:222 47% 7%; --foreground:210 40% 96%;
  --card:222 44% 10%; --card-foreground:210 40% 96%;
  --popover:222 44% 10%; --popover-foreground:210 40% 96%;
  /* Dark indigo lifted 67%→71%: at 67% the pair failed AA with near-black (4.04) AND white (4.43);
     at 71% near-black on indigo is 4.96 (passes AA). Verified 2026-07-02. */
  --primary:239 84% 71%; --primary-foreground:222 47% 11%;
  --secondary:217 33% 17%; --secondary-foreground:210 40% 96%;
  --muted:217 33% 17%; --muted-foreground:215 20% 65%;
  --accent:217 33% 17%; --accent-foreground:210 40% 96%;
  --border:217 33% 20%; --input:217 33% 20%; --ring:239 84% 71%;
  --reading-secondary:215 20% 70%;
  --primary-ink:239 84% 76%; --suite-ink:239 84% 76%; --ai-ink:262 83% 76%;
  --destructive-ink:0 80% 72%; --success-ink:142 60% 64%;
  --warning-ink:38 92% 65%; --info-ink:199 85% 68%;
  /* Dark tint triad (INTAKE-2026-019): deep tinted grounds with -300-stop text. Verified 2026-08-17,
     on-surface against tint/--background: destructive 8.05/10.20 · success 8.03/12.65 ·
     warning 9.98/15.50 · info 7.65/10.64 · primary 8.32/9.99. Borders 1.90-3.79 on --background,
     against the incumbent dark --border at 1.43. */
  --destructive-surface:0 63% 18%; --destructive-border:0 74% 32%; --destructive-on-surface:0 94% 82%;
  --success-surface:144 61% 15%; --success-border:142 72% 29%; --success-on-surface:156 72% 67%;
  --warning-surface:28 73% 18%; --warning-border:36 84% 32%; --warning-on-surface:48 97% 77%;
  --info-surface:224 64% 23%; --info-border:221 70% 40%; --info-on-surface:213 97% 79%;
  --primary-surface:243 47% 20%; --primary-border:243 55% 41%; --primary-on-surface:239 84% 84%;
  --status-new-ink:221 83% 72%; --status-open-ink:262 83% 76%;
  --status-pending-ink:38 92% 65%; --status-resolved-ink:142 60% 64%;
  --status-closed-ink:215 20% 70%;
  --priority-low-ink:142 60% 64%; --priority-medium-ink:38 92% 65%;
  --priority-high-ink:25 95% 68%; --priority-urgent-ink:0 80% 72%;
  /* Dark-visible elevation: higher-opacity black keeps hover-lift perceptible on dark surfaces while
     staying calm/enterprise. Components already pair shadows with border-border, so no edge var needed. */
  --shadow-1:0 1px 2px 0 hsl(0 0% 0% / 0.45);
  --shadow-2:0 4px 12px -2px hsl(0 0% 0% / 0.55);
  --shadow-3:0 12px 32px -4px hsl(0 0% 0% / 0.65);
}
/* per-suite accent: flows into --primary / --ring / --suite */
[data-suite="ai"]{   --suite:262 83% 58%; --suite-ink:262 83% 45%; --primary:262 83% 58%; --primary-ink:262 83% 45%; --ring:262 83% 58%; }
[data-suite="comm"]{ --suite:221 83% 53%; --suite-ink:221 83% 42%; --primary:221 83% 53%; --primary-ink:221 83% 42%; --ring:221 83% 53%; }
/* HC teal: white on teal is only 3.65:1 (fails AA) — pair with the near-black foreground
   like WM: 4.91:1 in both themes. Verified 2026-07-02. */
[data-suite="hc"]{   --suite:175 84% 32%; --suite-ink:175 84% 24%; --primary:175 84% 32%; --primary-ink:175 84% 24%; --ring:175 84% 32%; --primary-foreground:222 47% 11%; }
/* WM amber: white text on amber-600 is only 3.15:1 (fails WCAG AA). Keep the brand amber
   shade but pair it with a DARK foreground — near-black on amber-600 is 5.68:1 (passes AA
   in both themes). See Sage-Screen-Element-UX-Matrix §A suite-accent contrast note. */
[data-suite="wm"]{   --suite:32 95% 44%; --suite-ink:32 95% 29%; --primary:32 95% 44%; --primary-ink:32 95% 29%; --ring:32 95% 44%; --primary-foreground:222 47% 11%; }
/* Dark-theme suite foregrounds: the dark block's near-black foreground fails AA on the ai (3.16)
   and comm (3.44) accents — white passes (ai 5.67, comm 5.20). hc/wm keep near-black (4.91 / 5.68).
   Verified 2026-07-02. Requires data-theme/.dark and data-suite on the SAME element (<html>, §A). */
[data-theme="dark"][data-suite="ai"],.dark[data-suite="ai"]{     --primary-foreground:0 0% 100%; --primary-ink:262 83% 76%; --suite-ink:262 83% 76%; }
[data-theme="dark"][data-suite="comm"],.dark[data-suite="comm"]{ --primary-foreground:0 0% 100%; --primary-ink:221 83% 72%; --suite-ink:221 83% 72%; }
[data-theme="dark"][data-suite="hc"],.dark[data-suite="hc"]{     --primary-ink:175 70% 57%; --suite-ink:175 70% 57%; }
[data-theme="dark"][data-suite="wm"],.dark[data-suite="wm"]{     --primary-ink:32 95% 65%; --suite-ink:32 95% 65%; }
[data-density="compact"]{ --control:2.75rem; --radius:0.5rem; --row-py:0.3rem; }
/* Target-size floor: compact never shrinks interactive controls below 44px (2.75rem) on touch —
   WCAG 2.5.8 + the Sage 44px touch rule beat density. */
@media (pointer: coarse){ [data-density="compact"]{ --control:2.75rem; } }
/* AX §8.4: on coarse pointers interactive controls stay ≥44px (2.75rem) in EVERY density — comfortable
   (root) included, not only compact. Fine-pointer (desktop) sizing is unchanged. */
@media (pointer: coarse){ :root{ --control:2.75rem; } }
html{font-family:var(--font-sans);}
/* Density-driven data-table row height: vertical cell padding (comfortable 0.45rem, compact 0.30rem). Tune --row-py. */
.sage-table td, .sage-table th{ padding-top:var(--row-py); padding-bottom:var(--row-py); }
/* Compact mode shrinks row avatars so rows can get tighter (the content floor, not just padding). */
[data-density="compact"] .sage-row-avatar{ height:1.25rem; width:1.25rem; }
/* Adaptive table strategies are explicit. `sage-table` supplies density only. Use
   `sage-table--stack` only when each row is an independent record and cross-column comparison is not
   the task. Comparison grids use a labelled `.sage-table-region` and retain their two-dimensional form. */
.sage-table-region,.sage-two-dimensional-region{width:100%;min-width:0;max-width:100%;overflow:auto;overscroll-behavior-inline:contain;contain:layout paint;}
@media (max-width:639px){
  .sage-table--stack thead{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0;}
  .sage-table--stack tr{display:block;border:1px solid hsl(var(--border));border-radius:var(--radius);margin-bottom:0.5rem;}
  .sage-table--stack td{display:flex;align-items:center;justify-content:space-between;gap:0.75rem;padding:0.5rem 0.75rem;text-align:right;}
  .sage-table--stack td::before{content:attr(data-label);font-weight:500;color:hsl(var(--muted-foreground));text-align:left;}
  .sage-table--stack td[data-label=""]::before{content:none;}
  .sage-table--stack td[data-label=""]{justify-content:flex-end;}
}
/* Shared entrance/feedback keyframes (same names + content as tokens/tailwind.preset.ts so Tailwind
   and vanilla apps can coexist). Pair with the --motion-* tokens above. */
@keyframes fade-in{from{opacity:0}to{opacity:1}}
@keyframes scale-in{from{opacity:0;transform:scale(.96)}to{opacity:1;transform:scale(1)}}
@keyframes slide-in-right{from{transform:translateX(100%)}to{transform:translateX(0)}}
@keyframes slide-in-left{from{transform:translateX(-100%)}to{transform:translateX(0)}}
@keyframes slide-in-up{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}
@keyframes draw-up{from{transform:scaleY(0)}to{transform:scaleY(1)}}
@keyframes check-pop{0%{transform:scale(0)}60%{transform:scale(1.15)}100%{transform:scale(1)}}
/* Reduced-motion backstop — enforced at the token layer so it never depends on per-class
   `motion-safe:` discipline: animations/transitions become effectively instant (WCAG 2.3.3,
   Sage-Delight-Standard). */
@media (prefers-reduced-motion: reduce){
  *,*::before,*::after{animation-duration:.01ms !important;animation-iteration-count:1 !important;transition-duration:.01ms !important;scroll-behavior:auto !important;}
}
/* Windows high-contrast/forced-colors: box-shadow focus rings and token colors can be suppressed by the
   user agent, so preserve boundaries, focus, selection, and state with system colors. */
@media (forced-colors: active){
  :root{
    --shadow-1:none; --shadow-2:none; --shadow-3:none;
  }
  :where(a,button,input,select,textarea,[role="button"],[role="tab"],[role="menuitem"],[tabindex]):focus-visible{
    outline:2px solid Highlight !important;
    outline-offset:2px !important;
    box-shadow:none !important;
  }
  :where(button,input,select,textarea,[role="dialog"],[role="menu"],[role="listbox"],.sage-table-region){
    border-color:CanvasText;
  }
  :where([aria-current="page"],[aria-selected="true"],[aria-pressed="true"],[data-state="active"]){
    border:2px solid Highlight !important;
  }
  :where([disabled],[aria-disabled="true"]){
    color:GrayText;
    border-color:GrayText;
  }
  ::selection{background:Highlight;color:HighlightText;}
}
