/* ============================================================================
   MY FINANCIAL EDGE — FOUNDATION
   The design system, before any page layout: one layout unit and the grid
   cell it drives, the type roles, spacing, colour ramps, the outline / hard
   shadow / keycap language shared with the illustrations, and the primitives
   (keys, tiles, chips, fields, marks). Token names follow
   topper/v1/assets/foundation.css; the values are Edge's.

   Every size, colour and duration in styles.css comes from here.
   ========================================================================== */

:root {
  /* ---- the unit ---------------------------------------------------------- */
  /* 16px at the 1440 × 800 design. Grows with whichever runs out first, width
     or height, up to 1.5×; ultrawide width becomes layout (see --content). */
  --u: clamp(11px, min(100vw / 90, 100vh / 50), 24px);
  --p: max(1px, calc(var(--u) / 16));          /* one design pixel */

  /* ---- the grid: the page is graph paper ----------------------------------- */
  /* One cell is 56px at the design size. Section rhythm, tile sizes and art
     placement are whole cells. The content width is rounded down to an even
     number of cells so its edges land on grid lines (the grid is centred).
     It stops at 96u (26 cells at the 1.5× cap): a statement reads as one
     composition, so ultrawide screens keep it together and the paper, which
     runs edge to edge, carries the extra width. */
  --cell: calc(var(--u) * 3.5);
  --plus: calc(13 * var(--p));            /* registration marks at container corners */
  --gutter-min: calc(var(--u) * 3.5);
  --content: round(down, min(100vw - var(--gutter-min) * 2, var(--u) * 96), var(--cell) * 2);

  /* ---- type: seven roles --------------------------------------------------- */
  /*                                                              at 1440 */
  --type-figure:  max(56px, calc(var(--u) * 7));       /* 112 */
  --type-display: max(40px, calc(var(--u) * 4.5));     /*  72 */
  --type-title:   max(30px, calc(var(--u) * 3));       /*  48 */
  --type-heading: max(21px, calc(var(--u) * 1.5));     /*  24 */
  --type-lead:    max(18px, calc(var(--u) * 1.3125));  /*  21 */
  --type-body:    max(16px, calc(var(--u) * 1.0625));  /*  17 */
  --type-small:   max(14px, calc(var(--u) * .875));    /*  14 */

  /* Archivo's width axis, pinned so line breaks hold at every size. */
  --sans: 'Archivo', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --display: var(--sans);
  --display-stretch: 112%;
  --mono: 'Geist Mono', ui-monospace, SFMono-Regular, Menlo, monospace;

  /* ---- spacing: multiples of the unit -------------------------------------- */
  --space-1:  calc(var(--u) * .5);   /*   8 */
  --space-2:  var(--u);              /*  16 */
  --space-3:  calc(var(--u) * 1.5);  /*  24 */
  --space-4:  calc(var(--u) * 2);    /*  32 */
  --space-6:  calc(var(--u) * 3);    /*  48 */
  --space-8:  calc(var(--u) * 4);    /*  64 */
  --space-12: calc(var(--u) * 6);    /*  96 */

  --copy-width: calc(var(--u) * 34); /* reading measure */
  --nav-h: var(--cell);

  /* ---- colour -------------------------------------------------------------- */
  /* Semantic, and never broken: lime = gained, orange = missing,
     cobalt = data and action detail, ink = text and structure. */
  --ink-900: #0A0E1A;   /* ink: text, outlines, hard shadows */
  --ink-700: #262C45;
  --ink-600: #3C425C;
  --ink-500: #4A5170;   /* secondary text, 7.4:1 on paper */
  --ink-400: #7A8099;   /* large text and hairlines only */
  --ink-300: #A6ACC4;
  --ink-200: #CBD0E0;
  --ink-100: #E3E6F2;
  --ink-50:  #EEF0F7;

  --paper: #F6F7FB;
  --white: #FFFFFF;

  --lime-200: #F0FDB8;   /* wash */
  --lime-400: #D6FA4C;   /* gained, highlighter, primary key */
  --lime-500: #C4EA31;   /* hover */
  --lime-700: #7E9C12;   /* keycap side in art */

  --orange-200: #FFD9C4;
  --orange-300: #FFB48C;   /* peach */
  --orange-500: #FF6A2B;   /* missing: rings, markers, fills (never text) */

  --cobalt-100: #E4E8FF;
  --cobalt-300: #8E9CFF;   /* periwinkle, matched to the renders */
  --cobalt-500: #1A3AF5;   /* data, links, the closing block */
  --cobalt-600: #0F27C4;

  --grey-300: #C9D4E0;   /* idle tiles in the art */
  --grey-500: #8FA1B5;

  --ink:   var(--ink-900);
  --ink-2: var(--ink-500);
  --canvas: var(--paper);
  --surface: var(--white);
  --accent-text: var(--cobalt-500);   /* 6.9:1 on white */
  --line: var(--ink-100);
  --focus: var(--cobalt-500);

  --grid-line:  rgba(10, 14, 26, .045);
  --grid-major: rgba(10, 14, 26, .08);

  /* ---- emphasis: heavy ink means action or proof ---------------------------- */
  /* Two surface weights. Quiet paper (a hairline edge and a soft lift) is the
     default for everything. The drawn treatment (ink outline, hard shadow or
     keycap depth, borrowed from the illustrations) is reserved for what
     matters: the keys you press and the figures that prove the value. */
  --hairline: rgba(10, 14, 26, .12);
  --shadow-soft: 0 1px 2px rgba(10, 14, 26, .05), 0 18px 40px -24px rgba(10, 14, 26, .24);
  --stroke: max(1.5px, calc(2 * var(--p)));
  --shadow-tile: calc(6 * var(--p)) calc(6 * var(--p)) 0 0 var(--ink);
  --shadow-tile-sm: calc(4 * var(--p)) calc(4 * var(--p)) 0 0 var(--ink);
  --key-depth: calc(4 * var(--p));

  /* every illustration renders with this outline weight (tools/edge-art.py
     sizes each piece from its measured outline) */
  --art-line: calc(1.5 * var(--p));

  /* ---- shape ----------------------------------------------------------------- */
  --radius-key:   calc(12 * var(--p));
  --radius-tile:  0;                     /* containers are paper cut square */
  --radius-ink:   calc(14 * var(--p));   /* …except the emphasised ones, which stay rounded */
  --radius-chip:  calc(8 * var(--p));
  --control-height: calc(52 * var(--p));

  /* ---- motion: calm ambient, quick entrances ------------------------------- */
  --ease:     cubic-bezier(.2, .8, .2, 1);     /* entrances, state changes */
  --ease-key: cubic-bezier(.3, .7, .4, 1);     /* key press: snappy, no spring */
  --dur-key: 120ms;
  --dur-1:   240ms;
  --dur-2:   520ms;
}

/* ---- phones: their own unit and composition -------------------------------- */
@media (max-width: 767px) {
  :root {
    --u: clamp(13px, 3.6vw, 15px);
    --p: 1px;
    --art-line: 1px;
    /* the content is exactly eight cells, so with the grid centred its
       edges (and every container on it) land on lines here too */
    --gutter-min: 20px;
    --content: calc(100vw - 40px);
    --cell: calc(var(--content) / 8);
    --type-figure:  clamp(52px, 15vw, 64px);
    --type-display: clamp(36px, 10.6vw, 44px);
    --type-title:   clamp(30px, 8.2vw, 34px);
    --type-heading: 21px;
    --type-lead:    18px;
    --type-body:    16px;
    --type-small:   14px;
  }
}

/* ================================================================== base == */
*, *::before, *::after { box-sizing: border-box; }

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--cell) * 1.5);
}

body {
  margin: 0;
  background: var(--canvas);
  color: var(--ink);
  font-family: var(--sans);
  font-size: var(--type-body);
  font-weight: 500;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: clip;
}
body.lp-locked { overflow: hidden; }

h1, h2, h3, p, ul, ol, figure { margin: 0; }
ul, ol { padding: 0; list-style: none; }
button, input { font-family: inherit; }
img, svg { display: block; }

a { color: var(--accent-text); text-decoration: none; }

::selection { background: var(--lime-400); color: var(--ink); }
:focus-visible { outline: 3px solid var(--focus); outline-offset: 3px; border-radius: 4px; }

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

/* ============================================================ type roles == */
.t-figure {
  font-family: var(--display); font-stretch: var(--display-stretch);
  font-size: var(--type-figure); line-height: .9; font-weight: 900;
  letter-spacing: -.045em; font-variant-numeric: tabular-nums;
}
.t-display {
  font-family: var(--display); font-stretch: var(--display-stretch);
  font-size: var(--type-display); line-height: 1; font-weight: 850;
  letter-spacing: -.035em; text-wrap: balance;
}
.t-title {
  font-family: var(--display); font-stretch: var(--display-stretch);
  font-size: var(--type-title); line-height: 1.04; font-weight: 850;
  letter-spacing: -.03em; text-wrap: balance;
}
.t-heading {
  font-size: var(--type-heading); line-height: 1.2; font-weight: 750;
  letter-spacing: -.015em; text-wrap: balance;
}
.t-lead {
  font-size: var(--type-lead); line-height: 1.5; font-weight: 500;
  color: var(--ink-2); text-wrap: pretty;
}
.t-body  { font-size: var(--type-body); line-height: 1.55; font-weight: 500; }
.t-small { font-size: var(--type-small); line-height: 1.45; font-weight: 600; }
.t-mono  {
  font-family: var(--mono); font-weight: 500; letter-spacing: -.01em;
  font-variant-numeric: tabular-nums;
}

/* ================================================================= keys == */
/* Every button is a keycap: ink outline, a visible extrusion under it.
   Hover lifts it one step, press sinks it flat. Snappy, no spring. */
.key {
  --kd: var(--key-depth);
  position: relative;
  display: inline-flex; align-items: center; justify-content: center; gap: .55em;
  min-height: var(--control-height);
  padding: 0 max(22px, calc(var(--u) * 1.5));
  border: var(--stroke) solid var(--ink); border-radius: var(--radius-key);
  background: var(--lime-400); color: var(--ink);
  font: 750 var(--type-body)/1 var(--sans); letter-spacing: -.005em;
  white-space: nowrap; cursor: pointer; text-decoration: none;
  box-shadow: 0 var(--kd) 0 0 var(--ink);
  transform: translateY(0);
  transition: transform var(--dur-key) var(--ease-key), box-shadow var(--dur-key) var(--ease-key),
              background var(--dur-1) var(--ease);
  -webkit-tap-highlight-color: transparent;
}
.key:hover  { background: var(--lime-500); transform: translateY(calc(-1 * var(--p))); box-shadow: 0 calc(var(--kd) + var(--p)) 0 0 var(--ink); }
.key:active { transform: translateY(var(--kd)); box-shadow: 0 0 0 0 var(--ink); }
.key__arrow { width: 1.1em; height: 1.1em; flex: none; transition: transform var(--dur-1) var(--ease); }
.key:hover .key__arrow { transform: translateX(calc(3 * var(--p))); }

.key--lg { min-height: calc(60 * var(--p)); padding: 0 max(26px, calc(var(--u) * 1.9)); font-size: var(--type-lead); --kd: calc(5 * var(--p)); }
.key--sm { min-height: calc(42 * var(--p)); padding: 0 calc(16 * var(--p)); font-size: var(--type-small); --kd: calc(3 * var(--p)); border-radius: calc(10 * var(--p)); }
.key--ink { background: var(--ink); color: var(--white); box-shadow: 0 var(--kd) 0 0 var(--cobalt-500); }
.key--ink:hover { background: var(--ink-700); box-shadow: 0 calc(var(--kd) + var(--p)) 0 0 var(--cobalt-500); }
.key--ink:active { box-shadow: 0 0 0 0 var(--cobalt-500); }
.key--paper { background: var(--white); }
.key--paper:hover { background: var(--paper); }

.link {
  display: inline-flex; align-items: center; gap: .4em;
  font-weight: 750; color: var(--accent-text);
}
.link:hover { color: var(--cobalt-600); }
.link .key__arrow { width: 1em; height: 1em; }
.link:hover .key__arrow { transform: translateX(calc(3 * var(--p))); }

/* ================================================================ tiles == */
/* Quiet paper by default. .tile--ink is the drawn, emphasised version: one ink
   outline and a hard shadow, for the proof only. */
.tile {
  position: relative;
  background: var(--surface);
  border: 1px solid var(--hairline);
  border-radius: var(--radius-tile);
  box-shadow: var(--shadow-soft);
}
.tile--sm { border-radius: var(--radius-tile); }
.tile--ink { border: var(--stroke) solid var(--ink); border-radius: var(--radius-ink); box-shadow: var(--shadow-tile); }
.tile--ink.tile--sm { box-shadow: var(--shadow-tile-sm); }

/* Registration marks: a small, light plus on each corner of a quiet
   container, centred on the corner point. Containers are snapped to the grid
   (page.js), so the pluses sit on line intersections and show the alignment.
   Emphasised (.tile--ink) containers don't get them: they're rounded and
   stand apart from the grid on purpose. */
.reg::after {
  --b: 1px;
  --m: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M6 0v12M0 6h12' stroke='%23A6ACC4' stroke-width='1.2'/%3E%3C/svg%3E");
  content: ''; position: absolute; z-index: 1; pointer-events: none;
  inset: calc(var(--plus) / -2 - var(--b));
  background:
    var(--m) left top / var(--plus) var(--plus) no-repeat,
    var(--m) right top / var(--plus) var(--plus) no-repeat,
    var(--m) left bottom / var(--plus) var(--plus) no-repeat,
    var(--m) right bottom / var(--plus) var(--plus) no-repeat;
}

/* ================================================================ chips == */
/* flat fills, no outline: the colour carries the meaning */
.chip {
  display: inline-flex; align-items: center; gap: calc(6 * var(--p));
  min-height: calc(26 * var(--p)); padding: 0 calc(9 * var(--p));
  border-radius: var(--radius-chip);
  font-size: var(--type-small); font-weight: 750; line-height: 1; white-space: nowrap;
  color: var(--ink); background: var(--ink-50);
}
.chip--gained  { background: var(--lime-400); }
.chip--missing { background: var(--orange-500); }

/* =============================================================== fields == */
.field {
  width: 100%; min-height: var(--control-height); padding: 0 calc(16 * var(--p));
  border: var(--stroke) solid var(--ink); border-radius: var(--radius-key);
  background: var(--surface); color: var(--ink);
  font: 500 max(16px, var(--type-body))/1.2 var(--sans);
  transition: box-shadow var(--dur-1) var(--ease);
}
.field::placeholder { color: var(--ink-400); }
.field:focus { outline: none; box-shadow: 0 0 0 4px var(--cobalt-100), 0 0 0 calc(4px + var(--stroke)) var(--cobalt-500); }
.field[aria-invalid="true"] { border-color: var(--orange-500); }

/* an answer choice: quiet until you point at it */
.option {
  display: flex; align-items: center; justify-content: space-between; gap: calc(12 * var(--p));
  width: 100%; min-height: var(--control-height); padding: calc(12 * var(--p)) calc(18 * var(--p));
  border: 1px solid var(--hairline); border-radius: var(--radius-key);
  background: var(--white); color: var(--ink); text-align: left;
  font: 650 var(--type-body)/1.35 var(--sans); cursor: pointer;
  transition: border-color var(--dur-1) var(--ease), background var(--dur-1) var(--ease);
}
.option:hover  { background: var(--lime-200); border-color: var(--ink); }
.option:active { background: var(--lime-400); }
.option[aria-pressed="true"] { background: var(--lime-400); border-color: var(--ink); }

/* ================================================================ marks == */
/* The annotation layer (page.js draws into it): highlighter strokes sit under
   the text, rings and strikes over it. */
.marks { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; pointer-events: none; }
.marks--under { z-index: -1; }
.marks--over  { z-index: 3; }
.marks path { fill: none; }
.mark-hl     { stroke: var(--lime-400); stroke-linecap: butt; }
.mark-ring   { stroke: var(--orange-500); stroke-linecap: round; stroke-linejoin: round; }
.mark-strike { stroke: var(--ink); stroke-linecap: round; }
.has-marks { position: relative; isolation: isolate; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .key, .option { transition: none; }
}
