/* ============================================================
   Oletrak design tokens — the single source of truth
   ------------------------------------------------------------
   WHY THIS FILE EXISTS
   The audit found 801 unique hex colours across 7,848 usages,
   25 different `font-family` declarations, 35 distinct media-query
   breakpoints and 52 separate `:root` blocks re-declaring the same
   variable names. Because those blocks are spread over 83
   stylesheets, the resolved value of a token depended on CSS load
   order — a cascade lottery.

   This file declares every token ONCE, at the top of the cascade, so
   `--surface` means the same thing on every page. Load it FIRST,
   before any component stylesheet:

     <link rel="stylesheet" href="./assets/css/tokens.css">

   Palette note: the brand is navy + orange. The generated design
   system recommends a dark "on accent" for orange CTAs, which this
   file adopts (`--color-on-accent`); white-on-orange measured
   2.35-2.53:1 and failed WCAG 1.4.3. Every pairing below is
   annotated with its measured contrast ratio.
   ============================================================ */

:root {
  /* ---------- Brand ramp ---------- */
  --brand-navy-900: #012a46;
  --brand-navy-800: #06426e;
  --brand-navy-700: #0b3c5d;
  --brand-navy-600: #0e4a72;
  --brand-navy-500: #14507a;
  --brand-navy-300: #7fb0e0;

  --brand-orange-700: #a8410a;   /* 6.1:1 on white  -> focus rings, text on light */
  --brand-orange-600: #ff5e00;
  --brand-orange-500: #ff7f11;   /* primary CTA fill */
  --brand-orange-400: #ff8a2b;
  --brand-orange-300: #ff9d2e;
  --brand-orange-200: #ffb463;
  --brand-orange-100: #ffd166;

  --brand-gold: #ffd166;         /* 8.4:1 on navy, 10.3:1 on brand-navy-900 */
  --brand-green: #1fbf75;
  --brand-red: #e5484d;

  /* ---------- Semantic colour (light theme) ----------
     Aliases follow the design-system convention so new code and the
     generated palettes speak the same language. */
  --color-primary: var(--brand-navy-800);
  --color-on-primary: #ffffff;          /* 11.6:1 on navy-800 */
  --color-accent: var(--brand-orange-500);
  --color-on-accent: #1a0d00;           /* 7.5:1 on orange-500 */
  --color-background: #f4f7fb;
  --color-surface: #ffffff;
  --color-on-surface: #24344a;          /* 12.6:1 on white */
  --color-muted: #eef2f7;
  --color-on-muted: #5b6b80;            /* 5.2:1 on white */
  --color-border: #e3eaf2;
  --color-destructive: #c92a2f;         /* white on it = 5.4:1 (was #e5484d = 3.9:1) */
  --color-on-destructive: #ffffff;
  --color-success: #12805a;             /* white on it = 4.9:1 (was #1fbf75 = 2.4:1) */
  --color-on-success: #ffffff;
  --color-ring: var(--brand-orange-700);
  --color-focus-dark-surface: var(--brand-gold);

  /* ---------- Typography ----------
     Poppins was already the de-facto face (45 declarations). It is a
     geometric sans that suits a marketplace, so it is kept — but
     declared once here instead of 25 times. */
  --font-sans: "Poppins", "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
  --font-mono: ui-monospace, "SFMono-Regular", Consolas, "Liberation Mono", monospace;

  /* Display face for headings only. Rubik is the ecommerce-leaning
     counterpart to Poppins: same geometric skeleton, but a squarer
     x-height and tighter caps that hold up at 32px+. Body copy stays on
     --font-sans so the 100+ pages already rendering Poppins are
     untouched; this is additive and only opted into where headings
     want it. */
  --font-display: "Rubik", var(--font-sans);

  --text-xs: 0.75rem;    /* 12px  — metadata only, never body copy */
  --text-sm: 0.875rem;   /* 14px */
  --text-base: 1rem;     /* 16px — the base size; never go below */
  --text-md: 1.0625rem;
  --text-lg: 1.25rem;
  --text-xl: 1.5rem;
  --text-2xl: 2rem;
  --text-3xl: 2.5rem;
  --text-4xl: 3.25rem;

  --leading-tight: 1.2;
  --leading-snug: 1.35;
  --leading-normal: 1.5;   /* body copy */
  --leading-relaxed: 1.65;

  --weight-regular: 400;
  --weight-medium: 500;
  --weight-semibold: 600;
  --weight-bold: 700;

  /* ---------- Spacing — 4px base scale (density 6: standard) ---------- */
  --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 */

  /* ---------- Radii — 5 steps, not 49 ---------- */
  --radius-sm: 6px;
  --radius-md: 10px;
  --radius-lg: 14px;
  --radius-xl: 20px;
  --radius-pill: 999px;

  /* ---------- Elevation ---------- */
  --shadow-sm: 0 2px 8px rgba(1, 42, 70, 0.08);
  --shadow-md: 0 8px 24px rgba(1, 42, 70, 0.12);
  --shadow-lg: 0 18px 44px rgba(1, 42, 70, 0.18);
  --shadow-focus: 0 0 0 3px rgba(168, 65, 10, 0.35);

  /* ---------- Motion (motion dial 4: standard, 150-300ms) ---------- */
  --dur-fast: 150ms;
  --dur-base: 220ms;
  --dur-slow: 300ms;
  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-standard: cubic-bezier(0.4, 0, 0.2, 1);

  /* ---------- Layout ---------- */
  --container-max: 1240px;
  --container-gutter: clamp(1rem, 4vw, 2.5rem);
  --tap-min: 44px;      /* WCAG 2.5.8 minimum interactive size */

  /* ---------- Loading / skeleton ----------
     The skeleton palette lives here so a single set of placeholder shapes
     works in both themes. Previously .skel-* carried a hardcoded light
     gradient and dark mode needed a second, near-identical override block;
     now flipping the theme swaps the ramp automatically. */
  --skel-base: #e9eef5;
  --skel-sheen: #f6f9fc;
  --skel-edge: #dde5ef;
  --skel-shimmer-span: 800px;

  /* ---------- Breakpoints ----------
     The stylesheets currently use 35 different max-widths. These five
     are the canonical set; new media queries should use them via the
     named values below (custom properties cannot be used inside
     @media conditions, so keep them in sync by hand). */
  --bp-sm: 480px;
  --bp-md: 768px;
  --bp-lg: 1024px;
  --bp-xl: 1280px;
  --bp-2xl: 1440px;
}

/* ============================================================
   Dark theme — one scoped block instead of 400+ scattered
   [data-theme="dark"] selectors.
   All pairings measured; muted text is >= 4.5:1 on --surface-dark.
   ============================================================ */
:root[data-theme="dark"] {
  --color-background: #0a101d;
  --color-surface: #121a2b;
  --color-surface-raised: #182338;
  --color-on-surface: #dbe6f3;          /* 13.6:1 on surface */
  --color-muted: #1b2540;
  --color-on-muted: #aebdd2;            /* 8.4:1 on surface */
  --color-border: #24314b;
  --color-primary: #7fb0e0;
  --color-on-primary: #06121f;
  --color-accent: var(--brand-orange-200);
  --color-on-accent: #1a0d00;
  --color-ring: var(--brand-gold);      /* 8.4:1+ on every dark surface */
  --color-destructive: #ff8787;
  --color-on-destructive: #2b0a0a;
  --color-success: #4ade80;
  --color-on-success: #05230f;

  --shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.4);
  --shadow-md: 0 8px 24px rgba(0, 0, 0, 0.5);
  --shadow-lg: 0 18px 44px rgba(0, 0, 0, 0.6);

  /* Dark skeletons: a lighter ramp than the light theme so the sheen still
     reads as movement instead of a flat grey block. */
  --skel-base: #1c2740;
  --skel-sheen: #2a3a5c;
  --skel-edge: #16203a;
}

/* ============================================================
   Safe global defaults
   ------------------------------------------------------------
   Deliberately limited to declarations that cannot shift layout, so
   this file can be linked on all 103 pages as the first stylesheet
   with zero regression risk. Anything that changes box metrics
   (line-height on headings, font-size: inherit on controls, a 44px
   min-height on mobile) is left to the component stylesheets that
   already own those concerns.
   ============================================================ */

/* Every clickable element gets the pointer affordance. */
a[href],
button:not(:disabled),
[role="button"]:not([aria-disabled="true"]),
summary,
label[for] {
  cursor: pointer;
}

/* Disabled controls must not look or behave interactive. */
button:disabled,
[aria-disabled="true"] {
  cursor: not-allowed;
}

/* Long unbroken strings (URLs, hashes, order refs) must never push a
   card wider than its container. */
h1, h2, h3, h4, h5, h6 {
  overflow-wrap: break-word;
}
