/* ==========================================================================
   Detty Season / The December Price List
   A printed price board: newsprint stock, a fixed set of spot inks, hairline
   rules, tabular numerals. Every listing is a ruled line carrying a date, a
   price and an act-by. Cards are not the structure here; rows are.
   ========================================================================== */

/* ── Ink & stock ─────────────────────────────────────────────────────────── */
:root {
  /* Spot inks are injected per-theme from PHP as --ink-1 / --ink-2. */
  --paper:      #F6F0E4;   /* the stock */
  --paper-2:    #EDE5D3;   /* a deeper stock for banded sections */
  --paper-3:    #E3D9C3;   /* pressed/inset */
  --ink:        #16130D;   /* the working black, warm */
  --ink-soft:   #605747;   /* secondary, tinted from the stock, never gray */
  --ink-faint:  #6E6555;
  --rule:       rgba(22, 19, 13, .16);
  --rule-hard:  rgba(22, 19, 13, .48);

  /* The slab: the high-contrast band the clock and the ink slips print on.
     By day it is the working black. At night the page is already dark, so the
     slab lifts instead of inverting. An inverted white band at night would
     both glare and strand the accent on top of it. */
  --slab:         #16130D;
  --on-slab:      #F6F0E4;
  --on-slab-soft: #C9C1AF;
  /* The scrim behind a sheet or drawer. Warm, because a neutral black over warm
     stock reads as a colour shift rather than as shade. */
  --scrim:        rgba(10, 9, 6, .55);

  /* The national colours. These are DECORATION ONLY and appear in exactly one
     component, the flag band. They are never applied to text, state, links or
     hover, because flag red and alarm vermilion are nearly the same colour and
     a decorative red would spend the meaning the deadline system depends on. */
  --gh-red:   #CE1126;
  --gh-gold:  #FCD116;
  --gh-green: #006B3F;

  /* Reserved. Vermilion means one thing: a deadline inside 14 days, or gone.
     It is never used for emphasis, links, hover, or decoration. */
  --alarm:      #C81E12;
  --alarm-soft: rgba(200, 30, 18, .10);
  /* Confirmed and open for business. */
  --go:         #1C6E38;

  /* The micro ramp: everything below body size resolves to one of four steps.
     Nine ad-hoc values were doing this job before, which is sprawl, not a scale. */
  --fs-3xs:     .64rem;   /* stamps, the stub's month, column heads */
  --fs-2xs:     .72rem;   /* form notes, chips, unconfirmed reasons */
  --fs-xs:      .8rem;    /* row metadata, nav, footer base */
  --fs-sm:      .9rem;    /* small body copy */

  --measure:    68ch;
  --gut:        clamp(16px, 4vw, 28px);
  --shell:      1180px;

  --step-fast:  90ms;
  --step:       200ms;
  --ease-out:   cubic-bezier(.16, 1, .3, 1);

  --font-display: "Bricolage Grotesque", "Archivo", system-ui, sans-serif;
  --font-text:    "Archivo", system-ui, -apple-system, sans-serif;

  color-scheme: light;
}

/* The night edition: the same press, the stock inverted. Not a different
   design. The paper goes dark and the ink goes light, rules and inks hold. */
@media (prefers-color-scheme: dark) {
  :root:not([data-stock="day"]) {
    --paper:     #14120C;
    --paper-2:   #1D1A12;
    --paper-3:   #262218;
    --ink:       #F4EEE1;
    --ink-soft:  #B0A794;
    --ink-faint: #8D8474;
    --rule:      rgba(244, 238, 225, .18);
    --rule-hard: rgba(244, 238, 225, .5);
    --alarm:      #FF6A5B;
    --alarm-soft: rgba(255, 106, 91, .12);
    --go:         #5BC47E;
    --slab:         #241F14;
    --on-slab:      #F4EEE1;
    --on-slab-soft: #A79E8C;
    color-scheme: dark;
  }
}
:root[data-stock="night"] {
  --paper: #14120C; --paper-2: #1D1A12; --paper-3: #262218;
  --ink: #F4EEE1; --ink-soft: #B0A794; --ink-faint: #8D8474;
  --rule: rgba(244,238,225,.18); --rule-hard: rgba(244,238,225,.5);
  --alarm: #FF6A5B; --alarm-soft: rgba(255,106,91,.12); --go: #5BC47E;
  --slab: #241F14; --on-slab: #F4EEE1; --on-slab-soft: #A79E8C;
  color-scheme: dark;
}

/* ── Reset ───────────────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  background: var(--paper);
  /* App-shell behaviours. A rubber-band bounce past the page edge is the
     clearest tell that a standalone PWA is really a web page. */
  overscroll-behavior-y: none;
  -webkit-tap-highlight-color: transparent;
  color: var(--ink);
  font-family: var(--font-text);
  font-size: 16px;
  line-height: 1.55;
  font-variant-numeric: tabular-nums;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
}
img, svg, video { display: block; max-width: 100%; height: auto; }
button, input, select, textarea { font: inherit; color: inherit; }

/* Browser surfaces belong to the design system too. */
::selection { background: var(--ink-1); color: var(--on-ink-1, #16130D); }
:root { caret-color: var(--ink-1); scrollbar-color: var(--rule-hard) transparent; }
:focus-visible {
  outline: 2px solid var(--ink-1);
  outline-offset: 2px;
  border-radius: 1px;
}
a { color: inherit; text-decoration-thickness: 1px; text-underline-offset: 3px; }
::-webkit-scrollbar { width: 11px; height: 11px; }
::-webkit-scrollbar-track { background: var(--paper-2); }
::-webkit-scrollbar-thumb { background: var(--rule-hard); border: 3px solid var(--paper-2); border-radius: 99px; }

/* ── Type scale ──────────────────────────────────────────────────────────── */
.d1, .d2, .d3, h1, h2, h3 {
  font-family: var(--font-display);
  font-weight: 800;
  line-height: .95;
  letter-spacing: -.03em;
  text-wrap: balance;
}
.d1 { font-size: clamp(2.6rem, 9vw, 5.4rem); }
.d2 { font-size: clamp(1.9rem, 5.4vw, 3.1rem); }
.d3 { font-size: clamp(1.35rem, 3.4vw, 1.9rem); }
h1 { font-size: clamp(2.1rem, 6.5vw, 3.6rem); }
h2 { font-size: clamp(1.6rem, 4.2vw, 2.4rem); }
h3 { font-size: clamp(1.15rem, 2.6vw, 1.4rem); letter-spacing: -.02em; }
p, li { max-width: var(--measure); }
.prose > * + * { margin-top: 1em; }
.prose h2 { margin-top: 1.8em; margin-bottom: .5em; }
.prose h3 { margin-top: 1.5em; margin-bottom: .35em; }
.prose ul, .prose ol { padding-left: 1.15em; }
.prose li + li { margin-top: .4em; }
.prose a { text-decoration: underline; text-decoration-color: var(--ink-1); }
.prose a:hover { background: var(--ink-1); color: var(--on-ink-1, #16130D); text-decoration-color: transparent; }

/* Set in the press's smallest size: labels, column heads, stamps. */
.label {
  font-size: var(--fs-2xs);
  font-weight: 700;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
.num { font-variant-numeric: tabular-nums; font-feature-settings: "tnum" 1; }
.lede { font-size: clamp(1.02rem, 2.2vw, 1.2rem); color: var(--ink-soft); max-width: 60ch; }

/* ── Shell & rules ───────────────────────────────────────────────────────── */
.shell { width: 100%; max-width: var(--shell); margin-inline: auto; padding-inline: var(--gut); }
.rule       { border: 0; border-top: 1px solid var(--rule); }
.rule--hard { border-top: 2px solid var(--ink); }
.band       { background: var(--paper-2); }
.band--ink  { background: var(--slab); color: var(--on-slab); }
.band--ink .label, .band--ink .lede { color: var(--on-slab-soft); }
.stack > * + * { margin-top: var(--flow, 1rem); }
.section { padding-block: clamp(38px, 7vw, 72px); }
.section--tight { padding-block: clamp(26px, 4.5vw, 42px); }

/* A section opens with a hard rule and its name set in the display face.
   No eyebrow above it. The heading carries itself. */
.section-head {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: .5rem 1.25rem;
  border-top: 2px solid var(--ink);
  padding-top: .75rem;
  margin-bottom: 1.5rem;
}
.section-head h2 { flex: 1 1 auto; }
.section-head .label { flex: 0 0 auto; }

/* ── The flag band ────────────────────────────────────────────────────────────
   A newspaper prints a colour bar along the head of the sheet. This one is the
   national flag in its own order, used twice per page and only ever at an
   extreme edge: the top of the masthead and the top of the footer. It touches
   no text and carries no state, which is what keeps the alarm ink meaningful. */
.flagband {
  height: 4px;
  background: linear-gradient(
    to right,
    var(--gh-red)   0 33.333%,
    var(--gh-gold)  33.333% 66.666%,
    var(--gh-green) 66.666% 100%
  );
}

/* ══ Masthead ══════════════════════════════════════════════════════════════
   The printed head of the sheet: name, date of issue, the sections. */
.masthead { border-bottom: 2px solid var(--ink); background: var(--paper); }
.masthead__bar {
  display: flex; align-items: center; gap: 1rem;
  padding-block: .8rem;
}
.wordmark {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: clamp(1.3rem, 3.6vw, 1.75rem);
  letter-spacing: -.045em;
  line-height: 1;
  text-decoration: none;
  display: inline-flex; align-items: center; gap: .5rem;
  white-space: nowrap;
}
.wordmark::before {
  content: ""; width: .78em; height: .78em; flex: none;
  background: var(--ink);
  /* The Black Star. Square, Line, Experience: this audience reads it instantly,
     and being black it costs the semantic palette nothing. */
  clip-path: polygon(50% 0%, 61% 35%, 98% 35%, 68% 57%, 79% 91%,
                     50% 70%, 21% 91%, 32% 57%, 2% 35%, 39% 35%);
}
.masthead__issue {
  margin-left: auto; text-align: right; line-height: 1.2;
  display: none;
}
@media (min-width: 900px) { .masthead__issue { display: block; } }

.mainnav { border-top: 1px solid var(--rule); }
.mainnav ul {
  display: flex; list-style: none; padding: 0; margin: 0;
  gap: clamp(.9rem, 2.4vw, 1.9rem);
  overflow-x: auto; scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}
.mainnav ul::-webkit-scrollbar { display: none; }
.mainnav a {
  display: block; padding: .7rem 0;
  font-size: var(--fs-xs); font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  text-decoration: none; white-space: nowrap;
  border-bottom: 3px solid transparent;
  color: var(--ink-soft);
  transition: color var(--step-fast) linear, border-color var(--step-fast) linear;
}
.mainnav a:hover { color: var(--ink); }
.mainnav a[aria-current="page"] { color: var(--ink); border-bottom-color: var(--ink-1); }

/* ══ The clock ═════════════════════════════════════════════════════════════
   One hard band. The count is the largest number on the page because it is
   the only one that changes on its own. */
.clock {
  background: var(--slab); color: var(--on-slab);
  border-bottom: 2px solid var(--slab);
}
.clock__inner {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: .35rem 1.1rem;
  padding-block: clamp(14px, 2.6vw, 22px);
}
.clock__n {
  font-family: var(--font-display); font-weight: 800;
  font-size: clamp(3.4rem, 13vw, 6rem);
  line-height: .82; letter-spacing: -.055em;
  color: var(--ink-1-slab, var(--ink-1));
}
.clock__unit {
  font-family: var(--font-display); font-weight: 800;
  font-size: clamp(1rem, 3vw, 1.5rem); line-height: 1; letter-spacing: -.02em;
}
.clock__note { flex: 1 1 260px; font-size: var(--fs-sm); color: var(--on-slab-soft); max-width: 46ch; }
.clock--live .clock__n { color: var(--go); }

/* ══ The board ═════════════════════════════════════════════════════════════
   The core component. One line, one decision: a date stub, the thing, and a
   fixed numeral rail on the right you can sweep with your thumb. */
.board { border-top: 2px solid var(--ink); }
.board__head {
  display: none;
  padding: .45rem 0;
  border-bottom: 1px solid var(--rule);
}
@media (min-width: 760px) {
  .board__head { display: grid; grid-template-columns: 5.5rem 1fr 9rem 8.5rem; gap: 1.25rem; }
  .board__head > :nth-child(3) { text-align: right; }
}

.row {
  display: grid;
  grid-template-columns: 3.6rem 1fr;
  grid-template-areas: "stub body" "stub rail";
  gap: .15rem 1rem;
  padding-block: clamp(14px, 2.2vw, 18px);
  border-bottom: 1px solid var(--rule);
  position: relative;
}
@media (min-width: 760px) {
  .row {
    grid-template-columns: 5.5rem 1fr 9rem 8.5rem;
    grid-template-areas: "stub body rail act";
    align-items: center;
    gap: 1.25rem;
  }
}
.row:hover { background: var(--paper-2); }
.row__stub { grid-area: stub; text-align: center; line-height: 1; padding-top: .15rem; }
.row__day {
  font-family: var(--font-display); font-weight: 800;
  font-size: clamp(1.5rem, 4vw, 2rem); letter-spacing: -.04em; display: block;
}
.row__mon { font-size: var(--fs-3xs); font-weight: 700; letter-spacing: .13em; text-transform: uppercase; color: var(--ink-soft); }
.row__body { grid-area: body; min-width: 0; }
.row__title {
  font-family: var(--font-display); font-weight: 700;
  font-size: clamp(1.02rem, 2.4vw, 1.22rem); letter-spacing: -.02em; line-height: 1.15;
}
.row__title a { text-decoration: none; }
.row__title a:hover { text-decoration: underline; text-decoration-color: var(--ink-1); text-decoration-thickness: 2px; }
/* The whole row is the target on touch; the visible link keeps the semantics. */
.row__title a::after { content: ""; position: absolute; inset: 0; }
.row__meta {
  margin-top: .25rem; font-size: var(--fs-xs); color: var(--ink-soft);
  display: flex; flex-wrap: wrap; align-items: center; gap: .3rem .55rem;
}
/* A hairline, not a middle dot. A meta strip can carry three or four items,
   and a dot between each of them is the tell every AI-built page ships.
   The rule is this world's own material and it reads quieter at 4 items. */
.row__meta > *:not(:last-child) { padding-right: .55rem; border-right: 1px solid var(--rule); }
.row__why { margin-top: .3rem; font-size: var(--fs-sm); color: var(--ink); max-width: 52ch; }
.row__rail { grid-area: rail; }
@media (min-width: 760px) { .row__rail { text-align: right; } }
.row__price {
  font-family: var(--font-display); font-weight: 700;
  font-size: 1.02rem; letter-spacing: -.02em; white-space: nowrap;
}
.row__act { grid-area: act; }
@media (max-width: 759px) {
  .row { grid-template-areas: "stub body" "stub rail" "stub act"; }
  .row__rail, .row__act { margin-top: .45rem; }
  .row__rail { display: flex; align-items: center; gap: .6rem; }
}

/* The rules lay themselves down once, left to right, like a press pulling a
   sheet. One authored moment on the page; nothing else animates on load. */
@media (prefers-reduced-motion: no-preference) {
  .board--ink .row { animation: ink-row 520ms var(--ease-out) both; }
  .board--ink .row:nth-child(1) { animation-delay: 20ms; }
  .board--ink .row:nth-child(2) { animation-delay: 55ms; }
  .board--ink .row:nth-child(3) { animation-delay: 90ms; }
  .board--ink .row:nth-child(4) { animation-delay: 125ms; }
  .board--ink .row:nth-child(5) { animation-delay: 160ms; }
  .board--ink .row:nth-child(n+6) { animation-delay: 195ms; }
}
@keyframes ink-row {
  from { clip-path: inset(0 100% 0 0); }
  to   { clip-path: inset(0 0 0 0); }
}

/* ── Stamps: small printed marks on a row ────────────────────────────────── */
.stamp {
  display: inline-block; padding: .12em .46em;
  font-size: var(--fs-3xs); font-weight: 800; letter-spacing: .1em; text-transform: uppercase;
  border: 1px solid currentColor; line-height: 1.5; white-space: nowrap;
}
.stamp--ink   { background: var(--ink-1); border-color: var(--ink-1); color: var(--on-ink-1, #16130D); }
.stamp--free  { color: var(--go); }
.stamp--paid  { color: var(--ink-soft); }          /* sponsored / featured placement */
.stamp--alarm { color: var(--alarm); background: var(--alarm-soft); border-color: currentColor; }

/* ── Unconfirmed type ────────────────────────────────────────────────────────
   A fact we have verified prints solid. A fact we have not prints hollow, and
   says so in words. The outline is the signal, never the only one. */
.tbc {
  color: var(--ink-faint);
  text-decoration: underline dotted;
  text-underline-offset: 3px;
}
@supports (-webkit-text-stroke: 1px currentColor) {
  .tbc--display {
    -webkit-text-stroke: 1.2px var(--ink-soft);
    color: transparent;
    text-decoration: none;
  }
}
.tbc__why { font-size: var(--fs-2xs); color: var(--ink-faint); font-style: italic; }
.row__rail .tbc__why { display: block; margin-top: .1rem; }

/* ── Deadlines: the act-by column ────────────────────────────────────────── */
.deadline {
  display: grid; grid-template-columns: 4.4rem 1fr; gap: .1rem .9rem;
  padding-block: .85rem; border-bottom: 1px solid var(--rule);
}
.deadline__n {
  font-family: var(--font-display); font-weight: 800; font-size: 1.55rem;
  line-height: 1; letter-spacing: -.04em; text-align: right;
}
.deadline__u { font-size: var(--fs-3xs); letter-spacing: .12em; text-transform: uppercase; text-align: right; color: var(--ink-soft); }
.deadline__label { font-weight: 700; font-size: var(--fs-sm); line-height: 1.25; }
.deadline__detail { font-size: var(--fs-xs); color: var(--ink-soft); margin-top: .2rem; }
.deadline__when { grid-column: 1; grid-row: 1 / span 2; }

.sev-info   .deadline__n { color: var(--ink); }
.sev-soon   .deadline__n { color: var(--ink-1); }
.sev-urgent .deadline__n { color: var(--alarm); }
.sev-urgent { background: var(--alarm-soft); }
.sev-passed { opacity: .5; }
.sev-passed .deadline__label { text-decoration: line-through; }

/* ── Buttons ─────────────────────────────────────────────────────────────── */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .5em;
  padding: .68em 1.15em;
  font-family: var(--font-display); font-weight: 700; font-size: var(--fs-sm); letter-spacing: -.01em;
  text-decoration: none; cursor: pointer;
  border: 2px solid var(--ink); background: var(--paper); color: var(--ink);
  transition: background var(--step-fast) linear, color var(--step-fast) linear,
              box-shadow var(--step-fast) linear, transform var(--step-fast) linear;
  position: relative; z-index: 1;
}
.btn:hover { background: var(--ink); color: var(--paper); }
.btn:active { transform: translateY(1px); }
.btn--ink { background: var(--ink-1); border-color: var(--ink-1); color: var(--on-ink-1, #16130D); }
.btn--ink:hover { background: var(--ink); border-color: var(--ink); color: var(--paper); }
.btn--solid { background: var(--ink); color: var(--paper); }
.btn--solid:hover { background: var(--ink-1); border-color: var(--ink-1); color: var(--on-ink-1, #16130D); }
.btn--sm { padding: .5em .8em; font-size: var(--fs-xs); }
.btn--wide { width: 100%; }
.btn[aria-disabled="true"], .btn:disabled {
  border-color: var(--rule); color: var(--ink-faint); background: var(--paper-2);
  cursor: not-allowed; pointer-events: none;
}
.btn--quiet { border-color: var(--rule-hard); }

/* ── Slip: a torn-off coupon. Used sparingly ,  the guide, the mailing list. */
.slip {
  border: 2px solid var(--ink);
  background: var(--paper-2);
  padding: clamp(18px, 3.5vw, 28px);
  position: relative;
}
.slip::before {
  /* the perforation down the head of the slip */
  content: ""; position: absolute; left: 0; right: 0; top: 6px; height: 1px;
  background: repeating-linear-gradient(to right, var(--rule) 0 5px, transparent 5px 10px);
}
.slip--ink { background: var(--slab); color: var(--on-slab); border-color: var(--slab); }
.slip--ink .label, .slip--ink .lede, .slip--ink p, .slip--ink .form-note { color: var(--on-slab-soft); }
.slip--ink h3, .slip--ink .d1, .slip--ink .d2, .slip--ink .d3 { color: var(--on-slab); }
.slip--ink .input { background: transparent; border-color: var(--on-slab-soft); color: var(--on-slab); }
.slip--ink .input::placeholder { color: var(--on-slab-soft); }
.slip--ink .input:focus { border-color: var(--on-slab); box-shadow: inset 0 -3px 0 var(--ink-1-slab, var(--ink-1)); }
.slip--ink .field > span { color: var(--on-slab-soft); }
.slip--ink .btn { border-color: var(--ink-1); background: var(--ink-1); color: var(--on-ink-1, #16130D); }
.slip--ink .btn:hover { background: var(--on-slab); border-color: var(--on-slab); color: var(--slab); }

/* ── Forms ───────────────────────────────────────────────────────────────── */
.field { display: block; }
.field + .field { margin-top: 1rem; }
.field > span, .field > label {
  display: block; margin-bottom: .3rem;
  font-size: var(--fs-2xs); font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: var(--ink-soft);
}
.input, .select, .textarea {
  width: 100%; padding: .68em .8em;
  background: var(--paper);
  border: 1px solid var(--rule-hard);
  border-radius: 0;
  transition: border-color var(--step-fast) linear, box-shadow var(--step-fast) linear;
}
.input::placeholder, .textarea::placeholder { color: var(--ink-faint); }
.input:focus, .select:focus, .textarea:focus {
  outline: none; border-color: var(--ink); box-shadow: inset 0 -3px 0 var(--ink-1);
}
.textarea { min-height: 8rem; resize: vertical; }
.select {
  appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, currentColor 50%), linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: right 1em top 55%, right .65em top 55%;
  background-size: 6px 6px, 6px 6px;
  background-repeat: no-repeat;
  padding-right: 2.2em;
}
.field-error { color: var(--alarm); font-size: var(--fs-xs); margin-top: .3rem; font-weight: 600; }
.input[aria-invalid="true"] { border-color: var(--alarm); }
.form-grid { display: grid; gap: 1rem; }
@media (min-width: 640px) { .form-grid--2 { grid-template-columns: 1fr 1fr; } }
.form-note { font-size: var(--fs-xs); color: var(--ink-faint); }

/* A headline figure has to fit its rail at any magnitude. Sizing from the
   container rather than the viewport is what keeps a six-figure cedi total from
   running out of a 20rem aside. */
.slip { container-type: inline-size; }
.costtotal {
  font-size: clamp(1.5rem, 11cqi, 2.4rem);
  line-height: 1.02;
  overflow-wrap: anywhere;
}

/* ── Alert form ───────────────────────────────────────────────────────────────
   Sits inline on a row or in an aside, so it has to survive both widths. */
.alertform { display: flex; flex-wrap: wrap; gap: .5rem; align-items: stretch; }
.alertform .input { min-width: 0; }
.alertform .btn { flex: 0 0 auto; }
.alertform__opt {
  flex: 1 1 100%; display: flex; align-items: center; gap: .45rem;
  font-size: var(--fs-2xs); color: var(--ink-soft);
}
.slip--ink .alertform__opt { color: var(--on-slab-soft); }

/* ── Flash / notices ─────────────────────────────────────────────────────── */
.notice {
  border: 1px solid var(--rule-hard); border-top: 3px solid var(--ink);
  padding: .85rem 1rem; font-size: var(--fs-sm); background: var(--paper-2);
}
.notice--ok    { border-top-color: var(--go); }
.notice--error { border-top-color: var(--alarm); }

/* ── Empty states ────────────────────────────────────────────────────────────
   The season has not been filled in yet. Say that plainly rather than dressing
   an empty list as a finished one. */
.empty {
  border: 1px dashed var(--rule-hard);
  padding: clamp(24px, 5vw, 44px);
  text-align: center;
}
.empty h3 { margin-bottom: .4rem; }
.empty p { color: var(--ink-soft); margin-inline: auto; max-width: 44ch; }
.empty .btn { margin-top: 1.1rem; }

/* ── Layout helpers ──────────────────────────────────────────────────────── */
.split { display: grid; gap: clamp(28px, 5vw, 52px); }
@media (min-width: 940px) { .split { grid-template-columns: minmax(0, 1fr) 20rem; align-items: start; } }
.aside { position: sticky; top: 1rem; }
@media (max-width: 939px) { .aside { position: static; } }
.cluster { display: flex; flex-wrap: wrap; gap: .6rem; align-items: center; }
.spread { display: flex; flex-wrap: wrap; gap: 1rem; align-items: baseline; justify-content: space-between; }

/* Filter chips ,  set like the column heads on a printed board. */
.chips { display: flex; flex-wrap: wrap; gap: .4rem; }
.chip {
  display: inline-block; padding: .38em .7em;
  font-size: var(--fs-2xs); font-weight: 700; letter-spacing: .06em; text-transform: uppercase;
  border: 1px solid var(--rule-hard); text-decoration: none; color: var(--ink-soft);
  transition: background var(--step-fast) linear, color var(--step-fast) linear, border-color var(--step-fast) linear;
}
.chip:hover { border-color: var(--ink); color: var(--ink); }
.chip[aria-pressed="true"], .chip.is-on {
  background: var(--ink); border-color: var(--ink); color: var(--paper);
}

/* ── Plates ───────────────────────────────────────────────────────────────────
   A newspaper prints photographs, so the world has always had room for them.
   What it does not have is a full-bleed hero under a gradient: a plate is a
   framed, captioned image sitting in the column, and the caption is a real
   credit because the licences require one. No page depends on a plate. */
.plate { aspect-ratio: 3 / 2; background: var(--paper-3); overflow: hidden; position: relative;
         border: 1px solid var(--rule); }
.plate img { width: 100%; height: 100%; object-fit: cover; display: block; }
.plate--tall { aspect-ratio: 4 / 5; }
.plate--wide { aspect-ratio: 21 / 9; }
.plate--empty::after {
  content: "No photograph yet";
  position: absolute; inset: 0; display: grid; place-items: center;
  font-size: var(--fs-2xs); letter-spacing: .12em; text-transform: uppercase; color: var(--ink-faint);
}
/* The credit rail. Small, factual, under the plate, never floating on it. */
.plate-credit {
  display: flex; flex-wrap: wrap; gap: .2rem .6rem; justify-content: space-between;
  padding-top: .35rem; font-size: var(--fs-2xs); color: var(--ink-faint);
}
.plate-credit a { color: inherit; }
.figure { margin: 0; }

/* Row thumbnail: a contact print at the head of the line. Hidden under 560px,
   where the row is already three stacked areas and a photo would crowd it. */
.row__plate { display: none; }
@media (min-width: 560px) {
  .row--plated { grid-template-columns: 4.6rem 3.6rem 1fr; grid-template-areas: "plate stub body" "plate stub rail" "plate stub act"; }
  .row__plate {
    grid-area: plate; display: block; width: 4.6rem; aspect-ratio: 1;
    overflow: hidden; background: var(--paper-3); border: 1px solid var(--rule);
  }
  .row__plate img { width: 100%; height: 100%; object-fit: cover; display: block; }
}
@media (min-width: 760px) {
  .row--plated { grid-template-columns: 5rem 5.5rem 1fr 9rem 8.5rem;
                 grid-template-areas: "plate stub body rail act"; }
  .row__plate { width: 5rem; }
}

/* ── Footer ──────────────────────────────────────────────────────────────── */
.foot { margin-top: auto; border-top: 2px solid var(--ink); background: var(--paper-2); }
.foot__cols { display: grid; gap: clamp(20px, 4vw, 36px); padding-block: clamp(30px, 5vw, 48px); }
@media (min-width: 700px) { .foot__cols { grid-template-columns: 1.4fr 1fr 1fr; } }
.foot ul { list-style: none; padding: 0; }
.foot li + li { margin-top: .4rem; }
.foot a { text-decoration: none; font-size: var(--fs-sm); color: var(--ink-soft); }
.foot a:hover { color: var(--ink); text-decoration: underline; }
.foot__base {
  border-top: 1px solid var(--rule); padding-block: 1rem;
  display: flex; flex-wrap: wrap; gap: .5rem 1.25rem; justify-content: space-between;
  font-size: var(--fs-xs); color: var(--ink-faint);
}

/* ══ Mobile app shell ══════════════════════════════════════════════════════
   Under 700px the scrolling masthead nav is replaced by a fixed bottom bar.
   Thumbs live at the bottom of a phone, and a horizontally-scrolling nav at the
   top is the thing that most reads as "website" rather than "app".
   Text labels rather than icons: this world is typographic and inventing an
   icon system for five destinations would be the wrong kind of effort. */
.tabbar { display: none; }

@media (max-width: 699px) {
  .mainnav { display: none; }

  .tabbar {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: 1fr;
    position: fixed;
    left: 0; right: 0; bottom: 0;
    z-index: 40;
    background: var(--paper);
    border-top: 2px solid var(--ink);
    padding-bottom: env(safe-area-inset-bottom, 0px);
  }
  .tabbar a {
    display: flex; flex-direction: column; align-items: center; justify-content: center;
    gap: .18rem;
    min-height: 3.25rem;                 /* comfortably past the 44px tap target */
    padding: .5rem .25rem;
    font-size: var(--fs-3xs);
    font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
    text-decoration: none; color: var(--ink-soft);
    border-top: 3px solid transparent;
    margin-top: -2px;                    /* sit the marker on the bar's own rule */
    transition: color var(--step-fast) linear, border-color var(--step-fast) linear;
  }
  .tabbar a:active { background: var(--paper-2); }
  .tabbar a[aria-current="page"] { color: var(--ink); border-top-color: var(--ink-1); }

  /* Clear the bar so the footer and any sticky action are never underneath it. */
  body { padding-bottom: calc(3.25rem + env(safe-area-inset-bottom, 0px)); }

  /* Standalone launches have no browser chrome, so the masthead carries the
     status-bar inset itself. */
  .masthead { padding-top: env(safe-area-inset-top, 0px); }
}

/* ── The More sheet ──────────────────────────────────────────────────────────
   A bottom sheet, because it opens from the bar it was tapped on and a thumb is
   already down there. Slides up from the bar rather than fading in from
   nowhere, so the origin of the panel is legible. */
.sheet[hidden] { display: none; }
.sheet {
  position: fixed; inset: 0; z-index: 60;
  display: flex; flex-direction: column; justify-content: flex-end;
}
.sheet__scrim {
  position: absolute; inset: 0;
  background: var(--scrim);
  animation: sheet-scrim 180ms var(--ease-out) both;
}
.sheet__panel {
  position: relative;
  background: var(--paper);
  border-top: 2px solid var(--ink);
  max-height: 82dvh; overflow-y: auto;
  padding: 1rem var(--gut) calc(1.25rem + env(safe-area-inset-bottom, 0px));
  animation: sheet-rise 240ms var(--ease-out) both;
}
@media (prefers-reduced-motion: reduce) {
  .sheet__scrim, .sheet__panel { animation: none; }
}
@keyframes sheet-rise  { from { transform: translateY(14%); } to { transform: none; } }
@keyframes sheet-scrim { from { opacity: 0; } to { opacity: 1; } }

.sheet__head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem; padding-bottom: .75rem; border-bottom: 2px solid var(--ink);
}
.sheet__group { padding-block: .9rem; border-bottom: 1px solid var(--rule); }
.sheet__group:last-child { border-bottom: 0; }
.sheet__group ul { list-style: none; padding: 0; margin-top: .35rem; }
.sheet__group a {
  display: block; padding: .62rem 0;
  font-family: var(--font-display); font-weight: 700;
  font-size: 1.05rem; letter-spacing: -.02em; text-decoration: none;
}
.sheet__group a:active { color: var(--ink-soft); }
.sheet__group a[aria-current="page"] { color: var(--ink); }
.sheet__group a[aria-current="page"]::after {
  content: ""; display: inline-block; width: .42em; height: .42em; margin-left: .5em;
  background: var(--ink-1); vertical-align: middle;
  clip-path: polygon(50% 0, 100% 50%, 50% 100%, 0 50%);
}
/* The sheet is a mobile affordance; above the tab bar's breakpoint it never opens. */
@media (min-width: 700px) { .sheet { display: none !important; } }

/* Running from the home screen: no browser UI, so the sheet fills the device. */
@media (display-mode: standalone) {
  .masthead__issue { display: none; }
}

.visually-hidden {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.skip {
  position: absolute; left: .5rem; top: -3rem; z-index: 50;
  background: var(--ink); color: var(--paper); padding: .6rem 1rem; text-decoration: none;
  transition: top var(--step) var(--ease-out);
}
.skip:focus { top: .5rem; }
