/*
 * The shared foundation: tokens, base type, masthead, footer, buttons, motion.
 *
 * Extracted on 2026-09-23, when the site went from one page to three. Each page
 * keeps its own section CSS inline, because those rules are used once and
 * reading them next to the markup they style is worth more than the saved
 * bytes. What is in here is the part that must not diverge between pages.
 *
 * The legal pages (/privacy, /terms, /data-deletion, /404) do not use this file
 * and still carry the product's blue-violet palette inline. That is a known
 * seam, not an oversight: retheming four legal documents is its own job with
 * its own review risk.
 *
 * `_headers` carries `style-src 'self' 'unsafe-inline'`. The `'self'` is for
 * this file; the `'unsafe-inline'` is for the per-page blocks and for the legal
 * pages, which are entirely inline.
 */

/* ---------------------------------------------------------------- faces */
@font-face{font-family:"Plex Sans";src:url("/fonts/plex-sans.woff2") format("woff2-variations");font-weight:100 700;font-display:swap}
@font-face{font-family:"Plex Mono";src:url("/fonts/plex-mono-400.woff2") format("woff2");font-weight:400;font-display:swap}
@font-face{font-family:"Plex Mono";src:url("/fonts/plex-mono-500.woff2") format("woff2");font-weight:500;font-display:swap}

/* Arial re-declared with Plex Sans's measured vertical metrics, so the line box
   is the same height before and after the swap and display type does not
   reflow. Measured off the shipped file: ascent 1.03, descent .28. */
@font-face{font-family:"Plex fallback";src:local("Arial"),local("Helvetica Neue"),local("Liberation Sans");ascent-override:103%;descent-override:28%;line-gap-override:0%;size-adjust:100%}

/* --------------------------------------------------------------- tokens
   One visual world, committed to on purpose. There is no light theme.

   The six oxbloods are the brief's. `--ember` and `--bone` are derived, and
   the reason is measurable: #8B1810 on #121111 is 1.98:1, which makes it a
   graphic fill and not a text colour at any size. The ember is the same hue
   carried up in lightness until it clears text contrast; the bone is warm
   rather than neutral so it belongs to the oxblood rather than sitting on it. */
:root{
  color-scheme:dark;
  --ink:#121111;
  --ox-1:#3C0B04;
  --ox-2:#450602;
  --ox-3:#5D1411;
  --ox-4:#71170D;
  --ox-5:#8B1810;
  --ember:#C8503A;
  --bone:#F2E9E6;
  --ash:#A9968F;
  --faint:#6E5A55;
  --rule:color-mix(in oklab, var(--ox-5) 34%, transparent);
  --rule-soft:color-mix(in oklab, var(--ox-5) 16%, transparent);
  --step-0:clamp(.95rem,.9rem + .25vw,1.0625rem);
  --step-1:clamp(1.125rem,1rem + .6vw,1.375rem);
  --step-2:clamp(1.5rem,1.25rem + 1.2vw,2.125rem);
  --step-3:clamp(2rem,1.4rem + 2.6vw,3.5rem);
  --step-4:clamp(2.5rem,1.4rem + 4.8vw,5.5rem);
  --display:clamp(2.6rem,1rem + 7.4vw,7rem);
}

*,*::before,*::after{box-sizing:border-box}
html{scroll-behavior:smooth}
@media (prefers-reduced-motion:reduce){html{scroll-behavior:auto}}

body{
  margin:0;background:var(--ink);color:var(--bone);
  font-family:"Plex Sans","Plex fallback",Arial,sans-serif;
  font-size:var(--step-0);line-height:1.6;
  -webkit-font-smoothing:antialiased;overflow-x:hidden;
}

/* Grain, fixed to the viewport so it reads as a property of the screen rather
   than of any one band. */
body::after{
  content:"";position:fixed;inset:0;z-index:200;pointer-events:none;
  opacity:.2;mix-blend-mode:overlay;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.82' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='220' height='220' filter='url(%23n)' opacity='.42'/%3E%3C/svg%3E");
}

h1,h2,h3{font-weight:600;letter-spacing:-.035em;line-height:1;text-wrap:balance;margin:0}
p{margin:0}
a{color:inherit}
a:focus-visible{outline:2px solid var(--ember);outline-offset:4px;border-radius:2px}

.mono{font-family:"Plex Mono",ui-monospace,SFMono-Regular,Menlo,monospace;font-size:.6875rem;font-weight:500;letter-spacing:.14em;text-transform:uppercase}
.inner{width:min(100% - 3rem,88rem);margin-inline:auto}
@media (min-width:60rem){.inner{width:min(100% - 7rem,88rem)}}

.skip{position:absolute;left:-9999px}
.skip:focus{left:1rem;top:1rem;z-index:300;background:var(--ox-2);color:var(--bone);padding:.6rem 1rem;border-radius:2px}

.eyebrow{display:flex;align-items:center;gap:.85rem;color:var(--ember)}
.eyebrow::after{content:"";height:1px;flex:1;max-width:14rem;background:linear-gradient(90deg,var(--ember),transparent)}

.lede{font-size:var(--step-1);line-height:1.45;color:var(--ash);max-width:46ch;text-wrap:pretty}
.lede strong{color:var(--bone);font-weight:500}

/* ------------------------------------------------------------- buttons */
.btn{
  display:inline-flex;align-items:center;gap:.7rem;padding:.9rem 1.5rem;
  border:1px solid color-mix(in oklab,var(--ember) 55%,transparent);border-radius:2px;
  color:var(--bone);text-decoration:none;font-weight:500;
  background:color-mix(in oklab,var(--ox-3) 46%,transparent);
  transition:background .3s,border-color .3s;white-space:nowrap;
}
.btn::after{content:"\2192";transition:transform .3s}
.btn:hover{background:color-mix(in oklab,var(--ox-4) 62%,transparent);border-color:var(--ember)}
.btn:hover::after{transform:translateX(3px)}
.btn-quiet{background:transparent;border-color:var(--rule);color:var(--ash)}
.btn-quiet:hover{color:var(--bone);background:color-mix(in oklab,var(--ox-2) 40%,transparent)}

.chip{display:inline-flex;align-items:center;gap:.5rem;padding:.3rem .6rem .3rem .5rem;border:1px solid var(--rule);border-radius:2px;color:var(--ash);width:max-content}
.chip::before{content:"";width:.4rem;height:.4rem;border-radius:50%;background:currentColor;flex:none}
.chip.live{color:var(--ember);border-color:color-mix(in oklab,var(--ember) 45%,transparent)}

/* ------------------------------------------------------------ masthead */
.masthead{position:absolute;top:0;left:0;right:0;z-index:60;padding-block:1.75rem}
.masthead .inner{display:flex;align-items:center;gap:1rem}
.wordmark{display:flex;align-items:center;gap:.65rem;text-decoration:none;font-weight:600;letter-spacing:-.02em;font-size:1.0625rem}
.wordmark svg{width:1.375rem;height:1.375rem;display:block;flex:none}
.wordmark .sep{color:var(--faint);font-weight:400}
.masthead nav{margin-left:auto;display:flex;align-items:center;gap:1.75rem}
.masthead nav a{color:var(--ash);text-decoration:none;transition:color .25s}
.masthead nav a:hover{color:var(--bone)}
.masthead .nav-cta{color:var(--bone);border:1px solid var(--rule);border-radius:2px;padding:.45rem .8rem}
.masthead .nav-cta:hover{border-color:var(--ember)}
@media (max-width:52rem){.masthead nav a:not(.nav-cta){display:none}}

/* -------------------------------------------------------------- footer */
footer{background:var(--ink);border-top:1px solid var(--rule);padding-block:clamp(3.5rem,6vw,5rem)}
footer .inner{display:grid;gap:2.5rem}
@media (min-width:56rem){footer .inner{grid-template-columns:minmax(0,1fr) auto auto;gap:4rem}}
footer p{color:var(--faint);max-width:52ch;font-size:.9375rem;line-height:1.6}
footer p + p{margin-top:1rem}
footer a{color:var(--ash);text-decoration:underline;text-underline-offset:.2em;text-decoration-color:var(--rule);transition:color .25s,text-decoration-color .25s}
footer a:hover{color:var(--bone);text-decoration-color:var(--ember)}
.footer-nav{display:grid;gap:.6rem;list-style:none;margin:0;padding:0;align-content:start}
.footer-nav a{text-decoration:none;color:var(--ash)}
.footer-nav a:hover{color:var(--bone)}
.footer-nav .mono{color:var(--faint);margin-bottom:.4rem}
.abn{color:var(--faint);margin-top:1.5rem}

/* -------------------------------------------------------------- motion
   Authored so the unsupported state is the finished state: a browser without
   animation-timeline shows everything already in place, never hidden. */
@keyframes rise{from{opacity:0;transform:translateY(1.5rem)}to{opacity:1;transform:none}}
@keyframes lift{from{opacity:0;transform:translateY(1.25rem)}to{opacity:1;transform:none}}
@media (prefers-reduced-motion:reduce){*{transition-duration:.01ms !important}}
