/* site.css — schradernator.com
 *
 * The palette is schrad.works' front door, not an adaptation of it: the same
 * navy ink on the same cool paper, the same lime for the one thing you are
 * meant to press, and the badge's rainbow used exactly the way it is used
 * there — as weather behind the hero and nowhere else. The two sites are one
 * company and they should look like it.
 *
 * The page is short on purpose (2026-10-01): hero, services, the platforms,
 * why it holds, the free tools, contact. The radio station gets the one big
 * scene because it has the most to show; the other four products are cards.
 *
 * Every value is a token here. Nothing below :root writes a raw colour, and
 * every ink was measured on the surface it sits on: 4.5:1 for body copy, 3:1
 * for display type and non-text edges.
 */

/* ---------------------------------------------------------------- fonts --
 * Vendored under /vendor/fonts and served from this origin. No CDN anywhere
 * on this page: the estate's nginx refuses CDN traffic, and a page that goes
 * flat when someone else's server is down is not a page you hand to a client.
 * Archivo is one variable file carrying weight AND width, which is what lets
 * the display type be condensed and the body type normal on one download. */
@font-face {
  font-family: 'Archivo';
  src: url('/vendor/fonts/archivo-var.woff2') format('woff2-variations');
  font-weight: 100 900;
  font-stretch: 62% 125%;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'JetBrains Mono';
  src: url('/vendor/fonts/jetbrains-mono-var.woff2') format('woff2-variations');
  font-weight: 100 800;
  font-style: normal;
  font-display: swap;
}

:root {
  /* ---- the badge, as a palette ------------------------------------------
   * Straight out of schrad.works' landing-sw.css, which took them straight
   * out of the mark. The navy is the badge's outline; the lime is its
   * green-yellow; the sky is its blue. */
  --navy:    #1B2140;
  --navy-2:  #2A3260;
  --ink:     #171A2B;   /* 15.9:1 on paper */
  --ink-2:   #4A5070;   /*  8.4:1 on paper — the quietest text allowed */
  --paper:   #FFFFFF;
  --slab:    #F3F4F9;   /* the alternating band */
  --slab-2:  #E8EAF3;   /* a well inside a band */
  --line:    #D6D9E6;
  --lime:    #C8F542;
  --lime-ink:#12160A;   /* text ON the lime — 15.4:1 */
  --sky:     #2F7CF6;   /* the badge's blue: icons, edges, large type */
  --sky-ink: #1A5FD0;   /* the same blue where it has to carry small text */
  --ok-ink:  #157A4B;   /* a green that can be text: the one "done" line in a mock */

  /* ---- the rainbow ------------------------------------------------------
   * The badge's six. They are weather in the hero, they identify a
   * project in the work section, and they are the soft lights behind the
   * QR generator (decoration, never the code itself). They are never a
   * status and never body text:
   * the yellow is 1.6:1 on paper and would be unreadable. */
  --r-yellow:  #F7D53A;
  --r-green:   #2FE39A;
  --r-blue:    #2F7CF6;
  --r-violet:  #8F4CF7;
  --r-pink:    #F45BA9;
  --r-orange:  #F7913A;

  /* The same hues a shade deeper, for the one place the rainbow becomes
   * TYPE — the accent line of the headline. Every stop here clears 4.5:1 on
   * paper, which the badge's own values do not. */
  --grad-a: #2563EB;
  --grad-b: #7C3AED;
  --grad-c: #DB2777;

  /* ---- per-project wavelengths -----------------------------------------
   * One badge colour each, deepened so the name beside the dot is readable.
   * A project is the same colour everywhere it appears. */
  --w-works:  #1A5FD0;
  --w-ksch:   #C2530A;
  --w-wire:   #7C3AED;
  --w-ai:     #BE1D6E;
  --w-books:  #9A5A08;  /* Sunbear's honey, deepened: 5.5:1 on paper */

  /* ---- the product cards ------------------------------------------------
   * Each product wears its own colour, not this page's: the stripe is the
   * brand as it is (bright), the ink is the same hue deepened so it can carry
   * small text on paper (every one clears 4.5:1). Sunbear's stripe is the
   * honey straight off its logo. */
  --p-works:      #8F4CF7;  --p-works-ink: #6D28D9;
  --p-wire:       #E4222A;  --p-wire-ink:  #B91C22;
  --p-ai:         #2F7CF6;  --p-ai-ink:    #1A5FD0;
  --p-books:      #FDB84C;  --p-books-ink: #9A5A08;
  --rail-books:   #FDB84C;

  /* ---- type ------------------------------------------------------------- */
  --display: 'Archivo', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  --mono: 'JetBrains Mono', ui-monospace, 'SF Mono', Menlo, Consolas, monospace;

  --t-hero:  clamp(2.25rem, 5.3vw, 4.75rem);
  --t-mega:  clamp(2.125rem, 5.6vw, 4.5rem);
  --t-h2:    clamp(1.75rem, 3.4vw, 3rem);
  --t-h3:    clamp(1.1875rem, 1.8vw, 1.5rem);
  --t-lead:  clamp(1.0625rem, 1.3vw, 1.3125rem);
  --t-body:  1.0625rem;
  --t-sm:    0.9375rem;
  --t-label: 0.75rem;

  /* ---- metrics ---------------------------------------------------------- */
  --page: 1180px;
  --gutter: clamp(1rem, 4vw, 2.5rem);
  --band: clamp(4rem, 8vw, 8rem);
  --tap: 48px;                  /* schrad.works' figure, not the 44 floor */

  --r-sm: 12px;
  --r-md: 16px;
  --r-lg: 22px;
  --pill: 999px;

  /* Real shadows, because the page is paper now and paper has depth. This is
   * most of what "lifelike" means here: the cards sit ON something. */
  --shadow:    0 1px 2px rgba(23,26,43,.06), 0 8px 24px rgba(23,26,43,.08);
  --shadow-lg: 0 2px 4px rgba(23,26,43,.05), 0 18px 40px rgba(23,26,43,.16);

  --ease: cubic-bezier(.22,.61,.36,1);
}

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

html {
  scroll-behavior: smooth;
  scroll-padding-top: 7.75rem;
  -webkit-text-size-adjust: 100%;
  color-scheme: light;
}

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--display);
  font-size: var(--t-body);
  line-height: 1.6;
  font-variation-settings: 'wdth' 100;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

img, svg, canvas { display: block; max-width: 100%; }
a { color: var(--sky-ink); }

h1, h2, h3, h4 {
  margin: 0;
  font-weight: 800;
  line-height: 1.05;
  letter-spacing: -.022em;
  color: var(--navy);
  text-wrap: balance;
}

p { margin: 0 0 1.1em; max-width: 62ch; }
p:last-child { margin-bottom: 0; }

::selection { background: var(--lime); color: var(--lime-ink); }

:focus-visible {
  outline: 3px solid var(--sky);
  outline-offset: 3px;
  border-radius: 6px;
}

.skip {
  position: absolute; left: -9999px; top: 0; z-index: 200;
  background: var(--navy); color: var(--paper);
  padding: .8rem 1.25rem; font-weight: 700; border-radius: 0 0 var(--r-sm) 0;
}
.skip:focus { left: 0; }

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

/* ---------------------------------------------------------------- pieces -- */
.eyebrow {
  font-family: var(--mono);
  font-size: var(--t-label);
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--navy-2);
  display: flex;
  align-items: center;
  gap: .7rem;
  margin: 0 0 1.1rem;
}
/* The rule is the lime's job here. Lime is 1.2:1 on paper and can never be
 * text, but as a 3px bar beside navy type it is the brand's loudest signal. */
.eyebrow::before {
  content: '';
  width: 28px; height: 3px; border-radius: 2px;
  background: var(--lime);
  flex: none;
}
.eyebrow--plain::before { display: none; }

.lead {
  font-size: var(--t-lead);
  line-height: 1.6;
  color: var(--ink-2);
  max-width: 56ch;
}

.hint {
  font-family: var(--mono);
  font-size: var(--t-label);
  letter-spacing: .04em;
  color: var(--ink-2);
}

/* Buttons are pills with a 2px navy edge, the way schrad.works draws them.
 * The edge is what makes the lime one legible: lime alone on paper has no
 * boundary, and the outline is doing accessibility work, not decoration. */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .55rem;
  min-height: var(--tap);
  padding: .75rem 1.5rem;
  border-radius: var(--pill);
  border: 2px solid var(--navy);
  background: var(--paper);
  color: var(--navy);
  font: inherit;
  font-weight: 800;
  font-size: var(--t-sm);
  text-decoration: none;
  cursor: pointer;
  transition: transform .16s var(--ease), background-color .18s var(--ease),
              box-shadow .18s var(--ease);
}
.btn:active { transform: translateY(1px); }
.btn--go { background: var(--lime); color: var(--lime-ink); box-shadow: var(--shadow); }
.btn--go:hover { filter: brightness(.96); }
.btn--ghost:hover { background: var(--slab); }
.btn--quiet {
  border-color: var(--line); color: var(--navy-2);
  min-height: 44px; padding: .6rem 1.15rem; font-weight: 700;
}
.btn--quiet:hover { background: var(--slab); border-color: var(--navy-2); }

.panel {
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow);
}

.sechead { margin-bottom: clamp(1.75rem, 3.5vw, 3rem); }
.sechead h2 { font-size: var(--t-h2); font-variation-settings: 'wdth' 94; }
.sechead .lead { margin-top: 1rem; }
/* A heading with a button beside it, for the one section whose next step is
 * obvious enough to put on the same line. Wraps under the heading on a
 * phone rather than squeezing it. */
.sechead--row {
  display: flex; flex-wrap: wrap; align-items: end; justify-content: space-between;
  gap: 1rem 2rem;
}
.sechead--row .eyebrow { margin-bottom: .8rem; }

section[id] { scroll-margin-top: 7.25rem; }

/* ---------------------------------------------------------------- header --
 * Two rows, both fixed. The top one is the network rail: the four properties,
 * always reachable, wearing their own marks. The bottom one is this site's
 * own navigation. Keeping them as separate rows rather than one crowded bar
 * is what lets the rail be dense and the nav be roomy.
 */
.nav {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 100;
  display: block;
  background: rgba(255,255,255,.72);
  backdrop-filter: blur(10px) saturate(140%);
  border-bottom: 1px solid transparent;
  transition: background-color .3s var(--ease), border-color .3s var(--ease),
              box-shadow .3s var(--ease);
}
.nav.is-stuck {
  background: rgba(255,255,255,.97);
  backdrop-filter: blur(16px) saturate(150%);
  border-bottom-color: var(--line);
  box-shadow: 0 1px 14px rgba(23,26,43,.07);
}

/* ---- row one: the network rail ---- */
.rail { background: var(--navy); }
.rail .wrap {
  display: flex; align-items: center; gap: .15rem;
  height: 42px;
  overflow-x: auto;
  scrollbar-width: none;
}
.rail .wrap::-webkit-scrollbar { display: none; }
.rail-label {
  font-family: var(--mono); font-size: 10px; font-weight: 700;
  letter-spacing: .16em; text-transform: uppercase;
  color: rgba(255,255,255,.52);
  margin-right: auto; white-space: nowrap;
  padding-right: .75rem;
}
.rail a {
  display: inline-flex; align-items: center; gap: .45rem;
  padding: .3rem .6rem; border-radius: var(--pill);
  color: rgba(255,255,255,.84);
  font-size: 12.5px; font-weight: 700; letter-spacing: -.005em;
  text-decoration: none; white-space: nowrap;
  transition: background-color .18s var(--ease), color .18s var(--ease);
}
.rail a:hover { background: rgba(255,255,255,.12); color: #FFFFFF; }
.rail a img { width: 20px; height: 20px; border-radius: 6px; flex: none; }
/* The dot is the property's own colour, so the rail reads as four brands
 * rather than four words. */
.rail a i { width: 6px; height: 6px; border-radius: 50%; background: currentColor; opacity: .65; }
.rail .r-works { --dot: #8F4CF7; }
.rail .r-ksch  { --dot: #F7913A; }
.rail .r-wire  { --dot: #E4222A; }
.rail .r-ai    { --dot: #B9A6FF; }
.rail .r-books { --dot: var(--rail-books); }
.rail a i { background: var(--dot); opacity: 1; }

/* ---- row two: this site's nav ---- */
.navrow { display: flex; align-items: center; gap: 1.25rem; height: 4.25rem; }

.brand {
  display: flex; align-items: center; gap: .65rem;
  text-decoration: none; color: var(--navy);
  font-weight: 800; letter-spacing: -.01em; font-size: 1rem;
  margin-right: auto; white-space: nowrap;
}
.brand img {
  width: 36px; height: 36px; flex: none;
  border-radius: 10px;
  box-shadow: 0 2px 8px rgba(23,26,43,.18);
}
.brand b { font-variation-settings: 'wdth' 90; }
.brand span { color: var(--ink-2); font-weight: 700; }

/* LLC is a legal designation, not part of the name anybody says out loud: set
 * small, in the mono, raised to the cap height. */
.brand em {
  font-style: normal; font-family: var(--mono);
  font-size: .64em; font-weight: 600; letter-spacing: .1em;
  color: var(--ink-2); vertical-align: .24em; margin-left: .1em;
}

.navlinks { display: flex; align-items: center; gap: .2rem; }
.navlinks a {
  padding: .5rem .75rem;
  border-radius: var(--pill);
  text-decoration: none;
  font-size: var(--t-sm);
  font-weight: 700;
  color: var(--ink-2);
  transition: color .18s var(--ease), background-color .18s var(--ease);
}
.navlinks a:hover { color: var(--navy); background: var(--slab); }
.navlinks a.is-on { color: var(--navy); background: var(--slab-2); }

.navtoggle { display: none; }

/* ------------------------------------------------------------------ hero --
 * Paper, with the badge's rainbow moving slowly behind it. That drifting
 * light is what the brief meant by lifelike: the page is not a flat sheet,
 * it has weather. The canvas is decorative and aria-hidden, and it is the
 * first thing the motion switch removes. */
.hero {
  position: relative;
  min-height: 100svh;
  display: flex;
  align-items: center;
  padding: 9rem 0 3.5rem;
  overflow: hidden;
  isolation: isolate;
}
#fiber {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  z-index: -2;
}
/* A paper scrim so the type never sits on a saturated patch. The aurora is
 * still visible through it; it is held to the strength where navy at 16px
 * still clears 4.5:1 over the brightest stop. */
.hero::after {
  content: '';
  position: absolute; inset: 0; z-index: -1;
  background:
    radial-gradient(110% 80% at 12% 45%, rgba(255,255,255,.93) 0%, rgba(255,255,255,.72) 42%, rgba(255,255,255,0) 78%),
    linear-gradient(to bottom, rgba(255,255,255,.55) 0%, rgba(255,255,255,0) 22%, rgba(255,255,255,.7) 88%, var(--paper) 100%);
  pointer-events: none;
}

.hero-in { position: relative; z-index: 1; }
.hero-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 282px;
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: center;
}

.hero h1 {
  font-size: var(--t-hero);
  font-variation-settings: 'wdth' 88;
  line-height: .96;
  letter-spacing: -.035em;
  margin: 0 0 1.5rem;
}

/* The one place the rainbow becomes type. The deepened stops are used, not
 * the badge's own, and a solid colour is painted first so a browser without
 * background-clip still gets a readable line rather than an invisible one. */
.hero h1 em {
  font-style: normal;
  color: var(--grad-b);
  background: linear-gradient(96deg, var(--grad-a) 6%, var(--grad-b) 48%, var(--grad-c) 94%);
  -webkit-background-clip: text;
  background-clip: text;
}
@supports (-webkit-background-clip: text) or (background-clip: text) {
  .hero h1 em { -webkit-text-fill-color: transparent; }
}

.rise { display: block; overflow: hidden; padding-bottom: .08em; }
.rise > b { display: block; font-weight: inherit; will-change: transform; }

.hero .lead { font-size: clamp(1.0625rem, 1.4vw, 1.3125rem); max-width: 48ch; }
.hero-cta { display: flex; flex-wrap: wrap; gap: .8rem; margin-top: 2rem; }

/* The sign: the badge hung off a navy rail, which is how schrad.works
 * presents it. It sways a few degrees on load and then stops. */
.sign {
  position: relative;
  width: 262px; max-width: 100%;
  margin-inline: auto;
  transform-origin: 50% 6px;
}
.sign-rail {
  width: 100%; height: 52px;
  background: var(--navy);
  border-radius: 10px 10px 4px 4px;
  display: grid; place-items: center;
}
.sign-rail span {
  font-family: var(--mono); font-size: 11px; font-weight: 700;
  letter-spacing: .22em; text-transform: uppercase; color: var(--lime);
}
.sign img {
  width: 232px; height: 232px;
  margin: -6px auto 0;
  border-radius: 26px;
  filter: drop-shadow(0 16px 26px rgba(23,26,43,.28));
}

.scrollcue {
  position: absolute; left: var(--gutter); bottom: 1.5rem; z-index: 1;
  display: flex; align-items: center; gap: .6rem;
  font-family: var(--mono); font-size: var(--t-label); font-weight: 600;
  letter-spacing: .14em; text-transform: uppercase; color: var(--ink-2);
}
.scrollcue i {
  display: block; width: 2px; height: 32px; border-radius: 2px;
  background: linear-gradient(to bottom, var(--navy), rgba(27,33,64,0));
}

/* ------------------------------------------------------------------- map --
 * The estate, drawn as roles rather than addresses. Nothing here names a
 * host, a port or a number: what runs on Nick's network and whether it is up
 * is private, and a diagram that says so tells a stranger when the house is
 * empty. */
.map { padding: var(--band) 0; background: var(--slab); }
.mapgrid {
  display: grid; grid-template-columns: minmax(0, 19rem) minmax(0, 1fr);
  gap: clamp(2rem, 5vw, 3.5rem); align-items: start;
}
.mapnote { display: grid; gap: 1.4rem; }
.mapfact { border-left: 3px solid var(--lime); padding-left: 1rem; }
.mapfact h3 { font-size: 1.0625rem; margin-bottom: .35rem; }
.mapfact p { font-size: var(--t-sm); color: var(--ink-2); margin: 0; }

.mapframe {
  position: relative;
  background: var(--paper);
  border: 2px solid var(--navy);
  border-radius: var(--r-lg);
  padding: clamp(1rem, 2.5vw, 1.75rem);
  box-shadow: var(--shadow-lg);
  overflow: hidden;
}
.mapframe svg { width: 100%; height: auto; }

/* --------------------------------------------------------------- services -- */
.services { padding: var(--band) 0; }
.svcgrid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(17rem, 100%), 1fr));
  gap: clamp(.9rem, 1.8vw, 1.25rem);
}
.svc {
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow);
  padding: clamp(1.4rem, 2.4vw, 1.9rem);
  display: grid; gap: .75rem; align-content: start;
  transition: transform .22s var(--ease), box-shadow .22s var(--ease);
}
.svc:hover { transform: translateY(-3px); box-shadow: var(--shadow-lg); }
/* The icon tile is schrad.works' own: a lime square with a navy edge and a
 * navy stroke inside. It is the single most recognisable piece of furniture
 * on that site, so it is the piece that carries the family resemblance. */
/* The icon tile is schrad.works' own furniture — a saturated square with a
 * navy edge and a navy stroke inside. Here each one takes a different colour
 * from the badge, so the row reads as the mark's palette laid out rather than
 * six of the same chip. Every fill carries navy at 3:1 or better. */
.svc i {
  width: 50px; height: 50px; border-radius: 14px;
  background: var(--tile, var(--lime)); border: 2px solid var(--navy);
  display: grid; place-items: center; flex: none;
  transition: transform .22s var(--ease);
}
.svc:hover i { transform: rotate(-4deg) scale(1.04); }
.svc:nth-child(1) { --tile: #C8F542; }
.svc:nth-child(2) { --tile: #7FC4FF; }
.svc:nth-child(3) { --tile: #FFD35C; }
.svc:nth-child(4) { --tile: #9DE8C4; }
.svc:nth-child(5) { --tile: #FFB08A; }
.svc:nth-child(6) { --tile: #D6BCFF; }
.svc i svg { width: 26px; height: 26px; fill: none; stroke: var(--navy); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.svc h3 { font-size: 1.0625rem; }
.svc p { font-size: var(--t-sm); color: var(--ink-2); margin: 0; }

/* ------------------------------------------------------------------ work --
 * The platforms. One flagship scene — the radio station, which has the most
 * to show — then four product cards. A scene sets --wl to its own colour and
 * everything inside reads that variable, so a project is the same colour
 * everywhere and the page needs no inline styles — which is what lets the
 * CSP carry no 'unsafe-inline'. */
.work { padding: var(--band) 0; }

/* Copy on the left, the on-air screen on the right and a little wider: the
 * screen is the evidence, and it has a program log to fit. */
.scene {
  display: grid;
  grid-template-columns: minmax(0, .9fr) minmax(0, 1.1fr);
  gap: clamp(2rem, 5vw, 4rem);
  align-items: center;
  padding: clamp(2.25rem, 5vw, 4rem) 0;
  border-top: 1px solid var(--line);
}

.scene-copy h3 {
  font-size: clamp(1.625rem, 2.8vw, 2.25rem);
  font-variation-settings: 'wdth' 92;
  margin-bottom: .85rem;
}
.scene-host {
  display: inline-flex; align-items: center; gap: .55rem;
  font-family: var(--mono); font-size: var(--t-label); font-weight: 700;
  letter-spacing: .1em; text-transform: uppercase;
  color: var(--wl, var(--sky-ink)); margin-bottom: .9rem;
}
.scene-host img {
  width: 28px; height: 28px; border-radius: 8px; flex: none;
  box-shadow: 0 2px 8px rgba(23,26,43,.18);
}
.scene-copy p { color: var(--ink-2); }

/* The feature list: four things the product does, name over a one-line
 * what-it-means. Hairline grid like the services, so it reads as one block
 * and not a bulleted list. */
.feats {
  list-style: none; margin: 1.4rem 0 1.5rem; padding: 0;
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1px; background: var(--line);
  border: 1px solid var(--line); border-radius: var(--r-md); overflow: hidden;
}
.feats li {
  background: var(--paper); padding: .85rem 1rem;
  display: grid; gap: .2rem; align-content: start;
}
.feats b { font-size: var(--t-sm); font-weight: 800; color: var(--navy); }
.feats span {
  font-family: var(--mono); font-size: 11px; letter-spacing: .03em;
  color: var(--ink-2);
}

.scene-link {
  display: inline-flex; align-items: center; gap: .5rem;
  font-weight: 800; font-size: var(--t-sm); text-decoration: none;
  color: var(--wl, var(--sky-ink));
  border-bottom: 2px solid color-mix(in srgb, currentColor 30%, transparent);
  padding-bottom: 2px;
  transition: border-color .2s var(--ease), gap .2s var(--ease);
}
.scene-link:hover { border-bottom-color: currentColor; gap: .75rem; }

/* ---- the mock interfaces ----------------------------------------------
 * Paper, with a navy edge and a real shadow — the way schrad.works frames a
 * screenshot. Every one is drawn from markup and holds invented content:
 * nothing here reaches a real system, because a live feed on a public page
 * would publish somebody's job, somebody's address, or Nick's own network. */
.mk {
  background: var(--paper);
  border: 2px solid var(--navy);
  border-radius: var(--r-lg);
  overflow: hidden;
  box-shadow: var(--shadow-lg);
  font-size: var(--t-sm);
}
.mk-bar {
  display: flex; align-items: center; gap: .55rem;
  padding: .7rem .9rem;
  background: var(--navy);
  font-family: var(--mono); font-size: 11px; font-weight: 600;
  letter-spacing: .05em; color: rgba(255,255,255,.72);
}
.mk-bar i { width: 8px; height: 8px; border-radius: 50%; flex: none; background: var(--wl, var(--lime)); }
.mk-bar .mk-live { margin-left: auto; color: var(--lime); }
.mk-body { padding: .85rem; display: grid; gap: .5rem; background: var(--slab); }

.mk-row {
  display: grid; grid-template-columns: auto 1fr auto; align-items: center;
  gap: .7rem;
  padding: .6rem .7rem;
  background: var(--paper);
  border: 1px solid var(--line);
  border-radius: var(--r-sm);
}
.mk-row--solo { grid-template-columns: minmax(0, 1fr); }
.mk-row b { font-weight: 800; font-size: var(--t-sm); color: var(--navy); }
.mk-row small { display: block; color: var(--ink-2); font-size: 11px; font-family: var(--mono); }
.mk-tick {
  width: 24px; height: 24px; border-radius: 7px; flex: none;
  display: grid; place-items: center;
  background: var(--slab-2); color: var(--navy-2);
  font-family: var(--mono); font-size: 10px; font-weight: 700;
}
.mk-chip {
  font-family: var(--mono); font-size: 10px; font-weight: 700;
  letter-spacing: .06em; text-transform: uppercase;
  padding: .28rem .55rem; border-radius: var(--pill);
  background: var(--slab-2); color: var(--navy-2); white-space: nowrap;
  border: 1.5px solid transparent;
}
.mk-chip--go { background: var(--lime); color: var(--lime-ink); border-color: var(--navy); }
.mk-chip--wl { background: color-mix(in srgb, var(--wl) 14%, white); color: var(--wl); border-color: color-mix(in srgb, var(--wl) 40%, white); }

.mk-head {
  font-family: var(--mono); font-size: 10px; font-weight: 700; letter-spacing: .11em;
  text-transform: uppercase; color: var(--ink-2); padding: .15rem .1rem;
}

.mk-cols { display: grid; gap: .5rem; grid-template-columns: repeat(2, minmax(0,1fr)); }
.mk-cols--4 { grid-template-columns: repeat(4, minmax(0,1fr)); }
.mk-col { display: grid; gap: .4rem; align-content: start; }

.mk-wave { display: flex; align-items: flex-end; gap: 3px; height: 40px; padding: 0 .1rem; }
.mk-wave i {
  flex: 1; border-radius: 2px 2px 0 0; height: 22%;
  background: linear-gradient(to top, color-mix(in srgb, var(--wl) 45%, white), var(--wl));
  transform-origin: bottom;
}

.mk-chat { display: grid; gap: .35rem; font-family: var(--mono); font-size: 11.5px; padding: .1rem; }
.mk-chat p { margin: 0; max-width: none; color: var(--ink-2); }
.mk-chat p b { color: var(--wl); font-weight: 700; }
.mk-chat p.self { color: var(--navy); }
.mk-caret { color: var(--wl); }

.mk-pipe {
  display: grid; grid-template-columns: repeat(4, 1fr);
  gap: .4rem; align-items: center;
  padding: .7rem;
  background: var(--paper); border: 1px solid var(--line); border-radius: var(--r-sm);
  position: relative;
}
.mk-stage { text-align: center; font-family: var(--mono); font-size: 10px; color: var(--ink-2); }
.mk-stage b { display: block; color: var(--navy); font-size: 10px; font-weight: 700; letter-spacing: .07em; text-transform: uppercase; }
.mk-token {
  position: absolute; top: 50%; left: 12.5%;
  width: 10px; height: 10px; margin-top: -22px; margin-left: -5px;
  border-radius: 50%; background: var(--wl); border: 1.5px solid var(--navy);
}

.mk-tiles { display: grid; grid-template-columns: repeat(3, 1fr); gap: .4rem; }
.mk-tile {
  aspect-ratio: 1; border-radius: 10px; border: 1px solid var(--line);
  background:
    radial-gradient(80% 80% at 30% 20%, color-mix(in srgb, var(--wl) 18%, white), var(--paper) 72%);
  display: grid; place-items: center;
  font-family: var(--mono); font-size: 9px; font-weight: 700; letter-spacing: .08em;
  color: var(--navy-2); text-transform: uppercase;
}
.mk-log {
  font-family: var(--mono); font-size: 11px; line-height: 1.75; color: var(--ink-2);
  background: var(--paper); border: 1px solid var(--line); border-radius: var(--r-sm);
  padding: .6rem .7rem; margin: 0; max-width: none;
}
.mk-log b { color: var(--wl); font-weight: 700; }
.mk-log .ok { color: var(--ok-ink); font-weight: 700; }

/* ---- the on-air screen ------------------------------------------------
 * Modelled on ksch.stream's own on-air card: a dark now-playing block with
 * the art, the title, a progress bar and who is presenting, then the program
 * log underneath in the studio's columns. Only the now-playing block is dark;
 * the log is a document and reads better on paper. */
.mk--radio .mk-body { gap: .6rem; }
.np {
  display: grid; grid-template-columns: 96px minmax(0, 1fr); gap: .9rem;
  align-items: center;
  padding: .9rem;
  background: var(--navy); color: var(--paper);
  border-radius: var(--r-md);
}
/* Album art stands in for itself: a tile in the station's colour with the
 * call letters on it. No real cover, because no real song. */
.np-art {
  width: 96px; height: 96px; border-radius: 10px;
  background:
    radial-gradient(90% 90% at 25% 20%, color-mix(in srgb, var(--wl) 70%, white), var(--wl) 55%, var(--navy-2) 100%);
  display: grid; place-items: center;
  font-family: var(--mono); font-size: 13px; font-weight: 800; letter-spacing: .2em;
  color: var(--paper);
  box-shadow: 0 8px 18px rgba(8,10,24,.4);
}
.np-meta { display: grid; gap: .25rem; min-width: 0; }
.np-meta p { margin: 0; max-width: none; }
.np-flag {
  display: flex; align-items: center; gap: .5rem;
  font-family: var(--mono); font-size: 10px; font-weight: 700;
  letter-spacing: .16em; text-transform: uppercase; color: var(--paper);
}
.np-flag i { width: 8px; height: 8px; border-radius: 50%; background: var(--lime); box-shadow: 0 0 0 3px rgba(200,245,66,.22); }
.np-flag small { font-size: 9px; letter-spacing: .16em; color: rgba(255,255,255,.5); }
.np-title {
  font-size: clamp(1.25rem, 1.6vw, 1.5rem); font-weight: 800; line-height: 1.05;
  font-variation-settings: 'wdth' 92; letter-spacing: -.02em;
  color: var(--paper); overflow-wrap: anywhere;
}
.np-sub { font-size: var(--t-sm); color: rgba(255,255,255,.72); }
.np-bar { height: 4px; border-radius: 2px; background: rgba(255,255,255,.18); overflow: hidden; margin-top: .35rem; }
.np-bar i { display: block; height: 100%; width: 45%; border-radius: 2px; background: var(--lime); }
.np-times {
  display: flex; justify-content: space-between;
  font-family: var(--mono); font-size: 11px; color: rgba(255,255,255,.6);
}
.np-host {
  display: grid; gap: .1rem;
  padding: .55rem .85rem;
  background: var(--paper); border: 1px solid var(--line); border-left: 3px solid var(--wl);
  border-radius: var(--r-sm);
}
.np-host small { font-family: var(--mono); font-size: 9px; font-weight: 700; letter-spacing: .14em; text-transform: uppercase; color: var(--ink-2); }
.np-host b { font-size: var(--t-sm); font-weight: 800; color: var(--navy); }
.np-host span { font-size: 12px; color: var(--ink-2); }

/* The program log, in the studio's own columns: time, item, length, status.
 * Three states are drawn — aired (dimmed), on the air (lime), cued (the
 * station's colour) — and site.js walks the on-air row down the log. */
.log {
  background: var(--paper); border: 1px solid var(--line); border-radius: var(--r-sm);
  overflow: hidden;
  font-family: var(--mono); font-size: 11px;
}
.log-h, .log-row {
  display: grid; grid-template-columns: 64px minmax(0, 1fr) 44px 64px;
  gap: .6rem; align-items: center;
  padding: .45rem .7rem;
}
.log-h {
  font-size: 9px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase;
  color: var(--ink-2); background: var(--slab);
}
.log-row { border-top: 1px solid var(--line); transition: background-color .3s var(--ease); }
.log-t { color: var(--ink-2); }
.log-i { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: .15rem .5rem; align-items: center; min-width: 0; }
.log-i b { font-family: var(--display); font-size: 13px; font-weight: 800; color: var(--navy); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.log-i small { grid-column: 2; font-size: 10px; color: var(--ink-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.log-k {
  font-style: normal; font-size: 9px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
  padding: .15rem .4rem; border-radius: 4px;
  background: var(--slab-2); color: var(--navy-2); white-space: nowrap;
}
.log-l { color: var(--ink-2); text-align: right; }
.log-s {
  justify-self: end;
  font-size: 9px; font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  padding: .22rem .5rem; border-radius: var(--pill);
  color: var(--ink-2); border: 1.5px solid transparent; white-space: nowrap;
}
.log-row.is-done { opacity: .55; }
.log-row.is-on { background: color-mix(in srgb, var(--lime) 22%, white); }
.log-row.is-on .log-s { background: var(--lime); color: var(--lime-ink); border-color: var(--navy); }
.log-row.is-cued .log-s { background: color-mix(in srgb, var(--wl) 14%, white); color: var(--wl); border-color: color-mix(in srgb, var(--wl) 40%, white); }

/* ---- the product cards --------------------------------------------------
 * Four cards, one per product, each with a small mock of its own screen. They
 * sit on this page's paper and carry only a stripe of their own colour: one
 * line of brand per card is enough to tell them apart, and four full themes
 * was noise. */
.prodgrid {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(1rem, 2vw, 1.5rem);
  padding-top: clamp(2rem, 4vw, 3rem);
  border-top: 1px solid var(--line);
}
.prod {
  position: relative;
  display: grid; grid-template-rows: auto auto 1fr auto; gap: .9rem;
  padding: clamp(1.35rem, 2.2vw, 1.75rem);
  background: var(--paper); border: 1px solid var(--line); border-radius: var(--r-lg);
  box-shadow: var(--shadow);
  overflow: hidden;
  transition: transform .22s var(--ease), box-shadow .22s var(--ease), border-color .22s var(--ease);
}
.prod::before {
  content: ''; position: absolute; inset: 0 0 auto 0; height: 4px;
  background: var(--pc, var(--lime));
}
.prod:hover { transform: translateY(-3px); box-shadow: var(--shadow-lg); border-color: color-mix(in srgb, var(--pc) 45%, var(--line)); }
.prod-head { display: flex; align-items: center; gap: .85rem; }
.prod-head > div { min-width: 0; }
.prod-mark {
  width: 44px; height: 44px; border-radius: 12px; flex: none;
  box-shadow: 0 2px 10px rgba(23,26,43,.16);
}
/* wire.schradernator.com is 22 characters: small, tight, and allowed to
 * break rather than clipped. */
.prod-host {
  font-family: var(--mono); font-size: 10px; font-weight: 700;
  letter-spacing: .07em; text-transform: uppercase;
  color: var(--pc-ink, var(--ink-2));
  margin: 0 0 .15rem; overflow-wrap: anywhere;
}
.prod h3 { font-size: 1.125rem; line-height: 1.2; margin: 0; }
.prod > p { font-size: var(--t-sm); color: var(--ink-2); margin: 0; max-width: none; }

/* The chevron is 11px and inside the text baseline: a 24px arrow reads as
 * clip-art. */
.prod-go {
  display: inline-flex; align-items: center; gap: .4rem;
  font-family: var(--mono); font-size: 11px; font-weight: 700;
  letter-spacing: .08em; text-transform: uppercase;
  color: var(--pc-ink, var(--navy)); text-decoration: none;
  padding-top: .85rem; border-top: 1px solid var(--line);
  margin: 0; max-width: none; align-self: end;
}
.prod-go svg { width: 11px; height: 11px; transition: transform .2s var(--ease); }
.prod-go:hover svg { transform: translateX(3px); }
.prod-go--quiet { color: var(--ink-2); letter-spacing: .04em; text-transform: none; font-weight: 600; }

.prod--works { --pc: var(--p-works); --pc-ink: var(--p-works-ink); --wl: var(--p-works-ink); }
.prod--wire  { --pc: var(--p-wire);  --pc-ink: var(--p-wire-ink);  --wl: var(--p-wire-ink); }
.prod--ai    { --pc: var(--p-ai);    --pc-ink: var(--p-ai-ink);    --wl: var(--p-ai-ink); }
.prod--books { --pc: var(--p-books); --pc-ink: var(--p-books-ink); --wl: var(--p-books-ink); }

/* The compact mock inside a card: same frame, less padding, smaller type. */
.mk--mini { font-size: 13px; box-shadow: var(--shadow); }
.mk--mini .mk-bar { padding: .5rem .75rem; font-size: 10px; }
.mk--mini .mk-body { padding: .6rem; gap: .4rem; }
.mk--mini .mk-row { padding: .45rem .6rem; gap: .55rem; }
.mk--mini .mk-row b { font-size: 13px; }
.mk--mini .mk-pipe { padding: .55rem; }
.mk--mini .mk-log { font-size: 10.5px; line-height: 1.7; }
/* The narrator's progress: a track the fill grows along while the card is on
 * screen. 0% to begin with, so the first frame says "about to". */
.mk-bar2 { height: 4px; border-radius: 2px; background: var(--line); overflow: hidden; margin: 0 .2rem; }
.mk-bar2 i { display: block; height: 100%; width: 0%; border-radius: 2px; background: var(--wl); }

/* ----------------------------------------------------------------- tools -- */
.tools { padding: var(--band) 0; }
.toolgrid {
  display: grid;
  /* min() on the floor, not a bare 20rem: on a 320px phone a 20rem minimum
   * plus the gutters is wider than the screen, and a grid honours its minimum
   * by overflowing rather than by shrinking. */
  grid-template-columns: repeat(auto-fit, minmax(min(20rem, 100%), 1fr));
  gap: clamp(1rem, 2vw, 1.5rem);
}
.tool { padding: clamp(1.4rem, 2.5vw, 2rem); display: grid; gap: 1rem; align-content: start; }
.tool h3 { font-size: 1.25rem; }
.tool > p { font-size: var(--t-sm); color: var(--ink-2); margin: 0; }

.field { display: grid; gap: .35rem; }
.field > span {
  font-family: var(--mono); font-size: var(--t-label); font-weight: 700;
  letter-spacing: .09em; text-transform: uppercase; color: var(--ink-2);
}
.field input, .field select, .field textarea {
  width: 100%; min-height: var(--tap);
  padding: .7rem .85rem;
  background: var(--paper); color: var(--ink);
  border: 2px solid var(--line); border-radius: var(--r-sm);
  font: inherit; font-size: 1rem;
}
.field input:focus, .field select:focus, .field textarea:focus {
  border-color: var(--sky); outline: none;
  box-shadow: 0 0 0 3px rgba(47,124,246,.18);
}
.field--mono input { font-family: var(--mono); font-weight: 600; }

.swap { display: grid; grid-template-columns: 1fr auto 1fr; gap: .7rem; align-items: end; }
.swapbtn {
  width: var(--tap); height: var(--tap); flex: none;
  border-radius: var(--r-sm); border: 2px solid var(--navy);
  background: var(--lime); color: var(--navy); cursor: pointer;
  display: grid; place-items: center;
}
.swapbtn:hover { filter: brightness(.96); }
.swapbtn svg { width: 18px; height: 18px; }

.readout {
  font-family: var(--mono); font-weight: 600;
  font-size: clamp(1rem, 1.9vw, 1.25rem);
  color: var(--navy);
  padding: .8rem 1rem; border-radius: var(--r-sm);
  background: var(--slab); border: 2px dashed var(--line);
  overflow-wrap: anywhere;
}
.qrout {
  position: relative; overflow: hidden; isolation: isolate;
  display: grid; place-items: center; gap: .7rem;
  padding: 1.25rem; border-radius: var(--r-sm);
  background: var(--slab); border: 2px solid var(--line);
  min-height: 15rem;
}
/* The code stays black on white with its quiet zone: a scanner expects that
 * polarity, and restyling it to match the page is the classic way to make one
 * that will not scan on a cheap phone camera. The colour lives in the field
 * BEHIND the code (toolviz.js), never in it. */
.qrout canvas {
  position: relative; z-index: 2;
  background: #fff; border-radius: 8px; padding: 10px;
  image-rendering: pixelated; width: 190px; height: 190px;
  box-shadow: var(--shadow-lg);
}
/* The weather behind the code: six soft lights in the badge's colours on a
 * ring around it, placed by toolviz.js. Blurred by filter rather than by
 * gradient so one small element per light is enough. */
.qrsky {
  position: absolute; inset: 0; z-index: 0;
  overflow: hidden; pointer-events: none;
}
.qrsky i {
  position: absolute; display: block;
  width: 52%; aspect-ratio: 1; border-radius: 50%;
  transform: translate(-50%, -50%);
  filter: blur(26px); opacity: .5;
}
.qrsky .r-yellow, .qrring.r-yellow { --rc: var(--r-yellow); }
.qrsky .r-green,  .qrring.r-green  { --rc: var(--r-green); }
.qrsky .r-blue,   .qrring.r-blue   { --rc: var(--r-blue); }
.qrsky .r-violet, .qrring.r-violet { --rc: var(--r-violet); }
.qrsky .r-pink,   .qrring.r-pink   { --rc: var(--r-pink); }
.qrsky .r-orange, .qrring.r-orange { --rc: var(--r-orange); }
.qrsky i { background: var(--rc); }
/* The rings a redraw sends out from the code. They start on the canvas box
 * (toolviz.js measures it) and grow past the edge of the well. */
.qrring {
  position: absolute; z-index: 1; opacity: 0; pointer-events: none;
  border: 3px solid var(--rc); border-radius: 14px;
  box-sizing: border-box;
}
.qrscan {
  position: absolute; z-index: 3; height: 3px; opacity: 0; pointer-events: none;
  background: var(--lime); border-radius: 2px;
  box-shadow: 0 0 12px 2px var(--lime);
}

/* The tape: a meter scale over a feet scale on one axis. Lime body with the
 * navy edge every lime surface carries; the scales are navy ink on it. */
.tape { display: block; width: 100%; height: auto; overflow: visible; }
.tape-body { fill: var(--lime); stroke: var(--navy); stroke-width: 2; }
.tape-lead { stroke: var(--navy); stroke-width: 3; }
.tape-reel-case { fill: var(--navy); }
.tape-reel-hub { fill: var(--lime); }
.tape-reel-spoke { stroke: var(--lime); stroke-width: 3; stroke-linecap: round; fill: none; }
.tape .tick { stroke: var(--navy); stroke-width: 1; }
.tape .tick--major { stroke-width: 2; }
.tape .tick-label, .tape-unit {
  font-family: var(--mono); font-size: 13px; font-weight: 700;
  fill: var(--ink-2); text-anchor: middle;
}
.tape-unit { fill: var(--sky-ink); font-size: 10px; text-transform: uppercase; letter-spacing: .06em; }
.tape-cursor line { stroke: var(--sky); stroke-width: 3; }
.tape-cursor path { fill: var(--sky); }
.toolrow { display: flex; flex-wrap: wrap; gap: .6rem; align-items: center; }

/* ---------------------------------------------------------------- contact --
 * A conversation, not a form. The navy band is schrad.works' "Ask" section:
 * the page has been paper all the way down, so the one dark block is where
 * the eye stops, which is exactly where the thing you are meant to do is. */
.contact { padding: var(--band) 0; background: var(--navy); color: #FFFFFF; }
.contact h2 { color: #FFFFFF; }
.contact .eyebrow { color: var(--lime); }
.contact .lead { color: rgba(255,255,255,.80); }
.contact .hint { color: rgba(255,255,255,.62); }
.contactgrid {
  display: grid; grid-template-columns: minmax(0, 23rem) minmax(0, 1fr);
  gap: clamp(2rem, 5vw, 4rem); align-items: start;
}

/* The contact headline is the one h2 outside a .sechead, so it carries its
 * own size and the space under it. Without this it sits straight on its own
 * paragraph. */
.h2 { font-size: var(--t-h2); margin-bottom: 1.1rem; }

.presence {
  display: inline-flex; align-items: center; gap: .5rem;
  font-family: var(--mono); font-size: var(--t-label); font-weight: 700;
  letter-spacing: .09em; text-transform: uppercase; color: rgba(255,255,255,.66);
  margin-top: 1.6rem; margin-bottom: 1rem;
}
.presence i { width: 9px; height: 9px; border-radius: 50%; background: rgba(255,255,255,.4); }
.presence.is-here { color: var(--lime); }
.presence.is-here i { background: var(--lime); box-shadow: 0 0 0 4px rgba(200,245,66,.2); }

.chat {
  padding: clamp(1.1rem, 2.4vw, 1.75rem);
  display: grid; gap: 1rem;
  background: var(--paper); border: 0; border-radius: var(--r-lg);
  box-shadow: 0 24px 60px rgba(8,10,24,.35);
}
.chat .field > span { color: var(--ink-2); }
.thread {
  display: grid; gap: .6rem; align-content: start;
  max-height: 20rem; overflow-y: auto; padding-right: .3rem;
  scrollbar-width: thin; scrollbar-color: var(--line) transparent;
}
.msg {
  padding: .7rem .9rem; border-radius: var(--r-md);
  font-size: var(--t-sm); line-height: 1.55;
  max-width: 44ch; overflow-wrap: anywhere;
}
.msg small {
  display: block; margin-top: .3rem;
  font-family: var(--mono); font-size: 10px; letter-spacing: .07em;
  text-transform: uppercase; opacity: .64;
}
.msg--them { background: var(--slab-2); color: var(--ink); justify-self: start; border-bottom-left-radius: 5px; }
.msg--me { background: var(--lime); color: var(--lime-ink); justify-self: end; border-bottom-right-radius: 5px; }
.msg--sys {
  justify-self: center; text-align: center; background: transparent;
  color: var(--ink-2); font-family: var(--mono); font-size: 11px;
  max-width: 40ch; padding: 1.25rem .2rem;
}
.chatrow { display: grid; grid-template-columns: repeat(2, minmax(0,1fr)); gap: .7rem; margin-top: .7rem; }
.chatbar { display: flex; flex-wrap: wrap; gap: .75rem; align-items: center; margin-top: 1rem; }
.chat .hint { color: var(--ink-2); }

/* Off-screen rather than display:none, because a bot that reads computed
 * style skips the hidden one and fills this. */
.trap { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

/* ---------------------------------------------------------------- footer -- */
.foot { border-top: 1px solid var(--line); padding: 2.75rem 0 2.25rem; background: var(--paper); }
.footgrid { display: flex; flex-wrap: wrap; gap: 1.25rem 3rem; align-items: flex-start; justify-content: space-between; }
.foot .brand { margin-right: 0; }
.footlinks { display: flex; flex-wrap: wrap; gap: 1.1rem; font-size: var(--t-sm); }
.footlinks a { color: var(--ink-2); text-decoration: none; font-weight: 700; }
.footlinks a:hover { color: var(--navy); }
.footnote { width: 100%; margin-top: 1.75rem; padding-top: 1.25rem; border-top: 1px solid var(--line); }
.footnote p { font-family: var(--mono); font-size: 11px; color: var(--ink-2); max-width: none; }

/* ------------------------------------------------------------------ 404 -- */
.gone { min-height: 100svh; display: grid; place-items: center; text-align: center; padding: 5rem var(--gutter); }
.gone h1 { font-size: var(--t-mega); font-variation-settings: 'wdth' 90; margin-bottom: 1rem; }
.gone p { margin-inline: auto; color: var(--ink-2); }
.gone .code { font-family: var(--mono); font-weight: 700; color: var(--sky-ink); letter-spacing: .18em; font-size: var(--t-label); text-transform: uppercase; margin-bottom: 1.25rem; }
.gone .hero-cta { justify-content: center; }

/* ------------------------------------------------------------ responsive -- */
@media (max-width: 980px) {
  .mapgrid, .contactgrid { grid-template-columns: minmax(0, 1fr); }
  .hero-grid { grid-template-columns: minmax(0, 1fr); }
  .sign { order: -1; width: 220px; }
  .sign img { width: 176px; height: 176px; }
  .scene { grid-template-columns: minmax(0, 1fr); gap: 1.75rem; }
  .mk-cols--4 { grid-template-columns: repeat(2, minmax(0,1fr)); }
}
@media (max-width: 860px) {
  /* The rail keeps the marks and the label goes: a row of logos still says
   * "here they are". */
  .rail a span { display: none; }
  .rail a { padding: .3rem .45rem; }
  .rail-label { font-size: 9px; }
  .prodgrid { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 720px) {
  .feats { grid-template-columns: minmax(0, 1fr); }
  /* The log loses its length column: on a phone the title needs the room,
   * and the status is the thing a glance is after. */
  .log-h, .log-row { grid-template-columns: 56px minmax(0, 1fr) 58px; gap: .45rem; padding-inline: .55rem; }
  .log-l, .log-h span:nth-child(3) { display: none; }
  /* The hero is shorter now and the cue was sitting on the second button. */
  .scrollcue { display: none; }
  .np { grid-template-columns: 72px minmax(0, 1fr); }
  .np-art { width: 72px; height: 72px; font-size: 11px; }
  .navlinks { display: none; }
  .navlinks.is-open {
    display: grid; position: absolute; top: 100%; left: 0; right: 0;
    background: rgba(255,255,255,.98); backdrop-filter: blur(12px);
    border-bottom: 1px solid var(--line);
    box-shadow: 0 12px 24px rgba(23,26,43,.08);
    padding: .75rem var(--gutter) 1.25rem; gap: .1rem;
  }
  .navlinks a { padding: .8rem .7rem; font-size: 1rem; }
  .navtoggle {
    display: grid; place-items: center;
    width: var(--tap); height: var(--tap);
    background: var(--paper); border: 2px solid var(--navy);
    border-radius: var(--r-sm); color: var(--navy); cursor: pointer;
  }
  .navtoggle svg { width: 20px; height: 20px; }
  .chatrow, .swap { grid-template-columns: minmax(0,1fr); }
  .swapbtn { justify-self: center; transform: rotate(90deg); }
}

/* --------------------------------------------------------- reduced motion --
 * One way in: the OS setting, which head.js writes onto <html> as
 * data-motion="off". Everything that moves is switched off rather than
 * shortened, and the aurora canvas is removed so no frame is ever drawn. */
@media (prefers-reduced-motion: reduce) {
  html:not([data-motion="full"]) { scroll-behavior: auto; }
  html:not([data-motion="full"]) *,
  html:not([data-motion="full"]) *::before,
  html:not([data-motion="full"]) *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
}
html[data-motion="off"] { scroll-behavior: auto; }
html[data-motion="off"] *,
html[data-motion="off"] *::before,
html[data-motion="off"] *::after {
  animation-duration: .001ms !important;
  animation-iteration-count: 1 !important;
  transition-duration: .001ms !important;
}
html[data-motion="off"] #fiber { display: none; }
/* With motion off the mocks hold their first frame, which is written out in
 * the markup as a complete state: one song on the air, one break cued, the
 * narrator about to start. Nothing on the page depends on a tween to appear. */

/* The reveal pattern. head.js adds .js before first paint; until then nothing
 * is hidden, so a visitor with JavaScript off gets the whole page. */
.js .rv { opacity: 0; transform: translateY(16px); }
html[data-motion="off"] .rv { opacity: 1 !important; transform: none !important; }
