/* ================================================================
   FROZEN SNAPSHOT of the Greenville Triumph design system tokens.
   Source : https://design.greenvilletriumph.club/tokens.css
   Frozen : 2026-05-31, for the public 6/3 Home Opener guide.
   Why    : this page is shared publicly, so it must NOT change when
            the live design system is edited. Tokens + brand fonts are
            self-hosted here. To re-sync: re-fetch the source, rewrite
            the font url()s to fonts/, redeploy.
   ================================================================ */
/* ============================================================
   GREENVILLE TRIUMPH - DASHBOARD DESIGN TOKENS
   design.greenvilletriumph.club/tokens.css
   2026 rebrand. Brand palette byte-verified against the .aco swatch.
   Brandpad source of truth: https://brandpad.io/greenville-triumph/

   What this is: the design system that builds Triumph dashboards and
   staff-facing tools. On-brand (the seven brand colors, the brand fonts)
   but tuned for dense data at desk distance, not poster viewing.

   How to consume in any Triumph dashboard:
     <link rel="stylesheet" href="https://design.greenvilletriumph.club/tokens.css">
     <link rel="stylesheet" href="https://design.greenvilletriumph.club/components.css">
   Then use var(--token-name) in CSS, never hex/RGBA/OKLCH.

   Chart.js exception: the canvas API can't resolve CSS vars, so dataset
   colors must be hex literals. Use the --brand-* / --series-* hex values.
   ============================================================ */

/* ============================================================
   BRAND FONTS  (self-hosted, served from this domain, CORS open)
   ------------------------------------------------------------
   Two families, per Brandpad:
     • Fabiola Capitals - display / hero ONLY (single-weight 400 OTF)
     • Inter            - every working heading + body + UI (variable 100–900)

   Fabiola is a SINGLE-WEIGHT OTF. Requesting weight > 400 makes the
   browser SYNTHETICALLY bold it - fattening strokes, crushing spacing
   into the "smashed serif" look. `font-synthesis: none` in the base
   reset is the guardrail: any stray heavy weight on a Fabiola element
   falls back to the real 400. Never override it. Use 400 only.

   Inter, by contrast, is a real variable font - its 700/800/900 weights
   are genuine cut weights, not synthesized. That is why all working
   headings are Inter heavy: brand-correct AND structurally sound.
   ============================================================ */
@font-face {
  font-family: 'Fabiola Capitals';
  src: url('fonts/Fabiola-Capitals.otf') format('opentype');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Inter';
  src: url('fonts/Inter-VariableFont.ttf') format('truetype-variations');
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Inter';
  src: url('fonts/Inter-Italic-VariableFont.ttf') format('truetype-variations');
  font-weight: 100 900;
  font-style: italic;
  font-display: swap;
}

:root {
  color-scheme: only dark;

  /* ============================================================
     BRAND PALETTE  (canonical 7, never extend)
     ------------------------------------------------------------
     The seven approved colors. Every other token is derived from
     one of these. Never introduce an 8th brand color. The surface
     ladder below is NOT a new color - it is Deep Night lifted toward
     Upstate Fog, the same way a tint card already worked.
     ============================================================ */
  --brand-greenville-blue: #002855;  /* PMS 295 C    - formal navy, deep emphasis bands */
  --brand-triumph-green:   #61a631;  /* PMS 369 C    - primary brand accent */
  --brand-upstate-fog:     #f2fafa;  /* PMS 7541 C   - primary text on dark */
  --brand-morning-mist:    #d2e6e5;  /* PMS 5455 C   - soft text on dark */
  --brand-deep-night:      #020022;  /* PMS Black 6 C - page canvas */
  --brand-electric-lime:   #69b3e7;  /* PMS 292 C    - sky-blue accent (Brandpad name is misleading) */
  --brand-light-green:     #97d700;  /* PMS 375 C    - lime accent (never paired with electric-lime) */

  /* ============================================================
     SURFACE ELEVATION LADDER  (derived from Deep Night)
     ------------------------------------------------------------
     A calm slate ladder, each step a little lighter, carrying the
     brand's blue-violet undertone. This replaces the old "every card
     is saturated navy #002855" approach that made dashboards read as
     a heavy wall. Reserve true Greenville Blue for ONE deep band
     (hero base, footer) via --color-band-navy.

       --color-bg          page canvas
       --color-surface-1   faint band  (alternating sections)
       --color-surface-2   card / panel default
       --color-surface-3   hover / raised card
       --color-surface-4   overlay / popover / drawer
     ============================================================ */
  --color-bg:        #14181f;   /* calm cool slate, low chroma. NOT the saturated Deep Night,
                                   which is a near-black blurple that reads harsh as a full canvas. */
  --color-surface-1: #191e27;   /* faint band (alternating sections) */
  --color-surface-2: #22262e;   /* card / panel default */
  --color-surface-3: #2d3039;   /* hover / raised card */
  --color-surface-4: #383b45;   /* overlay / popover / drawer */
  --color-band-navy: var(--brand-greenville-blue);   /* deep emphasis band, used sparingly */
  --brand-deep-night-bg: #14181f;   /* alias for the dark-mode lock literal */

  /* Aliases - keep older code working; new code uses the ladder above */
  --color-surface:     var(--color-surface-2);
  --color-surface-alt: var(--color-surface-1);

  /* ============================================================
     TEXT HIERARCHY
     ============================================================ */
  --color-text:        var(--brand-upstate-fog);            /* primary body + headings */
  --color-text-soft:   var(--brand-morning-mist);           /* secondary / supporting */
  --color-text-muted:  rgba(242, 250, 250, 0.58);           /* captions, labels, meta */
  --color-text-faint:  rgba(242, 250, 250, 0.38);           /* disabled, placeholder */

  /* ============================================================
     BORDERS
     ============================================================ */
  --color-border:          rgba(242, 250, 250, 0.10);       /* default hairline */
  --color-border-emphasis: rgba(242, 250, 250, 0.20);       /* table headers, input underline */
  --color-border-strong:   rgba(242, 250, 250, 0.32);       /* active / hovered edges */

  /* ============================================================
     ACCENT ROLES
     ------------------------------------------------------------
     One accent per layout. Pick --color-blue OR --color-pop, not
     both. A dashboard-system rule (Brandpad does not mandate it).
     Exception: KPI tiles and chart series may key through the full
     accent set to tell metrics apart (like the data-series block).
     ============================================================ */
  --color-accent:        var(--brand-triumph-green);   /* primary CTA, active nav, KPI 1st */
  --color-accent-hover:  var(--brand-light-green);     /* CTA hover pop */
  --color-blue:          var(--brand-electric-lime);   /* secondary accent, KPI 2nd */
  --color-pop:           var(--brand-light-green);     /* third accent, KPI 3rd */
  --accent-subtle:       rgba(97, 166, 49, 0.10);      /* row tint, chip fill */
  --accent-muted:        rgba(97, 166, 49, 0.18);      /* active chip, focus glow */

  /* ============================================================
     STATUS COLORS  (system signals only, NEVER decorative)
     ------------------------------------------------------------
     Reserve for state: success / warning / danger / info. Do not
     use --color-warning as a 4th accent. Yellow means warning; using
     it decoratively means a real warning gets missed.
     ============================================================ */
  --color-success:        var(--brand-triumph-green);
  --color-success-subtle: rgba(97, 166, 49, 0.16);
  --color-warning:        #d4a14b;
  --color-warning-subtle: rgba(212, 161, 75, 0.16);
  --color-danger:         #ef4444;
  --color-danger-subtle:  rgba(239, 68, 68, 0.16);
  --color-info:           var(--brand-electric-lime);
  --color-info-subtle:    rgba(105, 179, 231, 0.16);

  /* ============================================================
     DATA SERIES  (hex literals - Chart.js can't read CSS vars)
     ------------------------------------------------------------
     Stays inside the seven brand colors (never an 8th). These are the
     four that read cleanly as lines/bars on the dark canvas, in
     rotation order. Status colors (success/warning/danger) are for
     state, not series. Need a 5th series? Tint one of these, don't
     invent a colour.
     Order: green → sky → lime → mist.
     ============================================================ */
  --series-green: #61a631;   /* Triumph Green */
  --series-sky:   #69b3e7;   /* Electric Lime (sky blue) */
  --series-lime:  #97d700;   /* Light Green (lime) */
  --series-mist:  #d2e6e5;   /* Morning Mist - neutral series */

  /* ============================================================
     TYPOGRAPHY FAMILIES
     ------------------------------------------------------------
     Fabiola = display / hero ONLY (opt in with .h-display).
     Inter   = every working heading (h1–h6) + body + UI.
     JetBrains Mono = numbers, eyebrows, code (a dashboard utility,
     not a brand face; pages that show numbers load it themselves).
     ============================================================ */
  --font-display: 'Fabiola Capitals', Georgia, 'Times New Roman', serif;
  --font-sans:    'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --font-mono:    'JetBrains Mono', 'Fira Code', Consolas, monospace;

  /* ============================================================
     TYPE SCALE  (fluid, dashboard-dense)
     ------------------------------------------------------------
     Tight clamp ranges so a component looks the same at 1280px and
     1920px instead of ballooning. The old poster scale (h1 → 139px,
     h2 → 67px) is gone; --text-display is the one big moment and it
     is Fabiola-only.

       --text-xs       0.69–0.78rem  captions, eyebrows, table heads
       --text-sm       0.81–0.90rem  labels, dense body, meta
       --text-base     0.94–1.00rem  body default
       --text-lg       1.06–1.20rem  lead body, card titles
       --text-xl       1.25–1.60rem  h3 / large value
       --text-2xl      1.50–2.10rem  h2 / section titles
       --text-3xl      1.90–2.90rem  h1 / page titles
       --text-display  2.6–5.25rem   Fabiola hero ONLY (.h-display)
     ============================================================ */
  --text-xs:      clamp(0.74rem,  0.70rem + 0.18vw, 0.84rem);
  --text-sm:      clamp(0.81rem,  0.78rem + 0.16vw, 0.90rem);
  --text-base:    clamp(0.94rem,  0.91rem + 0.18vw, 1.00rem);
  --text-lg:      clamp(1.06rem,  1.00rem + 0.30vw, 1.20rem);
  --text-xl:      clamp(1.25rem,  1.10rem + 0.55vw, 1.60rem);
  --text-2xl:     clamp(1.50rem,  1.30rem + 0.90vw, 2.10rem);
  --text-3xl:     clamp(1.90rem,  1.60rem + 1.35vw, 2.90rem);
  --text-display: clamp(2.40rem,  2.70rem + 3.10vw, 6.25rem);   /* dashboard hero, visually calibrated: ~88px @1440. Sweet spot between too-small (~73px, reads as H2) and too-big (Brandpad poster 8.7rem/117px). Keep the rendered hero ~85-100px; do not drift either way. */

  /* ============================================================
     WEIGHT SCALE
     ------------------------------------------------------------
     Body default is 400 (Regular) for dashboard legibility. Brandpad
     ships marketing body at 300 (Light); 300 is reserved here for
     large lede / hero subtitle where thin reads as elegant, not weak.
     Working headings are Inter 700–900 (real variable cut weights).
     ============================================================ */
  --weight-light:    300;
  --weight-regular:  400;
  --weight-medium:   500;
  --weight-semibold: 600;
  --weight-bold:     700;
  --weight-extra:    800;
  --weight-black:    900;

  /* ============================================================
     LEADING + MEASURE
     ============================================================ */
  --leading-tight:   1.15;
  --leading-snug:    1.35;
  --leading-normal:  1.5;
  --leading-relaxed: 1.65;
  --measure:         64ch;   /* readable line length cap */

  /* ============================================================
     SPACING - FLUID  (rhythm between blocks)
     ============================================================ */
  --space-xs:  clamp(0.3rem,  0.25rem + 0.15vw, 0.45rem);
  --space-sm:  clamp(0.55rem, 0.45rem + 0.3vw,  0.85rem);
  --space-md:  clamp(0.9rem,  0.75rem + 0.5vw,  1.35rem);
  --space-lg:  clamp(1.35rem, 1.1rem + 0.85vw,  2rem);
  --space-xl:  clamp(2rem,    1.5rem + 1.4vw,   3rem);
  --space-section: clamp(2.75rem, 2rem + 3vw,   5rem);   /* top/bottom of every <section> */

  /* ============================================================
     SPACING - FIXED  (4px base, for precise component work)
     ============================================================ */
  --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;
  --space-16: 4rem;

  /* ============================================================
     LAYOUT SHELLS  (page utilization)
     ------------------------------------------------------------
     Three container widths so dashboards use the screen instead of
     stranding a skinny column in the middle of a wide monitor:
       --content-max   1200px  reading / prose / single column
       --content-wide  1440px  KPI grids, charts, multi-column data
       --content-full  none    full-bleed dense tables (padding only)
     ============================================================ */
  --content-max:  1200px;
  --content-wide: 1440px;
  --gutter:       clamp(1.25rem, 1rem + 2vw, 2.5rem);
  --sidebar-w:    248px;
  --nav-h:        60px;
  --card-pad:     var(--space-md);

  /* ============================================================
     RADIUS  (Triumph is sharp by default)
     ============================================================ */
  --radius:      0px;     /* everything that isn't a pill or thumb */
  --radius-full: 999px;   /* badges, pills, toggle thumb, accent dots */

  /* ============================================================
     SHADOW ELEVATION  (hierarchy, not decoration - use sparingly)
     ============================================================ */
  --shadow-ring: 0 0 0 1px rgba(2, 0, 34, 0.40);
  --shadow-sm:   0 1px  2px rgba(2, 0, 34, 0.45);
  --shadow-md:   0 6px  18px rgba(2, 0, 34, 0.50);
  --shadow-lg:   0 18px 44px rgba(2, 0, 34, 0.62);

  /* ============================================================
     MOTION
     ============================================================ */
  --duration-fast: 0.15s;
  --duration:      0.25s;
  --duration-slow: 0.45s;
  --ease-out:      cubic-bezier(0.2, 0, 0.1, 1);
  --ease-in-out:   cubic-bezier(0.4, 0, 0.2, 1);
  --ease-spring:   cubic-bezier(0.34, 1.4, 0.64, 1);
}

/* ============================================================
   BASE RESET
   ============================================================ */
* { box-sizing: border-box; margin: 0; padding: 0; }

html {
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--nav-h) + 12px);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  background-color: var(--color-bg);
  color-scheme: only dark;
}

body {
  font-family: var(--font-sans);
  font-size: 16px;
  font-weight: var(--weight-regular);   /* 400 - dashboard legibility */
  line-height: var(--leading-normal);
  color: var(--color-text);
  background: var(--color-bg);
  overflow-x: hidden;
  /* Brand guardrail: refuse browser-synthesized weights/italics. Fabiola
     is single-weight 400; without this a stray heavy weight would render a
     crushed fake-bold. Inter's real cut weights are unaffected. Never remove. */
  font-synthesis: none;
}

a {
  color: var(--color-accent);
  text-decoration: none;
  transition: color var(--duration-fast) var(--ease-out);
}
a:hover { color: var(--color-pop); }

img, svg { display: block; max-width: 100%; }

::selection { background: var(--accent-muted); color: var(--color-text); }

code, kbd, samp {
  font-family: var(--font-mono);
  font-size: 0.875em;
  background: rgba(242, 250, 250, 0.08);
  padding: 0.12em 0.4em;
  color: var(--color-accent);
}

::-webkit-scrollbar { width: 9px; height: 9px; }
::-webkit-scrollbar-track { background: var(--color-bg); }
::-webkit-scrollbar-thumb { background: var(--color-surface-3); border: 2px solid var(--color-bg); }
::-webkit-scrollbar-thumb:hover { background: var(--color-accent); }

/* ============================================================
   HEADINGS
   ------------------------------------------------------------
   DEFAULT: every heading is Inter heavy. Fabiola is opt-in for the
   single page hero via .h-display. This is deliberate:

     • Brandpad assigns Fabiola to H1/H2/H3. On a poster that sings.
       On a data-dense dashboard at desk distance it fights the data
       and (at H2/H3) repeatedly synthetic-bolds into mush.
     • So the dashboard system restricts Fabiola to ONE hero moment
       (.h-display, rendered at the real Brandpad spec) and uses Inter
       700–900 for the working hierarchy. Fewer Fabiola lines, each
       one correct, instead of many lines each slightly wrong.

   .h-display is the Brandpad H1: Fabiola, weight 400, line-height 1.0,
   tracking normal, text-transform none. The display size is capped for
   screens (Brandpad's own poster max is ~8.7rem; here ~5.25rem).
   ============================================================ */
h1, h2, h3, h4, h5, h6 {
  font-family: var(--font-sans);
  color: var(--color-text);
  text-transform: none;
}
h1 { font-size: var(--text-3xl); font-weight: var(--weight-extra); line-height: var(--leading-tight); letter-spacing: -0.02em; }
h2 { font-size: var(--text-2xl); font-weight: var(--weight-extra); line-height: 1.2;  letter-spacing: -0.018em; }
h3 { font-size: var(--text-xl);  font-weight: var(--weight-bold);  line-height: 1.3;  letter-spacing: -0.012em; }
h4 { font-size: var(--text-lg);  font-weight: var(--weight-bold);  line-height: 1.35; letter-spacing: -0.008em; }
h5 { font-size: var(--text-base);font-weight: var(--weight-bold);  line-height: 1.4;  letter-spacing: -0.004em; }
h6 {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  line-height: 1.4;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-text-muted);
}

/* The one Fabiola moment. Brandpad H1 spec, screen-capped. */
.h-display {
  font-family: var(--font-display);
  font-weight: var(--weight-regular);   /* 400 - never heavier */
  font-size: var(--text-display);
  line-height: 0.85;                    /* Brandpad ships H1 tight (0.8); 0.85 stays tight + multi-line safe */
  letter-spacing: normal;               /* Brandpad: normal tracking on H1 */
  text-transform: none;
  color: var(--color-text);
}

/* ============================================================
   LAYOUT PRIMITIVES
   ------------------------------------------------------------
   .container       1200px reading column
   .container-wide  1440px dashboard column (KPIs, charts, tables)
   .container-full  full width, gutter padding only
   section          vertical rhythm; .bg-surface alternates a faint band
   .band-navy       the one deep Greenville-Blue emphasis band
   ============================================================ */
.container,
.container-wide,
.container-full {
  margin: 0 auto;
  padding-left: var(--gutter);
  padding-right: var(--gutter);
  width: 100%;
}
.container      { max-width: var(--content-max); }
.container-wide { max-width: var(--content-wide); }

section {
  padding: var(--space-section) 0;
  scroll-margin-top: var(--nav-h);
  position: relative;
}
section.bg-surface { background: var(--color-surface-1); }
section.band-navy  { background: var(--color-band-navy); }

.table-scroll { overflow-x: auto; }

/* ============================================================
   GRID HELPERS  (the page-utilization fix)
   ------------------------------------------------------------
   Drop-in responsive grids so a dashboard fills the width instead
   of stacking everything in one column.
     .grid        12-col base (use --col-span utilities or inline)
     .grid-2/3/4  equal columns, collapse to 1 on narrow
     .grid-kpi    auto-fit KPI/stat tiles (min 180px)
     .grid-cards  auto-fit cards (min 260px)
     .grid-auto   auto-fit, min 220px
   Gap defaults to --space-md; override with --grid-gap.
   ============================================================ */
.grid,
.grid-2, .grid-3, .grid-4,
.grid-kpi, .grid-cards, .grid-auto {
  display: grid;
  gap: var(--grid-gap, var(--space-md));
}
.grid    { grid-template-columns: repeat(12, 1fr); }
.grid-2  { grid-template-columns: repeat(2, 1fr); }
.grid-3  { grid-template-columns: repeat(3, 1fr); }
.grid-4  { grid-template-columns: repeat(4, 1fr); }
.grid-kpi   { grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); }
.grid-cards { grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }
.grid-auto  { grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }

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

/* Span utilities for the 12-col .grid */
.col-2 { grid-column: span 2; } .col-3 { grid-column: span 3; }
.col-4 { grid-column: span 4; } .col-5 { grid-column: span 5; }
.col-6 { grid-column: span 6; } .col-7 { grid-column: span 7; }
.col-8 { grid-column: span 8; } .col-9 { grid-column: span 9; }
.col-12{ grid-column: span 12; }
@media (max-width: 900px) {
  .col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9 { grid-column: span 12; }
}

/* ============================================================
   TEXT UTILITIES
   ============================================================ */
.text-soft   { color: var(--color-text-soft); }
.text-muted  { color: var(--color-text-muted); }
.text-accent { color: var(--color-accent); }
.text-light  { font-weight: var(--weight-light); }   /* 300 - large lede only */
.measure     { max-width: var(--measure); }
.mono        { font-family: var(--font-mono); }
.tnum        { font-variant-numeric: tabular-nums; }

/* ============================================================
   EYEBROW  (uppercase mono kicker above a heading)
   ============================================================ */
.eyebrow {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-weight: var(--weight-bold);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-accent);
}

/* ============================================================
   REDUCED MOTION
   ============================================================ */
@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;
  }
}
