/* ═══════════════════════════════════════════════════════════════════════════
   CHAINFAX — brand theme
   Tokens, type and the mark. Layout and copy live elsewhere and are not
   touched here.

   FONTS ARE SELF-HOSTED, not linked from Google. The card is rendered offline
   from file:// four times a day and the plot sheet ships with zero external
   refs; a <link> to fonts.googleapis.com would break the first and quietly
   undo the second. Latin-basic subsets only — the tracked-out mono labels and
   uppercase display never need cyrillic or greek, which is ~120KB saved.

   PALETTE REVISION 2026-08-10: the signal family moved from cyan/violet
   (#54D2F5 / #A86BF0) to blue-violet/hot-pink (#6B7BFF / #FF5ED4), and the
   ramp with it. Re-measured rather than assumed:

     status    signal vs peak-hi   deutan ΔE 2.4 -> 60.8   was indistinguishable
     direction signal vs settle    worst-case ΔE 26.9      safe (floor is ~6)
     contrast  every token on --gs-rack passes 4.5:1, except the ramp START
               (#2B3BF5, 2.92:1) which is a FILL and never carries text —
               see --gs-ramp-btn.

   The previous revision carried a documented deviation here: status could not
   rest on hue, because healthy and attention were ΔE 2.4 apart under
   deuteranopia — indistinguishable, not merely close. THE NEW PALETTE FIXES
   THAT. Status states still carry a mono uppercase label as well, because the
   brief prefers it and because a label survives a greyscale screenshot, but
   they are no longer doing the work alone.
   ═══════════════════════════════════════════════════════════════════════════ */

@font-face{font-family:Archivo;font-weight:800;font-style:normal;font-display:swap;
  src:url("fonts/Archivo-800.woff2") format("woff2")}
@font-face{font-family:Archivo;font-weight:900;font-style:normal;font-display:swap;
  src:url("fonts/Archivo-900.woff2") format("woff2")}
@font-face{font-family:"Space Grotesk";font-weight:400;font-style:normal;font-display:swap;
  src:url("fonts/SpaceGrotesk-400.woff2") format("woff2")}
@font-face{font-family:"Space Grotesk";font-weight:500;font-style:normal;font-display:swap;
  src:url("fonts/SpaceGrotesk-500.woff2") format("woff2")}
@font-face{font-family:"Space Grotesk";font-weight:600;font-style:normal;font-display:swap;
  src:url("fonts/SpaceGrotesk-600.woff2") format("woff2")}
@font-face{font-family:"JetBrains Mono";font-weight:400;font-style:normal;font-display:swap;
  src:url("fonts/JetBrainsMono-400.woff2") format("woff2")}
@font-face{font-family:"JetBrains Mono";font-weight:500;font-style:normal;font-display:swap;
  src:url("fonts/JetBrainsMono-500.woff2") format("woff2")}
@font-face{font-family:"JetBrains Mono";font-weight:700;font-style:normal;font-display:swap;
  src:url("fonts/JetBrainsMono-700.woff2") format("woff2")}

:root{
  /* surfaces */
  --gs-rack:#07070C; --gs-panel:#0C0C15; --gs-panel-alt:#08080F;
  --gs-rule:#1D1D2E; --gs-rule-strong:#26264A;
  /* ink */
  --gs-text:#F6F6FC; --gs-text-dim:#9D9DB8; --gs-text-mute:#82829C;
  /* signal — blue-violet through hot pink */
  --gs-signal:#6B7BFF; --gs-settle:#FF5ED4; --gs-peak:#A9B4FF; --gs-peak-hi:#FF9BE9;

  --gs-ramp:linear-gradient(100deg,#2B3BF5 0%,#FF5ED4 100%);
  --gs-ramp-4:linear-gradient(to top right,#2B3BF5 0%,#6B4BFF 34%,#C94CEB 66%,#FF5ED4 100%);
  /* BUTTON RAMP, and why it is not --gs-ramp.
     The brief puts #07070C text on --gs-ramp. Against the ramp's start,
     #2B3BF5, that is 2.92:1 — under the 4.5:1 a 15px bold label needs, so the
     left third of every primary button label would be under-contrast. Starting
     the button's ramp at --gs-signal instead keeps the same blue-to-pink
     identity and measures 5.65:1 rising to 7.47:1 across the fill. The full
     ramp is still used where nothing sits on top of it: the mark, and data
     bars. */
  --gs-ramp-btn:linear-gradient(100deg,#6B7BFF 0%,#FF5ED4 100%);

  --gs-display:Archivo,"Arial Narrow",system-ui,sans-serif;
  --gs-body:"Space Grotesk",system-ui,-apple-system,"Segoe UI",sans-serif;
  --gs-mono:"JetBrains Mono",ui-monospace,SFMono-Regular,Menlo,monospace;
}

/* ── type ──────────────────────────────────────────────────────────────── */
.gs-display,h1,h2,.gs-hero{
  font-family:var(--gs-display);font-weight:800;text-transform:uppercase;
  letter-spacing:-.035em;line-height:1.02;
}
.gs-hero{font-weight:900;font-size:46px;max-width:520px}
p,li,.gs-body{text-wrap:pretty}

/* Tracked-out mono label. The section eyebrow and every small caption. */
.eyebrow,.gs-eyebrow{
  font-family:var(--gs-mono);font-size:11px;font-weight:500;letter-spacing:.16em;
  text-transform:uppercase;color:var(--gs-text-mute);
}

/* EVERY number is mono with tabular figures, so columns of digits line up and
   a value cannot change width as it ticks. This single rule does most of the
   visual work in the brief. */
.num,.gs-num{font-family:var(--gs-mono);font-variant-numeric:tabular-nums;font-weight:500}

/* ── links: both states declared, never inherited ──────────────────────── */
a{color:var(--gs-signal);text-decoration:none}
a:hover{color:var(--gs-settle)}

/* ── the mark ──────────────────────────────────────────────────────────── */
.gs-lockup{display:flex;align-items:center;gap:11px;text-decoration:none;flex:none}
.gs-lockup:hover{color:inherit}
.gs-wordmark{
  font-family:var(--gs-display);font-weight:800;font-size:17px;
  letter-spacing:-.035em;text-transform:uppercase;color:var(--gs-text);
}
/* width:auto, explicitly. Host pages style charts with `svg{width:100%}`, and
   the mark would inherit it — blowing out to the full container, overflowing
   the lockup and shoving the wordmark under whatever follows it. A class
   selector outranks the element rule regardless of source order, and `auto`
   hands sizing back to the element's own width/height attributes. */
.gs-mark{display:block;flex:none;width:auto;height:auto;max-width:none}
/* Glow only at 60px+ on a dark surface, per the brief. */
.gs-mark.lg{filter:drop-shadow(0 0 18px rgba(140,180,255,.4))}

/* ── components ────────────────────────────────────────────────────────── */
.gs-panel{
  border:1px solid var(--gs-rule);border-radius:18px;
  background:linear-gradient(180deg,var(--gs-panel),var(--gs-panel-alt));
}
.gs-panel-hd{padding:16px 22px;border-bottom:1px solid var(--gs-rule)}
.gs-panel-bd{padding:24px}

.gs-btn{
  font-family:var(--gs-display);font-weight:700;text-transform:uppercase;
  letter-spacing:-.02em;border-radius:8px;padding:12px 22px;border:0;cursor:pointer;
  background:var(--gs-ramp-btn);color:#07070C;
}
.gs-btn-2{
  font-family:var(--gs-display);font-weight:700;text-transform:uppercase;
  letter-spacing:-.02em;border-radius:8px;padding:12px 22px;cursor:pointer;
  background:transparent;border:1px solid var(--gs-rule-strong);color:var(--gs-text-dim);
}

/* Ambient glow: hero only, and only one per screen. */
.gs-ambient{background-image:radial-gradient(ellipse at 20% 0%,rgba(120,170,255,.09),transparent 62%)}
