/* SWOFT Design Tokens
 *
 * CSS custom properties consumed by MiniJinja templates and Lit components.
 * THIS FILE is the source of truth for the SWOFT Platform Design System
 * (ds-SQewD9-0Db, "Swoft Product Design System" — id corrected 2026-08-05,
 * the old ds-P8oEE5sjq9 no longer resolved in the metamodel).
 * The UXD metamodel tracks it — not the other way around.
 *
 * 2026-08-05 — repainted to the "v41" palette (source of truth:
 * swoft-react-ui/packages/design-tokens/src/v41.css), so Business/Core/Build
 * Cockpit and every server-rendered page match Swoft Build's live look
 * (build.swoft.ai). Deliberately UNCHANGED / out of v41's scope: the
 * EventStorming palette, the Strategic-distillation palette, the dataviz
 * chart-1..6 series, and the streaming/live --swoft-color-accent triad — v41
 * has no opinion on any of these (DDD/chart concepts don't exist in the
 * Build product), so they keep their original hues. Spacing and layout
 * tokens are untouched: v41's 4px grid already matches this file's.
 *
 * Workflow:
 *   just diff-tokens       # preview drift (read-only)
 *   just plan-tokens       # show every swoft-uxd call apply would make
 *   just sync-tokens       # write changes to the metamodel
 *
 * Implementation: tools/swoft-agent/swoft_agent/uxd_sync.py
 * (`swoft agent uxd sync diff|plan|apply`).
 */

/* v41 typeface — Inter and JetBrains Mono, SELF-HOSTED next to this file
   (fonts/, @fontsource-variable 5.3.0, latin subset incl. € — SIL OFL 1.1, see
   fonts/OFL-*.txt). Was a Google Fonts @import: every cockpit's CSP
   (font-src 'self' data:) blocked it, so they rendered the system fallback, and
   a desktop app shipped to customers would send each user's IP to Google.
   URLs are relative to this file, so they resolve under /css/ wherever it is
   served (public/, the swoft-design-system-assets crate). */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-display: swap;
  font-weight: 100 900;
  src: url("fonts/inter-latin-wght-normal.woff2") format("woff2");
}
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-display: swap;
  font-weight: 100 800;
  src: url("fonts/jetbrains-mono-latin-wght-normal.woff2") format("woff2");
}

:root {
  /* Colors — Primary (v41 signature orange; white-on-primary 3.74:1 — large
     text/icons/buttons, same tier this file already accepted for the old
     indigo primary. Body text never rides this token.) */
  --swoft-color-primary: #ff4405;
  --swoft-color-primary-hover: #d63b05;
  --swoft-color-primary-light: rgba(255, 68, 5, 0.15);
  /* Primary in the FOREGROUND role — text/icons painted ON primary-light. The
     block above excludes that use ("body text never rides this token"), but
     chips/badges need it, so it gets its own stop instead of borrowing one that
     was validated as a fill. This is v41's `--v41-accent-dark`, created in the
     site design system for exactly this pair: 5.98:1 on the composited
     primary-light tint (#ffe3da). Never paint text with --swoft-color-primary
     (2.84:1 there); never use this token as a fill. */
  --swoft-color-primary-text: #9e2e2e;

  /* Colors — Semantic (v41; all pass AA 4.5:1 on #f7f8f5 page bg) */
  --swoft-color-success: #0f7a47;
  --swoft-color-success-bg: #d7f1e2;
  --swoft-color-warning: #8a5a00;
  --swoft-color-warning-bg: #fcebc7;
  --swoft-color-error: #b42318;
  --swoft-color-error-bg: #fce4e1;
  --swoft-color-info: #175cd3;
  --swoft-color-info-bg: #d9e7fb;

  /* Duotone icon body — secondary layer for <swoft-icon weight="duotone" intent="…">.
     Mid-tints (not the near-white -bg) so the body reads as a fill under the deep outline. */
  --swoft-icon-duotone-secondary-success: #86efac;
  --swoft-icon-duotone-secondary-warning: #fdba74;
  --swoft-icon-duotone-secondary-danger: #fca5a5;
  --swoft-icon-duotone-secondary-info: #93c5fd;
  --swoft-icon-duotone-secondary-brand: #ffd6bd; /* v41: tracks the orange primary, was indigo */

  /* EventStorming palette (Brandolini) — the DDD community's sticky-note colour
     language, governed as tokens so every DDD surface (aggregate detail, message
     catalog, context map) speaks the same vocabulary. Per family: `accent` =
     icon outline + chip border, `text` = chip label (AA ≥ 4.5:1 on its own bg),
     `bg` = chip tint, `tint` = duotone icon body. Light theme. */
  --swoft-color-es-command: #2563eb;        /* command — blue */
  --swoft-color-es-command-text: #1e40af;
  --swoft-color-es-command-bg: rgba(37, 99, 235, 0.10);
  --swoft-color-es-command-tint: #93c5fd;
  --swoft-color-es-event: #ea580c;          /* event — orange */
  --swoft-color-es-event-text: #9a3412;
  --swoft-color-es-event-bg: rgba(234, 88, 12, 0.10);
  --swoft-color-es-event-tint: #fdba74;
  --swoft-color-es-entity: #ca8a04;         /* aggregate / entity — yellow */
  --swoft-color-es-entity-text: #854d0e;
  --swoft-color-es-entity-bg: rgba(202, 138, 4, 0.12);
  --swoft-color-es-entity-tint: #fde047;
  --swoft-color-es-policy: #9333ea;         /* policy / invariant / saga / rule — lilac */
  --swoft-color-es-policy-text: #6b21a8;
  --swoft-color-es-policy-bg: rgba(147, 51, 234, 0.10);
  --swoft-color-es-policy-tint: #d8b4fe;
  --swoft-color-es-readmodel: #16a34a;      /* read model / projection / query — green */
  --swoft-color-es-readmodel-text: #166534;
  --swoft-color-es-readmodel-bg: rgba(22, 163, 74, 0.10);
  --swoft-color-es-readmodel-tint: #86efac;

  /* Strategic distillation (Evans) — subdomain investment tiers. A different
     vocabulary from the EventStorming tactical palette above: Core stands out
     (warm gold — invest here, the crown jewels), Supporting is present-but-calm,
     Generic recedes (commodity). All AA ≥ 4.5:1 as heading text on surface, and
     double as the rail / dot / distribution-bar accent. Light theme. */
  --swoft-color-strategic-core: #b45309;
  --swoft-color-strategic-supporting: #0369a1;
  --swoft-color-strategic-generic: #6b7280;

  /* Colors — Text (v41; all pass AA 4.5:1 on #f7f8f5 / #ffffff) */
  --swoft-color-text: #0a0d12;
  --swoft-color-text-secondary: #535861;
  --swoft-color-text-muted: #707274;  /* 4.53:1 on #f7f8f5, 4.62:1 on #ffffff — the block claim above only holds at this value; #717680 was 4.28:1 on the page bg and failed AA */
  --swoft-color-text-disabled: rgba(10, 13, 18, 0.35);

  /* Colors — Surface (v41 cream) */
  --swoft-color-bg: #f7f8f5;
  --swoft-color-surface: #ffffff;
  --swoft-color-surface-alt: #eff2ec;        /* v41 "soft" — recessed/sunken surface: code & JSON panels, inset wells */
  --swoft-color-border: rgba(10, 13, 18, 0.07);   /* v41 "line" — decorative hairline: cards, panels, internal dividers (WCAG 1.4.11 exempt — surface elevation provides the boundary cue) */
  --swoft-color-border-strong: rgba(10, 13, 18, 0.12); /* v41 "line-strong" — decorative emphasis: dashed empty-state outlines, accent dividers */
  --swoft-color-control-border: #717680;     /* interactive: form fields, inputs, selects, comboboxes, checkboxes (WCAG 1.4.11 ≥ 3:1 required) */
  --swoft-color-text-inverse: #ffffff;
  --swoft-color-link: #175cd3;               /* kept distinct from --swoft-color-primary on purpose — v41 reserves orange for CTAs/emphasis, not body links */
  --swoft-color-neutral-100: #eff2ec;
  --swoft-color-surface-hover: rgba(10, 13, 18, 0.04);  /* v41 "bg-hover" — semantic hover tint, works over any surface */

  /* Semantic aliases — components reached for these names and got only their
     hardcoded dark-hex fallback, so light theme rendered dark patches and the
     theme switcher was a no-op on them. Declared as var() references, NOT copied
     literals: they resolve against the *computed* value on :root, so the
     [data-theme="dark"] block below re-themes them for free. Never give an alias
     its own per-theme value — re-theme the token it points at. */
  --swoft-color-danger: var(--swoft-color-error);
  --swoft-color-danger-light: var(--swoft-color-error-bg);
  --swoft-color-success-light: var(--swoft-color-success-bg);
  --swoft-color-success-subtle: var(--swoft-color-success-bg);
  --swoft-color-warning-subtle: var(--swoft-color-warning-bg);
  /* Foreground on a --swoft-color-primary fill. Inherits primary's own caveat:
     3.74:1 on light primary, 4.82:1 on dark primary — the light side is the
     "large text/icons only" tier, not body copy. Same constraint the primary
     block states. */
  --swoft-color-on-primary: var(--swoft-color-text-inverse);
  --swoft-color-code-bg: var(--swoft-color-surface-alt);       /* recessed code/JSON wells */

  /* Syntax highlighting, for read-only source (<swoft-code-view>). One token per
     lezer tag family, NOT per language. Every value below is >= 4.5:1 against
     --swoft-color-code-bg in its own theme (measured, not eyeballed) — syntax
     colour is body copy you are asked to read character by character, so the
     "large text" tier does not apply. Re-check with the same ratio if the code
     surface ever moves. */
  --swoft-code-keyword: #7b1fa2;      /* 7.26:1 on #eff2ec */
  --swoft-code-string: #2e7d32;       /* 4.54:1 */
  --swoft-code-comment: #5f6b62;      /* 4.93:1 */
  --swoft-code-number: #a34700;       /* 5.37:1 */
  --swoft-code-type: #8a5a00;         /* 5.24:1 */
  --swoft-code-function: #1565c0;     /* 5.08:1 */
  --swoft-code-property: #00695c;     /* 5.85:1 */
  --swoft-code-variable: #0a0d12;     /* 17.22:1 — plain identifiers read as body text */
  --swoft-code-meta: #0b5578;         /* 7.19:1 */
  --swoft-code-punctuation: #4a5a63;  /* 6.33:1 */
  --swoft-code-invalid: #b3261e;      /* 5.78:1 */
  --swoft-code-inserted: #1b5e20;     /* 6.96:1 */
  --swoft-code-deleted: #b3261e;      /* 5.78:1 */

  /* Brand secondary — the gradient partner to --swoft-color-primary (avatar,
     hero, CTA) and the fill for tone="accent" surfaces. v41 has no second
     brand hue (its accent ramp is monochrome orange), so this now holds v41's
     own darkest accent stop — keeps the existing 2-colour gradient formulas
     (below) reading as a plausible orange→ink warm ramp instead of drifting
     back to purple. White text on it is 13.9:1 (AA, very dark stop). One
     value across both themes on purpose — do not restate per-theme. */
  --swoft-color-brand-purple: #612311;

  /* Accent — the AI streaming/live indicator hue (pulse dot, stream cursor).
     Deliberately UNCHANGED from the pre-v41 palette: this is a status/liveness
     signal orthogonal to brand identity, not a v41 concept, and needs to stay
     visually distinct from the orange primary rather than compete with it.
     Light theme darkens it to 5.36:1 on #ffffff, clearing the 3:1 WCAG 1.4.11
     asks of non-text UI. */
  --swoft-color-accent: #0e7490;
  --swoft-color-on-accent: #ffffff;        /* text ON an accent fill (note pins): 5.36:1 on #0e7490 */
  --swoft-color-surface-accent: #ede9fe;   /* tinted panel behind accent-tone rows */
  --swoft-color-accent-text: #5b21b6;      /* 7.57:1 on --swoft-color-surface-accent */
  --swoft-color-surface-muted: rgba(10, 13, 18, 0.08);  /* v41 "bg-active" — neutral inset fill: swatch wells */
  --swoft-color-scrim: rgba(0, 0, 0, 0.6);  /* modal scrim behind dialogs, drawers, palettes, drop zones — dark in both themes */

  /* Spacing — 4px base grid */
  --swoft-spacing-2xs: 2px;   /* hairline half-step (off-grid by design): borders, tight insets */
  --swoft-spacing-xs: 4px;
  --swoft-spacing-sm: 8px;
  --swoft-spacing-smd: 12px;  /* compact step between sm(8) and md(16) — control/chip padding */
  --swoft-spacing-md: 16px;
  --swoft-spacing-lg: 24px;
  --swoft-spacing-xl: 32px;
  --swoft-spacing-2xl: 48px;
  /* Editorial scale (off the dense-UI grid by design): dramatic whitespace for
     brand/marketing bands — heroes, section breathing room, full-bleed wells. */
  --swoft-spacing-3xl: 64px;
  --swoft-spacing-4xl: 96px;
  --swoft-spacing-5xl: 128px;

  /* Typography — v41: Inter, with the same system-ui/-apple-system/
     BlinkMacSystemFont fallback chain this file already relied on (imported
     above), so a blocked/slow font fetch still resolves through the same
     WKWebView-safe path as before instead of a bare browser default. */
  --swoft-font-family: 'Inter', system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  --swoft-font-mono: 'JetBrains Mono', 'SF Mono', Monaco, 'Cascadia Code', Consolas, monospace;
  --swoft-font-size-2xs: 0.625rem; /* micro-labels: chart ticks, meta captions, kickers — below v41's smallest tier, left as-is */
  --swoft-font-size-xs: 0.6875rem;  /* v41 11px */
  --swoft-font-size-sm: 0.8125rem;  /* v41 13px */
  --swoft-font-size-base: 0.875rem; /* v41 14px */
  --swoft-font-size-lg: 1rem;       /* v41 16px */
  --swoft-font-size-xl: 1.125rem;   /* v41 18px */
  --swoft-font-size-2xl: 1.5rem;    /* v41 24px */
  --swoft-font-weight-normal: 400;
  --swoft-font-weight-medium: 500;
  --swoft-font-weight-semibold: 600;
  --swoft-font-weight-bold: 700;
  --swoft-font-weight-extrabold: 800;
  --swoft-font-weight-black: 900;

  /* Display / editorial typography — expressive scale for brand/marketing
     surfaces (landing heroes, section titles). Per-brand override the display
     FAMILY as a token value, same mechanism as the colour palette. */
  --swoft-font-family-display: 'Iowan Old Style', Georgia, 'Times New Roman', serif;
  --swoft-font-size-3xl: 2rem;      /* v41 32px — its largest defined tier */
  --swoft-font-size-4xl: 3rem;      /* v41 has no editorial scale beyond 3xl — left as-is */
  --swoft-font-size-5xl: 3.75rem;
  --swoft-font-size-6xl: 4.5rem;
  --swoft-font-size-display: clamp(2.5rem, 1.8rem + 3.5vw, 4.5rem);
  --swoft-line-height-tight: 1.05;   /* editorial-only, out of v41's dense-UI scale — left as-is */
  --swoft-line-height-snug: 1.25;    /* v41 "tight" */
  --swoft-line-height-normal: 1.5;   /* v41 "normal" — unchanged, already matched */
  --swoft-line-height-relaxed: 1.75; /* v41 "relaxed" */
  --swoft-letter-spacing-tight: -0.02em;
  --swoft-letter-spacing-wide: 0.08em;

  /* Radii — v41 sm/md/lg/full match exactly; xl comes down from 20px to
     v41's 16px. 2xl (dramatic hero shape) has no v41 tier — left as-is. */
  --swoft-radius-sm: 4px;
  --swoft-radius-md: 8px;
  --swoft-radius-lg: 12px;
  --swoft-radius-xl: 16px;    /* v41 xl */
  --swoft-radius-2xl: 32px;   /* dramatic soft shape: hero surfaces, pull-quote blocks — out of v41's scope */
  --swoft-radius-full: 9999px;

  /* Shadows — v41 sm/md/lg. xl (topmost overlay, command-palette) has no v41
     tier — left as-is, still the largest blur in the ramp. */
  --swoft-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
  --swoft-shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
  --swoft-shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
  --swoft-shadow-xl: 0 28px 64px rgba(0, 0, 0, 0.18);  /* topmost overlay (command-palette) — blur > lg so the ramp stays monotonic */
  --swoft-shadow-focus: 0 0 0 3px rgba(255, 68, 5, 0.4);  /* keyboard focus ring (primary-tinted) */

  /* Gradients — brand depth for colour-block surfaces / hero bands.
     Built FROM the colour rail, so a per-product theme that overrides
     --swoft-color-primary / -accent / -brand-purple gets branded gradients
     for free (no per-brand gradient authoring). */
  --swoft-gradient-primary: linear-gradient(135deg, var(--swoft-color-primary) 0%, var(--swoft-color-primary-hover) 100%);
  --swoft-gradient-accent: linear-gradient(135deg, var(--swoft-color-primary) 0%, var(--swoft-color-brand-purple, #612311) 100%);
  --swoft-gradient-hero: linear-gradient(160deg, var(--swoft-color-primary) 0%, var(--swoft-color-brand-purple, #612311) 55%, var(--swoft-color-text) 100%);
  --swoft-gradient-subtle: linear-gradient(180deg, var(--swoft-color-surface) 0%, var(--swoft-color-surface-alt) 100%);

  /* Motion — durations and easings. Compose these; never write raw ms/s
     (gate: HardcodedDesignToken). Every --swoft-duration-* MUST be zeroed in the
     prefers-reduced-motion block below (test: motion-tokens.test.ts). */
  --swoft-duration-instant: 80ms;   /* press, toggle — feedback under the 100ms threshold */
  --swoft-duration-fast: 150ms;     /* hover, colour, small state change */
  --swoft-duration-normal: 200ms;   /* enter/leave of small surfaces: toast, popover */
  --swoft-duration-slow: 320ms;     /* panel, page-region change */
  --swoft-ease-standard: cubic-bezier(0.2, 0, 0, 1);
  --swoft-ease-out: cubic-bezier(0, 0, 0, 1);     /* entering */
  --swoft-ease-in: cubic-bezier(0.3, 0, 1, 1);    /* leaving */
  --swoft-ease-spring: linear(0, 0.25 7%, 0.69 17%, 1.02 28%, 1.1 36%, 1.06 45%, 0.99 58%, 1 100%);

  /* Transitions — composed from the motion tokens above */
  --swoft-transition-fast: var(--swoft-duration-fast) var(--swoft-ease-standard);
  --swoft-transition-normal: var(--swoft-duration-normal) var(--swoft-ease-standard);

  /* App-shell sizing — consumed by sidebar/header chrome via height: var(--swoft-header-height) etc. */
  --swoft-sidebar-width: 18rem;
  --swoft-sidebar-width-collapsed: 3rem;
  --swoft-header-height: 3.5rem;

  /* Control sizing — shared baseline so any control row (toolbar, form) lines up.
     INTERACTIVE controls only: button/select/toggle-group. These are touch
     targets and are raised under a coarse pointer (see the block below), so a
     non-interactive element must NOT ride this scale — use --swoft-chip-height-*. */
  --swoft-control-height-sm: 28px;   /* dense toolbars */
  --swoft-control-height-md: 36px;   /* default forms */
  --swoft-control-inset-x: 12px;     /* unified L/R control padding (== spacing-smd) */

  /* Non-interactive inline chips (badge, kbd). Same 28px as control-height-sm so
     a badge still lines up in a dense control row — but a SEPARATE token,
     because a badge is not a tap target and must not grow on touch. */
  --swoft-chip-height-sm: 28px;

  /* Readable max inline-size for forms/prose; the pane fills around it. */
  --swoft-content-max: 72ch;
  --swoft-page-max: 80rem;      /* <swoft-page max="wide"> — app pages: lists, records, dashboards */

  /* Layout / grid — page-level composition */
  --swoft-grid-gutter: var(--swoft-spacing-lg, 24px);  /* gap between grid tracks & sibling sections */
  --swoft-card-min-metric: 140px;  /* compact KPI/metric tile track */
  --swoft-card-min-compact: 200px; /* dense card track */
  --swoft-card-min: 240px;       /* base/standard card track: repeat(auto-fill, minmax(var(--swoft-card-min), 1fr)) */
  --swoft-card-min-wide: 300px;  /* wide card variant — dashboards, data tiles */

  /* Drag and drop */
  --swoft-dnd-preview-opacity: 0.7;
  --swoft-dnd-preview-scale: 1.02;
  --swoft-dnd-indicator-color: var(--swoft-color-primary, #ff4405);
  --swoft-dnd-indicator-size: 2px;
  --swoft-dnd-active-bg: rgba(255, 68, 5, 0.05);
  --swoft-dnd-over-bg: rgba(255, 68, 5, 0.1);
  --swoft-dnd-transition: 150ms ease;

  /* Breakpoints (canonical values — use raw numbers in @media queries) */
  /* CSS custom properties cannot be used in @media conditions.          */
  /* These tokens document the standard breakpoints for reference.       */
  --swoft-bp-sm: 640px;   /* mobile → tablet */
  --swoft-bp-md: 1024px;  /* tablet → desktop */

  /* Rating scale, low → high (red → orange → yellow → lime → green). Segment
     fills for <swoft-score-meter>; non-text marks only, the value is always
     text beside them. Mirrors v41's --v41-scale-1..5. */
  --swoft-color-scale-1: #d92d20;
  --swoft-color-scale-2: #f97316;
  --swoft-color-scale-3: #eab308;
  --swoft-color-scale-4: #84cc16;
  --swoft-color-scale-5: #16a34a;

  /* Data-viz — series palette (light). Promoted from in-code hex fallbacks so
     the palette is theme-aware and centrally governed. */
  --swoft-color-chart-1: #5a67d8;
  --swoft-color-chart-2: #0891b2;
  --swoft-color-chart-3: #059669;
  --swoft-color-chart-4: #d97706;
  --swoft-color-chart-5: #db2777;
  --swoft-color-chart-6: #7c3aed;
  --swoft-color-chart-grid: var(--swoft-color-border, #e5e7eb);
  --swoft-color-chart-axis: var(--swoft-color-border, #e5e7eb);

  /* Data-viz — finish (light = Refined: gradient, no glow). */
  --swoft-chart-fill-opacity-top: 0.35;
  --swoft-chart-fill-opacity-bottom: 0;
  --swoft-chart-stroke-width: 2;
  --swoft-chart-glow-blur: 0;
  --swoft-chart-glow-opacity: 0;
  --swoft-chart-reference-color: var(--swoft-color-text-muted, #6b7280);
  --swoft-chart-reference-dash: 4 4;
  /* Bar fill gradient (vertical gloss — opaque, never fades to transparent like the area fill). */
  --swoft-chart-bar-opacity-top: 1;
  --swoft-chart-bar-opacity-bottom: 0.72;
}

/* Dark theme (default for AI workspace) */
[data-theme="dark"] {
  /* Colors — Primary (v41 has no dark variant; this is an extrapolation).
     Base = v41's own "accent-deep" stop, chosen because white-on-it already
     clears full AA (4.82:1) — using the brighter accent (#ff4405/#ff6a2b)
     here would put white text under 3:1. Hover brightens toward the lighter
     v41 stops (mirrors the pre-v41 dark theme's "hover is lighter" rule);
     white-on-hover is ~3.4:1, same "large text/icons only" tier this file
     already accepted for the old indigo hover. */
  --swoft-color-primary: #d63b05;
  --swoft-color-primary-hover: #ff4405;
  --swoft-color-primary-light: rgba(255, 68, 5, 0.18);
  /* Foreground counterpart — see the :root note. The base above is validated
     for white-ON-it, i.e. as a FILL; inverted into the text role it collapses
     to 3.28:1 on the composited primary-light tint (#3e1b0d). Dark needs a
     LIGHTER stop where light needed a darker one, so the two themes cannot
     share a value: #ff6a2b (a v41 stop, named in the block above) gives 5.37:1
     on that tint and 6.54:1 on the page bg. #ff4405 was rejected — 4.45:1 on
     the tint, a near-miss that only passes if you measure against the page
     background instead of the chip's own. */
  --swoft-color-primary-text: #ff6a2b;

  /* Colors — Semantic (AA-safe on #0f1117 bg) */
  --swoft-color-success: #22c55e;
  --swoft-color-success-bg: rgba(34, 197, 94, 0.15);
  --swoft-color-warning: #fbbf24;
  --swoft-color-warning-bg: rgba(245, 158, 11, 0.15);
  --swoft-color-error: #f87171;
  --swoft-color-error-bg: rgba(239, 68, 68, 0.15);
  --swoft-color-info: #60a5fa;
  --swoft-color-info-bg: rgba(59, 130, 246, 0.15);

  /* Duotone icon body — deeper tints so the brighter dark-theme outline still leads. */
  --swoft-icon-duotone-secondary-success: #166534;
  --swoft-icon-duotone-secondary-warning: #92400e;
  --swoft-icon-duotone-secondary-danger: #991b1b;
  --swoft-icon-duotone-secondary-info: #1e40af;
  --swoft-icon-duotone-secondary-brand: #6b2a10; /* v41: tracks the orange primary, was indigo */

  /* EventStorming palette (dark) — brighter accents/text so they lead on the
     dark surface, deeper duotone tints for the icon body. */
  --swoft-color-es-command: #60a5fa;
  --swoft-color-es-command-text: #93c5fd;
  --swoft-color-es-command-bg: rgba(96, 165, 250, 0.15);
  --swoft-color-es-command-tint: #1e40af;
  --swoft-color-es-event: #fb923c;
  --swoft-color-es-event-text: #fdba74;
  --swoft-color-es-event-bg: rgba(251, 146, 60, 0.15);
  --swoft-color-es-event-tint: #7c2d12;
  --swoft-color-es-entity: #facc15;
  --swoft-color-es-entity-text: #fde047;
  --swoft-color-es-entity-bg: rgba(250, 204, 21, 0.15);
  --swoft-color-es-entity-tint: #713f12;
  --swoft-color-es-policy: #c084fc;
  --swoft-color-es-policy-text: #d8b4fe;
  --swoft-color-es-policy-bg: rgba(192, 132, 252, 0.15);
  --swoft-color-es-policy-tint: #4c1d95;
  --swoft-color-es-readmodel: #4ade80;
  --swoft-color-es-readmodel-text: #86efac;
  --swoft-color-es-readmodel-bg: rgba(74, 222, 128, 0.15);
  --swoft-color-es-readmodel-tint: #14532d;

  /* Strategic distillation (dark) — brighter so Core's gold leads on the dark
     surface; Generic stays a recessive grey. */
  --swoft-color-strategic-core: #fbbf24;
  --swoft-color-strategic-supporting: #38bdf8;
  --swoft-color-strategic-generic: #8b95a5;

  /* Colors — Text (v41-derived warm dark palette; --swoft-color-text is v41's
     own "inverse" cream, i.e. what v41 uses for text painted on a dark fill —
     repurposed here as this theme's primary text) */
  --swoft-color-text: #f7f8f5;
  --swoft-color-text-secondary: #d8d5d0;
  --swoft-color-text-muted: #a3a099;
  --swoft-color-text-disabled: #625e57;

  /* Colors — Surface (warm ink, matches v41's undertone instead of the old
     cool indigo-tinted dark palette) */
  --swoft-color-bg: #14120f;
  --swoft-color-surface: #201c18;
  --swoft-color-surface-alt: #0c0a08;        /* recessed/sunken surface: code & JSON panels, inset wells */
  --swoft-color-border: rgba(247, 248, 245, 0.1);   /* decorative hairline: cards, panels, internal dividers */
  --swoft-color-border-strong: rgba(247, 248, 245, 0.16);  /* decorative emphasis */
  --swoft-color-control-border: #8a857c;     /* interactive: form fields & inputs (WCAG 1.4.11 ≥ 3:1 on #14120f and #201c18) */
  --swoft-color-text-inverse: #ffffff;
  --swoft-color-link: #58a6ff;                /* v41 has no dark variant to derive from — kept from the pre-v41 dark theme, already AA-proven on a near-black bg */
  --swoft-color-neutral-100: #211d19;

  /* Syntax highlighting — same families, re-measured against this theme's
     --swoft-color-code-bg (#0c0a08). */
  --swoft-code-keyword: #c792ea;      /* 8.21:1 on #0c0a08 */
  --swoft-code-string: #c3e88d;       /* 14.35:1 */
  --swoft-code-comment: #8b9099;      /* 6.16:1 */
  --swoft-code-number: #f78c6c;       /* 8.40:1 */
  --swoft-code-type: #ffcb6b;         /* 13.18:1 */
  --swoft-code-function: #82aaff;     /* 8.60:1 */
  --swoft-code-property: #80cbc4;     /* 10.59:1 */
  --swoft-code-variable: #f7f8f5;     /* 18.54:1 */
  --swoft-code-meta: #89ddff;         /* 13.03:1 */
  --swoft-code-punctuation: #a8b3bd;  /* 9.27:1 */
  --swoft-code-invalid: #ff8a80;      /* 8.66:1 */
  --swoft-code-inserted: #a5d6a7;     /* 12.02:1 */
  --swoft-code-deleted: #ff8a80;      /* 8.66:1 */
  --swoft-color-surface-hover: rgba(247, 248, 245, 0.06);  /* semantic hover tint — lighten on dark */

  /* Accent family (dark). The seven semantic aliases in :root — danger,
     danger-light, success-light, success-subtle, warning-subtle, on-primary,
     code-bg — are var() references and re-theme automatically from the tokens
     overridden above; do NOT restate them here. --swoft-color-brand-purple is
     deliberately theme-invariant. Only these four need dark values. */
  --swoft-color-accent: #6ee7ff;                      /* streaming/live cyan, leads on dark */
  --swoft-color-on-accent: #0a0d12;                   /* white on the cyan was 1.44:1; this is 13.47:1 */
  --swoft-color-surface-accent: #3b3566;
  --swoft-color-accent-text: #c4b5fd;                 /* 6.03:1 on --swoft-color-surface-accent */
  --swoft-color-surface-muted: rgba(255, 255, 255, 0.08);
  --swoft-color-scrim: rgba(0, 0, 0, 0.6);

  /* Shadows (darker for dark theme) */
  --swoft-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.3);
  --swoft-shadow-md: 0 4px 6px rgba(0, 0, 0, 0.4);
  --swoft-shadow-lg: 0 20px 60px rgba(0, 0, 0, 0.5);
  --swoft-shadow-xl: 0 28px 64px rgba(0, 0, 0, 0.55);
  --swoft-shadow-focus: 0 0 0 3px rgba(214, 59, 5, 0.45);

  /* Drag and drop (dark) */
  --swoft-dnd-active-bg: rgba(214, 59, 5, 0.12);
  --swoft-dnd-over-bg: rgba(214, 59, 5, 0.22);

  /* Rating scale (dark): one step lighter so the low end holds on #1a1d29. */
  --swoft-color-scale-1: #f04438;
  --swoft-color-scale-2: #fb923c;
  --swoft-color-scale-3: #facc15;
  --swoft-color-scale-4: #a3e635;
  --swoft-color-scale-5: #22c55e;

  /* Data-viz — series palette (dark: brighter/saturated for contrast on #1a1d29). */
  --swoft-color-chart-1: #7c8cff;
  --swoft-color-chart-2: #38bdf8;
  --swoft-color-chart-3: #34d399;
  --swoft-color-chart-4: #fbbf24;
  --swoft-color-chart-5: #f472b6;
  --swoft-color-chart-6: #a78bfa;
  --swoft-color-chart-grid: var(--swoft-color-border, #2d3148);
  --swoft-color-chart-axis: var(--swoft-color-border, #2d3148);

  /* Data-viz — finish (dark = Bold: deeper gradient + stroke glow). */
  --swoft-chart-fill-opacity-top: 0.60;
  --swoft-chart-fill-opacity-bottom: 0.02;
  --swoft-chart-stroke-width: 2;
  --swoft-chart-glow-blur: 3;
  --swoft-chart-glow-opacity: 0.55;
  --swoft-chart-reference-color: var(--swoft-color-text-muted, #8b95a5);
  --swoft-chart-reference-dash: 4 4;
  /* Bar fill gradient (vertical gloss — bars fade toward the baseline for the bold dark look). */
  --swoft-chart-bar-opacity-top: 1;
  --swoft-chart-bar-opacity-bottom: 0.5;
}

/* Respect user motion preferences (WCAG 2.3.3) */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
  /* Custom properties inherit through shadow roots; the `*` rule above does not
     reach inside them. Zeroing the tokens is what silences Lit components. */
  :root {
    --swoft-duration-instant: 0ms;
    --swoft-duration-fast: 0ms;
    --swoft-duration-normal: 0ms;
    --swoft-duration-slow: 0ms;
  }
}

/* Touch targets (WCAG 2.5.5 / Apple HIG 44px). A coarse pointer is a finger, so
   every INTERACTIVE control gets a real tap target — button, select,
   toggle-group, which are the only consumers of the control-height scale.
   Non-interactive chips (badge, kbd) ride --swoft-chip-height-* and deliberately
   do NOT grow here; inflating a status badge to 44px would wreck every list.

   Device query, not layout — one of the sanctioned @media cases under ADR-210
   (alongside the reduced-motion block above). This is invisible in the Tauri
   cockpits, which are always pointer:fine; the surface it actually serves is the
   server-rendered runtime UI (Core :8001 / Business :8002 / Technical :8003 /
   Runner :8006) viewed on a phone. */
@media (pointer: coarse) {
  :root {
    --swoft-control-height-sm: 44px;
    --swoft-control-height-md: 44px;
  }
}

/* Scrollbar theming — classic-scrollbar environments (Edge/Windows, macOS
   "Show scroll bars: Always") render the UA-default ~16px white track on every
   overflow:auto container, slicing up the dark theme (overlay-scrollbar engines
   like WKWebView never show this, so it goes unnoticed in the Tauri cockpits).
   scrollbar-color / scrollbar-width are INHERITED properties, so this single
   declaration reaches every scroller in every shadow root (sidebar nav,
   <swoft-resizable-panel>, tables). Same palette as <swoft-scroll-area>.
   (Plain `html` selector on purpose — the uxd_sync token parser only reads
   :root / [data-theme] blocks.) */
html {
  scrollbar-color: var(--swoft-color-border-strong, rgba(247, 248, 245, 0.16)) transparent;
  scrollbar-width: thin;
}
