/* FoxSDR site — Type 71 console.
 *
 * The application dresses itself as 1960s bench equipment: enamelled steel,
 * engraved brass plates, recessed wells, rocker switches, nixie readouts and a
 * phosphor scope. This stylesheet puts the site in the same cabinet, so the
 * page somebody lands on and the program they download read as one object
 * rather than two products that share a name.
 *
 * TWO RULES CARRIED THROUGH FROM THE APPLICATION'S OWN DESIGN, and worth
 * keeping when editing this file:
 *
 *   1. CABINET IS CHROME, GLASS IS DATA. Anything drawn as panel metal is
 *      something the hand operates — a plate, a screw, a button, a rocker.
 *      Anything in a dark recessed well is something the receiver actually
 *      measured or somebody actually reported. A reading never sits on the
 *      cabinet and a control never sits on the glass, so what is changeable is
 *      legible at a glance.
 *
 *   2. STATE IS CARRIED TWICE, never by colour alone. A lamp is lit AND its
 *      caption changes; an open fault is amber AND says "investigating". The
 *      palette below is warm and low-contrast by design, which makes a
 *      colour-only signal weaker here than on the dark-blue theme it replaced,
 *      so it is not used.
 *
 * Figures are monospaced everywhere (Nova Mono), prose and plates are
 * condensed (Saira Condensed): a number that changes must not shift the
 * characters around it.
 */

/* --- typefaces --------------------------------------------------------
   Self-hosted because the CSP is default-src 'self': a fonts.googleapis.com
   link is blocked outright, and the page would fall back to a system stack
   while looking, from the server's side, like a perfectly good deploy. Every
   stack below names real fallbacks so a font that fails to load still lands
   on something condensed. See web/assets/fonts/README.md. */

@font-face {
  font-family: "Nova Mono";
  src: url("/assets/fonts/nova-mono-400.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Saira Condensed";
  src: url("/assets/fonts/saira-condensed-400.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Saira Condensed";
  src: url("/assets/fonts/saira-condensed-500.woff2") format("woff2");
  font-weight: 500; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Saira Condensed";
  src: url("/assets/fonts/saira-condensed-600.woff2") format("woff2");
  font-weight: 600; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Saira Condensed";
  src: url("/assets/fonts/saira-condensed-700.woff2") format("woff2");
  font-weight: 700; font-style: normal; font-display: swap;
}

:root {
  /* Cabinet */
  --panel-hi: #6e6552;
  --panel-mid:#514a3b;
  --panel-lo: #3b3529;
  --edge:     #8b8069;
  --ink:      #2a251c;

  /* Wells and glass */
  --well-hi:  #26211a;
  --well-lo:  #1f1b14;
  --inset:    #14110c;
  --glass:    #0d0b07;
  --line:     #4a4132;

  /* Text */
  --ivory:    #EFE7D2;
  --bone:     #C9BFA4;
  --dust:     #9C9078;
  --mute:     #948A72;

  /* Signals. Rust is the accent, amber warns, phosphor confirms, nixie is for
     lit figures only — a number behind glass, never a label on metal. */
  --rust:      #B8552F;   /* fills, rules and borders — the application's own */
  --rust-text: #D4703C;   /* the same accent as TEXT on a dark ground */
  --rust-hi:   #E8A07A;   /* hover */
  --amber:    #D9B23C;
  --nixie:    #F0A840;
  --phos:     #8FD9A0;
  --alarm:    #E0623C;

  --radius:   4px;
  --wrap:     1180px;

  --plate: linear-gradient(#d3caaf, #a89c80);
  --metal: linear-gradient(var(--panel-hi), var(--panel-mid) 40%, var(--panel-lo));
  --well:  linear-gradient(var(--well-hi), var(--well-lo));
  --emboss: inset 0 1px 0 rgba(255,255,255,.4), 0 3px 0 var(--panel-lo);
  --recess: inset 0 0 0 2px var(--edge), inset 0 3px 10px rgba(0,0,0,.6);
}

* { box-sizing: border-box; }

html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  background: #15120d radial-gradient(120% 90% at 50% -10%, #2a251c 0%, #15120d 70%) fixed;
  color: var(--bone);
  font: 400 16px/1.6 "Saira Condensed", "Roboto Condensed", "Segoe UI Semi Condensed", system-ui, sans-serif;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4 { line-height: 1.12; letter-spacing: .01em; margin: 0 0 .5em; color: var(--ivory); font-weight: 600; }
p { margin: 0 0 1em; }
a { color: var(--rust-text); text-decoration: none; }
a:hover { color: var(--rust-hi); }

/* Every figure and every machine-readable token is monospaced. */
code, .mono, .num {
  font-family: "Nova Mono", ui-monospace, "Cascadia Mono", Consolas, monospace;
}
code {
  font-size: .85em; line-height: 1.5;
  background: var(--glass); border: 1px solid var(--line);
  color: var(--nixie);
  padding: .12em .4em; border-radius: 2px; word-break: break-all;
}

.wrap { max-width: var(--wrap); margin: 0 auto; padding: 0 24px; }
.muted { color: var(--dust); }
.small { font-size: 13.5px; }

.skip {
  position: absolute; left: -9999px; top: 0;
  background: var(--plate); color: var(--ink); font-weight: 600;
  letter-spacing: .18em; padding: 10px 18px; z-index: 100;
}
.skip:focus { left: 0; }

/* Keyboard focus has to survive a palette this warm: a brass ring on ink. */
a:focus-visible, button:focus-visible, input:focus-visible,
select:focus-visible, textarea:focus-visible, .tile:focus-visible {
  outline: 2px solid var(--nixie); outline-offset: 2px;
}

/* --- the rail ----------------------------------------------------------
   A brass strip across the top of the cabinet: nameplate on the left,
   engraved legends across it, one lit button at the end. */

.nav {
  position: sticky; top: 0; z-index: 20;
  display: flex; align-items: center; gap: 22px;
  padding: 10px 24px;
  background: linear-gradient(#d3caaf, #b0a488);
  border-bottom: 2px solid var(--ink);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.5), inset 0 -3px 8px rgba(0,0,0,.28), 0 6px 20px rgba(0,0,0,.55);
}
.brand {
  display: inline-flex; align-items: center; gap: 11px;
  color: var(--ink); text-decoration: none;
  font-size: 20px; font-weight: 700; letter-spacing: .06em;
  text-shadow: 0 1px 0 rgba(255,248,225,.35);
}
.brand img { border-radius: 2px; display: block; box-shadow: 0 1px 3px rgba(0,0,0,.6); }
.brand b { color: #5c2a13; font-weight: 700; }
.nav nav { display: flex; gap: 4px; margin-left: 6px; }
.nav nav a {
  color: var(--ink); text-decoration: none;
  font-family: "Nova Mono", monospace; font-size: 10.5px; letter-spacing: .18em;
  padding: 7px 11px; border-radius: 2px;
  box-shadow: inset 0 0 0 1px rgba(42,37,28,.28);
}
.nav nav a:hover { background: rgba(20,17,12,.22); box-shadow: inset 0 0 0 1px var(--ink); }
.nav > .btn {
  margin-left: auto;
  background: linear-gradient(#A34A28, #8E3F22);
  color: var(--ivory);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.28), 0 3px 0 #5f2c17;
}
.nav > .btn:active { box-shadow: inset 0 1px 0 rgba(255,255,255,.2), 0 0 0 #5f2c17; }
@media (max-width: 900px) { .nav nav { display: none; } }

/* --- buttons: brass, and they travel -----------------------------------
   Rest stands 3px proud; pressed collapses that edge and moves down by the
   same 3px, so the press is felt rather than tinted. */

.btn {
  display: inline-flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 2px;
  background: var(--plate); color: var(--ink);
  font-family: "Nova Mono", monospace; font-size: 12px; letter-spacing: .14em;
  border: 0; border-radius: 2px;
  padding: 12px 22px; text-decoration: none; cursor: pointer; text-align: center;
  box-shadow: var(--emboss);
  transition: filter .12s ease;
}
.btn:hover { filter: brightness(1.07); color: var(--ink); }
.btn:active { transform: translateY(3px); box-shadow: inset 0 1px 0 rgba(255,255,255,.3), 0 0 0 var(--panel-lo); }
.btn small {
  font-family: "Saira Condensed", sans-serif;
  font-weight: 500; font-size: 12.5px; letter-spacing: .02em; opacity: .8;
}
.btn-lg { padding: 15px 28px; font-size: 13px; }
.btn-sm { padding: 8px 14px; font-size: 10px; }
.btn-ghost {
  background: linear-gradient(#4a4234, #241f18); color: var(--bone);
  box-shadow: inset 0 1px 0 rgba(255,248,225,.16), 0 3px 0 var(--inset);
}
.btn-ghost:hover { color: var(--ivory); filter: brightness(1.15); }

/* --- hero: the scope ---------------------------------------------------
   The canvas is the instrument's glass, so it sits behind a scanline overlay
   and a vignette. Everything readable sits on the cabinet in front of it. */

.hero {
  position: relative; overflow: hidden;
  border-bottom: 2px solid var(--ink);
  background: var(--metal);
}
.hero canvas {
  position: absolute; inset: 0; width: 100%; height: 100%;
  opacity: .62;
}
.hero::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background:
    repeating-linear-gradient(rgba(0,0,0,.26) 0 1px, transparent 1px 3px),
    radial-gradient(130% 105% at 68% 42%, rgba(21,18,13,.18) 0%, rgba(21,18,13,.72) 52%, rgba(21,18,13,.95) 100%);
}
.hero-inner {
  position: relative; z-index: 2;
  max-width: var(--wrap); margin: 0 auto; padding: 84px 24px 72px;
}
/* The instrument's own designation, stencilled above everything else — the
   line that ties this page to the console the application draws. */
.kicker {
  font-family: "Nova Mono", monospace; font-size: 11px;
  text-transform: uppercase; letter-spacing: .3em; color: var(--rust-text);
  margin: 0 0 14px;
}
.eyebrow {
  display: flex; flex-wrap: wrap; align-items: center; gap: 0 4px;
  font-family: "Nova Mono", monospace; font-size: 11px;
  text-transform: uppercase; letter-spacing: .16em; color: var(--dust);
  margin-bottom: 18px;
}
.hero h1 {
  font-size: clamp(40px, 6.6vw, 68px); font-weight: 600;
  color: var(--ivory); letter-spacing: .01em; margin-bottom: 18px;
}
.hero h1 em { color: var(--nixie); font-style: normal; text-shadow: 0 0 22px rgba(240,168,64,.35); }
.lede { font-size: clamp(16px, 1.9vw, 19px); color: var(--bone); max-width: 64ch; }

/* "Open beta", stated where a visitor reads it rather than discovered. A
   person who knows they are running a beta reports a fault; a person who
   thinks they have a finished product uninstalls it and says nothing. */
.beta-tag {
  display: inline-block; margin-right: 12px; padding: 3px 10px;
  background: var(--plate); color: var(--ink);
  font-weight: 700; letter-spacing: .18em; border-radius: 2px;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.4);
}
.beta-line { color: var(--bone); font-size: clamp(15px, 1.7vw, 17px); max-width: 64ch; margin: -4px 0 18px; }
.beta-line b { color: var(--nixie); font-weight: 600; }

.cta { display: flex; flex-wrap: wrap; gap: 14px; margin: 30px 0 26px; }

/* Lamp rows: a lit dot AND the sentence, never the dot alone. */
.trust {
  display: flex; flex-wrap: wrap; gap: 10px 28px;
  list-style: none; padding: 0; margin: 0;
  font-family: "Nova Mono", monospace; font-size: 11px; letter-spacing: .1em;
  text-transform: uppercase; color: var(--dust);
}
.trust li { display: flex; align-items: center; gap: 9px; }
.trust li::before {
  content: ""; width: 9px; height: 9px; border-radius: 50%; flex: none;
  background: var(--phos);
  box-shadow: 0 0 8px rgba(143,217,160,.8), 0 0 0 1px var(--line);
}

/* --- counter strip: drums behind glass --------------------------------- */

.strip {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 2px; background: var(--ink);
  border-bottom: 2px solid var(--ink);
  padding: 2px;
}
.strip div {
  background: var(--well); padding: 22px 20px 20px; text-align: center;
  box-shadow: var(--recess);
}
.strip b {
  display: block; font-family: "Nova Mono", monospace;
  font-size: 34px; line-height: 1.1; color: var(--nixie);
  text-shadow: 0 0 14px rgba(240,168,64,.45);
}
.strip span {
  display: block; padding-top: 7px;
  font-family: "Nova Mono", monospace; font-size: 9.5px;
  color: var(--mute); text-transform: uppercase; letter-spacing: .2em;
}

/* --- sections ---------------------------------------------------------- */

section.wrap, .band { padding-top: 72px; padding-bottom: 72px; }
.band {
  background: linear-gradient(#1b1811, #15120d);
  border-top: 1px solid var(--line); border-bottom: 1px solid var(--line);
}
.band > .wrap { padding: 0; }

/* An engraved plate rather than a heading: the section title is stamped into
   the cabinet, the way a real panel labels its own region. */
.section-title {
  display: inline-block;
  font-size: clamp(22px, 3vw, 30px); font-weight: 600; letter-spacing: .16em;
  text-transform: uppercase; color: var(--ink);
  background: var(--plate); border-radius: 2px;
  padding: 6px 22px; margin-bottom: 20px;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.4), 0 2px 3px rgba(0,0,0,.5);
  text-shadow: 0 1px 0 rgba(255,248,225,.3);
}
.section-lede { color: var(--dust); max-width: 70ch; font-size: 16.5px; margin-bottom: 30px; }

/* --- feature cards: recessed wells -------------------------------------- */

.cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); gap: 16px; }
.card {
  background: var(--well); border-radius: var(--radius);
  box-shadow: var(--recess);
  padding: 22px 20px;
  transition: box-shadow .15s ease, transform .15s ease;
}
.card:hover {
  transform: translateY(-2px);
  box-shadow: inset 0 0 0 2px var(--rust), inset 0 3px 10px rgba(0,0,0,.6);
}
.card h3 { font-size: 18px; letter-spacing: .04em; color: var(--ivory); }
.card p { color: var(--dust); margin: 0; font-size: 14.5px; }
.ico {
  width: 40px; height: 40px; border-radius: 2px; margin-bottom: 14px;
  background: var(--inset); display: grid; place-items: center;
  box-shadow: inset 0 0 0 1px var(--line);
}
.ico svg {
  width: 22px; height: 22px; fill: none; stroke: var(--rust);
  stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round;
}

/* --- browser section ---------------------------------------------------- */

.split { display: grid; grid-template-columns: 1.05fr .95fr; gap: 44px; align-items: center; }
@media (max-width: 900px) { .split { grid-template-columns: 1fr; gap: 32px; } }
.split p { color: var(--dust); }
.browser-intro { max-width: 84ch; }
.browser-intro p { color: var(--dust); }

.ticks { list-style: none; padding: 0; margin: 0; }
.ticks li {
  color: var(--dust); padding-left: 26px; position: relative;
  margin-bottom: 12px; font-size: 15px;
}
.ticks li::before {
  content: ""; position: absolute; left: 2px; top: .55em;
  width: 9px; height: 9px;
  background: var(--rust); box-shadow: 0 0 0 1px var(--inset);
}
.ticks b { color: var(--ivory); font-weight: 600; }

/* The screenshot sits behind glass in a bezel, like the scope. */
.mock {
  background: var(--glass); border-radius: var(--radius); overflow: hidden;
  box-shadow: 0 0 0 2px var(--ink), 0 0 0 4px var(--edge), 0 26px 60px rgba(0,0,0,.7);
}
.mock img { display: block; width: 100%; height: auto; }
.mock-wide { margin-top: 32px; }

.note-strip {
  background: var(--inset); box-shadow: inset 0 0 0 1px var(--line);
  border-left: 3px solid var(--amber);
  padding: 13px 16px; margin: 0 0 24px; max-width: 82ch;
  color: var(--dust); font-size: 14.5px;
}
.note-strip b { color: var(--ivory); }
/* A single wide figure outside the .shots grid still needs the grid's own
   caption treatment, which .shot supplies; this just stops it inheriting the
   two-column sizing. */
.shot.mock-wide { display: block; }

/* --- the screen gallery -------------------------------------------------
   Screenshots of the application's own windows, each behind glass in a bezel
   with an engraved caption beneath it.

   THE CAPTION IS PART OF THE PICTURE, not decoration under it. A screenshot
   of a receiver is the page's evidence that the thing works, and a picture of
   computed positions is indistinguishable on a web page from a picture of
   received ones — the satellite window plots propagated orbital elements, a
   file source and the signal generator both look exactly like off-air
   reception. So every shot states what it is: `.shot-src` carries that
   sentence, and it is required rather than optional. */

.shots { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; }
@media (max-width: 900px) { .shots { grid-template-columns: 1fr; } }
/* The lead shot is the whole console and earns the full width. */
.shot-lead { grid-column: 1 / -1; }

.shot { display: flex; flex-direction: column; gap: 0; }
.shot figure { margin: 0; }
.shot img {
  display: block; width: 100%; height: auto;
  background: var(--glass);
}
.shot .mock { margin: 0; }
.shot figcaption {
  background: var(--inset); box-shadow: inset 0 0 0 1px var(--line);
  border-left: 3px solid var(--rust);
  padding: 13px 15px; margin-top: 10px;
}
.shot-name {
  display: block; font-size: 15.5px; font-weight: 600;
  letter-spacing: .03em; color: var(--ivory);
}
.shot-what { display: block; color: var(--dust); font-size: 14px; margin-top: 5px; line-height: 1.5; }
/* Provenance, in three cases. Phosphor for something the radio actually
   heard; amber for anything computed, replayed or generated; bone for a
   window showing the application's own state, where no signal is on display
   at all and claiming either of the other two would be the wrong answer. The
   words say which, so the colour never carries it alone. */
/* Monospaced and coloured like an instrument legend, but NOT forced to
   uppercase: these run to a couple of sentences, and 30 words of tracked
   capitals is a wall nobody reads — which would defeat the whole point of
   making the provenance prominent. The marker word carries the emphasis. */
.shot-src {
  display: block; margin-top: 9px;
  font-family: "Nova Mono", monospace; font-size: 11px; line-height: 1.65;
  letter-spacing: .02em; color: var(--mute);
}
.shot-src b { font-weight: 400; letter-spacing: .14em; }
.shot-src.live { color: var(--phos); }
.shot-src.computed { color: var(--amber); }
.shot-src.state { color: var(--bone); }

/* --- plugin catalogue: data plates ------------------------------------- */

.plugins { display: grid; grid-template-columns: repeat(auto-fit, minmax(290px, 1fr)); gap: 14px; }
.plug {
  display: flex; flex-direction: column; gap: 10px;
  background: var(--inset); border-radius: 2px;
  box-shadow: inset 0 0 0 1px var(--line);
  padding: 16px 16px 14px;
  transition: box-shadow .15s ease, transform .15s ease;
}
.plug:hover { transform: translateY(-2px); box-shadow: inset 0 0 0 1px var(--edge); }
.plug h3 {
  margin: 0; font-size: 16.5px; letter-spacing: .03em; color: var(--ivory);
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px;
}
.plug p { color: var(--dust); font-size: 14px; margin: 0; flex: 1 1 auto; }
.plug-tags { display: flex; flex-wrap: wrap; gap: 6px; }
.plug-foot {
  margin-top: 2px; padding-top: 10px; border-top: 1px solid var(--line);
  color: var(--mute); font-family: "Nova Mono", monospace; font-size: 11px; letter-spacing: .04em;
}

/* Tags are stamped legends, not pills. Each carries a word, so the colour is
   reinforcement and never the message. */
.tag {
  font-family: "Nova Mono", monospace; font-size: 9.5px;
  text-transform: uppercase; letter-spacing: .14em;
  padding: 3px 8px; border-radius: 1px; border: 1px solid;
}
.tag.cap     { color: var(--ink); background: var(--plate); border-color: var(--edge); }
.tag.ok      { color: var(--phos);  border-color: rgba(143,217,160,.45); background: rgba(143,217,160,.10); }
.tag.warn    { color: var(--amber); border-color: rgba(217,178,60,.45);  background: rgba(217,178,60,.10); }
.tag.neutral { color: var(--dust);  border-color: var(--line); background: rgba(255,255,255,.03); }
.tag.note    { color: #8FBCD9; border-color: rgba(143,188,217,.45); background: rgba(143,188,217,.10); cursor: help; }

.fineprint { color: var(--mute); font-size: 13.5px; margin-top: 24px; max-width: 80ch; }

/* --- the test record ---------------------------------------------------- */

.honest { display: grid; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); gap: 18px; }
.honest > div {
  background: var(--inset); padding: 16px 18px;
  border-left: 3px solid var(--rust);
  box-shadow: inset 0 0 0 1px var(--line);
}
.honest h3 {
  font-family: "Nova Mono", monospace; font-size: 11px;
  text-transform: uppercase; letter-spacing: .18em; color: var(--rust-text);
  margin-bottom: .7em;
}
.honest p { color: var(--dust); font-size: 14.5px; margin: 0; }

/* --- download: the dispatch panel --------------------------------------- */

.dlcard {
  display: grid; grid-template-columns: 1.15fr .85fr;
  border-radius: var(--radius); overflow: hidden;
  background: var(--metal);
  border: 2px solid var(--edge);
  box-shadow: 0 30px 70px rgba(0,0,0,.7), inset 0 2px 0 rgba(255,248,225,.28), inset 0 -3px 10px rgba(0,0,0,.55);
}
@media (max-width: 900px) { .dlcard { grid-template-columns: 1fr; } }
.dlmain { padding: 26px; }
.dlmain > h3 { font-size: 23px; letter-spacing: .04em; color: var(--ivory); }
.dlmain > p { color: var(--bone); max-width: 54ch; }
.dlside {
  padding: 26px; background: var(--well);
  box-shadow: var(--recess);
}
.dlside h4 {
  font-family: "Nova Mono", monospace; font-size: 10px;
  text-transform: uppercase; letter-spacing: .2em; color: var(--mute);
}
.dlside ul { padding-left: 18px; margin: 0; }
.dlside li { color: var(--dust); font-size: 14px; margin-bottom: 12px; }
.dlside b { color: var(--ivory); }

/* The published checksum reads as a readout, because that is what it is. */
.hash {
  margin: 20px 0 0; font-family: "Nova Mono", monospace; font-size: 10px;
  letter-spacing: .16em; color: var(--mute); text-transform: uppercase;
}
.hash code {
  display: block; margin-top: 7px; padding: 9px 11px;
  letter-spacing: .02em; text-transform: none;
  background: var(--glass); box-shadow: inset 0 0 0 1px var(--line);
  border: 0; color: var(--nixie);
}

/* Channel legends. Stable is quiet, nightly is warmer: the visual weight
   follows the risk, and the default download must not look adventurous. */
.chan {
  display: inline-block; vertical-align: middle; margin-left: 10px;
  padding: 3px 9px; border-radius: 1px; border: 1px solid var(--line);
  font-family: "Nova Mono", monospace; font-size: 10px; font-weight: 400;
  letter-spacing: .16em; text-transform: uppercase;
  color: var(--dust); background: var(--inset);
}
.chan-n { color: var(--amber); border-color: rgba(217,178,60,.5); background: rgba(217,178,60,.10); }

.nightly { margin-top: 26px; padding-top: 22px; border-top: 1px solid rgba(20,17,12,.5); }
.nightly h4 { margin: 0 0 8px; font-size: 17px; letter-spacing: .04em; }
.nightly > p { color: var(--bone); font-size: 14px; max-width: 62ch; margin: 0 0 14px; }
.nightly .btn { font-size: 11px; }
.nightly .hash { margin-top: 14px; }

.licence {
  margin-top: 24px; border-radius: var(--radius);
  background: var(--inset); box-shadow: inset 0 0 0 1px var(--line);
  padding: 26px 28px;
}
.licence h3 { font-size: 20px; color: var(--nixie); letter-spacing: .03em; }
.licence p { color: var(--dust); max-width: 82ch; }

/* --- the issue ledger ---------------------------------------------------
   Rendered server-side from the live crash store (issues.go), so the markup
   here is fixed: .tracker-cols / .tracker-col / .issues / .issue-line /
   .tag-status / .pill and the data-issue attribute. Style them; do not expect
   to change them from this file. It is the service log of the instrument, so
   it is drawn as one: a well, ruled entries, a stamped verdict on each. */

.tracker {
  margin-top: 24px; border-radius: var(--radius);
  background: var(--well); box-shadow: var(--recess);
  padding: 24px 26px;
}
.tracker > h3 { font-size: 20px; letter-spacing: .1em; text-transform: uppercase; color: var(--ivory); }
.tracker > p { color: var(--dust); max-width: 82ch; }
.tracker-cols { display: grid; grid-template-columns: 1fr 1fr; gap: 26px; margin-top: 20px; }
@media (max-width: 900px) { .tracker-cols { grid-template-columns: 1fr; } }
.tracker-col > h4 {
  display: flex; align-items: center; gap: 10px; margin-bottom: 14px;
  font-family: "Nova Mono", monospace; font-size: 10px;
  text-transform: uppercase; letter-spacing: .2em; color: var(--mute);
}
.issues { list-style: none; margin: 0; padding: 0; display: grid; gap: 9px; align-content: start; }
.issues li {
  background: var(--inset); box-shadow: inset 0 0 0 1px var(--line);
  border-radius: 2px; padding: 13px 15px;
}
.issue-line { display: flex; flex-wrap: wrap; align-items: center; gap: 9px; margin-bottom: 6px; }
.issues b { font-size: 15px; letter-spacing: .02em; color: var(--ivory); font-weight: 600; }
.issues p { color: var(--dust); font-size: 14px; margin: 0 0 8px; }
.issues i {
  font-style: normal; display: block;
  font-family: "Nova Mono", monospace; font-size: 10px;
  letter-spacing: .12em; text-transform: uppercase; color: var(--mute);
}
.tracker .fineprint { margin-top: 20px; margin-bottom: 0; }

/* --- status legends ----------------------------------------------------
   Shared by the ledger and the tester portal. Every one of these sits beside
   a word that says the same thing; none of them is the only signal. */

.tag-status {
  font-family: "Nova Mono", monospace; font-size: 9.5px;
  text-transform: uppercase; letter-spacing: .14em;
  padding: 3px 8px; border-radius: 1px; border: 1px solid;
}
.st-open      { color: var(--amber); border-color: rgba(217,178,60,.5);  background: rgba(217,178,60,.10); }
.st-confirmed { color: #8FBCD9; border-color: rgba(143,188,217,.5); background: rgba(143,188,217,.10); }
.st-fixed,
.st-logged    { color: var(--phos); border-color: rgba(143,217,160,.5); background: rgba(143,217,160,.10); }
.st-wontfix,
.st-duplicate { color: var(--mute); border-color: var(--line); background: rgba(255,255,255,.03); }

/* A lit count behind glass. */
.pill {
  font-family: "Nova Mono", monospace; font-size: 12px;
  min-width: 26px; text-align: center; padding: 2px 8px; border-radius: 1px;
  color: var(--nixie); background: var(--glass);
  box-shadow: inset 0 0 0 1px var(--line);
  text-shadow: 0 0 8px rgba(240,168,64,.45);
}

/* --- beta board --------------------------------------------------------- */

.beta { margin-top: 8px; }
.beta-board { display: grid; grid-template-columns: 1.25fr 1fr; gap: 18px; align-items: start; }
@media (max-width: 900px) { .beta-board { grid-template-columns: 1fr; } }

.beta-pool, .beta-mine {
  background: var(--well); border-radius: var(--radius);
  box-shadow: var(--recess);
  padding: 18px 18px 20px;
}
.beta-mine { box-shadow: inset 0 0 0 2px var(--rust), inset 0 3px 10px rgba(0,0,0,.6); }
.beta-head h3 {
  font-size: 16px; letter-spacing: .12em; text-transform: uppercase;
  margin-bottom: 4px; display: flex; align-items: center; gap: 10px;
}
.beta-head p { color: var(--dust); font-size: 13.5px; margin: 0 0 14px; }
.beta-head kbd {
  font-family: "Nova Mono", monospace; font-size: 11px;
  border: 1px solid var(--line); border-bottom-width: 2px; border-radius: 2px;
  padding: 1px 5px; color: var(--bone); background: var(--inset);
}

.beta-tiles { display: flex; flex-wrap: wrap; gap: 8px; align-content: flex-start; }
.beta-drop {
  min-height: 190px; border: 1px dashed var(--line); border-radius: 2px; padding: 12px;
  transition: border-color .15s ease, background .15s ease;
}
.beta-drop.over { border-color: var(--nixie); background: rgba(240,168,64,.08); }
.beta-empty { color: var(--mute); font-size: 14px; margin: 0; align-self: center; }

/* Tiles are engraved keys: they drag with a mouse and press on a phone or a
   keyboard. A div with a drag handler would work for neither. */
.tile {
  display: flex; flex-direction: column; align-items: flex-start; gap: 2px;
  background: linear-gradient(#4a4234, #241f18); color: var(--bone);
  font: inherit; text-align: left;
  border: 0; border-radius: 2px; padding: 9px 12px;
  box-shadow: inset 0 1px 0 rgba(255,248,225,.16), 0 2px 0 var(--inset);
  cursor: grab; transition: filter .12s ease, transform .12s ease;
}
.tile:hover { filter: brightness(1.2); transform: translateY(-1px); }
.tile:active { cursor: grabbing; transform: translateY(2px); box-shadow: inset 0 1px 0 rgba(255,248,225,.1), 0 0 0 var(--inset); }
.tile span { font-size: 14px; font-weight: 600; letter-spacing: .02em; color: var(--ivory); }
.tile i {
  font-style: normal; font-family: "Nova Mono", monospace; font-size: 9px;
  color: var(--mute); letter-spacing: .12em; text-transform: uppercase;
}
.tile.dragging { opacity: .4; }
.tile.need { box-shadow: inset 0 0 0 1px var(--amber), 0 2px 0 var(--inset); }
.tile.need i { color: var(--amber); }
.beta-drop .tile {
  position: relative; padding-right: 26px;
  background: var(--plate);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.4), 0 2px 0 var(--panel-lo);
}
.beta-drop .tile span { color: var(--ink); }
.beta-drop .tile i { color: var(--ink); }
.beta-drop .tile::after {
  content: "×"; position: absolute; right: 9px; top: 6px;
  color: var(--ink); font-size: 15px;
}

/* --- forms: recessed, lit when focused ---------------------------------- */

.beta-fields {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 14px;
  margin-top: 18px;
}
.beta-fields label { display: flex; flex-direction: column; gap: 5px; }
.beta-fields label > span {
  font-family: "Nova Mono", monospace; font-size: 9.5px;
  text-transform: uppercase; letter-spacing: .18em; color: var(--mute);
}
.beta-fields b { color: var(--rust-text); }
.beta-wide { grid-column: 1 / -1; }
.beta-fields input[type=text], .beta-fields input[type=email],
.beta-fields select, .beta-fields textarea {
  background: var(--glass); color: var(--nixie);
  font-family: "Nova Mono", monospace; font-size: 14px;
  border: 0; border-radius: 2px; padding: 10px 12px; width: 100%;
  box-shadow: inset 0 0 0 1px var(--line), inset 0 2px 6px rgba(0,0,0,.6);
}
.beta-fields textarea { resize: vertical; line-height: 1.6; }
.beta-fields input::placeholder, .beta-fields textarea::placeholder { color: #8a5a2a; }
.beta-fields input:focus, .beta-fields select:focus, .beta-fields textarea:focus {
  outline: none; box-shadow: inset 0 0 0 1px var(--nixie), inset 0 2px 6px rgba(0,0,0,.6);
}
.beta-fields input.bad { box-shadow: inset 0 0 0 1px var(--alarm), inset 0 2px 6px rgba(0,0,0,.6); }
.beta-check { flex-direction: row !important; align-items: flex-start; gap: 10px; }
.beta-check input { margin-top: 4px; width: 16px; height: 16px; accent-color: var(--rust); }
/* This one is a sentence, not a field caption: it must not inherit the
   engraved-legend treatment above, which set it in 9.5px uppercase mono and
   made a consent statement unreadable. */
.beta-check span {
  font-family: "Saira Condensed", sans-serif;
  font-size: 13.5px; letter-spacing: normal; text-transform: none;
  color: var(--dust); line-height: 1.55;
}

.beta-submit { display: flex; flex-wrap: wrap; align-items: center; gap: 16px; margin-top: 18px; }
.beta-status { margin: 0; font-size: 14px; color: var(--dust); }
.beta-status.ok  { color: var(--phos); }
.beta-status.err { color: var(--alarm); }

/* --- tester portal ------------------------------------------------------ */

.portal { margin-top: 22px; display: grid; gap: 16px; }
.portal[hidden] { display: none; }

.portal-key, .portal-report, .portal-mine {
  background: var(--well); border-radius: var(--radius);
  box-shadow: var(--recess); padding: 20px;
}
.portal-key {
  display: grid; grid-template-columns: 1fr 1fr; gap: 20px; align-items: center;
  box-shadow: inset 0 0 0 2px var(--rust), inset 0 3px 10px rgba(0,0,0,.6);
}
@media (max-width: 780px) { .portal-key { grid-template-columns: 1fr; } }
.portal-key p { color: var(--dust); font-size: 13.5px; margin: 4px 0 0; }
.portal-copy { display: flex; gap: 8px; }
.portal-copy input {
  flex: 1; background: var(--glass); color: var(--nixie);
  border: 0; border-radius: 2px; padding: 10px 12px;
  font-family: "Nova Mono", monospace; font-size: 12px;
  box-shadow: inset 0 0 0 1px var(--line), inset 0 2px 6px rgba(0,0,0,.6);
}
.portal-report h3, .portal-mine h3 { font-size: 16px; letter-spacing: .1em; text-transform: uppercase; }
.portal-lede { color: var(--dust); font-size: 14px; margin-bottom: 6px; }

.mine-list { display: grid; gap: 8px; }
.mine {
  display: flex; flex-wrap: wrap; gap: 10px; align-items: baseline;
  background: var(--inset); border-radius: 2px; padding: 11px 13px;
  box-shadow: inset 0 0 0 1px var(--line);
}
.mine b { font-size: 14px; color: var(--ivory); }
.mine .muted { font-size: 12.5px; }
/* A reply from us, set apart so a tester can see at a glance that somebody
   answered rather than re-reading the row they wrote themselves. */
.mine-reply {
  grid-column: 1 / -1; margin: 6px 0 0; padding-left: 10px;
  border-left: 2px solid var(--rust); color: var(--bone); font-size: 13px;
}

.portal-leave { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; }
.portal-leave .muted { font-size: 13px; }

/* --- footer: the maker's plate ------------------------------------------ */

.foot {
  border-top: 2px solid var(--ink); padding: 46px 0 36px;
  background: linear-gradient(#1b1811, #15120d);
}
.footgrid { display: grid; grid-template-columns: 2fr 1fr 1fr; gap: 34px; margin-bottom: 26px; }
@media (max-width: 760px) { .footgrid { grid-template-columns: 1fr; } }
.footgrid h4 {
  font-family: "Nova Mono", monospace; font-size: 10px;
  text-transform: uppercase; letter-spacing: .2em; color: var(--mute);
}
.footgrid a {
  display: block; color: var(--dust); text-decoration: none;
  font-size: 14.5px; margin-bottom: 8px;
}
.footgrid a:hover { color: var(--rust-hi); }
.footgrid .brand { color: var(--bone); margin-bottom: 12px; text-shadow: none; }
.footgrid .brand b { color: var(--rust-text); }
.footgrid .brand:hover { color: var(--ivory); }
.foot .small { max-width: 80ch; color: var(--mute); }

/* --- consent: a panel-mounted notice ------------------------------------ */

.consent {
  position: fixed; left: 16px; right: 16px; bottom: 16px; z-index: 40;
  max-width: 780px; margin: 0 auto;
  display: flex; flex-wrap: wrap; gap: 18px; align-items: center;
  background: var(--metal); border: 2px solid var(--edge); border-radius: var(--radius);
  padding: 18px 20px;
  box-shadow: 0 24px 60px rgba(0,0,0,.8), inset 0 2px 0 rgba(255,248,225,.28);
}
.consent[hidden] { display: none; }
.consent b {
  display: block; margin-bottom: 4px; color: var(--ivory);
  letter-spacing: .1em; text-transform: uppercase; font-size: 14px;
}
.consent p { color: var(--bone); font-size: 13.5px; margin: 0; }
.consent > div:first-child { flex: 1 1 380px; }
/* The banner is panel metal, where the accent hue cannot carry link text at
   all (2.4:1). Ivory, underlined, so it still reads as a link. */
.consent a { color: var(--ivory); text-decoration: underline; }
.consent a:hover { color: #fff; }
.consent-btns { display: flex; gap: 10px; margin-left: auto; }

/* --- document pages ----------------------------------------------------- */

.doc { max-width: 820px; padding-top: 52px; padding-bottom: 76px; }
.doc h1 { font-size: 34px; letter-spacing: .04em; }
.doc h2 {
  font-family: "Nova Mono", monospace; font-size: 13px;
  text-transform: uppercase; letter-spacing: .18em; color: var(--rust-text);
  margin-top: 40px;
}
.doc h3 { font-size: 17px; margin-top: 26px; letter-spacing: .03em; }
.doc p, .doc li { color: var(--dust); }
.doc table {
  width: 100%; border-collapse: collapse; margin: 16px 0 24px;
  background: var(--inset); box-shadow: inset 0 0 0 1px var(--line);
}
.doc th, .doc td {
  text-align: left; padding: 10px 12px; border-bottom: 1px solid var(--line);
  font-size: 14px; vertical-align: top;
}
.doc th {
  color: var(--bone); font-family: "Nova Mono", monospace; font-size: 10px;
  text-transform: uppercase; letter-spacing: .16em; background: var(--well-lo);
}
.doc td { color: var(--dust); }
.doc .back {
  display: inline-block; margin-bottom: 24px; text-decoration: none;
  font-family: "Nova Mono", monospace; font-size: 11px;
  letter-spacing: .16em; text-transform: uppercase;
}
