/* css/tokens.css
 *
 * The shared token layer for evoai.bio. Owned by the site builder, imported by the site and by the app.
 * Import it FIRST, before css/site.css, css/app.css and css/viz.css:
 *
 *   <link rel="stylesheet" href="/css/tokens.css">
 *   <link rel="stylesheet" href="/css/site.css">
 *
 * Everything here is a custom property, a @font-face, or a reset that both surfaces need. No component
 * lives in this file. The palette is docs/SPEC.md section 6 verbatim, sampled from the owner's own mark.
 *
 * Three house rules this file encodes:
 *   1. There are no box shadows on this site. Depth is a hairline, a gradient border and a backdrop blur.
 *   2. Motion is ease, ease-in-out and ease-out only. Nothing overshoots, springs or bounces.
 *   3. Every number in the UI is mono and tabular: use .num or font-variant-numeric: tabular-nums.
 */

/* ------------------------------------------------------------------------------------------ fonts */
/* Self hosted, never a CDN. Both files live in /fonts and are served immutable for a year. */

@font-face {
  font-family: 'Inter';
  src: url('/fonts/inter-var-latin.woff2') format('woff2');
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
  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: 'Geist Mono';
  src: url('/fonts/geist-mono-latin.woff2') format('woff2');
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
  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;
}

/* ------------------------------------------------------------------------------------------ tokens */

:root {
  /* -- palette, docs/SPEC.md section 6, sampled from the mark ------------------------------- */
  --bg:          #01100a;
  --bg-deep:     #000b04;
  --surface:     #04170d;
  --surface-2:   #082110;
  --line:        #143024;
  --line-bright: #1e4a34;

  --green-300:   #7CFFB2;
  --green-400:   #4FD98A;
  --green-500:   #35B86B;
  --green-600:   #19A355;
  --moss:        #167532;
  --olive:       #19520E;

  --text:        #E8F5EC;
  --text-muted:  #9FBFAB;
  --text-faint:  #5E7D6B;
  --warn:        #FFC46B;

  --lattice-fill: rgba(64, 232, 148, 0.14);
  --scan:        #C9FFE3;
  /* The low end of the heat ramp has to sit visibly above the panel ground, or the bottom half of a heat map
     reads as "the lattice got dimmer" rather than as a scale. #14532D is 0.083 luma, inside the ground's own
     0.074 lift; this is 0.16. Mirrored in js/viz/palette.js. */
  --heat-lo:     #1E7A52;
  --heat-hi:     #B6FF7A;

  /* --text-faint is 4.28:1 on --bg, which is under the WCAG 4.5 the layout gate enforces. Use it for
     24px or larger display type, for rules and for icon strokes. For small copy use --text-dim, which
     is the same colour family at 5.2:1, or --text-muted at 9.7:1. */
  --text-dim:    #6A8C78;

  /* -- type ---------------------------------------------------------------------------------- */
  --font-sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
  --font-mono: 'Geist Mono', ui-monospace, SFMono-Regular, 'SF Mono', Menlo, Consolas, monospace;

  /* A calm scale, borrowed from lightprotocol: one family, few steps, nothing shouts.
     Every clamp floor is at or above its own mobile size, so no step ever shrinks as the page grows. */
  --t-display:  clamp(40px, 7.2vw, 78px);   /* the wordmark in the hero */
  --t-h2:       clamp(28px, 3.2vw, 40px);
  --t-h3:       clamp(19px, 1.5vw, 22px);
  --t-lede:     clamp(17px, 1.6vw, 22px);
  --t-body:     16px;
  --t-small:    14px;
  --t-micro:    12px;
  --t-nano:     11px;

  --lh-tight:   1.1;
  --lh-heading: 1.2;
  --lh-body:    1.7;
  --lh-prose:   1.75;

  --track-label: 0.08em;  /* the instrument voice: uppercase mono micro labels */
  --track-wide:  0.14em;

  /* -- spacing, the lightprotocol scale, counted from their computed styles ------------------ */
  --sp-1: 4px;   --sp-2: 8px;   --sp-3: 12px;  --sp-4: 16px;  --sp-5: 20px;
  --sp-6: 24px;  --sp-7: 32px;  --sp-8: 40px;  --sp-9: 48px;  --sp-10: 64px;
  --sp-11: 80px; --sp-12: 100px;

  /* -- layout -------------------------------------------------------------------------------- */
  --measure:   680px;   /* real prose, one column */
  --w-wide:    1180px;  /* the instrument panel grid */
  --gutter:    24px;
  --header-h:  64px;
  --section-y: clamp(64px, 8vw, 112px);

  /* -- edges. No shadows anywhere, so depth is a hairline and a gradient border. -------------- */
  --hairline: 1px solid var(--line);
  --hairline-bright: 1px solid var(--line-bright);
  --r-xs: 2px;
  --r-sm: 4px;
  --r-pill: 999px;
  --panel-border: linear-gradient(to left top,
                    rgba(20, 48, 36, 0.35) 55%,
                    rgba(53, 184, 107, 0.45)) 1 / 1px / 0 stretch;
  --blur: blur(20px);

  /* -- motion, docs/SPEC.md section 6 --------------------------------------------------------- */
  --dur-micro:  0.18s;
  --dur-fast:   0.2s;
  --dur-line:   0.3s;
  --dur-reveal: 0.5s;
  --dur-canvas: 1s;
  --ease:        ease;
  --ease-in-out: ease-in-out;
  --ease-out:    ease-out;

  --z-header: 50;
  --z-dialog: 90;

  color-scheme: dark;
}

/* Under 768 the header carries its nav on a second row, so it is taller, not shorter. js/shell.js measures
   the real header and overwrites --header-h on :root, so this value only has to be right before the first
   measurement lands. */
@media (max-width: 719px) {
  :root {
    --gutter: 16px;
    --header-h: 104px;
  }
}

/* ------------------------------------------------------------------------------------------ reset */

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

html {
  -webkit-text-size-adjust: 100%;
  /* No smooth scrolling. The header is fixed, so every anchor target and every programmatic scroll has to
     clear it, which is what scroll-padding-block-start does. Smooth scrolling on top of that was a real cost
     and no benefit: on the run console the WebGL loop starves the browser's own scroll animation, so a
     keyboard user tabbing down the page sat about 900 ms behind their own focus ring and never saw the
     intermediate stops. An instant jump is always exactly where the visitor asked to be. */
  scroll-behavior: auto;
  /* Every anchor target, including the skip link's #main, lands below the fixed header instead of under it.
     js/shell.js keeps --header-h equal to the real measured header. */
  scroll-padding-block-start: calc(var(--header-h) + var(--sp-2));
  scrollbar-color: var(--line-bright) var(--bg-deep);
}

/* scroll-padding on the scrolling box covers the anchors the browser scrolls to; scroll-margin on the target
   itself covers scrollIntoView from script, which does not read scroll-padding in every engine. */
:target,
[id^="s0"], [id^="s1"], #main, main > section, .section {
  scroll-margin-block-start: calc(var(--header-h) + var(--sp-2));
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-sans);
  font-size: var(--t-body);
  line-height: var(--lh-body);
  font-synthesis-weight: none;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

h1, h2, h3, h4, h5, h6 { margin: 0; font-weight: 600; line-height: var(--lh-heading); }
p, ul, ol, dl, figure, table, pre { margin: 0; }
img, svg, canvas, video { max-width: 100%; }
img { height: auto; }

a { color: inherit; }

button, input, select, textarea { font: inherit; color: inherit; }

:focus-visible { outline: 2px solid var(--green-400); outline-offset: 2px; }

::selection { background: var(--green-500); color: var(--bg-deep); }

/* Every number in the UI is mono and tabular. */
.num, .mono {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-feature-settings: 'tnum' 1;
}

/* The bracketed uppercase mono micro label. The instrument voice, from the aptoslabs capture. */
.label {
  font-family: var(--font-mono);
  font-size: var(--t-micro);
  font-weight: 400;
  line-height: 1.2;
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}

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

::-webkit-scrollbar { width: 8px; height: 8px; }
::-webkit-scrollbar-track { background: var(--bg-deep); }
::-webkit-scrollbar-thumb { background: var(--line-bright); border-radius: var(--r-pill); }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.001ms !important;
    scroll-behavior: auto !important;
  }
}
