:root{
    /* A dim stage, not a neutral black — the ground is biased warm so brass
       sits on it the way it does under house lights. */
    --stage:      #141013;
    --stage-lift: #1c1619;
    --stage-edge: #2a2126;

    --brass:      #d89a3c;   /* lacquered brass */
    --brass-hi:   #f5d48a;   /* polished edge */
    --brass-dim:  #8a6428;

    /* Used ONLY for the saxophone. It is the one instrument here that is not
       brass, and the colour is the only place that fact is stated silently. */
    --nickel:     #8fa9b8;
    --nickel-dim: #4a5a66;

    --ink:        #f4ece4;
    --ink-2:      #c9bcb2;
    --muted:      #8c7f78;

    --measure: 62ch;
    --bar-h: 60px;
  }

  *{box-sizing:border-box}

  html{-webkit-text-size-adjust:100%}

  body{
    margin:0;
    background:var(--stage);
    color:var(--ink);
    font:400 17px/1.6 Figtree,ui-sans-serif,system-ui,sans-serif;
    -webkit-font-smoothing:antialiased;
    overflow-x:hidden;
  }

  ::selection{background:var(--brass);color:var(--stage)}

  /* width:100% matters: the hero is a column flex container, and an auto
     inline margin on a flex child cancels align-items:stretch — without this
     the wrap shrinks to its content and the whole page sits off-centre. */
  .wrap{width:100%;max-width:1080px;margin:0 auto;padding:0 24px}

  .eyebrow{
    font-family:"JetBrains Mono",ui-monospace,monospace;
    font-size:11.5px;letter-spacing:.22em;text-transform:uppercase;
    color:var(--muted);
  }

  /* ── hero ─────────────────────────────────────────────────────── */

  .hero{
    min-height:100svh;
    display:flex;flex-direction:column;justify-content:center;
    padding:72px 0 40px;position:relative;
  }

  /* A single warm pool of light, as if one fixture is on. */
  .hero::before{
    content:"";position:absolute;inset:0;pointer-events:none;
    background:radial-gradient(ellipse 70% 55% at 22% 38%,
      rgba(216,154,60,.13), transparent 70%);
  }

  .hero > *{position:relative}

  .name{
    font-family:"Big Shoulders Display",Impact,sans-serif;
    font-weight:800;
    font-size:clamp(88px,20vw,240px);
    line-height:.82;
    letter-spacing:-.01em;
    margin:14px 0 0;
    text-transform:uppercase;
    background:linear-gradient(178deg,var(--brass-hi) 4%,var(--brass) 42%,var(--brass-dim) 96%);
    -webkit-background-clip:text;background-clip:text;
    color:transparent;
    text-wrap:balance;
  }

  .horns{
    display:flex;flex-wrap:wrap;gap:0 18px;align-items:baseline;
    margin:26px 0 0;
    font-family:"Big Shoulders Display",sans-serif;
    font-weight:500;font-size:clamp(20px,3.4vw,30px);
    text-transform:uppercase;letter-spacing:.05em;
    color:var(--ink-2);
  }
  .horns .sep{color:var(--brass);font-size:.7em;transform:translateY(-.18em)}
  .horns .sax{color:var(--nickel)}

  .lede{margin:30px 0 0;max-width:44ch;color:var(--ink-2);font-size:18px}

  .jump{
    display:inline-flex;align-items:center;gap:11px;
    margin-top:40px;padding:14px 22px;
    border:1px solid var(--brass-dim);border-radius:2px;
    background:transparent;color:var(--brass-hi);
    font:600 14px/1 Figtree,sans-serif;letter-spacing:.02em;
    text-decoration:none;cursor:pointer;
    transition:background .18s ease,border-color .18s ease,transform .18s ease;
  }
  .jump:hover{background:rgba(216,154,60,.1);border-color:var(--brass);transform:translateY(-1px)}
  .jump .arr{transition:transform .18s ease}
  .jump:hover .arr{transform:translateY(2px)}

  /* ── instruments ──────────────────────────────────────────────── */

  .horns-section{padding:40px 0 96px}

  .section-head{
    display:flex;align-items:baseline;gap:16px;flex-wrap:wrap;
    padding-bottom:10px;margin-bottom:34px;
    border-bottom:1px solid var(--stage-edge);
  }
  .section-head h2{
    font-family:"Big Shoulders Display",sans-serif;
    font-weight:700;font-size:clamp(30px,5vw,46px);
    text-transform:uppercase;letter-spacing:.01em;
    margin:0;color:var(--ink);
  }
  .section-head .note{color:var(--muted);font-size:14px;margin-left:auto}

  .horn{
    border:1px solid var(--stage-edge);
    border-radius:3px;
    background:var(--stage-lift);
    padding:26px 26px 30px;
    margin-bottom:18px;
  }
  .horn.is-sax{border-color:#2b3238}

  .horn-top{display:flex;align-items:baseline;gap:14px;flex-wrap:wrap;margin-bottom:4px}
  .horn-kind{
    font-family:"Big Shoulders Display",sans-serif;
    font-weight:800;font-size:34px;letter-spacing:.03em;
    text-transform:uppercase;color:var(--brass);line-height:1;
  }
  .is-sax .horn-kind{color:var(--nickel)}
  .horn-name{
    font-family:"JetBrains Mono",monospace;font-size:12px;
    letter-spacing:.16em;text-transform:uppercase;color:var(--muted);
  }
  .horn-say{color:var(--ink-2);font-size:15.5px;margin:6px 0 22px;max-width:52ch}

  .readout{
    font-family:"JetBrains Mono",monospace;
    font-size:12px;color:var(--muted);
    margin-left:auto;white-space:nowrap;
    font-variant-numeric:tabular-nums;
  }
  .readout b{color:var(--brass-hi);font-weight:500}
  .is-sax .readout b{color:var(--nickel)}

  /* — trombone slide — */
  .slide{
    position:relative;height:74px;margin:0 6px;
    touch-action:none;cursor:grab;
  }
  .slide:active{cursor:grabbing}
  .slide-rail{
    position:absolute;top:30px;left:0;right:0;height:8px;border-radius:4px;
    background:linear-gradient(180deg,#3a2f26,#241d18);
    box-shadow:inset 0 1px 0 rgba(245,212,138,.14);
  }
  .slide-fill{
    position:absolute;top:30px;left:0;height:8px;border-radius:4px;
    background:linear-gradient(180deg,var(--brass-hi),var(--brass));
    width:0;
  }
  .slide-grip{
    position:absolute;top:16px;width:26px;height:36px;border-radius:3px;
    background:linear-gradient(180deg,var(--brass-hi),var(--brass) 55%,var(--brass-dim));
    box-shadow:0 3px 10px rgba(0,0,0,.5);
    transform:translateX(-50%);
    transition:box-shadow .15s ease;
  }
  .slide:focus-visible{outline:none}
  .slide:focus-visible .slide-grip{box-shadow:0 0 0 3px rgba(245,212,138,.55),0 3px 10px rgba(0,0,0,.5)}
  .slide.playing .slide-grip{box-shadow:0 0 0 4px rgba(216,154,60,.28),0 3px 14px rgba(0,0,0,.55)}

  .positions{
    display:flex;justify-content:space-between;
    font-family:"JetBrains Mono",monospace;font-size:11px;color:var(--muted);
    margin:2px 4px 0;
  }
  .positions span{transition:color .12s ease}
  .positions span.on{color:var(--brass-hi)}

  /* — baritone valves — */
  .valves{display:flex;gap:16px;align-items:flex-end;padding:6px 0 4px}
  .valve{
    width:66px;height:92px;padding:0;border:0;background:none;cursor:pointer;
    display:flex;flex-direction:column;align-items:center;gap:9px;
  }
  .valve-cap{
    width:52px;height:52px;border-radius:50%;
    background:radial-gradient(circle at 34% 28%,var(--brass-hi),var(--brass) 46%,var(--brass-dim));
    box-shadow:0 5px 0 #3a2a12,0 7px 12px rgba(0,0,0,.5);
    transition:transform .07s ease,box-shadow .07s ease;
  }
  .valve[aria-pressed="true"] .valve-cap,
  .valve:active .valve-cap{
    transform:translateY(5px);
    box-shadow:0 0 0 #3a2a12,0 2px 6px rgba(0,0,0,.5);
  }
  .valve:focus-visible .valve-cap{box-shadow:0 0 0 3px rgba(245,212,138,.55),0 5px 0 #3a2a12}
  .valve-num{
    font-family:"JetBrains Mono",monospace;font-size:11px;color:var(--muted);
  }
  .valve[aria-pressed="true"] .valve-num{color:var(--brass-hi)}

  /* — saxophone keys — */
  .keys{display:flex;gap:9px;flex-wrap:wrap;padding:4px 0}
  .key{
    width:60px;height:78px;border-radius:30px/34px;
    border:1px solid #3a464e;padding:0;cursor:pointer;
    background:linear-gradient(180deg,#b9ccd6,#7f98a6 60%,#5d707d);
    box-shadow:0 4px 0 #2b343a,0 6px 12px rgba(0,0,0,.45);
    display:flex;align-items:flex-end;justify-content:center;
    font:500 11px/1 "JetBrains Mono",monospace;color:#20292e;
    padding-bottom:9px;
    transition:transform .07s ease,box-shadow .07s ease;
  }
  .key:active,.key[aria-pressed="true"]{
    transform:translateY(4px);
    box-shadow:0 0 0 #2b343a,0 2px 5px rgba(0,0,0,.45);
  }
  .key:focus-visible{outline:none;box-shadow:0 0 0 3px rgba(143,169,184,.6),0 4px 0 #2b343a}


  /* ── field ────────────────────────────────────────────────────── */

  /* The one section that isn't about an instrument gets the only other
     material in Jaiden's world: the field both halves of Friday night
     happen on. Yard lines are drawn faintly rather than illustrated. */
  .field{
    position:relative;
    border-top:1px solid var(--stage-edge);
    margin-top:20px;padding:64px 0 8px;
    overflow:hidden;
  }
  .field::before{
    content:"";position:absolute;inset:0;pointer-events:none;
    background:repeating-linear-gradient(90deg,
      rgba(244,236,228,.055) 0 1px, transparent 1px 10%);
    mask-image:linear-gradient(180deg,transparent,#000 22%,#000 72%,transparent);
    -webkit-mask-image:linear-gradient(180deg,transparent,#000 22%,#000 72%,transparent);
  }
  .field > *{position:relative}

  .field h2{
    font-family:"Big Shoulders Display",sans-serif;
    font-weight:700;font-size:clamp(28px,4.4vw,44px);
    text-transform:uppercase;margin:0 0 6px;letter-spacing:.01em;
  }
  .field .yard{
    font-family:"JetBrains Mono",monospace;font-size:11px;
    letter-spacing:.22em;text-transform:uppercase;color:var(--muted);
    margin:0 0 20px;
  }
  .field p{max-width:var(--measure);color:var(--ink-2);margin:0 0 16px}
  .field strong{color:var(--brass-hi);font-weight:600}

  .halves{
    display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));
    gap:18px;margin:32px 0 8px;
  }
  .half{
    border:1px solid var(--stage-edge);border-radius:3px;
    background:var(--stage-lift);padding:20px 22px 22px;
  }
  .half .when{
    font-family:"JetBrains Mono",monospace;font-size:10.5px;
    letter-spacing:.18em;text-transform:uppercase;color:var(--brass);
    display:block;margin-bottom:8px;
  }
  .half h3{
    font-family:"Big Shoulders Display",sans-serif;
    font-weight:700;font-size:25px;text-transform:uppercase;
    margin:0 0 8px;color:var(--ink);line-height:1.05;
  }
  .half p{font-size:15px;margin:0;color:var(--ink-2)}



  /* ── kicking game ─────────────────────────────────────────────── */

  .game{margin:34px 0 8px}
  .game-head{
    display:flex;align-items:baseline;gap:14px;flex-wrap:wrap;
    margin-bottom:12px;
  }
  .game-head h3{
    font-family:"Big Shoulders Display",sans-serif;
    font-weight:700;font-size:26px;text-transform:uppercase;
    margin:0;color:var(--ink);line-height:1;
  }
  .game-head .hint{
    font-family:"JetBrains Mono",monospace;font-size:11px;
    letter-spacing:.14em;text-transform:uppercase;color:var(--muted);
    margin-left:auto;
  }

  .board{
    position:relative;
    border:1px solid var(--stage-edge);border-radius:3px 3px 0 0;
    background:#0f1a12;                 /* night grass, not stage black */
    overflow:hidden;
    touch-action:manipulation;
    cursor:pointer;
  }
  .board canvas{display:block;width:100%;height:auto}
  .board:focus-visible{outline:2px solid var(--brass-hi);outline-offset:-2px}

  .scoreline{
    display:flex;gap:0;margin:0;
    border:1px solid var(--stage-edge);border-top:0;border-radius:0 0 3px 3px;
    background:var(--stage-lift);
  }
  .scoreline > div{
    flex:1;padding:11px 14px;
    border-right:1px solid var(--stage-edge);
  }
  .scoreline > div:last-child{border-right:0}
  .scoreline dt{
    font-family:"JetBrains Mono",monospace;font-size:10px;
    letter-spacing:.16em;text-transform:uppercase;color:var(--muted);margin:0 0 4px;
  }
  .scoreline dd{
    margin:0;font-family:"Big Shoulders Display",sans-serif;
    font-weight:700;font-size:23px;color:var(--ink);line-height:1;
    font-variant-numeric:tabular-nums;
  }
  .scoreline dd.good{color:var(--brass-hi)}

  @media (max-width:640px){
    .scoreline{flex-wrap:wrap}
    .scoreline > div{flex:1 1 50%;border-bottom:1px solid var(--stage-edge)}
    .game-head .hint{margin-left:0;width:100%}
  }

  /* ── security ─────────────────────────────────────────────────── */

  /* No new hue here on purpose — the palette stays brass and nickel. This
     section separates itself by material instead: monospace, tighter rhythm,
     a terminal register rather than a stage one. */
  .sec{
    border-top:1px solid var(--stage-edge);
    margin-top:20px;padding:64px 0 8px;
  }
  .sec h2{
    font-family:"Big Shoulders Display",sans-serif;
    font-weight:700;font-size:clamp(28px,4.4vw,44px);
    text-transform:uppercase;margin:0 0 6px;letter-spacing:.01em;
  }
  .sec .yard{
    font-family:"JetBrains Mono",monospace;font-size:11px;
    letter-spacing:.22em;text-transform:uppercase;color:var(--muted);
    margin:0 0 20px;
  }
  .sec p{max-width:var(--measure);color:var(--ink-2);margin:0 0 16px}

  .lab{
    border:1px solid var(--stage-edge);border-radius:3px;
    background:var(--stage-lift);
    margin:32px 0 0;overflow:hidden;
  }
  .lab-head{
    display:flex;align-items:center;gap:10px;flex-wrap:wrap;
    padding:12px 18px;border-bottom:1px solid var(--stage-edge);
    font-family:"JetBrains Mono",monospace;font-size:11px;
    letter-spacing:.16em;text-transform:uppercase;color:var(--muted);
  }
  .lab-head .algo{color:var(--brass)}
  .lab-body{padding:20px 18px 22px}

  .lab label{
    display:block;font-family:"JetBrains Mono",monospace;
    font-size:11px;letter-spacing:.14em;text-transform:uppercase;
    color:var(--muted);margin-bottom:9px;
  }
  .lab input{
    width:100%;padding:13px 15px;
    background:#100c0f;color:var(--ink);
    border:1px solid var(--stage-edge);border-radius:2px;
    font:400 15px/1.4 "JetBrains Mono",monospace;
  }
  .lab input:focus{outline:none;border-color:var(--brass-dim);box-shadow:0 0 0 3px rgba(216,154,60,.16)}

  .digest{
    margin:20px 0 0;
    font-family:"JetBrains Mono",monospace;
    font-size:clamp(12px,1.55vw,15px);line-height:1.95;
    word-break:break-all;color:var(--ink-2);
    letter-spacing:.06em;
  }
  .digest i{font-style:normal;transition:color .35s ease,background .35s ease}
  /* A digit that just changed is lit, then fades back — the avalanche made
     visible rather than described. */
  .digest i.hot{color:var(--stage);background:var(--brass-hi);border-radius:2px}

  .churn{
    margin:16px 0 0;font-family:"JetBrains Mono",monospace;
    font-size:12px;color:var(--muted);
  }
  .churn b{color:var(--brass-hi);font-weight:500;font-variant-numeric:tabular-nums}

  .sec .kicker{
    margin:26px 0 0;max-width:var(--measure);
    color:var(--ink-2);
  }
  .sec .kicker strong{color:var(--brass-hi);font-weight:600}

  /* ── about ────────────────────────────────────────────────────── */

  .about{
    border-top:1px solid var(--stage-edge);
    padding:64px 0 0;
  }
  .about h2{
    font-family:"Big Shoulders Display",sans-serif;
    font-weight:700;font-size:clamp(28px,4.4vw,40px);
    text-transform:uppercase;margin:0 0 18px;
  }
  .about p{max-width:var(--measure);color:var(--ink-2);margin:0 0 16px}

  /* Column counts are fixed rather than auto-fit: there are six facts, and
     auto-fit picked five, leaving the last one alone next to an empty block.
     Two and three both divide six evenly. */
  .facts{
    display:grid;grid-template-columns:repeat(2,1fr);
    gap:1px;background:var(--stage-edge);
    border:1px solid var(--stage-edge);border-radius:3px;
    margin:34px 0 0;overflow:hidden;
  }
  @media (min-width:760px){
    .facts{grid-template-columns:repeat(3,1fr)}
  }
  .fact{background:var(--stage-lift);padding:18px 20px}
  .fact dt{
    font-family:"JetBrains Mono",monospace;font-size:10.5px;
    letter-spacing:.16em;text-transform:uppercase;color:var(--muted);margin:0 0 6px;
  }
  .fact dd{
    margin:0;font-family:"Big Shoulders Display",sans-serif;
    font-weight:700;font-size:26px;text-transform:uppercase;color:var(--ink);
    line-height:1.1;
  }


  /* ── quality floor ────────────────────────────────────────────── */

  :focus-visible{outline:2px solid var(--brass-hi);outline-offset:3px}

  @media (prefers-reduced-motion:reduce){
    *{transition:none!important;animation:none!important;scroll-behavior:auto!important}
  }

  html{scroll-behavior:smooth}

  @media (max-width:640px){
    body{font-size:16px}
    .horn{padding:20px 18px 24px}
    .valve{width:56px}
    .valve-cap{width:44px;height:44px}
    .key{width:48px;height:66px}
    .readout{margin-left:0;width:100%;padding-top:6px}
  }

  /* ── site chrome (multi-page) ─────────────────────────────────── */

  .skip{
    position:absolute;left:-9999px;top:0;z-index:100;
    background:var(--brass);color:var(--stage);
    padding:10px 16px;font:600 13px/1 Figtree,sans-serif;
  }
  .skip:focus{left:0}

  /* Fixed rather than sticky: the calculator mounts an app that manages its
     own scrolling, and a sticky bar rides that scroll container instead of the
     window. Fixed keeps it in place on every page regardless. */
  .topbar{
    position:fixed;top:0;left:0;right:0;z-index:50;
    background:rgba(20,16,19,.94);
    backdrop-filter:saturate(140%) blur(8px);
    border-bottom:1px solid var(--stage-edge);
  }
  /* The bar is out of flow now, so the page owes it that height back. */
  body{padding-top:var(--bar-h)}
  .bar{display:flex;align-items:center;gap:24px;min-height:60px;flex-wrap:wrap}

  .mark{
    font-family:"Big Shoulders Display",sans-serif;
    font-weight:800;font-size:22px;letter-spacing:.02em;
    text-transform:uppercase;color:var(--brass);text-decoration:none;
    line-height:1;white-space:nowrap;
  }
  .mark:hover{color:var(--brass-hi)}

  .topbar nav{display:flex;gap:4px;flex-wrap:wrap;margin-left:auto}
  .topbar nav a{
    font:500 14px/1 Figtree,sans-serif;
    color:var(--ink-2);text-decoration:none;
    padding:9px 12px;border-radius:2px;
    transition:color .15s ease,background .15s ease;
  }
  .topbar nav a:hover{color:var(--brass-hi);background:rgba(216,154,60,.09)}
  .topbar nav a[aria-current="page"]{color:var(--brass);background:rgba(216,154,60,.13)}

  main{display:block}
  .page{padding:52px 24px 40px}

  .page-h1{
    font-family:"Big Shoulders Display",sans-serif;
    font-weight:800;font-size:clamp(40px,7vw,74px);
    text-transform:uppercase;letter-spacing:-.005em;line-height:.92;
    margin:6px 0 0;color:var(--ink);
  }
  .page-lede{margin:20px 0 40px;max-width:56ch;color:var(--ink-2);font-size:18px}

  /* Sections were written to sit inside one long page; on their own page the
     leading rule and top padding are the page break, so they come off. */
  .field.bare,.sec.bare,.about.bare{border-top:0;margin-top:0;padding-top:0}

  /* ── home: the way in ─────────────────────────────────────────── */

  .hero{min-height:auto;padding:76px 0 26px}

  /* Fixed two columns, not auto-fit. With four cards, auto-fit chose three
     across and left the fourth stranded beside two empty columns. An even
     2x2 has no orphan — if a fifth card is ever added, revisit this. */
  .doors{
    display:grid;grid-template-columns:1fr;
    gap:16px;padding:14px 0 90px;
  }
  @media (min-width:660px){
    .doors{grid-template-columns:repeat(2,1fr)}
  }
  .door{
    display:flex;flex-direction:column;
    border:1px solid var(--stage-edge);border-radius:3px;
    background:var(--stage-lift);
    padding:22px 22px 20px;text-decoration:none;
    transition:border-color .18s ease,transform .18s ease,background .18s ease;
  }
  .door:hover{
    border-color:var(--brass-dim);transform:translateY(-2px);
    background:#221a1d;
  }
  .door-kind{
    font-family:"JetBrains Mono",monospace;font-size:10.5px;
    letter-spacing:.18em;text-transform:uppercase;color:var(--brass);
    margin-bottom:11px;
  }
  .door h2{
    font-family:"Big Shoulders Display",sans-serif;
    font-weight:700;font-size:27px;text-transform:uppercase;
    margin:0 0 9px;color:var(--ink);line-height:1.02;
  }
  .door p{margin:0 0 18px;color:var(--ink-2);font-size:15px;flex:1}
  .door-go{
    font:600 13px/1 Figtree,sans-serif;color:var(--brass-hi);
    transition:transform .18s ease;
  }
  .door:hover .door-go{color:var(--brass-hi);transform:translateX(3px)}

  /* footer.wrap, not footer: the element also carries .wrap, and a class
     selector outranks an element one — the plain `footer` rule was losing its
     margin and padding to .wrap's `margin:0 auto; padding:0 24px`. */
  footer.wrap{
    margin:72px auto 0;padding:26px 24px 52px;
    border-top:1px solid var(--stage-edge);
    color:var(--muted);font-size:13px;
    display:flex;gap:14px;flex-wrap:wrap;align-items:center;
  }
  footer .dot{color:var(--brass-dim)}

  /* ── calculator page ──────────────────────────────────────────── */

  /* Jaiden's own React app mounts into #root. It keeps its own look; the only
     job here is to stop it fighting the site's header. */
  #root{min-height:calc(100svh - var(--bar-h));}

  @media (max-width:700px){
    .bar{gap:10px;padding-top:8px;padding-bottom:8px}
    .topbar nav{margin-left:0;width:100%}
    .topbar nav a{padding:8px 10px;font-size:13px}
    .page{padding:34px 20px 30px}
  }

  /* ── hero illustration ────────────────────────────────────────── */

  /* The drawing is landscape and busy, so it is framed as a picture rather
     than floated loose — a border and a warm rim tie a purple-and-neon
     illustration to a brass page without repainting the artwork itself. */
  .hero-grid{display:block}
  .hero-words{min-width:0;container-type:inline-size}

  .dj{
    margin:34px 0 0;
    border:1px solid var(--stage-edge);
    border-radius:6px;
    overflow:hidden;
    background:#12161f;
    box-shadow:0 18px 44px rgba(0,0,0,.55), 0 0 0 1px rgba(216,154,60,.16);
    line-height:0;
  }
  .dj img{width:100%;height:auto;display:block}

  @media (min-width:940px){
    .hero-grid{
      display:grid;grid-template-columns:minmax(0,1fr) 400px;
      gap:44px;align-items:center;
    }
    .dj{margin:0}
    /* Sized off its own column, not the viewport. Measured: this face renders
       2.37px of ink per 1px of font-size at the longest line, so 40cqi always
       leaves room. A vw value cannot know how wide the column is. */
    .name{font-size:min(40cqi,196px)}
  }
  @media (min-width:1100px){
    .hero-grid{grid-template-columns:minmax(0,1fr) 460px}
  }

  /* ── intro sequence ───────────────────────────────────────────── */

  /* Plays once per visit, on the way in. It is an overlay rather than a
     separate page so there is no second load between it and the site — the
     homepage is already sitting underneath when the curtain lifts. */
  #intro{
    position:fixed;inset:0;z-index:200;
    background:#0c090b;
    display:flex;align-items:center;justify-content:center;
    overflow:hidden;
  }

  /* Stage light that swells as the letters land. */
  .intro-glow{
    position:absolute;width:120vmax;height:120vmax;border-radius:50%;
    background:radial-gradient(circle,rgba(216,154,60,.22),transparent 62%);
  }

  /* Yard lines rake past when the sequence turns toward the game. */
  .intro-yards{
    position:absolute;inset:0;opacity:0;
    background:repeating-linear-gradient(90deg,
      rgba(244,236,228,.12) 0 2px, transparent 2px 9%);
    opacity:.25;
  }

  .intro-stage{position:relative;text-align:center;padding:0 24px}

  .intro-line{
    display:flex;align-items:baseline;justify-content:center;gap:.06em;
    font-family:"Big Shoulders Display",Impact,sans-serif;
    font-weight:800;text-transform:uppercase;line-height:.86;
    background:linear-gradient(178deg,#f7dc9a 6%,#d89a3c 46%,#8a6428 98%);
    -webkit-background-clip:text;background-clip:text;color:transparent;
  }
  .intro-dj{font-size:clamp(96px,22vw,240px)}
  /* Each letter carries its own gradient rather than inheriting the parent's.
     Animating a child's opacity gives it a stacking context, and a parent's
     background-clip:text then has nothing to paint the child's glyphs with —
     the word rendered and the letters did not. */
  .intro-dj span{
    display:inline-block;
    background:linear-gradient(178deg,#f7dc9a 6%,#d89a3c 46%,#8a6428 98%);
    -webkit-background-clip:text;background-clip:text;
    color:transparent;
  }

  /* The reveal is driven by JavaScript adding .in, and CSS only describes what
     "in" looks like. Nothing depends on an animation actually running: if the
     browser suppresses transitions the elements simply appear on their beats
     instead of easing in. An element that is hidden until an animation reveals
     it is an element that stays hidden when animations are off. */
  .intro-to,
  .intro-glow{opacity:0}

  /* The letters are positioned entirely from JavaScript, frame by frame.
     CSS transitions are not usable here: a browser running with the system
     Reduce Motion setting on completes them instantly, so the type teleported
     from off-screen to its resting place and the fall was never seen. A
     requestAnimationFrame tween cannot be switched off by a preference. */
  .intro-dj span,
  .intro-word{opacity:0;will-change:transform,filter}

  .intro-to{transition:opacity .5s ease-out}
  .intro-to.in{opacity:1}

  .intro-glow{transform:scale(.45);transition:opacity .8s ease-out,transform 1.6s ease-out}
  .intro-glow.in{opacity:1;transform:scale(1.2)}

  .intro-yards{opacity:0;transform:translateX(-10%);
    transition:opacity .7s ease-out,transform 1s ease-out}
  .intro-yards.in{opacity:.28;transform:translateX(4%)}

  .shock{
    position:absolute;left:50%;top:50%;width:230px;height:230px;
    margin:-115px 0 0 -115px;border-radius:50%;
    border:3px solid rgba(245,212,138,.85);
    opacity:0;transform:scale(.2);pointer-events:none;
    will-change:transform,opacity;
  }

  .intro-stage{will-change:transform}

  #intro{transition:opacity .55s ease-out, transform .55s ease-out}
  #intro.done{opacity:0;transform:scale(1.05);pointer-events:none}



  /* Everything is visible by default and the entrance is layered on top, only
     where motion is welcome. Hiding first and revealing by animation means a
     browser that suppresses animations shows an empty screen forever. */

  .intro-word{
    font-size:clamp(30px,7.4vw,76px);letter-spacing:.06em;
    margin-top:.12em;
  }

  .intro-to{
    margin-top:26px;opacity:0;
    font-family:"JetBrains Mono",monospace;
    font-size:clamp(12px,1.7vw,15px);letter-spacing:.34em;
    text-transform:uppercase;color:var(--ink-2);
  }
  .intro-to b{color:#f5d48a;font-weight:500}

  .intro-skip{
    position:absolute;right:20px;bottom:18px;
    font:500 11px/1 "JetBrains Mono",monospace;letter-spacing:.18em;
    text-transform:uppercase;color:var(--muted);
    background:none;border:0;padding:10px;cursor:pointer;
  }
  .intro-skip:hover{color:var(--brass-hi)}

  /* The intro plays its full motion regardless of the system Reduce Motion
     setting. Deliberate for this site: four seconds, dismissible with a click
     or Escape, and without the movement there is nothing left of it. Every
     other transition on the site still honours the preference. */

  /* ── key exchange demo ────────────────────────────────────────── */

  /* Drawn as a comic strip: two characters, speech bubbles, a note that flies
     between them, and an eavesdropper underneath who cannot read it. The maths
     is real Diffie-Hellman; only the presentation is playing. */

  .kx{margin:36px 0 0}
  .kx-board{
    display:grid;grid-template-columns:1fr;gap:16px;position:relative;
  }
  @media (min-width:900px){
    .kx-board{grid-template-columns:1fr 260px 1fr;align-items:start}
  }

  .party{
    border:3px solid var(--brass-dim);border-radius:18px;
    background:var(--stage-lift);padding:16px 18px 18px;
    box-shadow:0 6px 0 rgba(0,0,0,.35);
    position:relative;
  }
  .party.friend{border-color:#4a5a66;box-shadow:0 6px 0 rgba(0,0,0,.35)}

  .avatar{display:flex;align-items:center;gap:12px;margin-bottom:12px}
  .avatar svg{width:74px;height:74px;flex:none}
  .avatar h3{
    font-family:"Big Shoulders Display",sans-serif;
    font-weight:800;font-size:26px;text-transform:uppercase;
    margin:0;color:var(--ink);line-height:1;
  }
  .avatar .who{
    font-family:"JetBrains Mono",monospace;font-size:10px;
    letter-spacing:.18em;text-transform:uppercase;color:var(--brass);
    display:block;margin-bottom:3px;
  }
  .party.friend .avatar .who{color:var(--nickel)}

  /* Speech bubble with a tail, pointing back at its character. */
  /* .sec p sets a light body colour and outranks a bare .bubble class, so the
     speech bubbles were rendering pale grey on cream — legible in the CSS,
     invisible on screen. Qualified so the dark text actually wins. */
  .sec p.bubble,
  .bubble{
    position:relative;background:#f4ece4;color:#1b1216;
    border-radius:14px;padding:11px 14px;margin:0 0 14px;
    font:500 13.5px/1.45 Figtree,sans-serif;
    box-shadow:0 3px 0 rgba(0,0,0,.3);
  }
  .bubble::after{
    content:"";position:absolute;top:-9px;left:26px;
    border-left:10px solid transparent;border-right:10px solid transparent;
    border-bottom:10px solid #f4ece4;
  }
  .party.friend .bubble::after{left:auto;right:26px}
  .bubble b{color:#8a5a08}

  .row{
    display:flex;justify-content:space-between;gap:12px;align-items:baseline;
    padding:7px 0;border-bottom:1px dashed rgba(244,236,228,.12);
    font-family:"JetBrains Mono",monospace;font-size:12.5px;
  }
  .row:last-child{border-bottom:0}
  .row .k{color:var(--muted)}
  .row .v{color:var(--ink);font-variant-numeric:tabular-nums}
  .row .v.secret{color:#e0776a;font-weight:500}
  .row .v.shared{color:var(--brass-hi);font-weight:500;font-size:15px}
  .row.pending .v{color:var(--muted)}

  /* The wire, and the note that travels it. */
  .wire{
    border:3px dashed var(--stage-edge);border-radius:18px;
    padding:14px 12px;text-align:center;background:rgba(255,255,255,.015);
    position:relative;min-height:170px;
  }
  .wire h4{
    font-family:"JetBrains Mono",monospace;font-size:9.5px;
    letter-spacing:.18em;text-transform:uppercase;color:var(--muted);
    margin:0 0 12px;font-weight:400;
  }
  .wire .packet{
    font-family:"JetBrains Mono",monospace;font-size:12px;
    color:var(--ink-2);background:#100c0f;
    border:2px solid var(--stage-edge);border-radius:9px;
    padding:6px 9px;margin-bottom:7px;word-break:break-all;
    opacity:0;transform:translateY(-8px) rotate(-2deg);
  }
  .wire .packet.on{opacity:1;transform:none}
  .wire .packet b{color:var(--brass)}

  .flyer{
    position:absolute;left:0;top:52%;width:42px;height:32px;
    opacity:0;pointer-events:none;
  }
  .flyer svg{width:100%;height:100%;display:block}

  .kx-controls{display:flex;gap:10px;flex-wrap:wrap;align-items:center;margin:22px 0 0}
  .kx-controls input{
    flex:1;min-width:200px;padding:12px 14px;background:#100c0f;color:var(--ink);
    border:2px solid var(--stage-edge);border-radius:10px;
    font:400 14px/1.4 "JetBrains Mono",monospace;
  }
  .kx-controls input:focus{outline:none;border-color:var(--brass-dim);box-shadow:0 0 0 3px rgba(216,154,60,.18)}
  .kx-btn{
    font:700 13.5px/1 Figtree,sans-serif;padding:13px 20px;border-radius:11px;
    border:0;background:var(--brass);color:#1b1216;cursor:pointer;
    box-shadow:0 4px 0 #8a6428;
  }
  .kx-btn:active{transform:translateY(3px);box-shadow:0 1px 0 #8a6428}
  .kx-btn.ghost{background:#2a2126;color:var(--brass-hi);box-shadow:0 4px 0 #171114}
  .kx-btn.ghost:active{box-shadow:0 1px 0 #171114}
  .kx-btn:disabled{opacity:.5;cursor:default;transform:none}

  /* The eavesdropper, sulking at the bottom. */
  .eve{
    margin:18px 0 0;border:3px solid #5a2f33;border-radius:18px;
    background:rgba(224,119,106,.06);padding:14px 18px 16px;
    display:flex;gap:14px;align-items:flex-start;
    box-shadow:0 6px 0 rgba(0,0,0,.3);
  }
  .eve svg{width:74px;height:74px;flex:none}
  .eve .eve-say{flex:1}
  .eve h4{
    font-family:"JetBrains Mono",monospace;font-size:10px;
    letter-spacing:.16em;text-transform:uppercase;color:#e0776a;
    margin:0 0 7px;font-weight:400;
  }
  .eve p{margin:0;color:var(--ink-2);font-size:14px}
  .eve code{
    background:#1a1216;border:1px solid #3a2126;border-radius:4px;
    padding:1px 5px;font-family:"JetBrains Mono",monospace;font-size:12px;color:#e0a99f;
  }

