/* ============================================================
   causl.org — shared page chrome.

   Every page links this stylesheet (after topbar.css) for the
   token system, typography, layout primitives, and content card
   styles. Page-specific rules live in each page's <style> block.

   Colors follow the Causl Brand Specification §8 verbatim:
   Void Black / Ink Black / Stack Slate / Rat Graphite /
   Snapshot Mist / Trace Ash / Async Cyan / Commit Green
   plus the secondary tokens (Copper Wire / Conflict Amber /
   Rollback Red / Mutation Violet). The legacy token names
   (--obsidian, --causal-cyan, --mist, …) are preserved as
   aliases of the spec tokens so existing pages keep rendering
   without per-file rewrites.
   ============================================================ */

/* ============================================================
   Self-hosted brand typefaces (issue #1262).

   Inter (rsms/inter) and IBM Plex Mono (IBM/plex) ship as WOFF2
   under ../fonts/. The fallback chain in --sans / --mono below
   is kept as a defensive layer for the brief window before swap
   and for users on networks where the WOFF2 fails. font-display:
   swap means body text paints in the fallback first, then
   re-renders once the brand face arrives — no FOIT.

   Source URLs (also documented in causl-org/fonts/README.md):
     Inter      https://rsms.me/inter/font-files/Inter-{weight}.woff2
     IBM Plex   https://raw.githubusercontent.com/IBM/plex/master/
                packages/plex-mono/fonts/split/woff2/
                IBMPlexMono-{weight}-Latin1.woff2
   ============================================================ */

@font-face {
  font-family: 'Inter';
  src: url('../fonts/Inter-Regular.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Inter';
  src: url('../fonts/Inter-Medium.woff2') format('woff2');
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Inter';
  src: url('../fonts/Inter-SemiBold.woff2') format('woff2');
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Inter';
  src: url('../fonts/Inter-Bold.woff2') format('woff2');
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Inter';
  src: url('../fonts/Inter-Black.woff2') format('woff2');
  font-weight: 800 900;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'IBM Plex Mono';
  src: url('../fonts/IBMPlexMono-Regular.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'IBM Plex Mono';
  src: url('../fonts/IBMPlexMono-Medium.woff2') format('woff2');
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'IBM Plex Mono';
  src: url('../fonts/IBMPlexMono-Bold.woff2') format('woff2');
  font-weight: 700;
  font-style: normal;
  font-display: swap;
}

:root {
  /* -- Primary spec tokens (Causl Brand Specification §8).
        Names below are the SEMANTIC SPEC TOKENS. Short names
        (--causl-cyan / red / amber / green / violet) are kept
        as aliases below so every existing reference still
        resolves; new code should prefer the semantic names. -- */
  --causl-void:            #070A0F;
  --causl-ink:             #0B1118;
  --causl-slate:           #101822;
  --causl-graphite:        #2B333D;
  --causl-mist:            #D7E6EA;
  --causl-ash:             #8FA2AA;
  --causl-async-cyan:      #11D9FF;
  --causl-commit-green:    #A7FF18;
  --causl-copper:          #C8743D;
  --causl-conflict-amber:  #FFB020;
  --causl-rollback-red:    #FF4D5E;
  --causl-mutation-violet: #7C4DFF;

  /* -- Short-name aliases (compat with all pre-T2.1 references). -- */
  --causl-cyan:    var(--causl-async-cyan);
  --causl-green:   var(--causl-commit-green);
  --causl-amber:   var(--causl-conflict-amber);
  --causl-red:     var(--causl-rollback-red);
  --causl-violet:  var(--causl-mutation-violet);

  /* -- Legacy aliases — keep them pointing at the new spec values. */
  --obsidian:        var(--causl-ink);
  --obsidian-2:      var(--causl-void);
  --slate-graphite:  var(--causl-slate);
  --surface:         var(--causl-slate);
  --surface-2:       #182032;
  --night-line:      var(--causl-graphite);
  --mist:            var(--causl-mist);
  --pure-light:      #F7F8FA;
  --steel:           var(--causl-ash);
  --fog:             var(--causl-ash);

  --causal-cyan:     var(--causl-cyan);
  --causal-cyan-2:   #4FE4FF;
  --signal-blue:     var(--causl-violet);
  --commit-amber:    var(--causl-amber);
  --conflict-coral:  var(--causl-red);
  --success-mint:    var(--causl-green);

  /* ============================================================
     Contrast-pair token system — §8.1 of Causl Brand Spec.

     Every text color is bound to a specific background by name.
     Components write the pair together; mismatching surfaces and
     text tokens is a brand-system violation caught at review.
     Issue #1268. The hue-named tokens above remain as the raw
     palette these pairs reference (and the legacy aliases keep
     pre-pair pages rendering).

     ------------------------------------------------------------
     DISCIPLINE RULE (issue #1276)

     Every CSS rule that sets `background` (or `background-color`,
     `background-image`) on a visible surface MUST do one of:

       (a) Use a pair-token whose value auto-flips for light mode
           (e.g. `background: var(--surface-elevated)` plus
           `color: var(--text-on-elevated)`) — both sides of the
           pair flip together via :root[data-theme="light"] below.

       (b) Set the background with a hardcoded color/gradient AND
           pair it with an explicit `color:` rule AND provide a
           matching `:root[data-theme="light"] <selector>` block
           that overrides the background to a light-mode value.

     Setting only `background:` (with a hardcoded value) and
     relying on inherited `color:` is the bug pattern that left
     `.cta-strip` invisible in light mode. The dev-only tool at
     `js/contrast-audit.js` walks all visible text nodes and
     flags failures via console.warn — opt in by setting
     `window.__CAUSL_CONTRAST_AUDIT__ = true` in DevTools.
     ============================================================ */

  /* SURFACES — backgrounds for hierarchy levels */
  --surface-base:        var(--causl-void);              /* page background */
  --surface-elevated:    var(--causl-slate);             /* cards, panels */
  --surface-overlay:     var(--causl-ink);               /* dialogs, popovers */
  --surface-emphasis:    var(--causl-async-cyan);        /* primary CTAs */
  --surface-emphasis-2:  var(--causl-mutation-violet);   /* secondary CTAs */
  --surface-success:     var(--causl-commit-green);
  --surface-warning:     var(--causl-conflict-amber);
  --surface-danger:      var(--causl-rollback-red);
  --surface-info:        var(--causl-async-cyan);
  --surface-muted:       var(--causl-graphite);

  /* TEXT — bound to a surface, contrast-safe by construction */
  --text-on-base:             var(--causl-mist);             /* primary body */
  --text-on-base-muted:       rgba(215, 230, 234, 0.86);     /* secondary text — ≥ 7:1 on void */
  --text-on-base-subtle:      rgba(215, 230, 234, 0.70);     /* meta/caption — ≥ 4.5:1 on void */
  --text-on-elevated:         var(--causl-mist);
  --text-on-elevated-muted:   rgba(215, 230, 234, 0.86);
  --text-on-elevated-subtle:  rgba(215, 230, 234, 0.72);
  --text-on-overlay:          var(--causl-mist);
  --text-on-overlay-muted:    rgba(215, 230, 234, 0.86);
  --text-on-emphasis:         var(--causl-void);             /* dark text on bright cyan */
  --text-on-emphasis-2:       var(--causl-mist);             /* light text on violet */
  --text-on-success:          var(--causl-void);             /* dark text on bright green */
  --text-on-warning:          var(--causl-void);             /* dark text on amber */
  --text-on-danger:           var(--causl-mist);             /* light text on red */
  --text-on-info:             var(--causl-void);             /* same as emphasis */
  --text-on-muted:            var(--causl-mist);

  /* BORDERS — paired with the surface they sit on */
  --border-on-base:           rgba(143, 162, 170, 0.15);     /* subtle hairline */
  --border-on-elevated:       rgba(143, 162, 170, 0.25);
  --border-on-overlay:        rgba(143, 162, 170, 0.18);
  --border-emphasis:          var(--causl-async-cyan);

  /* ============================================================
     STATE TOKENS — interaction + status layer (§8.2, #1266).

     Every interactive state (hover / focus / active / pressed /
     disabled) and every status semantic (error / warning / success
     / info) has a NAMED token here. Components MUST reference
     these tokens — never inline rgba()/hex — so that the entire
     state palette flips together in light theme below.

     Naming convention: --state-<role>-<slot> where slot is one of
     {bg, fg, border, outline, ring}. Every pair tracks WCAG AA
     contrast on its target surface in both themes.
     ============================================================ */

  /* Interaction states */
  --state-hover-bg:        rgba(17, 217, 255, 0.08);
  --state-hover-fg:        var(--causl-async-cyan);
  --state-focus-outline:   var(--causl-async-cyan);
  --state-focus-ring:      0 0 0 3px rgba(17, 217, 255, 0.4);
  --state-active-bg:       var(--causl-async-cyan);
  --state-active-fg:       var(--causl-void);
  --state-pressed-bg:      rgba(17, 217, 255, 0.16);
  --state-disabled-bg:     var(--causl-graphite);
  --state-disabled-fg:     var(--causl-ash);

  /* Status states — bg is a tint at the same ~8% alpha as hover so
     callouts and chips read as soft semantic surfaces; fg is the
     full-strength hue token; border is the same full-strength hue. */
  --state-error-bg:        rgba(255, 77, 94, 0.08);
  --state-error-fg:        var(--causl-rollback-red);
  --state-error-border:    var(--causl-rollback-red);
  --state-warning-bg:      rgba(255, 176, 32, 0.08);
  --state-warning-fg:      var(--causl-conflict-amber);
  --state-warning-border:  var(--causl-conflict-amber);
  --state-success-bg:      rgba(167, 255, 24, 0.08);
  --state-success-fg:      var(--causl-commit-green);
  --state-success-border:  var(--causl-commit-green);
  --state-info-bg:         rgba(17, 217, 255, 0.08);
  --state-info-fg:         var(--causl-async-cyan);
  --state-info-border:     var(--causl-async-cyan);

  --radius-xl: 28px;
  --radius-lg: 20px;
  --radius-md: 14px;
  --radius-sm: 10px;
  --shadow-soft: 0 12px 36px rgba(0, 0, 0, 0.32);
  --shadow-deep: 0 24px 80px rgba(0, 0, 0, 0.4);

  /* ============================================================
     Spacing grid — 4px base unit (#1265).

     Every page-chrome rule should use one of these tokens for
     padding / margin / gap. Ad-hoc values (0.4rem, 0.45rem,
     0.65rem, 1.1rem, 1.4rem, etc.) round to the wrong place on
     fractional-DPI displays and break visual rhythm at scale.
     Round to the nearest token below; if a per-page rule truly
     needs a sub-token value (rare), document why in a comment.
     ============================================================ */
  --space-0: 0;
  --space-1: 0.25rem;  /* 4px */
  --space-2: 0.5rem;   /* 8px */
  --space-3: 0.75rem;  /* 12px */
  --space-4: 1rem;     /* 16px */
  --space-5: 1.5rem;   /* 24px */
  --space-6: 2rem;     /* 32px */
  --space-7: 3rem;     /* 48px */
  --space-8: 4rem;     /* 64px */
  --space-9: 6rem;     /* 96px */

  --mono: "IBM Plex Mono", "JetBrains Mono", "SFMono-Regular",
          Consolas, monospace;
  --sans: Inter, ui-sans-serif, system-ui, -apple-system,
          BlinkMacSystemFont, "Segoe UI", sans-serif;

  --max-page: 1180px;
}

*, *::before, *::after { box-sizing: border-box; }

html { scroll-behavior: smooth; }

/* Body — paired with --surface-base. All descendants inherit
   --text-on-base by default; sections that swap to --surface-elevated
   must re-pair to --text-on-elevated. (#1268) */
body {
  margin: 0;
  font-family: var(--sans);
  background: var(--surface-base);
  color: var(--text-on-base);
  /* gradient overlay — purely cosmetic, sits on top of --surface-base */
  background:
    radial-gradient(circle at 18% 8%, rgba(17, 217, 255, 0.14),
                    transparent 32rem),
    radial-gradient(circle at 86% 18%, rgba(167, 255, 24, 0.08),
                    transparent 30rem),
    linear-gradient(180deg, var(--causl-void),
                    var(--causl-ink) 55%, var(--causl-slate));
  line-height: 1.6;
  min-height: 100vh;
}

/* -- Layout primitives -------------------------------------------- */

.page {
  width: 100%;
  max-width: var(--max-page);
  margin: 0 auto;
  padding: 0 var(--space-5);
}

.section { padding: var(--space-8) 0 var(--space-4); }
.section:first-of-type { padding-top: var(--space-7); }

.section-head {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-6);
  align-items: end;
  margin-bottom: var(--space-6);
}

@media (max-width: 800px) {
  .section { padding: var(--space-7) 0 var(--space-2); }
  .section-head { grid-template-columns: 1fr; gap: var(--space-3); align-items: start; }
}

.section-kicker {
  font-family: var(--mono);
  font-size: 0.78rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--causl-cyan);
  margin-bottom: var(--space-2);
}

.section-head .lead {
  /* lead text sits on the page background — pair with base. */
  color: var(--text-on-base);
  font-size: 1.05rem;
  max-width: 560px;
  margin: 0;
}

/* -- Typography ---------------------------------------------------
   Unified heading scale (#1265). One scale across every page, every
   per-page override stripped unless it serves a legitimate scoped
   purpose (brand-page hero, see pages/brand/index.html). Standard
   font weights only (Inter ships at 100/200/.../900 — anything in
   between rounds silently on most platforms). */

h1, h2, h3, h4, h5 { margin: 0 0 var(--space-3); color: var(--text-on-base); }
h1 { font-size: clamp(2.4rem, 5.5vw, 4rem); font-weight: 800; letter-spacing: -0.02em; line-height: 1.05; }
h2 { font-size: clamp(1.7rem, 3vw, 2.4rem); font-weight: 700; letter-spacing: -0.015em; line-height: 1.1; }
h3 { font-size: clamp(1.3rem, 2vw, 1.7rem); font-weight: 700; letter-spacing: -0.01em; line-height: 1.15; }
h4 { font-size: 1.1rem; font-weight: 600; }
h5 { font-size: 1rem; font-weight: 600; }
/* Body copy sits on --surface-base by default. Inside a .card,
   the more specific .card p rule re-pairs to --text-on-elevated. */
p { margin: 0 0 var(--space-4); color: var(--text-on-base); }

a { color: var(--causl-cyan); text-decoration: none; transition: color 0.15s; }
a:hover { color: var(--causal-cyan-2); text-decoration: underline; }

code, kbd, samp, pre {
  font-family: var(--mono);
  font-size: 0.92em;
}

p code, li code, td code {
  background: var(--state-info-bg);
  border: 1px solid rgba(17, 217, 255, 0.22);
  color: var(--text-on-base);
  padding: 0.05em 0.4em;
  border-radius: 5px;
  font-size: 0.86em;
}

/* -- Buttons ------------------------------------------------------ */

.button {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-4) var(--space-5);
  border-radius: 999px;
  font-weight: 700;
  font-size: 0.95rem;
  letter-spacing: 0.005em;
  text-decoration: none;
  cursor: pointer;
  border: 1px solid transparent;
  transition: transform 0.15s, box-shadow 0.15s, background 0.2s,
              color 0.2s, border-color 0.2s;
}

.button:hover { transform: translateY(-1px); }
.button:active { transform: translateY(0); }

/* Primary button — paired with --surface-emphasis. */
.button.primary {
  background: linear-gradient(135deg, var(--surface-emphasis),
                              var(--surface-success));
  color: var(--text-on-emphasis);
  box-shadow: 0 6px 24px rgba(17, 217, 255, 0.35);
}

.button.primary:hover {
  box-shadow: 0 10px 32px rgba(17, 217, 255, 0.45);
  color: var(--text-on-emphasis);
  text-decoration: none;
}

/* Ghost button — transparent overlay over whatever surface it's on,
   so we keep it paired with --text-on-base (most common ancestor). */
.button.ghost {
  background: rgba(255, 255, 255, 0.04);
  border-color: rgba(143, 162, 170, 0.28);
  color: var(--text-on-base);
}

.button.ghost:hover {
  border-color: var(--border-emphasis);
  color: var(--state-hover-fg);
  background: var(--state-hover-bg);
  text-decoration: none;
}

/* -- Cards -------------------------------------------------------- */

/* Card — paired with --surface-elevated. */
.card {
  background: linear-gradient(180deg,
    rgba(16, 24, 34, 0.78), rgba(11, 17, 24, 0.82));
  border: 1px solid var(--border-on-elevated);
  border-radius: var(--radius-lg);
  padding: var(--space-5);
  box-shadow: inset 0 1px rgba(255, 255, 255, 0.04);
  color: var(--text-on-elevated);
}

.card .mono-label {
  font-family: var(--mono);
  font-size: 0.74rem;
  color: var(--surface-emphasis);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  margin-bottom: var(--space-2);
}

.card h3 { color: var(--text-on-elevated); }
.card p { color: var(--text-on-elevated); }
.card p:last-child { margin-bottom: 0; }

.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-5); }
.grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-5); }
.grid-4 { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--space-5); }

@media (max-width: 900px) { .grid-3, .grid-4 { grid-template-columns: 1fr 1fr; } }
@media (max-width: 600px) { .grid-2, .grid-3, .grid-4 { grid-template-columns: 1fr; } }

/* -- Code blocks -------------------------------------------------- */

/* Code-block surface + foreground live in syntax.css (#1295) — that
 * file owns the .codeblock-source pair-token contract for every
 * theme. site.css only defines the per-language tok-* and brand-hue
 * palette that paints token spans inside any code block. */

.tok-kw { color: var(--causl-violet); }
.tok-fn { color: var(--causl-cyan); }
.tok-str { color: var(--causl-amber); }
.tok-num { color: var(--causl-green); }
.tok-com { color: var(--causl-ash); font-style: italic; }
.tok-typ { color: var(--causl-copper); }

/* -- Tables ------------------------------------------------------- */

/* Table wrapper — paired with --surface-elevated. */
.table-wrap {
  border: 1px solid var(--border-on-elevated);
  border-radius: var(--radius-lg);
  background: linear-gradient(180deg,
    rgba(16, 24, 34, 0.72), rgba(11, 17, 24, 0.78));
  color: var(--text-on-elevated);
  overflow: hidden;
  overflow-x: auto;
}

table.compare {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.92rem;
}

table.compare th,
table.compare td {
  padding: var(--space-3) var(--space-4);
  text-align: center;
  border-bottom: 1px solid rgba(143, 162, 170, 0.16);
  white-space: nowrap;
}

table.compare th {
  font-family: var(--mono);
  font-size: 0.78rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-on-elevated);
  background: rgba(11, 17, 24, 0.65);
  border-bottom: 1px solid rgba(17, 217, 255, 0.28);
}

table.compare td:first-child,
table.compare th:first-child {
  text-align: left;
  font-weight: 600;
  color: var(--text-on-elevated);
  white-space: normal;
  min-width: 320px;
}

table.compare th.col-causl,
table.compare td.col-causl {
  background: rgba(17, 217, 255, 0.10);
  color: var(--text-on-elevated);
}

table.compare th.col-causl {
  color: var(--surface-emphasis);
}

table.compare tr:last-child td { border-bottom: none; }

.glyph-yes { color: var(--causl-green); font-weight: 700; }
.glyph-partial { color: var(--causl-amber); font-weight: 700; }
.glyph-no { color: var(--causl-ash); font-weight: 700; }
.glyph-fut { color: var(--causl-cyan); font-weight: 700; }
.glyph-na { color: var(--causl-ash); font-style: italic; font-size: 0.84em; }

/* -- CTA strip ---------------------------------------------------- */
/* CTA strip sits over the elevated surface gradient; pair body
   text with --text-on-elevated. #1253, #1259, #1268. */

.cta-strip { color: var(--text-on-elevated); }
.cta-strip p,
.cta-strip h2,
.cta-strip h3 { color: var(--text-on-elevated); }

/* -- Footer ------------------------------------------------------- */

/* Site footer — paired with --surface-overlay (deep terminal). */
.site-footer {
  margin-top: var(--space-8);
  padding: var(--space-6) 0 var(--space-7);
  border-top: 1px solid var(--border-on-overlay);
  background:
    radial-gradient(circle at 50% 0%, rgba(17, 217, 255, 0.10),
                    transparent 24rem),
    rgba(7, 10, 15, 0.6);
  color: var(--text-on-overlay);
}

.site-footer .page {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: var(--space-5);
  align-items: center;
}

.site-footer p { margin: 0; color: var(--text-on-overlay); font-size: 0.88rem; }

.site-footer .footer-links {
  display: flex;
  gap: var(--space-5);
  flex-wrap: wrap;
}

.site-footer .footer-links a {
  color: var(--text-on-overlay);
  font-size: 0.88rem;
  font-weight: 600;
}

.site-footer .footer-links a:hover { color: var(--surface-emphasis); }

/* -- Light theme --------------------------------------------------
   Light-mode floor: body text rgba(11,16,32,0.92), meta text
   rgba(11,16,32,0.86), accent links use #0B95B0 (≥ 4.5:1 against
   #F7F8FA). #1254, #1255.
   ------------------------------------------------------------ */

:root[data-theme="light"] {
  --causl-void:            #F7F8FA;
  --causl-ink:             #FFFFFF;
  --causl-slate:           #F0F2F5;
  --causl-graphite:        #D4D9DE;
  --causl-mist:            #070A0F;
  --causl-ash:             #2B333D;
  --causl-async-cyan:      #0B95B0;
  --causl-commit-green:    #2B8A1F;
  --causl-mutation-violet: #5E36CC;
  --causl-copper:          #8A4F22;
  --causl-conflict-amber:  #B57500;
  --causl-rollback-red:    #C8202F;
  /* Short-name aliases re-point at the light values so consumers
     of the short names get the light palette too. */
  --causl-cyan:    var(--causl-async-cyan);
  --causl-green:   var(--causl-commit-green);
  --causl-amber:   var(--causl-conflict-amber);
  --causl-red:     var(--causl-rollback-red);
  --causl-violet:  var(--causl-mutation-violet);
  --obsidian:       #070A0F;
  --pure-light:     #070A0F;
  --mist:           #070A0F;
  --steel:          #2B333D;
  --fog:            #2B333D;
  --causal-cyan:    #0B95B0;
  --causal-cyan-2:  #0F7E96;
  --signal-blue:    #5E36CC;
  --commit-amber:   #B57500;
  --conflict-coral: #C8202F;
  --success-mint:   #2B8A1F;

  /* ============================================================
     Contrast-pair tokens — light-theme contract (#1268).
     Dimmed hues for AA contrast on white; light text always
     #FFFFFF on bright surfaces so the pair stays legible.
     ============================================================ */

  --surface-base:        #FFFFFF;
  --surface-elevated:    #F4F6F9;
  --surface-overlay:     #FFFFFF;
  --surface-emphasis:    #0B95B0;            /* dimmed cyan for AA-on-white */
  --surface-emphasis-2:  #5B30C9;            /* dimmed violet for AA-on-white */
  --surface-success:     #4A9300;            /* dimmed green */
  --surface-warning:     #B57500;
  --surface-danger:      #C32A38;            /* dimmed red */
  --surface-info:        #0B95B0;
  --surface-muted:       #DDE1E6;

  --text-on-base:             rgba(11, 16, 32, 0.92);
  --text-on-base-muted:       rgba(11, 16, 32, 0.82);
  --text-on-base-subtle:      rgba(11, 16, 32, 0.70);  /* ≥ 4.5:1 on white */
  --text-on-elevated:         rgba(11, 16, 32, 0.92);
  --text-on-elevated-muted:   rgba(11, 16, 32, 0.82);
  --text-on-elevated-subtle:  rgba(11, 16, 32, 0.70);
  --text-on-overlay:          rgba(11, 16, 32, 0.92);
  --text-on-overlay-muted:    rgba(11, 16, 32, 0.82);
  --text-on-emphasis:         #FFFFFF;        /* white text on dimmed cyan */
  --text-on-emphasis-2:       #FFFFFF;
  --text-on-success:          #FFFFFF;
  --text-on-warning:          #FFFFFF;
  --text-on-danger:           #FFFFFF;
  --text-on-info:             #FFFFFF;
  --text-on-muted:            rgba(11, 16, 32, 0.92);

  --border-on-base:           rgba(11, 16, 32, 0.12);
  --border-on-elevated:       rgba(11, 16, 32, 0.18);
  --border-on-overlay:        rgba(11, 16, 32, 0.12);
  --border-emphasis:          #0B95B0;

  /* ============================================================
     State tokens — light-theme overrides (§8.2, #1266).

     Each fg uses the AA-on-white dimmed hue
     (cyan #0B95B0 ≥ 4.5:1, red #C32A38 ≥ 4.5:1,
      amber #B57500 ≥ 4.5:1, green #4A9300 ≥ 4.5:1)
     so the foreground stays legible on the soft 8% tint and on
     plain white surfaces alike.
     ============================================================ */

  --state-hover-bg:        rgba(11, 149, 176, 0.08);
  --state-hover-fg:        #0B95B0;
  --state-focus-outline:   #0B95B0;
  --state-focus-ring:      0 0 0 3px rgba(11, 149, 176, 0.4);
  --state-active-bg:       #0B95B0;
  --state-active-fg:       #FFFFFF;
  --state-pressed-bg:      rgba(11, 149, 176, 0.16);
  --state-disabled-bg:     #DDE1E6;
  --state-disabled-fg:     #5A6470;

  --state-error-bg:        rgba(195, 42, 56, 0.08);
  --state-error-fg:        #C32A38;
  --state-error-border:    #C32A38;
  --state-warning-bg:      rgba(181, 117, 0, 0.08);
  --state-warning-fg:      #B57500;
  --state-warning-border:  #B57500;
  --state-success-bg:      rgba(74, 147, 0, 0.08);
  --state-success-fg:      #4A9300;
  --state-success-border:  #4A9300;
  --state-info-bg:         rgba(11, 149, 176, 0.08);
  --state-info-fg:         #0B95B0;
  --state-info-border:     #0B95B0;
}

:root[data-theme="light"] body {
  background:
    radial-gradient(circle at 18% 8%, rgba(11, 149, 176, 0.10),
                    transparent 32rem),
    radial-gradient(circle at 86% 18%, rgba(43, 138, 31, 0.06),
                    transparent 30rem),
    linear-gradient(180deg, #FFFFFF, #F7F8FA 60%, #F0F2F5);
  color: var(--text-on-base);
}

:root[data-theme="light"] p { color: var(--text-on-base-muted); }

:root[data-theme="light"] .section-head .lead { color: var(--text-on-base-muted); }

:root[data-theme="light"] .topbar {
  background: linear-gradient(180deg,
    rgba(255, 255, 255, 0.94), rgba(247, 248, 250, 0.94));
  border-bottom-color: rgba(11, 149, 176, 0.32);
  color: var(--text-on-overlay);
}

:root[data-theme="light"] .topbar-brand,
:root[data-theme="light"] .topbar .pronunciation,
:root[data-theme="light"] .topbar .tagline,
:root[data-theme="light"] .topbar-menu a {
  color: var(--text-on-overlay);
}

:root[data-theme="light"] .topbar-menu a { border-color: var(--border-on-overlay); }

:root[data-theme="light"] .topbar-menu a:hover {
  background: var(--state-hover-bg);
  border-color: rgba(11, 149, 176, 0.55);
  color: var(--text-on-overlay);
}

:root[data-theme="light"] .topbar-menu a.is-current {
  color: var(--text-on-emphasis);
  background: linear-gradient(135deg, var(--surface-emphasis), var(--surface-emphasis-2));
}

/* The brand mark is a single plate-less SVG (img/causl-mark.svg) —
   Async Cyan + Rollback Red read on both dark and light surfaces
   per Causl Brand Specification §11, so no theme-swap is needed.
   Earlier revisions toggled `content: url(...)`; that rule was
   silently ignored by Safari < 17.4 (#1259 review) and is gone. */

:root[data-theme="light"] .card {
  background: linear-gradient(180deg, #FFFFFF, #F7F8FA);
  border-color: var(--border-on-elevated);
  color: var(--text-on-elevated);
  box-shadow: 0 8px 24px rgba(11, 16, 32, 0.06);
}

:root[data-theme="light"] .card h3 { color: var(--text-on-elevated); }
:root[data-theme="light"] .card p  { color: var(--text-on-elevated-muted); }

/* #1295 — the previous "always dark" override that forced
 * homepage codeblocks to a dark gradient in light mode was removed.
 * Code blocks on EVERY page now share the same pair-token contract
 * as the rest of the site: --surface-elevated (light gray in light
 * mode, slate in dark mode) for the surface, --text-on-elevated for
 * the foreground. The runtime contrast audit in
 * causl-org/js/codeblock.js applies corrective inline colours to
 * any tok-* / hl-N / token spans that fall below WCAG AA on the
 * resolved surface, so brand tokens that read fine on dark stay
 * legible on the light gray surface too. */

:root[data-theme="light"] .table-wrap {
  background: var(--surface-base);
  border-color: var(--border-on-elevated);
  color: var(--text-on-elevated);
}

:root[data-theme="light"] table.compare th {
  background: var(--surface-elevated);
  color: var(--text-on-elevated);
  border-bottom-color: rgba(11, 149, 176, 0.28);
}

:root[data-theme="light"] table.compare td:first-child { color: var(--text-on-elevated); }
:root[data-theme="light"] table.compare td,
:root[data-theme="light"] table.compare th { border-bottom-color: var(--border-on-elevated); }

:root[data-theme="light"] table.compare th.col-causl { color: var(--surface-emphasis); }
:root[data-theme="light"] table.compare td.col-causl {
  background: rgba(11, 149, 176, 0.10);
  color: var(--text-on-elevated);
}

:root[data-theme="light"] .button.primary { color: var(--text-on-emphasis); }
:root[data-theme="light"] .button.primary:hover { color: var(--text-on-emphasis); }
:root[data-theme="light"] .button.ghost {
  background: rgba(11, 16, 32, 0.04);
  border-color: var(--border-on-elevated);
  color: var(--text-on-base);
}
:root[data-theme="light"] .button.ghost:hover {
  background: var(--state-hover-bg);
  border-color: rgba(11, 149, 176, 0.55);
  color: var(--text-on-base);
}

:root[data-theme="light"] .cta-strip,
:root[data-theme="light"] .cta-strip p,
:root[data-theme="light"] .cta-strip h2,
:root[data-theme="light"] .cta-strip h3 { color: var(--text-on-elevated); }

:root[data-theme="light"] .site-footer {
  background:
    radial-gradient(circle at 50% 0%, rgba(11, 149, 176, 0.14),
                    transparent 24rem),
    var(--surface-overlay);
  border-top-color: var(--border-on-overlay);
  color: var(--text-on-overlay);
}

:root[data-theme="light"] .site-footer p { color: var(--text-on-overlay-muted); }
:root[data-theme="light"] .site-footer .footer-links a { color: var(--text-on-overlay); }
