/* ===========================================================================
   Reel Lab Audio — redesign stylesheet
   ===========================================================================

   Loaded ONLY by templates/site_base.html. The old system (base.html's own
   <style> block + static/css/main.css) never loads this file and this file
   never loads them, so the token names below (--accent, --ink, …) can't
   collide with the old blue --accent and its 85 usages.

   Structure
     1. Fonts
     2. Tokens (colour, module colours, type, space)
     3. Grounds — data-ground="tan|ink|rack" on any element
     4. Base
     5. Components
     6. Motion
   =========================================================================== */


/* ===========================================================================
   1. FONTS — self-hosted, OFL (licences beside the files in static/fonts/)
   ---------------------------------------------------------------------------
   Bricolage Grotesque: headlines and body. One variable file per subset
   carrying opsz 12–96 and wght; we use 400–800.
   Martian Mono: labels, spec readouts and numbered tags ONLY — never body
   copy. One variable file per subset; we use 400 and 500.
   =========================================================================== */

@font-face {
  font-family: "Bricolage Grotesque";
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url("../fonts/bricolage-grotesque-latin.woff2") format("woff2");
  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: "Bricolage Grotesque";
  font-style: normal;
  font-weight: 400 800;
  font-display: swap;
  src: url("../fonts/bricolage-grotesque-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Martian Mono";
  font-style: normal;
  font-weight: 400 500;
  font-display: swap;
  src: url("../fonts/martian-mono-latin.woff2") format("woff2");
  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: "Martian Mono";
  font-style: normal;
  font-weight: 400 500;
  font-display: swap;
  src: url("../fonts/martian-mono-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C4, U+2113, U+2C60-2C7F, U+A720-A7FF;
}


/* ===========================================================================
   2. TOKENS — named by role, not by colour
   =========================================================================== */

:root {
  /* --- Tan ground: pages people READ ------------------------------------ */
  --ground:       #E8DCC4;   /* tan paper */
  --ground-sunk:  #DFD1B4;   /* recessed band on tan */
  --ink:          #15140F;   /* text and rules on tan */
  --ink-soft:     #45402F;   /* body copy on tan */
  --ink-faint:    #625A4D;   /* mono labels on tan — 5.01:1 on --ground, 4.51:1 on --ground-sunk */
  --rule:         #15140F;   /* hairlines on tan */

  /* --- Ink ground: pages people WORK in --------------------------------- */
  --ground-dark:  #15140F;   /* ink ground */
  --ground-black: #0B0B0C;   /* the rack, behind modules */
  --paper:        #E8DCC4;   /* text on ink */
  --paper-soft:   #BDB2A0;
  --paper-faint:  #8A8172;   /* 4.80:1 on --ground-dark, 5.12:1 on --ground-black */

  /* --- Accents -------------------------------------------------------------
     THESE THREE RESTRICTIONS ARE LOAD-BEARING, NOT ADVISORY. Each accent
     fails WCAG contrast on the other ground, so using it there makes text
     unreadable. Don't reach for these directly in components: use the
     ground-aware --c-accent / --c-live from section 3, which already pick
     the legal one.
       --accent       oxblood  TAN ONLY  (2.69:1 on ink — fails)
       --accent-warm  copper   INK ONLY  (2.18:1 on tan — fails)
       --signal       amber    INK ONLY  (1.59:1 on tan — fails)        */
  --accent:       #9B3B31;   /* oxblood — primary accent, TAN PAGES ONLY */
  --accent-warm:  #E8763C;   /* copper — rack and module labels, INK PAGES ONLY */
  --signal:       #E8A33D;   /* amber — readouts and the one live action, INK PAGES ONLY */

  /* --- Module colours --------------------------------------------------------
     One pair per module in core/site_home.py MODULES: --mod-<id>-bg and
     --mod-<id>-ink. "faceplate" = the plugin's own faceplate bg/ink pair
     (Interface.js faceInfo / masterFaceInfo); "render" = sampled from the
     module render, ink picked for contrast. Used for the glow behind the
     centred carousel card — never as a text colour on tan. */
  --mod-prism-bg: #1E4266;       --mod-prism-ink: #F2EFE6;        /* render */
  --mod-hit-body-bg: #8A968A;    --mod-hit-body-ink: #15140F;     /* render */
  --mod-ms-bg: #428A7E;          --mod-ms-ink: #15140F;           /* render */
  --mod-resonator-bg: #C6A272;   --mod-resonator-ink: #15140F;    /* render */
  --mod-galactic-bg: #2A5A8A;    --mod-galactic-ink: #F2EFE6;     /* render */
  --mod-tape-flange-bg: #969696; --mod-tape-flange-ink: #15140F;  /* render */
  --mod-phaser-bg: #965A8A;      --mod-phaser-ink: #F2EFE6;       /* render */
  --mod-ironclad-bg: #5E5E5C;    --mod-ironclad-ink: #E6E2D8;     /* faceplate */
  --mod-delay-bg: #C6C6BA;       --mod-delay-ink: #15140F;        /* render */
  --mod-chorus-bg: #BAA2A2;      --mod-chorus-ink: #15140F;       /* render */
  --mod-synapse-bg: #34494A;     --mod-synapse-ink: #A8E6CF;      /* faceplate */
  --mod-preamp-bg: #8A6A4A;      --mod-preamp-ink: #F2E6D2;       /* faceplate (master) */
  --mod-professor-bg: #C4C4C2;   --mod-professor-ink: #2A2A2A;    /* faceplate */
  --mod-glue-bg: #4A4F56;        --mod-glue-ink: #E6E2D8;         /* faceplate (master) */
  --mod-dynamax-bg: #C56A57;     --mod-dynamax-ink: #4A1E16;      /* faceplate */
  --mod-helix-bg: #2E4A78;       --mod-helix-ink: #E8A04A;        /* faceplate */
  --mod-limiter-bg: #3A3A3A;     --mod-limiter-ink: #E8A33D;      /* faceplate (master) */

  /* --- Type families ---------------------------------------------------- */
  --font-sans: "Bricolage Grotesque", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-mono: "Martian Mono", ui-monospace, SFMono-Regular, Menlo, monospace;

  /* --- Type scale: five display steps, four text steps ----------------- */
  --display-1: clamp(3rem, 2.1rem + 4.4vw, 5.75rem);      /* 48 → 92px  hero */
  --display-2: clamp(2.125rem, 1.6rem + 1.8vw, 3.25rem);  /* 34 → 52px  closing call */
  --display-3: clamp(1.875rem, 1.4rem + 1.4vw, 2.875rem); /* 30 → 46px  section heads */
  --display-4: clamp(1.5rem, 1.2rem + 0.9vw, 2.125rem);   /* 24 → 34px  sub-heads, stats */
  --display-5: 1.3125rem;                                 /* 21px       sleeves, panels */

  --text-lg: 1.25rem;    /* 20px — lead paragraphs */
  --text-md: 1.0625rem;  /* 17px — body */
  --text-sm: 0.9375rem;  /* 15px — secondary body, buttons */
  --text-xs: 0.875rem;   /* 14px — the floor for anything you read */

  /* Martian Mono labels — uppercase, 0.2em tracking, always --c-faint or
     stronger so they clear 4.5:1 at this size. */
  --label-md: 0.6875rem; /* 11px */
  --label-sm: 0.625rem;  /* 10px */
  --label-track: 0.2em;
  --readout: 0.875rem;   /* 14px — spec readout values */

  --leading-tight: 1.04;
  --leading-body: 1.55;

  /* --- Space ------------------------------------------------------------- */
  --space-1: 0.25rem;
  --space-2: 0.5rem;
  --space-3: 0.75rem;
  --space-4: 1rem;
  --space-5: 1.5rem;
  --space-6: 2rem;
  --space-7: 3rem;
  --space-8: 4.5rem;
  --space-9: 7rem;

  --gutter: 1rem;            /* 16px at phone width … */
  --wrap: 1360px;
  --hairline: 1px;
  --radius: 2px;             /* equipment, not app: near-square corners */
  --tap: 44px;               /* minimum touch target */

  --ease-out: cubic-bezier(.2, .7, .2, 1);
  --dur: 480ms;
}

@media (min-width: 720px) {
  :root { --gutter: 2rem; }  /* … 32px from tablet up */
}


/* ===========================================================================
   3. GROUNDS — data-ground="tan|ink" on any element
   ---------------------------------------------------------------------------
   Components only ever read the --c-* values, so the same markup works on
   both grounds. A band inside a page (the home page's ink console section)
   just sets data-ground="ink" on itself.

   color-scheme tells the browser each ground's colours are deliberate.
   Tan is "only light", not "light": Chrome's Auto Dark Mode for Web Contents
   still repaints a page that says plain "light" (tan comes out olive-brown,
   and oxblood lands on dark, the pairing below that fails contrast). "only"
   is the spec's opt-out from forced darkening. Ink and rack are "dark", so
   form controls, scrollbars and autofill inside them are drawn dark too, and
   Chrome leaves them alone. Set per ground, not on :root, so a nested ink
   band (download's list panel, the home console) gets dark controls inside a
   tan page, and anything tan inside an ink page stays light.
   =========================================================================== */

[data-ground="tan"] {
  color-scheme: only light;
  --c-bg: var(--ground);
  --c-sunk: var(--ground-sunk);
  --c-fg: var(--ink);
  --c-soft: var(--ink-soft);
  --c-faint: var(--ink-faint);
  --c-line: var(--rule);
  --c-line-soft: rgba(21, 20, 15, .22);
  --c-accent: var(--accent);         /* oxblood */
  --c-on-accent: var(--paper);       /* 5.05:1 */
  --c-live: var(--ink);              /* the one live action: solid ink on tan */
  --c-on-live: var(--paper);         /* 14.6:1 */
  --c-live-hover: var(--accent);     /* oxblood under the pointer */
  background-color: var(--c-bg);
  color: var(--c-fg);
}

[data-ground="ink"] {
  color-scheme: dark;
  --c-bg: var(--ground-dark);
  --c-sunk: var(--ground-black);
  --c-fg: var(--paper);
  --c-soft: var(--paper-soft);
  --c-faint: var(--paper-faint);
  --c-line: rgba(232, 220, 196, .55);
  --c-line-soft: rgba(232, 220, 196, .18);
  --c-accent: var(--accent-warm);    /* copper */
  --c-on-accent: var(--ink);         /* 6.22:1 */
  --c-live: var(--signal);           /* amber */
  --c-on-live: var(--ink);           /* 8.55:1 */
  --c-live-hover: var(--paper);
  background-color: var(--c-bg);
  color: var(--c-fg);
}

/* The rack: ink rules, one step deeper, so module renders are the only lit
   thing on screen (home page carousel and rack effects). */
[data-ground="rack"] {
  color-scheme: dark;
  --c-bg: var(--ground-black);
  --c-sunk: var(--ground-dark);
  --c-fg: var(--paper);
  --c-soft: var(--paper-soft);
  --c-faint: var(--paper-faint);     /* 5.12:1 */
  --c-line: rgba(232, 220, 196, .32);
  --c-line-soft: rgba(232, 220, 196, .14);
  --c-accent: var(--accent-warm);    /* copper, 6.64:1 */
  --c-on-accent: var(--ink);
  --c-live: var(--signal);
  --c-on-live: var(--ink);
  --c-live-hover: var(--paper);
  background-color: var(--c-bg);
  color: var(--c-fg);
}


/* ===========================================================================
   4. BASE
   =========================================================================== */

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

html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  scroll-behavior: smooth;
}

body {
  margin: 0;
  font-family: var(--font-sans);
  font-size: var(--text-md);
  font-weight: 400;
  font-optical-sizing: auto;
  line-height: var(--leading-body);
  -webkit-font-smoothing: antialiased;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}
body > main { flex: 1 0 auto; }

h1, h2, h3, h4 {
  font-family: var(--font-sans);
  font-weight: 700;
  line-height: var(--leading-tight);
  margin: 0;
  text-wrap: balance;
}
h1 { font-size: var(--display-1); }
h2 { font-size: var(--display-3); }
h3 { font-size: var(--display-5); line-height: 1.15; }
p  { margin: 0; text-wrap: pretty; }

a { color: inherit; text-underline-offset: .2em; text-decoration-thickness: 1px; }
a:hover { text-decoration-thickness: 2px; }

img, svg, video { display: block; max-width: 100%; }
button, input, select, textarea { font: inherit; color: inherit; }

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

.wrap {
  width: 100%;
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.band { padding-block: var(--space-8); }
.band--sunk { background-color: var(--c-sunk); }
.band + .band { border-top: var(--hairline) solid var(--c-line-soft); }

.lead { font-size: var(--text-lg); color: var(--c-soft); max-width: 38em; }
.body-soft { color: var(--c-soft); }

.display-1 { font-size: var(--display-1); }
.display-2 { font-size: var(--display-2); }
.display-3 { font-size: var(--display-3); }
.display-4 { font-size: var(--display-4); }
.display-5 { font-size: var(--display-5); }

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

.skip-link {
  position: absolute; left: var(--gutter); top: -100px; z-index: 500;
  padding: var(--space-3) var(--space-4);
  background: var(--ink); color: var(--paper);
  font-weight: 600; text-decoration: none;
}
.skip-link:focus { top: var(--space-3); }


/* ===========================================================================
   5. COMPONENTS — every one reads --c-*, so it works on both grounds
   =========================================================================== */

/* ---- 5.1 Mono label ---------------------------------------------------- */
.mono-label {
  font-family: var(--font-mono);
  font-size: var(--label-md);
  font-weight: 500;
  line-height: 1.4;
  letter-spacing: var(--label-track);
  text-transform: uppercase;
  color: var(--c-faint);
}
.mono-label--sm { font-size: var(--label-sm); }
.mono-label--accent { color: var(--c-accent); }
.mono-label--strong { color: var(--c-fg); }

/* ---- 5.2 Hairline rule ------------------------------------------------- */
.rule {
  border: 0;
  border-top: var(--hairline) solid var(--c-line);
  margin: var(--space-6) 0;
}
.rule--soft { border-top-color: var(--c-line-soft); }
.rule--labelled {
  display: flex; align-items: center; gap: var(--space-4);
  border: 0; margin: var(--space-6) 0;
}
.rule--labelled::after {
  content: ""; flex: 1;
  border-top: var(--hairline) solid var(--c-line);
}

/* ---- 5.3 Buttons ------------------------------------------------------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  gap: var(--space-2);
  min-height: var(--tap);
  padding: 0 var(--space-5);
  border: var(--hairline) solid transparent;
  border-radius: var(--radius);
  font-family: var(--font-mono);
  font-size: var(--label-md);
  font-weight: 500;
  letter-spacing: .14em;
  text-transform: uppercase;
  line-height: 1.1;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color 160ms var(--ease-out), color 160ms var(--ease-out), border-color 160ms var(--ease-out);
}
.btn:hover { text-decoration: none; }
.btn[disabled], .btn[aria-disabled="true"] { opacity: .5; cursor: not-allowed; }

.btn--primary { background: var(--c-live); color: var(--c-on-live); border-color: var(--c-live); }
.btn--primary:hover { background: var(--c-live-hover); border-color: var(--c-live-hover); color: var(--c-on-live); }
[data-ground="tan"] .btn--primary:hover { color: var(--paper); }

.btn--secondary { background: transparent; color: var(--c-fg); border-color: var(--c-fg); }
.btn--secondary:hover { background: var(--c-fg); color: var(--c-bg); }

.btn--ghost {
  background: transparent; color: var(--c-fg);
  padding-inline: var(--space-2);
  text-decoration: underline; text-underline-offset: .25em; text-decoration-thickness: 1px;
}
.btn--ghost:hover { text-decoration-thickness: 2px; }

.btn--sm { min-height: var(--tap); padding: 0 var(--space-4); }
.btn--lg { min-height: 60px; padding: 0 var(--space-6); font-size: var(--text-xs); letter-spacing: .12em; }
.btn--block { display: flex; width: 100%; }

.btn-row { display: flex; flex-wrap: wrap; gap: var(--space-3); align-items: center; }

/* ---- 5.4 Top bar ------------------------------------------------------- */
.topbar {
  position: sticky; top: 0; z-index: 100;
  border-bottom: var(--hairline) solid var(--c-line);
}
.topbar__inner {
  display: flex; align-items: center; gap: var(--space-5);
  min-height: 72px;
}
.wordmark {
  font-family: var(--font-sans);
  font-weight: 700;
  font-size: 1.125rem;
  text-decoration: none;
  white-space: nowrap;
}
.wordmark:hover { text-decoration: none; }
.topbar__nav { display: flex; align-items: center; gap: var(--space-5); flex: 1; }
.topbar__links { display: flex; gap: 26px; list-style: none; margin: 0; padding: 0; flex: 1; }
.topbar__links a,
.topbar__login {
  font-size: var(--text-xs);
  color: var(--c-soft);
  text-decoration: none;
  padding-block: var(--space-2);
}
.topbar__links a:hover,
.topbar__login:hover { color: var(--c-fg); text-decoration: underline; }
.topbar__links a[aria-current="page"] { color: var(--c-fg); text-decoration: underline; }
.topbar__actions { display: flex; align-items: center; gap: var(--space-4); }
.topbar__spec { white-space: nowrap; }
@media (max-width: 1099px) { .topbar__spec { display: none; } }
/* "Jan" on the nav items that open on 1 January (task 016). */
.jan-chip {
  display: inline-block; margin-left: .35em; padding: 1px 5px;
  font-family: var(--font-mono); font-size: var(--label-sm); font-weight: 500;
  letter-spacing: .12em; text-transform: uppercase; line-height: 1.4;
  color: var(--c-accent); border: var(--hairline) solid currentColor; border-radius: var(--radius);
  vertical-align: 1px;
}
.topbar__menu-btn {
  display: none;
  margin-left: auto;
  min-height: var(--tap); min-width: var(--tap);
  background: transparent; border: var(--hairline) solid var(--c-line);
  border-radius: var(--radius);
  cursor: pointer;
}
.topbar__menu-btn svg { margin: auto; }

@media (max-width: 899px) {
  .topbar__menu-btn { display: inline-flex; align-items: center; justify-content: center; }
  .topbar__nav {
    display: none;
    position: absolute; left: 0; right: 0; top: 100%;
    flex-direction: column; align-items: stretch; gap: 0;
    padding: var(--space-3) var(--gutter) var(--space-5);
    background: var(--c-bg);
    border-bottom: var(--hairline) solid var(--c-line);
  }
  .topbar.is-open .topbar__nav { display: flex; }
  .topbar__links { flex-direction: column; gap: 0; }
  .topbar__links a,
  .topbar__login { display: flex; align-items: center; min-height: var(--tap); font-size: var(--text-md); }
  .topbar__links li + li { border-top: var(--hairline) solid var(--c-line-soft); }
  .topbar__actions { flex-direction: column; align-items: stretch; margin-top: var(--space-3); }
}

/* ---- 5.5 Footer -------------------------------------------------------- */
.footer {
  padding-block: var(--space-8) var(--space-6);
  border-top: var(--hairline) solid var(--c-line);
}
.footer__grid {
  display: grid;
  grid-template-columns: 2fr 1fr 1fr 1fr;
  gap: var(--space-7);
}
.footer__col { display: flex; flex-direction: column; gap: var(--space-2); }
.footer__col > .mono-label { margin-bottom: var(--space-2); }
.footer__col a { font-size: var(--text-xs); text-decoration: none; min-height: 28px; display: inline-flex; align-items: center; align-self: flex-start; }
.footer__col a:hover { text-decoration: underline; }
.footer__brand { display: flex; align-items: center; gap: var(--space-4); flex-wrap: wrap; margin-bottom: var(--space-2); }
.footer__tagline { margin: 0; font-size: var(--text-xs); color: var(--c-soft); max-width: 22ch; }
.footer__spec { font-family: var(--font-mono); font-size: var(--label-md); letter-spacing: .08em; color: var(--c-faint); line-height: 1.9; }   /* casing is the copy's own: "kHz" */
@media (max-width: 899px) { .footer__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-6); } }
@media (max-width: 479px) { .footer__grid { grid-template-columns: 1fr; } }

/* ---- 5.6 Form fields --------------------------------------------------- */
.field { display: flex; flex-direction: column; gap: var(--space-2); }
.field__label { /* a .mono-label, on the real <label> */ }
.field__input {
  min-height: var(--tap);
  width: 100%;
  padding: var(--space-2) var(--space-3);
  background: transparent;
  color: var(--c-fg);
  border: var(--hairline) solid var(--c-line);
  border-radius: var(--radius);
  font-size: var(--text-md);   /* ≥16px keeps iOS from zooming on focus */
}
.field__input::placeholder { color: var(--c-faint); opacity: 1; }
.field__input:focus-visible { outline: 2px solid var(--c-fg); outline-offset: 1px; }
textarea.field__input { min-height: 7rem; resize: vertical; line-height: var(--leading-body); }
select.field__input { appearance: none; background-image: linear-gradient(45deg, transparent 50%, currentColor 50%), linear-gradient(135deg, currentColor 50%, transparent 50%); background-position: calc(100% - 18px) 50%, calc(100% - 13px) 50%; background-size: 5px 5px; background-repeat: no-repeat; padding-right: 2.25rem; }
.field__hint { font-size: var(--text-xs); color: var(--c-soft); }
.field__error { font-size: var(--text-xs); color: var(--c-accent); font-weight: 600; }
.field--invalid .field__input { border-color: var(--c-accent); border-width: 2px; }

/* An input and its button on one line (email signup). Stacks at phone width. */
.field-row { display: flex; gap: var(--space-2); align-items: flex-end; }
.field-row .field { flex: 1; }
@media (max-width: 479px) { .field-row { flex-direction: column; align-items: stretch; } }
.field-stack { display: flex; flex-direction: column; gap: var(--space-3); }

/* ---- 5.7 Spec readout block ------------------------------------------- */
.spec {
  display: grid;
  grid-template-columns: max-content 1fr;
  margin: 0;
  border-top: var(--hairline) solid var(--c-line);
}
.spec__row { display: contents; }
.spec dt, .spec dd {
  margin: 0;
  padding: var(--space-2) 0;
  border-bottom: var(--hairline) solid var(--c-line-soft);
}
.spec dt { padding-right: var(--space-5); }
.spec dd {
  font-family: var(--font-mono);
  font-size: var(--readout);
  font-weight: 400;
  text-align: right;
  font-variant-numeric: tabular-nums;
}

/* ---- 5.8 Numbered feature tag ----------------------------------------- */
.feature-tag {
  display: grid;
  grid-template-columns: 28px 1fr;
  column-gap: var(--space-5);
  row-gap: 5px;
  align-items: baseline;
  padding-block: 22px;
  border-bottom: var(--hairline) solid var(--c-line-soft);
}
.feature-tag__num {
  grid-row: span 2;
  font-family: var(--font-mono);
  font-size: var(--label-md);
  font-weight: 500;
  color: var(--c-accent);
}
.feature-tag__title { font-size: var(--text-md); font-weight: 600; line-height: 1.3; }
.feature-tag__body { font-size: var(--text-sm); color: var(--c-soft); }
.feature-list { list-style: none; margin: 0; padding: 0; border-top: var(--hairline) solid var(--c-line-soft); }

/* ---- 5.9 Kit sleeve ----------------------------------------------------
   The colour block is the kit's own — set --sleeve-bg and --sleeve-ink on
   the element (inline style from the kit's data). The ink colour must
   clear 4.5:1 on its bg; the sleeve macro picks dark or light ink by
   luminance when none is given. */
.sleeve {
  --sleeve-bg: var(--c-sunk);
  --sleeve-ink: var(--c-fg);
  display: flex; flex-direction: column; gap: var(--space-3);
  width: 100%;
  padding: 0;
  background: none; border: 0;
  text-align: left;
  color: inherit;
  text-decoration: none;
  cursor: pointer;
}
.sleeve:hover { text-decoration: none; }
.sleeve__block {
  position: relative;
  aspect-ratio: 1 / 1;
  background: var(--sleeve-bg);
  color: var(--sleeve-ink);
  border: var(--hairline) solid var(--c-line);
  border-radius: var(--radius);
  padding: 20px 18px 16px;
  display: flex; flex-direction: column; justify-content: space-between;
  overflow: hidden;
  transition: transform 220ms var(--ease-out);
}
/* Only the kit name and number sit on the colour — both pass 4.5:1 there.
   Creator and mic spec sit below, on the ground: small text on a kit
   colour would fail. */
.sleeve__name { font-size: var(--display-5); font-weight: 700; line-height: 1.22; max-width: 10ch; }
.sleeve__number { font-family: var(--font-mono); font-size: var(--label-sm); font-weight: 500; letter-spacing: var(--label-track); text-transform: uppercase; }
.sleeve__meta { display: flex; flex-direction: column; gap: var(--space-1); margin-top: 2px; }
.sleeve__creator { font-size: var(--text-sm); font-weight: 600; }
.sleeve__spec { font-family: var(--font-mono); font-size: var(--label-md); letter-spacing: .08em; text-transform: uppercase; color: var(--c-faint); }
.sleeve:hover .sleeve__block { transform: translateY(-3px); }
.sleeve[aria-pressed="true"] .sleeve__block { outline: 3px solid var(--c-fg); outline-offset: 4px; }
.sleeve:focus-visible { outline: none; }
.sleeve:focus-visible .sleeve__block { outline: 2px solid var(--c-fg); outline-offset: 4px; }
.sleeve[aria-pressed="true"]:focus-visible .sleeve__block { outline-width: 3px; outline-style: double; }

.sleeve-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 28px;
}
@media (max-width: 899px) { .sleeve-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

/* ---- 5.10 Stat block --------------------------------------------------- */
.stat { display: flex; flex-direction: column; gap: var(--space-2); padding: 22px var(--space-5) 0; }
.stat__value { font-size: var(--display-4); font-weight: 700; line-height: 1.1; font-variant-numeric: tabular-nums; }
.stat__value small { font-size: .5em; font-weight: 600; margin-left: .15em; }
.stat--live .stat__value { color: var(--c-live); }
.stat-row {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  border-top: var(--hairline) solid var(--c-line-soft);
}
.stat-row > * + * { border-left: var(--hairline) solid var(--c-line-soft); }
.stat-row > :first-child, .stat-row > :first-child .stat { padding-left: 0; }
@media (max-width: 719px) {
  .stat-row { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .stat-row > :nth-child(odd) { border-left: 0; }
  .stat-row > :nth-child(odd), .stat-row > :nth-child(odd) .stat { padding-left: 0; }
  .stat-row > :nth-child(n+3) { margin-top: var(--space-5); }
}

/* ---- 5.11 Bordered action panel (hero) -------------------------------- */
.panel {
  display: flex; flex-direction: column; gap: var(--space-3);
  padding: var(--space-5);
  border: var(--hairline) solid var(--c-line);
  border-radius: var(--radius);
}
.panel > .btn { align-self: flex-start; }
.panel > .btn-row { margin-top: auto; }

/* ---- 5.12 Flash messages ---------------------------------------------- */
.flashes { display: flex; flex-direction: column; gap: var(--space-2); padding-block: var(--space-4) 0; }
.flash {
  padding: var(--space-3) var(--space-4);
  border: var(--hairline) solid var(--c-line);
  border-left-width: 4px;
  font-size: var(--text-sm);
}
.flash.error { border-left-color: var(--c-accent); }

/* ---- 5.13 Sticky bottom bar — marketing pages only ---------------------
   Hidden until the page's hero scrolls past (site.js watches the element
   marked data-stickybar-after). A page opts in by filling the stickybar
   block in site_base.html; working pages never do. */
.stickybar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 90;
  border-top: var(--hairline) solid var(--c-line);
  transform: translateY(100%);
  visibility: hidden;
  transition: transform 260ms var(--ease-out), visibility 0s linear 260ms;
}
.stickybar.is-shown {
  transform: none;
  visibility: visible;
  transition: transform 260ms var(--ease-out), visibility 0s;
}
.stickybar__inner {
  display: flex; align-items: center; justify-content: space-between; gap: var(--space-4);
  min-height: 68px;
  padding-block: var(--space-3);
}
.stickybar__price { display: flex; flex-direction: column; gap: 2px; }
.stickybar__price strong { font-size: var(--display-5); font-weight: 700; line-height: 1.1; }
@media (max-width: 559px) {
  .stickybar__inner { flex-direction: column; align-items: stretch; gap: var(--space-2); }
  .stickybar__price { flex-direction: row; align-items: baseline; justify-content: space-between; }
  .stickybar .btn-row { display: grid; grid-template-columns: 1fr 1fr; }
  .stickybar .btn { white-space: normal; text-align: center; padding-inline: var(--space-3); letter-spacing: .1em; }
}
/* Leave room so the bar never covers the footer's last line. */
body.has-stickybar { padding-bottom: 0; }
body.has-stickybar > .footer { padding-bottom: calc(var(--space-6) + 96px); }

/* ---- 5.14 Admin in-place copy editing (edit mode) ----------------------
   Same behaviour as base.html's edit toolbar, restyled for this system. */
.edit-toolbar {
  position: fixed; bottom: var(--space-4); right: var(--space-4); z-index: 300;
  display: flex; align-items: center; gap: var(--space-2);
  padding: var(--space-2) var(--space-2) var(--space-2) var(--space-4);
  background: var(--ground-dark); color: var(--paper);
  border: var(--hairline) solid var(--signal);
  font-size: var(--text-xs);
}
.edit-toolbar form { margin: 0; display: inline; }
.edit-toolbar .et-label { font-family: var(--font-mono); font-size: var(--label-md); letter-spacing: .08em; color: var(--paper-soft); }
.edit-toolbar button { min-height: 36px; padding: 0 var(--space-3); font-weight: 600; font-size: var(--text-xs); cursor: pointer; border-radius: var(--radius); }
.edit-toolbar .et-toggle,
.edit-toolbar .et-publish { background: var(--signal); color: var(--ink); border: var(--hairline) solid var(--signal); }
.edit-toolbar .et-publish[disabled] { opacity: .45; cursor: not-allowed; }
.edit-toolbar .et-ghost { background: transparent; color: var(--paper); border: var(--hairline) solid var(--paper-faint); }
body.has-stickybar .edit-toolbar { bottom: calc(var(--space-4) + 96px); }

.pk-editable { outline: 1.5px dashed currentColor; outline-offset: 3px; cursor: text; }
.pk-editable:hover { outline-style: solid; }
.pk-editable.pk-editing { outline: 2px solid var(--c-fg); background: var(--c-sunk); }
.pk-editable.pk-draft { outline-color: var(--c-accent); }
.pk-editable.pk-saved-flash { outline: 2px solid var(--c-accent); }

/* ---- 5.15 Account and plugin-bridge pages ------------------------------
   Log in and sign up (tan), /connect and /account/computers (ink). Colours
   come only from --c-*, so one rule set serves both grounds: links take
   --c-accent (oxblood on tan, copper on ink) and the one live action takes
   --c-live (ink on tan, amber on ink). */
.auth { padding-block: var(--space-8) var(--space-9); }
.auth__grid {
  display: flex; flex-wrap: wrap; gap: var(--space-8);
  align-items: flex-start;
  max-width: 1040px; margin-inline: auto;
}
.auth__grid--narrow { max-width: 520px; }
.auth__grid--medium { max-width: 640px; }
.auth__main { flex: 999 1 400px; min-width: 0; display: flex; flex-direction: column; }
.auth__aside { flex: 1 1 280px; min-width: 0; }
.auth__aside--ruled { border-left: var(--hairline) solid var(--c-line); padding-left: var(--space-5); }
@media (max-width: 719px) { .auth__aside--ruled { border-left: 0; padding-left: 0; border-top: var(--hairline) solid var(--c-line); padding-top: var(--space-6); } }
.auth__title { font-size: var(--display-2); margin: var(--space-4) 0 var(--space-4); }
.auth__lead { font-size: var(--text-lg); color: var(--c-soft); max-width: 44ch; margin-bottom: var(--space-6); }
.auth__form { display: flex; flex-direction: column; gap: var(--space-5); max-width: 460px; }
.auth__form > .btn { margin-top: var(--space-1); }
.auth__note { font-size: var(--text-sm); color: var(--c-soft); }
.auth__note + .auth__note { margin-top: var(--space-2); }
.auth__section { margin-top: var(--space-7); padding-top: var(--space-5); border-top: var(--hairline) solid var(--c-line); display: flex; flex-direction: column; gap: var(--space-3); }
.auth a:not(.btn) { color: var(--c-accent); }
.auth a:not(.btn):hover { color: var(--c-fg); }
.auth .flash { margin-bottom: var(--space-5); }
.auth .flash form { margin-top: var(--space-3); }

/* A label row with a link on the right ("Password … Forgot it?"). */
.field__label-row { display: flex; justify-content: space-between; align-items: baseline; gap: var(--space-4); }
.field__label-row a { font-size: var(--text-xs); display: inline-flex; align-items: center; min-height: var(--tap); }

/* The code a plugin shows: typed into the big mono box, or read back. */
.code-input {
  min-height: 72px; width: 100%;
  padding: var(--space-3) var(--space-4);
  background: var(--c-sunk); color: var(--c-fg);
  border: var(--hairline) solid var(--c-line); border-radius: var(--radius);
  font-family: var(--font-mono); font-size: clamp(1.5rem, 1.1rem + 1.4vw, 2rem);
  letter-spacing: .18em; text-align: center; text-transform: uppercase;
}
.code-input::placeholder { color: var(--c-faint); opacity: 1; }
.code-input:focus-visible { outline: 2px solid var(--c-live); outline-offset: 1px; }
.code-readout {
  display: flex; flex-direction: column; align-items: center; gap: var(--space-4);
  padding: var(--space-6) var(--space-5);
  background: var(--c-sunk);
  border: var(--hairline) solid var(--c-line); border-radius: var(--radius);
  margin-bottom: var(--space-6);
}
.code-readout__code {
  font-family: var(--font-mono); font-weight: 500;
  font-size: clamp(1.75rem, 1.2rem + 2vw, 2.75rem); letter-spacing: .18em;
  color: var(--c-live);
  overflow-wrap: anywhere; text-align: center;
}
.auth .spec { margin-bottom: var(--space-6); }
.auth .spec dd { overflow-wrap: anywhere; }

/* Computers and devices: one row each, its action on the right. */
.device-list { list-style: none; margin: 0 0 var(--space-4); padding: 0; border-bottom: var(--hairline) solid var(--c-line-soft); }
.device-list li {
  display: flex; flex-wrap: wrap; gap: var(--space-3); justify-content: space-between; align-items: center;
  padding-block: var(--space-4);
  border-top: var(--hairline) solid var(--c-line-soft);
}
.device-list form { margin: 0; }
.device-list__name { font-size: var(--text-md); }
.device-list__meta { font-family: var(--font-mono); font-size: var(--text-xs); color: var(--c-faint); }
.device-list__empty { padding-block: var(--space-4); border-top: var(--hairline) solid var(--c-line-soft); color: var(--c-soft); font-size: var(--text-sm); }

.licence-key {
  display: inline-block;
  padding: var(--space-2) var(--space-3);
  background: var(--c-sunk); border: var(--hairline) solid var(--c-line); border-radius: var(--radius);
  font-family: var(--font-mono); font-size: var(--text-md); letter-spacing: .05em;
  overflow-wrap: anywhere;
}
.auth__gap { margin-top: var(--space-5); }
.auth__sub { margin-block: var(--space-2) var(--space-4); }
.auth__held { margin: calc(-1 * var(--space-4)) 0 var(--space-6); }
.auth__code { font-family: var(--font-mono); font-weight: 500; letter-spacing: .08em; }
.feature-tag--plain { grid-template-columns: 1fr; }
.auth__allow { flex: 999 1 220px; }
.auth__deny { flex: 1 1 140px; }
.auth__done-mark { display: flex; align-items: center; gap: var(--space-4); margin-bottom: var(--space-5); color: var(--c-live); }
.auth__product + .auth__product { margin-top: var(--space-8); }

/* ---- 5.16 Demo page only (/admin/design) ------------------------------ */
.demo-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); }
.demo-grid > section { padding: var(--space-6) var(--gutter); display: flex; flex-direction: column; gap: var(--space-6); min-width: 0; }
.demo-block { display: flex; flex-direction: column; gap: var(--space-3); }
.demo-block > .rule, .demo-block > .rule--labelled { margin: var(--space-2) 0; }
.demo-swatches { display: grid; grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); gap: var(--space-3); }
.demo-swatch { display: flex; flex-direction: column; gap: var(--space-1); }
.demo-swatch span:first-child { height: 56px; border: var(--hairline) solid var(--c-line-soft); }
.demo-frame { border: var(--hairline) solid var(--c-line-soft); position: relative; }
.demo-frame .topbar { position: relative; z-index: auto; }
.demo-frame .topbar__nav { position: static; }
@media (max-width: 899px) { .demo-grid { grid-template-columns: 1fr; } }


/* ===========================================================================
   6. MOTION — reveal on scroll (static/js/reveal.js)
   ---------------------------------------------------------------------------
   Elements are only hidden when <html> carries .reveal-on, which
   site_base.html adds before first paint — and ONLY when the visitor has
   not asked for reduced motion. Without JS, or with reduced motion,
   content is simply present.
   =========================================================================== */

.reveal-on [data-reveal] {
  opacity: 0;
  transform: translateY(10px);
  transition: opacity var(--dur) var(--ease-out), transform var(--dur) var(--ease-out);
  transition-delay: var(--reveal-delay, 0ms);
}
.reveal-on [data-reveal].is-in { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .reveal-on [data-reveal] { opacity: 1; transform: none; transition: none; }
  .sleeve__block, .btn, .stickybar, .stickybar.is-shown { transition: none; }
  .sleeve:hover .sleeve__block, .sleeve:focus-visible .sleeve__block { transform: none; }
}
