/* ==========================================================================
   MODULA — "Blueprint, warmed up."
   A technical-drawing UI system: deep blueprint blue under a drafting grid,
   mono for anything measured, grotesk for anything said, one handwritten
   voice in the margins. Structure stays sober; whimsy lives in annotations
   and micro-motion.

   Every value a designer might change lives in :root. Nothing below :root
   contains a literal color, length or font. Restyle by editing :root only.
   ========================================================================== */

/* --------------------------------------------------------------------------
   FONTS — self-hosted, latin subset. No network requests.
   Caveat and Space Grotesk are variable: one file spans their whole range.
   -------------------------------------------------------------------------- */

@font-face {
  font-family: 'Space Grotesk';
  font-style: normal;
  font-weight: 300 700;
  font-display: swap;
  src: url('fonts/space-grotesk-latin.woff2') format('woff2-variations');
}

@font-face {
  font-family: 'Caveat';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('fonts/caveat-latin.woff2') format('woff2-variations');
}

@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('fonts/ibm-plex-mono-400-latin.woff2') format('woff2');
}

@font-face {
  font-family: 'IBM Plex Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('fonts/ibm-plex-mono-500-latin.woff2') format('woff2');
}

/* --------------------------------------------------------------------------
   TOKENS
   -------------------------------------------------------------------------- */

:root {
  /* --- Palette -------------------------------------------------------- */
  --c-blueprint:      #142e52;  /* page ground, under the drafting grid    */
  --c-blueprint-deep: #132c4e;  /* body backstop behind the ground         */
  --c-ink-well:       #0d1e38;  /* sheet fill, inset fields                */
  --c-paper:          #f2efe6;  /* light surfaces, primary buttons         */
  --c-cyan:           #7fd4ff;  /* kickers, frames, active states, hover   */
  --c-frost:          #e4eefb;  /* headlines and primary values            */
  --c-haze:           #b9cdea;  /* body copy                               */
  --c-slate:          #8fabd4;  /* mono labels, secondary values           */
  --c-link:           #9fc6f2;  /* links at rest                           */
  --c-amber:          #ffd166;  /* handwritten notes, cautions             */
  --c-pass:           #8effc1;  /* status: good                            */
  --c-fail:           #ff8a7a;  /* status: bad                             */
  --c-white:          #ffffff;  /* link hover only                         */
  --c-ink:            #1c3a68;  /* deep accent on light surfaces           */

  /* Channel triplets, so every alpha below derives instead of repeating. */
  --rgb-rule: 178, 208, 246;    /* the drafting line color                 */
  --rgb-cyan: 127, 212, 255;
  --rgb-well:  10,  24,  46;
  --rgb-grid: 159, 199, 247;

  /* --- Lines and fills ------------------------------------------------ */
  --rule:        rgba(var(--rgb-rule), 0.55);  /* sheet + section borders  */
  --rule-soft:   rgba(var(--rgb-rule), 0.35);  /* inner panel borders      */
  --rule-faint:  rgba(var(--rgb-rule), 0.25);  /* hairlines               */
  --rule-idle:   rgba(var(--rgb-rule), 0.40);  /* control at rest          */
  --sheet-fill:  rgba( 13,  30,  56, 0.42);
  --panel-fill:  rgba(var(--rgb-well), 0.35);
  --field-fill:  rgba(var(--rgb-well), 0.60);
  --cyan-fill:   rgba(var(--rgb-cyan), 0.18);  /* active segment cell      */
  --cyan-ghost:  rgba(var(--rgb-cyan), 0.12);
  --grid-minor:  rgba(var(--rgb-grid), 0.055);
  --grid-major:  rgba(var(--rgb-grid), 0.12);

  /* --- Type ----------------------------------------------------------- */
  --font-display: 'Space Grotesk', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --font-mono:    'IBM Plex Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
  --font-hand:    'Caveat', 'Bradley Hand', cursive;

  --fw-body: 400;
  --fw-mid:  500;
  --fw-bold: 700;

  --fs-micro:  10.5px;  /* mono labels inside panels                       */
  --fs-mono:   11px;    /* mono running text, rules paragraphs             */
  --fs-kicker: 11.5px;  /* section kicker                                  */
  --fs-small:  13px;    /* buttons, dense controls                         */
  --fs-body:   15px;
  --fs-lead:   17px;
  --fs-h3:     20px;
  --fs-h2:     34px;
  --fs-h1:     44px;
  --fs-hero:   58px;
  --fs-note:   23px;    /* Caveat margin notes                             */

  --track-tight:  -0.01em;  /* display sizes                               */
  --track-body:    0.04em;
  --track-mono:    0.06em;
  --track-wide:    0.08em;
  --track-label:   0.12em;
  --track-kicker:  0.14em;
  --track-brand:   0.20em;  /* the wordmark                                */

  --lh-hero:    1.03;
  --lh-tight:   1.5;
  --lh-body:    1.6;
  --lh-relaxed: 1.7;

  --measure: 64ch;      /* max line length for body copy                   */

  /* --- Space (4px scale) ---------------------------------------------- */
  --s-1:  4px;
  --s-2:  8px;
  --s-3:  12px;
  --s-4:  16px;
  --s-5:  20px;
  --s-6:  24px;
  --s-8:  32px;
  --s-10: 40px;
  --s-12: 48px;
  --s-14: 56px;
  --s-16: 64px;

  /* --- Structure ------------------------------------------------------ */
  --sheet-max:     1200px;
  --border:        1px;
  --radius:        0;       /* square corners are the house rule           */
  --pad-page:      var(--s-6) var(--s-5);
  --pad-section:   var(--s-12);
  --pad-header:    var(--s-4) var(--s-8);
  --pad-panel:     var(--s-5) var(--s-6);
  --pad-control:   10px 12px;
  --pad-button:    13px var(--s-5);
  --control-h:     38px;
  --handle:        7px;     /* frame corner handle                         */
  --tick:          6px;     /* dimension line end tick                     */

  --grid-minor-size: 24px;
  --grid-major-size: 120px;

  /* --- Motion --------------------------------------------------------- */
  --t-hover:    0.15s;
  --ease:       ease;
  --ants-dur:   0.7s;
  --ants-dash:  8px;        /* dash length; gap is --ants-gap              */
  --ants-gap:   6px;
  --pulse-dur:  2.2s;
  --note-tilt:  -2.5deg;    /* Caveat notes sit between -1.5 and -4        */

  /* --- Breakpoints (referenced in comments; media queries need literals) */
  --bp-wide:   1024px;
  --bp-narrow: 640px;
}

/* --------------------------------------------------------------------------
   BASE
   -------------------------------------------------------------------------- */

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

body {
  margin: 0;
  background: var(--c-blueprint-deep);
  color: var(--c-frost);
  font-family: var(--font-display);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  -webkit-font-smoothing: antialiased;
}

a { color: var(--c-link); text-decoration: none; transition: color var(--t-hover) var(--ease); }
a:hover { color: var(--c-white); }

::selection { background: var(--c-cyan); color: var(--c-blueprint-deep); }

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

/* --------------------------------------------------------------------------
   GROUND — blueprint blue with a two-scale drafting grid.
   Four gradients: minor x, minor y, major x, major y.
   -------------------------------------------------------------------------- */

.bp-page {
  min-height: 100vh;
  padding: var(--pad-page);
  background-color: var(--c-blueprint);
  background-image:
    linear-gradient(var(--grid-minor) var(--border), transparent var(--border)),
    linear-gradient(90deg, var(--grid-minor) var(--border), transparent var(--border)),
    linear-gradient(var(--grid-major) var(--border), transparent var(--border)),
    linear-gradient(90deg, var(--grid-major) var(--border), transparent var(--border));
  background-size:
    var(--grid-minor-size) var(--grid-minor-size),
    var(--grid-minor-size) var(--grid-minor-size),
    var(--grid-major-size) var(--grid-major-size),
    var(--grid-major-size) var(--grid-major-size);
  background-position:
    calc(50% - (var(--grid-minor-size) / 2)) var(--s-1),
    calc(50% - (var(--grid-minor-size) / 2)) var(--s-1),
    calc(50% - (var(--grid-major-size) / 2)) var(--s-6),
    calc(50% - (var(--grid-major-size) / 2)) var(--s-6);
}

/* --------------------------------------------------------------------------
   SHEET — one bordered container per page. No cards, no shadows.
   -------------------------------------------------------------------------- */

.bp-sheet {
  max-width: var(--sheet-max);
  margin: 0 auto;
  border: var(--border) solid var(--rule);
  background: var(--sheet-fill);
}

.bp-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-6);
  flex-wrap: wrap;
  padding: var(--pad-header);
  border-bottom: var(--border) solid var(--rule);
}

.bp-brand { display: flex; align-items: baseline; gap: var(--s-3); }

.bp-brand__mark {
  font-family: var(--font-mono);
  font-weight: var(--fw-mid);
  font-size: 18px;
  letter-spacing: var(--track-brand);
  color: var(--c-frost);
}

.bp-brand__rev {
  font-family: var(--font-mono);
  font-size: var(--fs-mono);
  letter-spacing: var(--track-wide);
  color: var(--c-slate);
}

.bp-nav { display: flex; gap: var(--s-6); flex-wrap: wrap; }

.bp-nav a {
  font-family: var(--font-mono);
  font-size: var(--fs-small);
  letter-spacing: var(--track-mono);
  text-transform: uppercase;
  color: var(--c-link);
}

.bp-section {
  padding: var(--pad-section);
  border-bottom: var(--border) solid var(--rule);
}

.bp-section:last-child { border-bottom: 0; }

.bp-divider { border: 0; border-top: var(--border) solid var(--rule-faint); margin: var(--s-5) 0; }

/* --------------------------------------------------------------------------
   TYPE
   -------------------------------------------------------------------------- */

/* Sections open with a mono kicker in cyan. */
.bp-kicker {
  font-family: var(--font-mono);
  font-size: var(--fs-kicker);
  letter-spacing: var(--track-kicker);
  text-transform: uppercase;
  color: var(--c-cyan);
  margin: 0 0 var(--s-6) 0;
}

.bp-h1, .bp-h2, .bp-h3 {
  font-family: var(--font-display);
  font-weight: var(--fw-bold);
  letter-spacing: var(--track-tight);
  color: var(--c-frost);
  margin: 0 0 var(--s-3) 0;
  text-wrap: balance;
}

.bp-h1 { font-size: var(--fs-h1); line-height: var(--lh-hero); }
.bp-h2 { font-size: var(--fs-h2); line-height: var(--lh-tight); }
.bp-h3 { font-size: var(--fs-h3); line-height: var(--lh-tight); }

.bp-hero { font-size: var(--fs-hero); }

.bp-lead,
.bp-body {
  color: var(--c-haze);
  max-width: var(--measure);
  margin: 0;
  text-wrap: pretty;
}

.bp-lead { font-size: var(--fs-lead); line-height: var(--lh-body); }
.bp-body { font-size: var(--fs-body); line-height: var(--lh-body); }

/* Mono carries every number, unit, label and nav item. Always caps. */
.bp-mono {
  font-family: var(--font-mono);
  font-size: var(--fs-mono);
  letter-spacing: var(--track-mono);
  text-transform: uppercase;
  color: var(--c-slate);
}

.bp-label {
  display: block;
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--c-slate);
  margin-bottom: var(--s-2);
}

/* The mono RULES paragraph that closes a section. */
.bp-rules {
  font-family: var(--font-mono);
  font-size: var(--fs-mono);
  letter-spacing: var(--track-body);
  line-height: var(--lh-relaxed);
  color: var(--c-slate);
  margin: var(--s-5) 0 0 0;
  text-transform: none;
}

/* One or two per screen. Always amber, always slightly rotated. */
.bp-note {
  font-family: var(--font-hand);
  font-weight: var(--fw-mid);
  font-size: var(--fs-note);
  line-height: var(--lh-tight);
  color: var(--c-amber);
  transform: rotate(var(--note-tilt));
  width: max-content;
  max-width: 100%;
}

.bp-note--right { --note-tilt: 2deg; }

/* --------------------------------------------------------------------------
   BUTTONS — square, mono caps, verbs first.
   -------------------------------------------------------------------------- */

.bp-btn {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: var(--fs-small);
  letter-spacing: var(--track-mono);
  text-transform: uppercase;
  padding: var(--pad-button);
  border-radius: var(--radius);
  border: var(--border) solid transparent;
  cursor: pointer;
  transition: all var(--t-hover) var(--ease);
}

.bp-btn--primary {
  background: var(--c-paper);
  color: var(--c-blueprint);
  font-weight: var(--fw-mid);
}

.bp-btn--primary:hover { background: var(--c-cyan); color: var(--c-blueprint); }

.bp-btn--outline {
  background: transparent;
  border-color: var(--rule);
  color: var(--c-link);
}

.bp-btn--outline:hover { border-color: var(--c-cyan); color: var(--c-white); }

.bp-btn[disabled],
.bp-btn[aria-disabled='true'] {
  opacity: 0.45;
  cursor: not-allowed;
  pointer-events: none;
}

/* --------------------------------------------------------------------------
   CONTROLS — mono caps label above, dark inset field, cyan focus.
   -------------------------------------------------------------------------- */

.bp-field { display: block; margin-bottom: var(--s-4); }

.bp-input,
.bp-select,
.bp-textarea {
  width: 100%;
  font-family: var(--font-mono);
  font-size: var(--fs-small);
  letter-spacing: var(--track-body);
  color: var(--c-frost);
  background: var(--field-fill);
  border: var(--border) solid var(--rule-idle);
  border-radius: var(--radius);
  padding: var(--pad-control);
  transition: border-color var(--t-hover) var(--ease);
}

.bp-input:hover,
.bp-select:hover,
.bp-textarea:hover { border-color: var(--rule); }

.bp-input:focus,
.bp-select:focus,
.bp-textarea:focus {
  border-color: var(--c-cyan);
  outline: none;
}

.bp-input::placeholder,
.bp-textarea::placeholder { color: var(--c-slate); opacity: 0.7; }

.bp-textarea { min-height: calc(var(--control-h) * 2); resize: vertical; }

/* accent-color alone leaves the unfilled track at the UA default, which
   lands off-palette on a dark ground. Track and thumb are drawn instead. */
.bp-input[type='range'] {
  -webkit-appearance: none;
  appearance: none;
  padding: 0;
  height: var(--handle);
  background: var(--field-fill);
  border: var(--border) solid var(--rule-idle);
  cursor: pointer;
}

.bp-input[type='range']::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: var(--s-3);
  height: var(--s-3);
  background: var(--c-cyan);
  border: 0;
  border-radius: var(--radius);
  cursor: pointer;
}

.bp-input[type='range']::-moz-range-thumb {
  width: var(--s-3);
  height: var(--s-3);
  background: var(--c-cyan);
  border: 0;
  border-radius: var(--radius);
  cursor: pointer;
}

.bp-input[type='checkbox'] { width: auto; accent-color: var(--c-cyan); }
.bp-input[type='color'] {
  width: var(--s-16);
  height: var(--control-h);
  padding: var(--s-1);
  cursor: pointer;
}

.bp-check {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  cursor: pointer;
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--c-slate);
}

/* Mutually exclusive options join into one bordered row.
   Active cell gets the cyan fill and cyan text. */
.bp-seg {
  display: inline-flex;
  border: var(--border) solid var(--rule);
  border-radius: var(--radius);
  overflow: hidden;
}

.bp-seg__item {
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  letter-spacing: var(--track-wide);
  text-transform: uppercase;
  padding: var(--s-2) 14px;
  background: transparent;
  color: var(--c-link);
  border: 0;
  border-right: var(--border) solid var(--rule-faint);
  cursor: pointer;
  transition: all var(--t-hover) var(--ease);
}

.bp-seg__item:last-child { border-right: 0; }
.bp-seg__item:hover { color: var(--c-white); }

.bp-seg__item[data-active='true'] {
  background: var(--cyan-fill);
  color: var(--c-cyan);
}

/* --------------------------------------------------------------------------
   PANELS AND READOUTS — label left in slate, value right.
   Status words in caps after a middot.
   -------------------------------------------------------------------------- */

.bp-panel {
  border: var(--border) solid var(--rule-soft);
  background: var(--panel-fill);
  padding: var(--pad-panel);
}

.bp-readout { display: grid; gap: var(--s-2); }

.bp-readout__row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s-3);
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
}

.bp-readout__label { color: var(--c-slate); }
.bp-readout__value { color: var(--c-frost); text-align: right; }

.bp-status { color: var(--c-slate); }
.bp-status[data-state='pass'] { color: var(--c-pass); }
.bp-status[data-state='warn'] { color: var(--c-amber); }
.bp-status[data-state='fail'] { color: var(--c-fail); }

/* Advice says what to do, not what is wrong. Sits below a hairline. */
.bp-advice {
  margin-top: var(--s-3);
  padding-top: var(--s-3);
  border-top: var(--border) solid var(--rule-faint);
  font-family: var(--font-mono);
  font-size: var(--fs-mono);
  letter-spacing: var(--track-body);
  line-height: var(--lh-relaxed);
  color: var(--c-amber);
}

.bp-advice[data-state='fail'] { color: var(--c-fail); }

/* --------------------------------------------------------------------------
   SWATCHES
   -------------------------------------------------------------------------- */

.bp-swatches {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--s-5);
}

.bp-swatch { border: var(--border) solid var(--rule-soft); }

.bp-swatch__chip {
  height: var(--s-16);
  background: var(--swatch, var(--c-cyan));
  border-bottom: var(--border) solid var(--rule-soft);
}

.bp-swatch__meta {
  padding: var(--s-3) 14px;
  font-family: var(--font-mono);
  font-size: var(--fs-mono);
  line-height: var(--lh-tight);
}

.bp-swatch__name { color: var(--c-frost); letter-spacing: var(--track-label); text-transform: uppercase; }
.bp-swatch__hex  { color: var(--c-slate); margin-top: var(--s-1); }
.bp-swatch__use  { color: var(--c-slate); font-size: var(--fs-micro); margin-top: 6px; }

/* --------------------------------------------------------------------------
   FRAME — the house motif. A light surface held inside marching ants with
   cyan corner handles. Use it to single out anything the page is presenting:
   an image, a preview, a highlighted panel.
   Ants are four animated gradient edges, so no SVG is needed.
   -------------------------------------------------------------------------- */

.bp-frame {
  position: relative;
  display: inline-block;
  justify-self: start;
  padding: var(--s-2);
  background:
    linear-gradient(90deg,  var(--c-cyan) 50%, transparent 0) repeat-x,
    linear-gradient(90deg,  var(--c-cyan) 50%, transparent 0) repeat-x,
    linear-gradient(0deg,   var(--c-cyan) 50%, transparent 0) repeat-y,
    linear-gradient(0deg,   var(--c-cyan) 50%, transparent 0) repeat-y;
  background-size:
    calc(var(--ants-dash) + var(--ants-gap)) var(--border),
    calc(var(--ants-dash) + var(--ants-gap)) var(--border),
    var(--border) calc(var(--ants-dash) + var(--ants-gap)),
    var(--border) calc(var(--ants-dash) + var(--ants-gap));
  background-position: 0 0, 0 100%, 0 0, 100% 0;
  animation: bp-ants var(--ants-dur) linear infinite;
}

.bp-frame__inner { display: block; background: var(--c-paper); }
.bp-frame__inner > img,
.bp-frame__inner > svg { display: block; max-width: 100%; height: auto; }

/* Four 7px cyan corner handles, one pseudo-element, four gradients. */
.bp-frame::after {
  content: '';
  position: absolute;
  inset: calc(var(--handle) / -2);
  pointer-events: none;
  background:
    linear-gradient(var(--c-cyan), var(--c-cyan)) 0    0    / var(--handle) var(--handle) no-repeat,
    linear-gradient(var(--c-cyan), var(--c-cyan)) 100% 0    / var(--handle) var(--handle) no-repeat,
    linear-gradient(var(--c-cyan), var(--c-cyan)) 0    100% / var(--handle) var(--handle) no-repeat,
    linear-gradient(var(--c-cyan), var(--c-cyan)) 100% 100% / var(--handle) var(--handle) no-repeat;
}

@keyframes bp-ants {
  to {
    background-position:
      calc(var(--ants-dash) + var(--ants-gap)) 0,
      calc(0px - var(--ants-dash) - var(--ants-gap)) 100%,
      0 calc(0px - var(--ants-dash) - var(--ants-gap)),
      100% calc(var(--ants-dash) + var(--ants-gap));
  }
}

/* Dimension line with end ticks and a mono measurement between them. */
.bp-dim {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  margin-top: var(--s-2);
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  letter-spacing: var(--track-wide);
  color: var(--c-slate);
}

.bp-dim::before,
.bp-dim::after {
  content: '';
  flex: 1;
  height: var(--tick);
  border-top: var(--border) solid var(--rule-idle);
  border-left: var(--border) solid var(--rule-idle);
  border-right: var(--border) solid var(--rule-idle);
  transform: translateY(calc(var(--tick) / 2));
}

/* Numbered figure captions.
   Sized to its widest child so the dimension line spans the subject
   exactly, never the column. Keep running prose OUTSIDE the figure, or it
   becomes the widest child and stretches the dimension line with it. */
.bp-figure {
  display: grid;
  gap: var(--s-3);
  width: max-content;
  max-width: 100%;
}

.bp-figure__cap {
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  letter-spacing: var(--track-label);
  text-transform: uppercase;
  color: var(--c-cyan);
}

.bp-figure__note {
  font-family: var(--font-display);
  font-size: var(--fs-small);
  line-height: var(--lh-body);
  letter-spacing: normal;
  text-transform: none;
  color: var(--c-haze);
}

/* --------------------------------------------------------------------------
   INDEX LIST — an enumerated register. Rows divide with the same 1px rule
   the sheet uses, never with cards. Each row carries a mono ordinal.
   -------------------------------------------------------------------------- */

.bp-list {
  margin-top: var(--s-8);
  border-top: var(--border) solid var(--rule-soft);
}

.bp-list__row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--s-6);
  flex-wrap: wrap;
  padding: var(--s-5) var(--s-4);
  border-bottom: var(--border) solid var(--rule-soft);
  transition: background-color var(--t-hover) var(--ease);
}

.bp-list__row:hover { background-color: var(--cyan-ghost); }

.bp-list__main { display: flex; align-items: baseline; gap: var(--s-4); min-width: 0; }

.bp-list__no {
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  letter-spacing: var(--track-label);
  color: var(--c-cyan);
  flex: none;
}

.bp-list__name {
  font-family: var(--font-display);
  font-weight: var(--fw-bold);
  font-size: var(--fs-h3);
  letter-spacing: var(--track-tight);
  color: var(--c-frost);
  margin: 0;
}

.bp-list__path {
  font-family: var(--font-mono);
  font-size: var(--fs-micro);
  letter-spacing: var(--track-body);
  color: var(--c-slate);
  overflow-wrap: anywhere;
}

/* Says what to do next, not just that there is nothing here. */
.bp-empty {
  padding: var(--s-12) var(--s-4);
  border-bottom: var(--border) solid var(--rule-soft);
  text-align: center;
}

.bp-empty .bp-advice {
  max-width: var(--measure);
  margin-inline: auto;
}

/* --------------------------------------------------------------------------
   STATUS PULSE — the second and last permitted motion.
   -------------------------------------------------------------------------- */

.bp-pulse { display: inline-flex; gap: var(--s-1); align-items: center; }

.bp-pulse span {
  width: var(--s-1);
  height: var(--s-1);
  background: var(--c-cyan);
  animation: bp-pulse var(--pulse-dur) var(--ease) infinite;
}

.bp-pulse span:nth-child(2) { animation-delay: calc(var(--pulse-dur) / 6); }
.bp-pulse span:nth-child(3) { animation-delay: calc(var(--pulse-dur) / 3); }

@keyframes bp-pulse {
  0%, 100% { opacity: 0.2; }
  50%      { opacity: 1; }
}

/* --------------------------------------------------------------------------
   LAYOUT HELPERS
   -------------------------------------------------------------------------- */

.bp-split {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--s-14);
  align-items: start;
}

.bp-stack   { display: grid; gap: var(--s-3); }
.bp-stack--wide { gap: var(--s-6); }
.bp-row     { display: flex; gap: var(--s-3); align-items: center; flex-wrap: wrap; }

/* --------------------------------------------------------------------------
   RESPONSIVE
   Media queries cannot read custom properties, so --bp-* above document
   these literals; change both together.

   Type steps are literals here, not references to other --fs-* tokens.
   Custom properties resolve lazily, so --fs-h1: var(--fs-h2) inside a block
   that also lowers --fs-h2 collapses down the whole chain.
   -------------------------------------------------------------------------- */

@media (max-width: 1024px) {
  :root {
    --pad-section: var(--s-8);
    --fs-hero: 44px;
  }
  .bp-split { grid-template-columns: 1fr; gap: var(--s-8); }
  .bp-swatches { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 640px) {
  :root {
    --pad-section: var(--s-6);
    --pad-header: var(--s-3) var(--s-4);
    --pad-page: var(--s-3);
    --fs-hero: 34px;
    --fs-h1:   34px;
    --fs-h2:   24px;
    --fs-h3:   18px;
    --fs-lead: 16px;
  }
  .bp-swatches { grid-template-columns: 1fr; }
  .bp-nav { gap: var(--s-3); }
}

/* A drawing does not animate; its annotations do. And not for everyone. */
@media (prefers-reduced-motion: reduce) {
  .bp-frame { animation: none; }
  .bp-pulse span { animation: none; opacity: 0.7; }
  * { transition-duration: 0.01ms !important; }
}
