/* ===========================================================================
   PalSingles design tokens — the single source of truth
   ===========================================================================

   Every colour, space, radius and type decision on the site resolves to a
   value in this file. Nothing else should contain a raw hex, a magic pixel
   gap, or a font stack. If you need a value that isn't here, add it here.

   Documented in BRANDING.md. Contrast ratios are measured, not assumed — see
   the checker referenced in that file, and re-run it after any colour edit.

   ---------------------------------------------------------------------------
   The one rule that makes three greens work
   ---------------------------------------------------------------------------
   Green appears in three different jobs on this site, so each one is pinned to
   a different SHAPE, not just a different shade:

     GREEN = ACTIONABLE   --brand, on solid fills and links. Buttons, links,
                          focus rings, the logo, and the in-stock dot (a card
                          you can actually buy is an actionable thing).
     GREEN = FACTION      --faction-green, only ever a 3px stripe or an
                          outlined pill, and always next to the word "Green".
                          Never a solid button, never a link colour.
     Availability         never encoded by hue alone. A stock state is a dot
                          plus a word, so it survives greyscale and colour
                          blindness.

   Faction colour is data. Brand colour is interaction. Keep them apart.
   =========================================================================== */

:root {
  /* -------------------------------------------------------------------------
     Surfaces — near-black slate so card images and prices carry the page
     ------------------------------------------------------------------------- */
  --surface-0: #0F1216;   /* page background */
  --surface-1: #171B21;   /* panels, tiles, header, footer */
  --surface-2: #212731;   /* raised: inputs, wells, art placeholders */
  --surface-3: #2B323C;   /* hover state of a raised thing */
  --surface-inset: #0B0E12; /* pressed / recessed, darker than the page */

  --border: #2B323C;         /* decorative separation between panels */
  /* An input outline is a UI boundary, so WCAG wants 3:1 against BOTH the
     panel and the raised surface it can sit on. #667283 is the first value up
     the ramp that clears it on both; anything darker looked fine and failed. */
  --border-strong: #667283;
  --border-hover: #808C9C;

  /* -------------------------------------------------------------------------
     Text
     ------------------------------------------------------------------------- */
  --text-strong: #F2F5F7;
  --text-muted: #A5B0BC;
  --text-faint: #8894A2;   /* uppercase micro-labels only, never prose */
  --text-on-light: #1A1F26; /* packing slip and other print-first surfaces */

  /* -------------------------------------------------------------------------
     Brand — signature green. Interactive things, and only interactive things.
     ------------------------------------------------------------------------- */
  --brand: #35C46A;
  --brand-rgb: 53 196 106;
  --brand-hover: #52D584;
  --brand-press: #29A455;
  --brand-fg: #04180B;    /* label sitting on a solid brand fill */
  --brand-dim: #1E6B3C;   /* brand at rest on a dark surface: progress tracks */

  /* -------------------------------------------------------------------------
     Faction colours — mirror the game's card colours. Data, never interaction.
     `-fg`   text on a dark surface (lightened until it passes AA)
     `-on`   text sitting on top of the solid colour
     `-rgb`  for tinted backgrounds via rgb(var(--x) / <alpha>)
     ------------------------------------------------------------------------- */
  --faction-red: #E24C4B;
  --faction-red-rgb: 226 76 75;
  --faction-red-fg: #F58381;
  --faction-red-on: #2A0908;

  --faction-blue: #3B82C4;
  --faction-blue-rgb: 59 130 196;
  --faction-blue-fg: #79B4E6;
  --faction-blue-on: #04121F;

  --faction-green: #3FA05A;
  --faction-green-rgb: 63 160 90;
  --faction-green-fg: #6FCB89;
  --faction-green-on: #04160A;

  --faction-purple: #8B5CF6;
  --faction-purple-rgb: 139 92 246;
  --faction-purple-fg: #B69BFB;
  /* White on this purple is only 4.23:1 — near-black clears 4.5:1 instead. */
  --faction-purple-on: #0D0418;

  /* The catalogue has a fifth colour the brief didn't list. It is a real
     value in the data (validate.js COLORS) so it needs a real token. */
  --faction-colorless: #8B97A8;
  --faction-colorless-rgb: 139 151 168;
  --faction-colorless-fg: #AFB9C6;
  --faction-colorless-on: #0D1116;

  /* -------------------------------------------------------------------------
     Marketplace semantics
     ------------------------------------------------------------------------- */
  --price: #F2F5F7;        /* the number a buyer is scanning for */
  --price-muted: #A5B0BC;  /* struck-through or secondary price */
  --sale: #F58381;

  --in-stock: #35C46A;
  --in-stock-rgb: 53 196 106;
  --low-stock: #E0A100;
  --low-stock-rgb: 224 161 0;
  --low-stock-fg: #EFBB3F;
  --out-of-stock: #8894A2;
  --out-of-stock-fg: #A5B0BC;

  --success: #35C46A;
  --success-rgb: 53 196 106;
  --success-fg: #63D58C;
  --warning: #E0A100;
  --warning-rgb: 224 161 0;
  --warning-fg: #EFBB3F;
  --error: #E2504C;
  --error-rgb: 226 80 76;
  --error-fg: #F58381;
  --info: #3B82C4;
  --info-rgb: 59 130 196;
  --info-fg: #79B4E6;

  /* Standard tint strengths, so a status wash is never an ad-hoc alpha. */
  --tint-weak: 0.08;
  --tint: 0.14;
  --tint-strong: 0.22;

  /* -------------------------------------------------------------------------
     Admin chrome — deliberately NOT storefront green, so it is impossible to
     mistake the admin bar for the shop at a glance.
     ------------------------------------------------------------------------- */
  --admin-bg: #201A12;
  --admin-border: #3D3120;
  --admin-fg: #E8C89A;
  --admin-accent: #E0A100;
  --admin-accent-rgb: 224 161 0;

  /* -------------------------------------------------------------------------
     Paper — the packing slip is print-first and must stay ink-on-white
     whatever the screen theme is. Tokenised so it is documented, not so it is
     themeable. Do not point these at the surface ramp.
     ------------------------------------------------------------------------- */
  --paper: #FFFFFF;
  --paper-ink: #111111;
  --paper-ink-muted: #555555;
  /* #777 was the inherited value and misses AA on white by 0.02:1. */
  --paper-ink-faint: #6E6E6E;
  --paper-rule: #E6E6E6;
  --paper-rule-strong: #111111;
  --paper-tick: #999999;

  /* -------------------------------------------------------------------------
     Typography
     ------------------------------------------------------------------------- */
  --font-display: 'Space Grotesk', 'Inter', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --font-ui: 'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;

  --text-2xs: 10px;
  --text-xs: 11px;
  --text-sm: 12.5px;
  --text-md: 14px;
  --text-base: 16px;
  --text-lg: 18px;
  --text-xl: 21px;
  --text-2xl: 26px;
  --text-3xl: 32px;
  --text-4xl: 40px;

  --weight-normal: 400;
  --weight-medium: 500;
  --weight-semibold: 600;
  --weight-bold: 700;
  --weight-black: 800;

  --leading-tight: 1.14;
  --leading-snug: 1.32;
  --leading-normal: 1.55;
  --leading-relaxed: 1.68;

  --tracking-tight: -0.022em;
  --tracking-normal: 0;
  --tracking-wide: 0.04em;
  --tracking-caps: 0.085em;

  /* -------------------------------------------------------------------------
     Space — 4px base. Use the scale; don't invent gaps.
     ------------------------------------------------------------------------- */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 20px;
  --space-6: 24px;
  --space-7: 32px;
  --space-8: 40px;
  --space-9: 56px;
  --space-10: 72px;

  /* -------------------------------------------------------------------------
     Radii, shadows, motion
     ------------------------------------------------------------------------- */
  --radius-sm: 6px;
  --radius-md: 10px;
  --radius-lg: 14px;
  --radius-xl: 20px;
  --radius-pill: 999px;
  /* Kept as an alias: a lot of existing rules say var(--radius). */
  --radius: var(--radius-md);

  /* Scrim for labels laid over card art: darker than any surface so a price
     stays legible whatever the scan behind it looks like. */
  --scrim-rgb: 10 12 16;

  --shadow-sm: 0 1px 2px rgb(0 0 0 / 0.35);
  --shadow-md: 0 4px 14px rgb(0 0 0 / 0.4);
  --shadow-lg: 0 10px 30px rgb(0 0 0 / 0.5);
  --shadow-inset: inset 0 1px 0 rgb(255 255 255 / 0.04);

  --dur-fast: 120ms;
  --dur-med: 200ms;
  --ease: cubic-bezier(0.4, 0, 0.2, 1);

  /* -------------------------------------------------------------------------
     Layout
     ------------------------------------------------------------------------- */
  --wrap-max: 1180px;
  --wrap-pad: 16px;
  --prose-max: 68ch;
  --card-aspect: 400 / 558;   /* the physical proportions of a TCG card */

  --z-header: 50;
  --z-overlay: 100;
}

/* Anyone who has asked their OS to calm down gets no transforms or transitions.
   Declared here rather than in styles.css because it is a token-level policy. */
@media (prefers-reduced-motion: reduce) {
  :root {
    --dur-fast: 0ms;
    --dur-med: 0ms;
  }
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ===========================================================================
   Self-hosted variable fonts
   ===========================================================================
   woff2, served same-origin. The CSP declares default-src 'self' and no
   font-src, so fonts inherit 'self' — self-hosting works with no CSP change,
   and a Google Fonts CDN link would be blocked. Keep it that way: it is also
   one fewer third party watching your buyers.

   font-display: swap — text renders immediately in the fallback and reflows
   when the file lands. On a storefront a visible price beats a perfect one. */

@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url('/fonts/inter-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url('/fonts/inter-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7,
    U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF,
    U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

@font-face {
  font-family: 'Space Grotesk';
  font-style: normal;
  font-weight: 500 700;
  font-display: swap;
  src: url('/fonts/space-grotesk-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA,
    U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193,
    U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Space Grotesk';
  font-style: normal;
  font-weight: 500 700;
  font-display: swap;
  src: url('/fonts/space-grotesk-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7,
    U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF,
    U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
