/* ==========================================================================
   rexchekal.com — design system tokens
   Source: Figma "Brand Rex", frame rexchekal.com_ai-lead (153:24), grid
   style "12". Every value below is read from that file or derived from its
   grid; see docs/DESIGN_SYSTEM.md for the reasoning and the component map.

   Two tiers. PRIMITIVES are raw values and are never used by components.
   ROLES name what a value is for and reference primitives with var() only,
   so re-skinning or adding a theme means changing roles, not components.
   ========================================================================== */

@import url('https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@300;400;500;600;700&family=IBM+Plex+Sans:wght@400;500&display=swap');

@font-face {
  font-family: 'PP Mondwest';
  src: url('fonts/PPMondwest-Regular.otf') format('opentype');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

:root {
  /* ---- COLOUR: written by assets/theme.js --------------------------------
     One colour in, a whole theme out; see the header of theme.js. These are
     the Ink theme's paper-mode values, the fallback when JavaScript is off.
     No pure white and no pure black anywhere: both ends carry a hue.

     --ground / --ink        the page and the text on it
     --panel                 cards: the ground one step toward the ink
     --image                 photo placeholders: two steps toward the ink
     --muted                 secondary text, held at 6:1 or better
     --disabled              an inactive button: the faintest ink at 3:1
     --ground-inv / --ink-inv / --muted-inv
                             the inverse band (footer): the same pair, flipped
     --primary / --partner   the colour and its tinted near-white or near-black

     Alphas are the ink at a percentage, never a new colour: a rule is 18%,
     a hover ground 9%, a pressed ground 16%. Those carry no text.          */
  /* primitives: the only raw colours in the system, the Ink theme's pair */
  --tint-light: #F6F7F7;
  --tint-dark:  #15161A;

  /* roles: theme.js overwrites these; the expressions are the no-JS path */
  --primary:    var(--tint-dark);
  --partner:    var(--tint-light);
  --ground:     var(--tint-light);
  --ink:        var(--tint-dark);
  --panel:      color-mix(in oklab, var(--ground) 95%, var(--ink));
  --image:      color-mix(in oklab, var(--ground) 90%, var(--ink));
  --muted:      color-mix(in oklab, var(--ink) 70%, var(--ground));
  --disabled:   color-mix(in oklab, var(--ink) 45%, var(--ground));
  --ink-hover:  var(--muted);   /* a link hovered on a card; theme.js sets the real value */
  --ground-inv: var(--tint-dark);
  --ink-inv:    var(--tint-light);
  --muted-inv:  color-mix(in oklab, var(--ink-inv) 60%, var(--ground-inv));
  --disabled-inv: color-mix(in oklab, var(--ink-inv) 45%, var(--ground-inv));

  --rule:        color-mix(in srgb, currentColor 18%, transparent);
  --ghost:       color-mix(in srgb, currentColor 9%,  transparent);
  --ghost-press: color-mix(in srgb, currentColor 16%, transparent);

  /* ---- ROLES: faces ---------------------------------------------------- */
  --display: 'PP Mondwest', ui-serif, Georgia, serif;            /* every heading */
  --mono:    'IBM Plex Mono', ui-monospace, 'SF Mono', Menlo, monospace; /* meta text, buttons */
  --text:    'IBM Plex Sans', ui-sans-serif, system-ui, sans-serif;  /* body prose */

  /* ---- GRID: straight from Figma's grid style "12" ---------------------
     12 columns, 40 gutter, 40 margin, stretch. So a column is
     (1440 - 2*40 - 11*40) / 12 = 76.67px, and N columns span
     N*76.67 + (N-1)*40. Place things with the .span-/.start- utilities in
     site.css rather than writing pixel widths.                            */
  --frame:   1440px;
  --cols:    12;
  --margin:  40px;                     /* outside the columns  (Figma: margin) */
  --gutter:  40px;                     /* between the columns  (Figma: gutter) */

  /* Distance from the viewport edge to the first column. A plain length on
     purpose: full-bleed rails use it for margin, padding and scroll-padding,
     and a percentage in scroll-padding resolves against the scrollport, not
     the containing block, which parks the rail already scrolled. */
  --inset: max(var(--margin), calc((100vw - var(--frame)) / 2 + var(--margin)));
  /* One column at the current width, and one column plus its gutter (a step):
     the rails size cards in columns, and the homepage indents a first line one step. */
  --col:  calc((min(100vw, var(--frame)) - 2 * var(--margin) - (var(--cols) - 1) * var(--gutter)) / var(--cols));
  --step: calc(var(--col) + var(--gutter));

  /* ---- SPACING ---------------------------------------------------------
     The frame's own values, on a scale. Two Figma artefacts were snapped
     onto it: 9.31 became 8, and the hero's 45 became 48.                   */
  --space-1:   4px;
  --space-2:   8px;
  --space-3:  16px;
  --space-4:  24px;     /* card padding */
  --space-5:  32px;
  --space-6:  40px;     /* = the gutter */
  --space-7:  48px;
  --space-8:  80px;
  --space-9: 112px;
  --section: 156px;     /* between every section, measured on all ten boundaries */
  --topbar:   99px;     /* the frame's header height, 153:136 */

  /* ---- TYPE ROLES ------------------------------------------------------
     Named for what they are. Fluid below the frame, exact at 1440.        */
  --type-hero:    clamp(2.5rem,  min(1.6rem + 4.0vw, 7vh), 4rem); /* 64  display; also bound by height, the hero must fit one screen */
  --type-feature: clamp(2rem,    1.1rem + 4.0vw, 4rem);     /* 64  display, case study title */
  --type-section: clamp(2rem,    1.5rem + 2.2vw, 3rem);     /* 48  display */
  --type-subhead: clamp(1.5rem,  1.2rem + 1.1vw, 2rem);     /* 32  display, h3 under a section h2 (2026-09-21: 24 sat too close to the 18 lede) */
  --type-card:    clamp(1.25rem, 1.1rem + 0.7vw, 1.5rem);   /* 24  display */
  --type-lead:    clamp(1rem,    0.94rem + 0.3vw, 1.125rem);/* 18  text */
  --type-body:    0.9375rem;                                 /* 15  text */
  --type-label:   0.875rem;                                  /* 14  mono */
  /* Every button's weight, one value: Medium, chosen by Rex 2026-09-21
     over SemiBold and Bold (design/button-weights.html). */
  --btn-weight: 500;
  --type-micro:   0.75rem;                                   /* 12  mono; the frame's 10, raised to the legibility floor */
}

/* ---- base ------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  background: var(--ground);
  color: var(--ink);
  font-family: var(--text);
  font-size: var(--type-body);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}
img, svg { display: block; max-width: 100%; }
h1, h2, h3 { font-family: var(--display); font-weight: 400; line-height: 1.08; margin: 0; }
p { margin: 0; }
ul, ol { margin: 0; padding: 0; list-style: none; }
a { color: inherit; text-decoration: none; }

/* Set by theme.js for the frame a theme changes in: colours snap together
   rather than fading across. The switch is let through, because its motion
   is the feedback for the change and it only transitions transform. */
:root.theming *, :root.theming *::before, :root.theming *::after { transition: none !important; }
@media (prefers-reduced-motion: no-preference) {
  :root.theming .mode-knob { transition: transform 220ms cubic-bezier(.3, .7, .2, 1) !important; }
  :root.theming .mode-sun, :root.theming .mode-moon { transition: transform 280ms cubic-bezier(.34, 1.56, .64, 1) !important; }
}

@media (prefers-reduced-motion: reduce) {
  * { transition-duration: 1ms !important; animation-duration: 1ms !important; }
}
