/* ============================================================================
 * design-tokens.css — Usability-heuristics remediation (type scale, text
 * colours, button components)
 * ----------------------------------------------------------------------------
 * WHAT THIS IS
 *   A drop-in, additive stylesheet. It defines ONE type scale, ONE text-colour
 *   ramp and ONE set of button components, then re-maps the ad-hoc utilities
 *   already in the markup onto them. Remove the <link> and you are back.
 *
 * WHY A SEPARATE FILE INSTEAD OF EDITING 200 class="" attributes
 *   Same reason as gsmwhale-contrast-fix.css: it is reversible, it does not
 *   touch the ~944 frozen #03D9F0 brand literals, and it follows the pattern
 *   this codebase already trusts (":root { --gw-* }" + "html:not(.dark)" and
 *   "html.dark" guards).
 *
 * HOW TO WIRE IT UP  (add AFTER gsmwhale-contrast-fix.css in each page)
 *   <link rel="stylesheet" href="assets/css/design-tokens.css?v=1">
 *
 * SPECIFICITY NOTE — IMPORTANT
 *   tailwindcss is loaded from the CDN and injects its generated rules into
 *   <head> at runtime, i.e. AFTER this file. A bare ".text-[11px]" here would
 *   lose on source order (equal specificity, Tailwind last). Every remap
 *   therefore adds the "html" / "html.dark" / "html:not(.dark)" prefix, which
 *   raises specificity above a single Tailwind class. Keep that prefix if you
 *   edit these rules.
 *
 * COMMENT SAFETY - NEVER PUT A COMMENT TERMINATOR INSIDE A COMMENT
 *   Line 33 of this header used to read "--gw-perf-" immediately followed by a
 *   comment terminator and then "--gw-seo-*". That embedded terminator closed
 *   the comment early, making the next line terminator a stray token at top
 *   level. CSS error recovery then skips to the next opening brace and DISCARDS
 *   that block - which was the section-1 ":root" type scale. Result: every
 *   "font-size: var(--gw-fs-*)" below became invalid at computed-value time and
 *   fell back to `inherit`, so the entire 7-step scale silently stopped
 *   applying (the hero h1 rendered at 16px instead of ~63px). Write
 *   "--gw-perf-* / --gw-seo-*" with spaces. If a token ever resolves to empty,
 *   count this file comment-open and comment-close markers and make them equal.
 *
 * WHAT THIS FIXES
 *   #1  18 distinct font sizes   -> 7 steps
 *   #2  49 distinct text colours -> 11 roles
 *   #3  20 button styles         -> 5 components (.gw-btn + 4 modifiers)
 *   #4/#7/#8  sub-12px body copy -> floored at 12px
 *   #9  theme-frozen "Zero wait" card (index.html) -> --gw-zero-* tokens (§7)
 *   #10 theme-frozen Performance + SEO cards      -> --gw-perf-* / --gw-seo-* (§8)
 * ==========================================================================*/

/* ---------------------------------------------------------------------------
 * 1. TYPE SCALE — 7 steps. Every font size on the page resolves to one of
 *    these. New markup should use the .gw-fs-* utilities below; the remap in
 *    §2 keeps legacy markup correct in the meantime.
 * ------------------------------------------------------------------------- */
:root {
    --gw-fs-hero: clamp(2.25rem, 5vw, 4.5rem);
    /* was: text-responsive-xl, 5xl, 4xl, 3xl */
    --gw-fs-title: clamp(1.5rem, 2.4vw, 2rem);
    /* was: 2xl, [1.85rem], [1.75rem], [1.6rem], [1.9rem] */
    --gw-fs-sub: 1.25rem;
    /* was: xl, lg, base */
    --gw-fs-body: 0.875rem;
    /* was: sm, 13, 13.5, 14, 14.5, 15, 16, 17 */
    --gw-fs-sm: 0.8125rem;
    /* was: 12, 12.5 */
    --gw-fs-xs: 0.75rem;
    /* was: xs, 10, 10.5, 11, 11.5  <- 12px floor for body copy */
    --gw-fs-micro: 0.6875rem;
    /* was: 8, 8.5, 9, 9.5          <- labels only, never body copy */
}

/* Utilities for any NEW markup. */
.gw-fs-hero {
    font-size: var(--gw-fs-hero)
}

.gw-fs-title {
    font-size: var(--gw-fs-title)
}

.gw-fs-sub {
    font-size: var(--gw-fs-sub)
}

.gw-fs-body {
    font-size: var(--gw-fs-body)
}

.gw-fs-sm {
    font-size: var(--gw-fs-sm)
}

.gw-fs-xs {
    font-size: var(--gw-fs-xs)
}

.gw-fs-micro {
    font-size: var(--gw-fs-micro)
}

/* ---------------------------------------------------------------------------
 * 2. TYPE REMAP — collapse the 17 ad-hoc px values + 9 Tailwind steps onto
 *    the 7-step scale. Nothing below 12px is used for prose any more.
 * ------------------------------------------------------------------------- */
html .text-responsive-xl,
html .text-5xl,
html .text-4xl,
html .text-3xl {
    font-size: var(--gw-fs-hero)
}

html .text-2xl,
html .text-\[1\.85rem\],
html .text-\[1\.75rem\],
html .text-\[1\.9rem\],
html .text-\[1\.6rem\] {
    font-size: var(--gw-fs-title)
}

html .text-xl,
html .text-lg,
html .text-base {
    font-size: var(--gw-fs-sub)
}

html .text-sm,
html .text-\[13px\],
html .text-\[13\.5px\],
html .text-\[14px\],
html .text-\[14\.5px\],
html .text-\[15px\],
html .text-\[16px\],
html .text-\[17px\] {
    font-size: var(--gw-fs-body)
}

html .text-\[12px\],
html .text-\[12\.5px\] {
    font-size: var(--gw-fs-sm)
}

html .text-xs,
html .text-\[10px\],
html .text-\[10\.5px\],
html .text-\[11px\],
html .text-\[11\.5px\] {
    font-size: var(--gw-fs-xs)
}

/* The 8–9.5px band survives ONLY as a micro-label size (badges, eyebrows,
   axis labels). It is never body copy — see the copy fixes in index.html. */
html .text-\[8px\],
html .text-\[8\.5px\],
html .text-\[9px\],
html .text-\[9\.5px\] {
    font-size: var(--gw-fs-micro)
}

/* ---------------------------------------------------------------------------
 * 3. TEXT COLOUR ROLES — 11 semantic roles. Light and dark each get their own
 *    value; dark stays byte-for-byte where it already passed AA.
 * ------------------------------------------------------------------------- */
:root {
    --gw-ink-strong: #18181b;
    /* headings */
    --gw-ink-body: #3f3f46;
    /* body copy */
    --gw-ink-muted: #52525b;
    /* secondary / supporting copy */
    --gw-ink-faint: #71717a;
    /* eyebrows, hints, table meta */
    --gw-ink-invert: #fafafa;
    /* text on dark surfaces */
    --gw-ink-brand: #0e7c8c;
    /* AA-safe cyan on light */
    --gw-ink-success: #047857;
    --gw-ink-warning: #b45309;
    --gw-ink-info: #0e7490;
    --gw-ink-danger: #be123c;
    --gw-ink-accent: #7c3aed;
}

html.dark {
    --gw-ink-strong: #fafafa;
    --gw-ink-body: #d4d4d8;
    --gw-ink-muted: #a1a1aa;
    --gw-ink-faint: #8f8f98;
    --gw-ink-invert: #fafafa;
    --gw-ink-brand: #03d9f0;
    --gw-ink-success: #10b981;
    --gw-ink-warning: #f59e0b;
    --gw-ink-info: #22d3ee;
    --gw-ink-danger: #fb7185;
    --gw-ink-accent: #a78bfa;
}

/* Strong / headings ------------------------------------------------------- */
html:not(.dark) .text-zinc-900,
html:not(.dark) .text-zinc-800,
html:not(.dark) .text-slate-900 {
    color: var(--gw-ink-strong)
}

html.dark .dark\:text-zinc-50,
html.dark .dark\:text-zinc-100,
html.dark .dark\:text-white,
html.dark .dark\:text-slate-50 {
    color: var(--gw-ink-strong)
}

/* Body copy --------------------------------------------------------------- */
html:not(.dark) .text-zinc-700,
html:not(.dark) .text-zinc-600,
html:not(.dark) .text-slate-600,
html:not(.dark) .text-slate-700 {
    color: var(--gw-ink-body)
}

html.dark .dark\:text-zinc-300,
html.dark .dark\:text-zinc-400,
html.dark .dark\:text-slate-300 {
    color: var(--gw-ink-body)
}

/* Muted / supporting ------------------------------------------------------ */
html:not(.dark) .text-zinc-500,
html:not(.dark) .text-slate-500 {
    color: var(--gw-ink-muted)
}

html.dark .dark\:text-zinc-500,
html.dark .dark\:text-slate-400 {
    color: var(--gw-ink-muted)
}

/* Faint: eyebrows, stat labels, table meta -------------------------------- */
html:not(.dark) .text-zinc-400,
html:not(.dark) .text-slate-400 {
    color: var(--gw-ink-faint)
}

/* Near-white text always sits on a dark surface; collapse to one value so the
   palette stops carrying five near-identical greys. */
html:not(.dark) .text-zinc-50,
html:not(.dark) .text-zinc-100,
html:not(.dark) .text-zinc-200,
html:not(.dark) .text-slate-50,
html:not(.dark) .text-slate-300 {
    color: var(--gw-ink-invert)
}

html.dark .dark\:text-zinc-200 {
    color: var(--gw-ink-invert)
}

/* Semantic ---------------------------------------------------------------- */
html:not(.dark) .text-emerald-500,
html:not(.dark) .text-emerald-600,
html:not(.dark) .text-emerald-400,
html:not(.dark) .text-emerald-300 {
    color: var(--gw-ink-success)
}

html.dark .dark\:text-emerald-400,
html.dark .dark\:text-emerald-300 {
    color: var(--gw-ink-success)
}

html:not(.dark) .text-amber-600,
html:not(.dark) .text-amber-400,
html:not(.dark) .text-amber-300 {
    color: var(--gw-ink-warning)
}

html.dark .dark\:text-amber-400,
html.dark .dark\:text-amber-300 {
    color: var(--gw-ink-warning)
}

html:not(.dark) .text-cyan-700,
html:not(.dark) .text-cyan-600 {
    color: var(--gw-ink-info)
}

html.dark .text-cyan-400 {
    color: var(--gw-ink-info)
}

html:not(.dark) .text-rose-300,
html:not(.dark) .text-red-500,
html:not(.dark) .text-orange-500 {
    color: var(--gw-ink-danger)
}

html:not(.dark) .text-violet-500,
html:not(.dark) .text-violet-400 {
    color: var(--gw-ink-accent)
}

/* ---------------------------------------------------------------------------
 * 4. CAPS DISCIPLINE
 *    All-caps is reserved for short labels (<= ~20 chars). Anything longer
 *    reads faster in sentence case; use .gw-label for the short ones so the
 *    size + tracking stay in one place.
 * ------------------------------------------------------------------------- */
.gw-label {
    font-size: var(--gw-fs-micro);
    text-transform: uppercase;
    letter-spacing: .14em;
    font-weight: 700
}

/* Sentence-case partner for .gw-label — same optical rhythm, no caps. */
.gw-label-text {
    font-size: var(--gw-fs-xs);
    text-transform: none;
    letter-spacing: .01em
}

/* ---------------------------------------------------------------------------
 * 5. TRUNCATION — never hide content with no way to recover it.
 *    .gw-clamp-2 keeps a hard two-line box (so cards stay equal height) but
 *    shows both lines instead of an ellipsis on line one.
 * ------------------------------------------------------------------------- */
.gw-clamp-2 {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    line-clamp: 2;
    overflow: hidden;
    overflow-wrap: anywhere;
    white-space: normal
}

/* ---------------------------------------------------------------------------
 * 6. BUTTONS — 5 components cover every button on the page.
 *
 *      .gw-btn                 base: layout + type + focus
 *      .gw-btn--primary        brand fill    (hero "Start free", section CTAs)
 *      .gw-btn--success        emerald fill  (pricing / auth submit)
 *      .gw-btn--secondary      outline       (hero "Live demo", neutral CTAs)
 *      .gw-btn--ghost          text link     ("Log in", tertiary actions)
 *      .gw-btn--block / --sm   size modifiers
 *
 *    Sentence case throughout: short caps on 2 hero buttons was the only
 *    place caps were used, and mixed casing across 10 CTAs was itself one of
 *    the 20 "styles" the audit counted.
 * ------------------------------------------------------------------------- */
.gw-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: .5rem;
    border: 1px solid transparent;
    border-radius: .75rem;
    padding: .875rem 1.75rem;
    font-family: 'Chakra Petch', Rajdhani, Inter, ui-sans-serif, system-ui, sans-serif;
    font-size: var(--gw-fs-body);
    font-weight: 700;
    line-height: 1.2;
    letter-spacing: .005em;
    text-transform: none;
    text-decoration: none;
    cursor: pointer;
    transition: transform .2s ease, background-color .2s ease, border-color .2s ease, box-shadow .2s ease, opacity .2s ease
}

.gw-btn svg {
    flex: none
}

.gw-btn--primary {
    background: #03D9F0;
    color: #04252b;
    box-shadow: 0 10px 30px rgba(3, 217, 240, .32)
}

.gw-btn--primary:hover {
    transform: scale(1.03)
}

.gw-btn--success {
    background: linear-gradient(90deg, #10b981, #0d9488);
    color: #fff;
    box-shadow: 0 1px 2px rgba(16, 185, 129, .2)
}

.gw-btn--success:hover {
    opacity: .95
}

.gw-btn--secondary {
    border-radius: 999px;
    background: rgba(255, 255, 255, .6);
    border-color: rgb(212, 212, 216);
    color: var(--gw-ink-body);
    backdrop-filter: blur(8px)
}

.gw-btn--secondary:hover {
    border-color: #03D9F0;
    background: #fff;
    box-shadow: 0 4px 14px rgba(0, 0, 0, .08)
}

html.dark .gw-btn--secondary {
    background: rgba(255, 255, 255, .05);
    border-color: rgba(255, 255, 255, .15);
    color: #e4e4e7
}

html.dark .gw-btn--secondary:hover {
    border-color: #03D9F0;
    background: rgba(255, 255, 255, .1)
}

.gw-btn--ghost {
    padding: .5rem .25rem;
    background: none;
    border-color: transparent;
    font-weight: 500;
    color: var(--gw-ink-muted)
}

.gw-btn--ghost:hover {
    color: var(--gw-ink-brand)
}

.gw-btn--sm {
    padding: .625rem 1rem;
    font-size: var(--gw-fs-sm)
}

.gw-btn--block {
    width: 100%
}

/* ---------------------------------------------------------------------------
 * 7. WHY SECTION — Column 2 "Zero wait" card (index.html)
 *
 *    That card paints a multi-stop gradient plus a gauge, an overlay and a
 *    progress bar, all from hardcoded inline colours. An inline style has no
 *    "dark:" hook, so the card rendered identically in both themes: a fully
 *    saturated green slab with near-black chips sitting inside a light page.
 *
 *    These tokens give the inline styles something theme-aware to reference.
 *    var() resolves per theme even when it is used inside a style="" attribute,
 *    which is what makes an otherwise frozen inline gradient flip.
 *
 *    Dark values reproduce the previous rendering exactly, so dark mode is
 *    unchanged; light mode becomes a pale emerald surface with dark ink.
 *
 *    NOTE: SVG presentation attributes (stroke="…", stop-color="…", fill="…")
 *    do NOT resolve var() — those must be written as style="stroke:var(…)".
 * ------------------------------------------------------------------------- */
:root {
    /* card + decoration */
    --gw-zero-bg-1: #ecfdf5;
    --gw-zero-bg-2: #bbf7d0;
    --gw-zero-bg-3: #86efac;
    --gw-zero-ray-a: rgba(255, 255, 255, .75);
    --gw-zero-ray-b: rgba(4, 120, 87, .10);
    --gw-zero-glow: rgba(255, 255, 255, .55);
    /* inner surfaces */
    --gw-zero-panel: rgba(255, 255, 255, .55);
    --gw-zero-pill: rgba(255, 255, 255, .85);
    --gw-zero-logo: #d1fae5;
    /* ink */
    --gw-zero-title: #064e3b;
    --gw-zero-text-dim: #065f46;
    /* gauge — the light ramp stops at emerald-700 so the filled arc still
       clears 3:1 (WCAG 1.4.11) against the translucent track behind it:
       #047857 on the composited track #bde2d0 = 3.90:1. A lighter stop
       (emerald-600 #059669) only reached 2.68:1 and read as one blob. */
    --gw-zero-gauge-1: #064e3b;
    --gw-zero-gauge-2: #065f46;
    --gw-zero-gauge-3: #047857;
    --gw-zero-track: rgba(6, 95, 70, .16);
    --gw-zero-ticks: rgba(6, 95, 70, .28);
    --gw-zero-dot: #ffffff;
    /* delivery bar */
    --gw-zero-bar-track: rgba(6, 95, 70, .13);
    --gw-zero-fill-1: #059669;
    --gw-zero-fill-2: #047857;
}

html.dark {
    --gw-zero-bg-1: #16a34a;
    --gw-zero-bg-2: #22c55e;
    --gw-zero-bg-3: #16a34a;
    --gw-zero-ray-a: rgba(255, 255, 255, .55);
    --gw-zero-ray-b: rgba(190, 255, 220, .18);
    --gw-zero-glow: rgba(255, 255, 255, .45);
    /* The dark card is a *bright* green slab, so the panel must do real work:
       it is the dark "screen" the gauge is drawn on. At .35 it only composited
       to rgb(69,170,117) and the white "Zero wait" label measured 2.89:1 --
       failing even the 3:1 large-text bar, and leaving the white track/ticks
       (which are authored for a dark surface) washed out. At .70 the panel
       composites to rgb(35,130,92) => 4.78:1 for white, clearing 4.5:1. */
    --gw-zero-panel: rgba(6, 95, 70, .70);
    --gw-zero-pill: rgba(24, 24, 27, .95);
    --gw-zero-logo: #ffffff;
    --gw-zero-title: #ffffff;
    --gw-zero-text-dim: rgba(255, 255, 255, .75);
    --gw-zero-gauge-1: #16a34a;
    --gw-zero-gauge-2: #4ade80;
    --gw-zero-gauge-3: #6ee7b7;
    --gw-zero-track: rgba(255, 255, 255, .16);
    --gw-zero-ticks: rgba(255, 255, 255, .45);
    --gw-zero-dot: #ffffff;
    --gw-zero-bar-track: rgba(255, 255, 255, .13);
    --gw-zero-fill-1: #6ee7b7;
    --gw-zero-fill-2: #22c55e;
}

/* ---------------------------------------------------------------------------
 * 8. WHY SECTION — Column 1 (Performance) and Column 3 (SEO storefront)
 *
 *    Same root cause as §7: both hero cards take their surface from a hardcoded
 *    inline gradient, so they stayed saturated slabs in light mode.
 *
 *    SCOPE DECISION — the inner mockups deliberately stay dark in BOTH themes.
 *    Column 1 wraps a near-black "YOUR PANEL" dashboard and Column 3 wraps a
 *    phone screen (`#08080c`); those read as product/device screenshots, which
 *    is normal on a light page. Only the card surface and the text sitting
 *    directly on it flip. So the tokens below cover the surface + that text,
 *    not the contents of the mockups.
 *
 *    Two PRE-EXISTING contrast bugs in Column 1's white card are fixed here as
 *    well: the trending-up glyph was #c084fc on its own chip (2.22:1 in light)
 *    and the stat-pill zap was #e9d5ff (1.18:1) — both effectively invisible.
 *    The chip glyph now reuses --gw-why-violet; the pill glyph gets
 *    --gw-why-pill-icon, which darkens only in light theme.
 * ------------------------------------------------------------------------- */
:root {
    /* Column 1 — white card accents (light only fix; dark unchanged) */
    --gw-why-pill-icon: #6b21a8;
    /* was #e9d5ff = 1.18:1 on the #f5ebfe pill */
    /* Column 1 — Performance hero surface */
    --gw-perf-glow: #ddd6fe;
    --gw-perf-bg-1: #f5f3ff;
    --gw-perf-bg-2: #ede9fe;
    --gw-perf-bg-3: #c4b5fd;
    --gw-perf-ripple: rgba(109, 40, 217, .10);
    /* Column 3 — SEO storefront surface + the ink that sits on it.
       title/body clear AA against the darkest stop (#ddd6fe): 10.66:1 / 7.22:1. */
    --gw-seo-bg-1: #fdf4ff;
    --gw-seo-bg-2: #fae8ff;
    --gw-seo-bg-3: #fbcfe8;
    --gw-seo-bg-4: #ddd6fe;
    --gw-seo-title: #4a044e;
    --gw-seo-body: #701a75;
    /* Phone bezel ring. The bezel itself is white-translucent, which vanishes
       on a pale card; a dark hairline keeps the handset reading as a device. */
    --gw-phone-ring: rgba(24, 24, 27, .18);
}

html.dark {
    --gw-why-pill-icon: #e9d5ff;
    --gw-perf-glow: #c084fc;
    --gw-perf-bg-1: #a855f7;
    --gw-perf-bg-2: #8b5cf6;
    --gw-perf-bg-3: #5b21b6;
    --gw-perf-ripple: rgba(255, 255, 255, .07);
    --gw-seo-bg-1: #0a0a10;
    --gw-seo-bg-2: #1b1018;
    --gw-seo-bg-3: #7d1d4a;
    --gw-seo-bg-4: #6d28d9;
    --gw-seo-title: #ffffff;
    --gw-seo-body: rgba(255, 255, 255, .65);
    --gw-phone-ring: rgba(255, 255, 255, .05);
}
