/* lapetitekozel — poster-brutalist gallery.
   Every value here traces to STYLE-DNA.md. Don't invent new colours or
   shadow offsets; add them to the DNA first. */

:root {
  --paper:      #F4EDE0;
  --card:       #FFFDF7;
  --ink:        #141210;
  --ink-soft:   #3A342C;
  --accent:     #C42B7A;
  --body:       #443E36;
  --muted:      #6B6257;
  --muted-2:    #8C8478;
  --panel-text: #F4EDE0;
  --panel-dim:  #CFC6B7;

  --kind-illustration: #F2B33D;
  --kind-craft:        #C4633A;
  --kind-digital:      #2B49C9;
  --kind-sculpture:    #6F7A3A;
  --kind-portrait:     #1F8A7A;
  --kind-mythic:       #6D4AA8;

  --display: Oswald, "Arial Narrow", sans-serif;
  --text:    "Golos Text", system-ui, sans-serif;
  --mono:    "JetBrains Mono", ui-monospace, monospace;

  --edge: 2px solid var(--ink);
  --max:  1480px;
  --gut:  36px;

  --min-col: 268px;   /* density: Comfortable */
}

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

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

body {
  margin: 0;
  min-height: 100vh;
  background: var(--paper);
  background-image: radial-gradient(var(--ink) 1px, transparent 1px);
  background-size: 22px 22px;
  background-position: 0 0;
  font-family: var(--text);
  color: var(--ink);
}

::selection { background: var(--accent); color: var(--paper); }

a { color: var(--accent); text-decoration: none; border-bottom: 2px solid var(--accent); }
a:hover { color: var(--ink); border-bottom-color: var(--ink); }

button { font: inherit; color: inherit; }

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

.sr-only {
  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: -9999px; top: 0; z-index: 100;
  background: var(--ink); color: var(--paper); border: 0;
  padding: 12px 18px; font-family: var(--mono); font-size: 12px;
}
.skip:focus { left: 8px; top: 8px; }

.mono {
  font-family: var(--mono);
  text-transform: uppercase;
}

.wrap { max-width: var(--max); margin: 0 auto; padding: 0 var(--gut); }
.wrap-b { padding-bottom: 90px; }

/* ── Header ───────────────────────────────────────────────────────────── */

.hdr {
  position: sticky; top: 0; z-index: 40;
  background: var(--paper);
  border-bottom: var(--edge);
}
.hdr-in {
  max-width: var(--max); margin: 0 auto;
  padding: 12px var(--gut);
  display: flex; align-items: center; justify-content: space-between; gap: 20px;
}
.brand { display: flex; align-items: center; gap: 12px; }

.mark { position: relative; width: 40px; height: 34px; display: block; flex: none; }
.mark-b {
  position: absolute; top: 5px; left: 9px; width: 30px; height: 29px;
  border: var(--edge); background: var(--accent); display: block; transform: rotate(6deg);
}
.mark-f {
  position: absolute; top: 0; left: 0; width: 30px; height: 29px;
  border: var(--edge); background: var(--ink);
  display: flex; align-items: center; justify-content: center; transform: rotate(-5deg);
}
.brand-name {
  font-family: var(--display); font-weight: 600; font-size: 19px;
  letter-spacing: .04em; text-transform: uppercase;
}

.hdr-right { display: flex; align-items: center; gap: 14px; }
.hdr-tag { font-size: 10px; letter-spacing: .18em; color: var(--muted); }

.lang { display: flex; border: var(--edge); }
.lang-btn {
  cursor: pointer; border: 0; padding: 7px 13px;
  font-family: var(--mono); font-size: 11px; letter-spacing: .1em;
  background: var(--paper); color: var(--ink);
}
.lang-btn + .lang-btn { border-left: var(--edge); }
.lang-btn[aria-pressed="true"] { background: var(--ink); color: var(--paper); }

/* Admin link — only ever visible to the signed-in owner (site.js). Styled as
   the language buttons' sibling rather than a call to action: it is a door
   back to work, not something to invite anyone through. */
.hdr-admin {
  border: var(--edge); padding: 7px 13px;
  font-size: 11px; letter-spacing: .1em; text-transform: uppercase;
  text-decoration: none; background: var(--paper); color: var(--ink);
}
.hdr-admin:hover { background: var(--ink); color: var(--paper); }

/* ── Masthead ─────────────────────────────────────────────────────────── */

.masthead { padding: 40px 0 24px; display: flex; flex-direction: column; gap: 38px; }
.letters-row { position: relative; padding-top: 16px; }
.letters { display: flex; gap: 9px; }
.letter {
  flex: 1; height: clamp(112px, 15.5vw, 208px);
  border: var(--edge); box-shadow: 7px 7px 0 var(--ink);
  display: flex; align-items: center; justify-content: center;
  font-family: var(--display); font-weight: 700;
  font-size: clamp(58px, 9.6vw, 138px); line-height: 1; text-transform: uppercase;
}
/* The RU masthead reads КО(Зь)Ё(Ль): a small soft sign tucked against the
   glyph, sized and placed off the glyph itself (em units) so it scales with
   the clamp. position:absolute keeps it out of layout — the main letters sit
   in exactly the same spot in both languages. */
.letter-ch { position: relative; }
.letter-soft {
  position: absolute;
  left: 100%; bottom: .04em;
  font-size: .34em; line-height: 1;
  text-transform: none;
}

.sticker-a {
  position: absolute; top: 0; left: 20px; transform: rotate(-3.5deg);
  background: var(--ink); color: var(--paper); border: var(--edge);
  padding: 8px 15px 7px;
  font-family: var(--display); font-weight: 600;
  font-size: clamp(15px, 2vw, 26px); letter-spacing: .1em; text-transform: uppercase;
}
.sticker-b {
  position: absolute; bottom: -13px; right: 22px; transform: rotate(2.5deg);
  background: var(--accent); color: var(--paper); border: var(--edge);
  padding: 6px 12px 5px;
  font-family: var(--mono); font-size: 11px; letter-spacing: .16em; text-transform: uppercase;
}

.counters {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 2fr);
  gap: 26px; align-items: center;
  border-top: var(--edge); padding-top: 30px;
}
.eyebrow {
  justify-self: start;
  background: var(--ink); color: var(--paper); border: var(--edge);
  box-shadow: 5px 5px 0 var(--accent);
  padding: 10px 15px 9px;
  font-family: var(--display); font-weight: 600;
  font-size: clamp(15px, 1.5vw, 21px); letter-spacing: .05em; text-transform: uppercase;
}
/* Capped rather than 1fr: stretched across the full column the boxes read as
   a banner, and three short values (6 / 0 / 1992) don't need that much room.
   justify-content keeps them anchored to the right edge. */
.counter-grid {
  display: grid; grid-template-columns: repeat(3, minmax(0, 180px));
  gap: 8px; justify-content: end;
}
.counter {
  border: var(--edge); background: var(--card); padding: 11px 13px;
  display: flex; flex-direction: column; gap: 4px;
}
.counter-label {
  font-family: var(--mono); font-size: 9.5px; letter-spacing: .14em;
  text-transform: uppercase; color: var(--muted);
}
.counter-value { font-family: var(--display); font-weight: 600; font-size: 26px; line-height: 1; }

/* ── Spotlight ────────────────────────────────────────────────────────── */

@keyframes pop { from { opacity: 0; transform: translateY(16px) scale(.985); } to { opacity: 1; transform: none; } }

.spot {
  /* Was 46px on top of the masthead's own 30px bottom padding, which pushed
     the pick of the day most of a screen down on shorter viewports. */
  margin: 22px 0 54px;
  border: var(--edge); background: var(--ink);
  box-shadow: 10px 10px 0 rgba(20, 18, 16, .22);
  display: grid; grid-template-columns: minmax(0, .95fr) minmax(0, 1.05fr);
  animation: pop .4s ease both;
}
.spot-plate {
  position: relative; aspect-ratio: 1 / 1;
  border-right: var(--edge); overflow: hidden;
  background: var(--kind-mythic);
}
.spot-plate img, .card-plate img {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; display: block;
}
.plate-no {
  position: absolute; top: 14px; left: 14px;
  font-size: 11px; letter-spacing: .1em;
  background: var(--ink); color: var(--paper);
  padding: 6px 9px; transform: rotate(-2deg);
}

.spot-body {
  padding: 30px 32px 28px;
  display: flex; flex-direction: column; gap: 20px; color: var(--panel-text);
}
.spot-head { display: flex; align-items: center; justify-content: space-between; gap: 14px; }
.spot-eyebrow { font-size: 10.5px; letter-spacing: .22em; color: var(--kind-illustration); }
.spot-rank {
  font-size: 9.5px; letter-spacing: .14em;
  border: 2px solid var(--paper); padding: 4px 9px;
}
.spot-title {
  margin: 0; font-family: var(--display); font-weight: 700;
  font-size: clamp(38px, 4.6vw, 68px); line-height: .9;
  text-transform: uppercase; letter-spacing: -.01em;
}
.spot-note {
  margin: 0; font-size: 16px; line-height: 1.55;
  color: var(--panel-dim); max-width: 780px; text-wrap: balance;
}
.spot-bars {
  flex: 1; display: flex; flex-direction: column;
  justify-content: space-evenly; gap: 14px;
  border-top: 2px solid var(--ink-soft); border-bottom: 2px solid var(--ink-soft);
  padding: 18px 0;
}
.spot-bar { display: flex; align-items: center; gap: 16px; }
.spot-bar-key {
  font-family: var(--display); font-weight: 600;
  font-size: clamp(14px, 1.4vw, 20px); letter-spacing: .1em;
  text-transform: uppercase; width: 132px; color: var(--panel-text);
}
.spot-bar-track {
  position: relative; flex: 1; height: clamp(20px, 2.4vw, 32px);
  border: 2px solid var(--paper); display: block;
}
.spot-bar-track .seg {
  background: repeating-linear-gradient(90deg, transparent 0 calc(10% - 2px), var(--paper) calc(10% - 2px) 10%);
}
.spot-bar-val {
  font-family: var(--display); font-weight: 700;
  font-size: clamp(20px, 2.2vw, 30px); line-height: 1; width: 52px; text-align: right;
}
.fill, .seg { position: absolute; inset: 0; display: block; }

.spot-actions { margin-top: auto; display: flex; gap: 10px; flex-wrap: wrap; }
.btn-shuffle, .btn-fav-spot {
  cursor: pointer; border: 2px solid var(--paper); color: var(--panel-text);
  padding: 12px 20px;
  font-family: var(--display); font-weight: 600; font-size: 14px;
  letter-spacing: .1em; text-transform: uppercase;
  /* Pinned rather than left at `normal`, which resolves from the FONT's own
     metrics — about 1.48 for Oswald but nearer 1.15 for the Arial Narrow
     fallback. That difference decides how much room the icon beside the label
     has, so leaving it to the font means the button changes height during a
     webfont swap. 1.5 gives a 21px line box either way, and the star below is
     sized to sit inside it. */
  line-height: 1.5;
  transition: transform .16s ease, background-color .16s ease;
}
.btn-shuffle { background: var(--accent); }
.btn-fav-spot { background: transparent; }
.btn-fav-spot[aria-pressed="true"] { background: var(--accent); }
.btn-shuffle:hover, .btn-fav-spot:hover { transform: translate(-2px, -2px); }

/* Icon + label, the same construction as the admin's .btn-ico: the icon is an
   element rather than a character, so flexbox centres it against the label's
   optical middle and there is no math axis to fight.

   justify-content is here for the same reason it is there — a <button> centres
   its text with text-align, which stops applying the moment the button becomes
   a flex container, and the pair would pack to flex-start. It costs nothing
   while the button is content-width and is correct the day it isn't. */
.btn-fav-spot {
  display: inline-flex; align-items: center; justify-content: center; gap: .55em;
}
/* 1.25em = 17.5px, against a label whose CAP HEIGHT is about 10.2px (Oswald's
   caps are ~0.73em). So the icon is roughly 1.7x the letters beside it, which
   sounds like a lot and is the point: the admin's plus and arrow are dense
   strokes spanning their whole viewBox and hold their own at 1.05x, while a
   star is mostly empty — a thin outline around a lot of nothing, with its
   points tapering to nearly zero ink at the corners of its box. Matching those
   icons by BOX made it match nothing by weight. It is still under the cards'
   19px, which is drawn with no label to balance against.

   The ceiling is the 21px line box pinned above: at 17.5px the star sits
   inside it, so the button's height is unchanged and it stays level with
   .btn-shuffle next to it. */
.btn-fav-spot .star {
  width: 1.25em; height: 1.25em; flex: none;
  /* Drawn once at a fixed size and never transformed — see .card-fav .star. */
  shape-rendering: geometricPrecision;
}
/* Outline when not favourited, filled when it is: the same grammar as the card
   stars, so the two controls mean the same thing by looking the same way. The
   button's own background flip to --accent already signals state; the fill is
   what makes the ICON legible on its own. */
.btn-fav-spot .star path {
  fill: currentColor;
  fill-opacity: 0;
  stroke: currentColor;
  transition: fill-opacity .24s cubic-bezier(.2, .7, .3, 1);
}
.btn-fav-spot[aria-pressed="true"] .star path { fill-opacity: 1; }
/* .btn-label deliberately carries NO line-height of its own. It inherits the
   button's 1.5, which is exactly what .btn-shuffle's bare text has — and the
   two sit side by side under `align-items: stretch`, so any difference here
   would show as one label riding higher than its neighbour. Centring the icon
   against that full line box is correct precisely because half-leading is
   split evenly above and below the text. */

/* ── Fact boxes ───────────────────────────────────────────────────────── */

.facts {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(258px, 1fr));
  gap: 14px; margin-bottom: 58px;
}
.fact {
  border: var(--edge); background: var(--card); padding: 20px 20px 22px;
  box-shadow: 5px 5px 0 var(--ink);
  display: flex; flex-direction: column; gap: 9px;
}
.fact-no { font-family: var(--display); font-weight: 700; font-size: 30px; line-height: 1; }
.fact-no-a { color: var(--accent); }
.fact-no-b { color: var(--kind-digital); }
.fact-title {
  font-family: var(--display); font-weight: 600; font-size: 17px;
  text-transform: uppercase; letter-spacing: .04em; text-wrap: balance;
}
.fact-body { margin: 0; font-size: 14px; line-height: 1.55; color: var(--body); text-wrap: balance; }
.fact-note {
  margin-top: auto; font-size: 9px; letter-spacing: .16em; color: var(--muted-2);
  border-top: var(--edge); padding-top: 9px;
}
.fact-fill { background: var(--kind-illustration); }
.fact-fill .fact-body { color: #3B3222; }
.fact-fill .fact-note { color: #6B5A2E; }

/* ── Herd controls ────────────────────────────────────────────────────── */

.herd-bar {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 20px; flex-wrap: wrap;
  border-top: var(--edge); padding: 22px 0 20px;
}
.herd-left { display: flex; flex-direction: column; gap: 14px; }
.herd-title {
  margin: 0; font-family: var(--display); font-weight: 700; font-size: 34px;
  text-transform: uppercase; letter-spacing: -.01em;
}
.herd-count { font-size: 13px; color: var(--muted); text-transform: none; }

.chips { display: flex; flex-wrap: wrap; gap: 6px; }
.chip {
  cursor: pointer; display: flex; align-items: center; gap: 7px;
  border: var(--edge); background: var(--card); color: var(--ink);
  padding: 8px 13px;
  font-family: var(--display); font-weight: 500; font-size: 13.5px;
  letter-spacing: .06em; text-transform: uppercase;
  transition: background-color .16s ease, color .16s ease;
}
.chip:hover { background: var(--ink); color: var(--paper); }
.chip[aria-pressed="true"] { background: var(--ink); color: var(--paper); }
.chip-count { font-family: var(--mono); font-size: 10px; opacity: .7; }

.herd-right { display: flex; gap: 8px; flex-wrap: wrap; }
.btn-ctl {
  cursor: pointer; border: var(--edge); background: var(--card); color: var(--ink);
  padding: 9px 15px;
  font-family: var(--mono); font-size: 10.5px; letter-spacing: .14em; text-transform: uppercase;
  box-shadow: 4px 4px 0 var(--ink);
  transition: box-shadow .16s ease, transform .16s ease;
}
.btn-ctl:hover { box-shadow: 0 0 0 var(--ink); transform: translate(4px, 4px); }

/* ── Grid ─────────────────────────────────────────────────────────────── */

.grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(var(--min-col), 1fr));
  gap: 20px;
}
body[data-density="Compact"]   { --min-col: 200px; }
body[data-density="Editorial"] { --min-col: 360px; }

.card {
  container-type: inline-size;
  cursor: pointer; text-align: left; padding: 0;
  background: var(--card); border: var(--edge); box-shadow: 6px 6px 0 var(--ink);
  display: flex; flex-direction: column;
  transition: transform .18s ease, box-shadow .18s ease;
  animation: pop .3s ease both;
}
.card:hover { transform: translate(-3px, -3px); box-shadow: 11px 11px 0 var(--ink); }

.card-plate {
  position: relative; aspect-ratio: 1 / 1;
  border-bottom: var(--edge); overflow: hidden;
}
.card-no {
  position: absolute; top: 10px; left: 10px;
  font-family: var(--mono); font-size: 10px; letter-spacing: .08em;
  background: var(--ink); color: var(--paper);
  padding: 5px 8px; transform: rotate(-2deg);
}
.card-fav {
  position: absolute; top: 10px; right: 10px; cursor: pointer;
  width: 34px; height: 34px; padding: 0;
  border: var(--edge); background: var(--card); color: var(--ink);
  display: flex; align-items: center; justify-content: center;
  box-shadow: 3px 3px 0 var(--ink);
  /* `color` belongs here too — the star inherits it via currentColor, so
     leaving it out made the icon snap while the background faded under it. */
  transition:
    transform .16s ease,
    box-shadow .16s ease,
    background-color .22s cubic-bezier(.2, .7, .3, 1),
    color .22s cubic-bezier(.2, .7, .3, 1);
}
.card-fav .star {
  width: 19px; height: 19px; display: block;
  /* The star is drawn once at this size and never transformed, so the
     renderer can keep a single clean rasterisation of it. */
  shape-rendering: geometricPrecision;
}
/* Unfavourited: outline only. Favourited: filled — the shapes differ, so the
   state doesn't depend on telling two colours apart.
   The fill is always currentColor and animates through fill-OPACITY, because
   `none` is not a colour and `fill: none → currentColor` cannot transition —
   the star used to pop in fully formed. */
.card-fav .star path {
  fill: currentColor;
  fill-opacity: 0;
  stroke: currentColor;
  transition: fill-opacity .24s cubic-bezier(.2, .7, .3, 1);
}
.card-fav[aria-pressed="true"] { background: var(--accent); color: var(--card); }
.card-fav[aria-pressed="true"] .star path { fill-opacity: 1; }
/* Presses into its shadow like every other button here.
   Translation ONLY — never scale. Scaling forces the SVG to re-rasterise at a
   fractional size on every frame of the transition, which shimmers; whole-pixel
   translation is composited and stays crisp. The press is expressed by the
   shadow collapsing and the fill deepening instead. */
.card-fav:hover { transform: translate(3px, 3px); box-shadow: 0 0 0 var(--ink); }
.card-fav:active {
  transform: translate(3px, 3px);
  background: var(--ink); color: var(--paper);
  transition-duration: .06s;   /* the press should feel instant, not eased */
}
.card-fav[aria-pressed="true"]:active { background: #9E1F60; }

/* The card is no longer a click target, so it shouldn't advertise itself as
   one — but it still lifts on hover, because the artwork is worth the motion. */
.card { cursor: default; }

.card-body { padding: 13px 14px 15px; display: flex; flex-direction: column; gap: 11px; }
.card-head { display: flex; flex-direction: column; gap: 3px; }
.card-title {
  margin: 0; font-family: var(--display); font-weight: 600;
  font-size: clamp(16px, var(--title-size, 20cqw), 22px);
  line-height: 1.08; text-transform: uppercase; letter-spacing: .01em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.card-meta {
  display: flex; flex-wrap: wrap; gap: 0 6px;
  font-family: var(--mono); font-size: 9.5px; letter-spacing: .12em;
  text-transform: uppercase; color: var(--muted);
}
.card-meta span { white-space: nowrap; }

.card-bars {
  display: flex; flex-direction: column; gap: 6px;
  border-top: var(--edge); padding-top: 10px;
}
.card-bar { display: flex; align-items: center; gap: 9px; }
.card-bar-key {
  font-family: var(--mono); font-size: 8.5px; letter-spacing: .12em;
  text-transform: uppercase; width: 62px; color: var(--muted);
}
.card-bar-track { position: relative; flex: 1; height: 9px; border: 1.5px solid var(--ink); display: block; }
.card-bar-track .seg {
  background: repeating-linear-gradient(90deg, transparent 0 calc(10% - 1.5px), var(--card) calc(10% - 1.5px) 10%);
}

.empty {
  font-family: var(--mono); font-size: 12px; letter-spacing: .14em;
  text-transform: uppercase; color: var(--muted);
  border: var(--edge); background: var(--card); padding: 28px; text-align: center;
}

/* ── Footer ───────────────────────────────────────────────────────────── */

.ftr { border-top: var(--edge); background: var(--ink); color: var(--panel-text); }
.ftr-in {
  max-width: var(--max); margin: 0 auto; padding: 44px var(--gut) 30px;
  display: grid; grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr);
  gap: 34px; align-items: center;
}
.ftr-left { display: flex; flex-direction: column; gap: 14px; }
.ftr-name {
  font-family: var(--display); font-weight: 700;
  font-size: clamp(30px, 4.4vw, 62px); line-height: .9;
  letter-spacing: -.01em; text-transform: uppercase;
}
.dot-com { color: var(--accent); }
.ftr-sub { font-size: 10px; letter-spacing: .16em; color: #9C9384; }

.ftr-right { justify-self: end; display: flex; align-items: center; gap: 12px; }
.bleat-word {
  font-family: var(--display); font-weight: 700;
  font-size: clamp(22px, 2.6vw, 38px); line-height: 1;
  text-transform: uppercase; color: var(--accent);
  /* Sized to the widest bleat so all six occupy an identical box — the word
     changes, nothing around it moves. Dropped to 0 on mobile, where it's
     left-aligned and the reservation would just be a gap. */
  min-width: 134px; text-align: right;
}
.btn-bleat {
  cursor: pointer; border: 2px solid var(--paper); background: transparent; color: var(--panel-text);
  padding: 13px 18px;
  font-family: var(--display); font-weight: 600; font-size: 14px;
  letter-spacing: .1em; text-transform: uppercase;
  transition: background-color .16s ease, border-color .16s ease, transform .16s ease;
}
.btn-bleat:hover { background: var(--accent); border-color: var(--accent); transform: translate(-2px, -2px); }

.ftr-rule { border-top: 2px solid var(--ink-soft); }
.ftr-in-b {
  max-width: var(--max); margin: 0 auto; padding: 14px var(--gut);
  display: flex; align-items: center; justify-content: space-between;
  gap: 20px; flex-wrap: wrap;
}
.small-print {
  font-size: 9.5px; letter-spacing: .16em; color: #6F675C;
  display: flex; flex-wrap: wrap; align-items: center; gap: 0 8px;
}
.small-print .sep { opacity: .6; }
/* Sized in em so it tracks the mono text it sits in; the baseline nudge is
   what makes it sit ON the line rather than float above it. */
.small-print .inf {
  width: 1.5em; height: .75em;
  vertical-align: -.08em;
  margin-left: .15em;
}
.btn-top {
  cursor: pointer; border: 2px solid #6F675C; background: transparent; color: var(--panel-text);
  padding: 7px 13px;
  font-family: var(--mono); font-size: 10px; letter-spacing: .16em; text-transform: uppercase;
  transition: border-color .16s ease;
}
.btn-top:hover { border-color: var(--paper); }

.nojs {
  max-width: var(--max); margin: 0 auto; padding: 24px var(--gut);
  border: var(--edge); background: var(--card);
  font-size: 14px; line-height: 1.55; color: var(--body);
}

/* ── Narrower viewports ───────────────────────────────────────────────── */

@media (max-width: 1080px) {
  .spot { grid-template-columns: minmax(0, 1fr); }
  .spot-plate { border-right: 0; border-bottom: var(--edge); }
  .spot-bar-key { width: 100px; }
}

@media (max-width: 860px) {
  :root { --gut: 20px; }
  .counters { grid-template-columns: minmax(0, 1fr); gap: 16px; }
  /* Stay 3-across: with three boxes a 2-column rule strands the last one on
     its own row, and these values (6 / 0 / 1992) are narrow enough to fit. */
  .counter-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 6px; }
  .counter { padding: 9px 10px; }
  .counter-value { font-size: 22px; }
  .ftr-in { grid-template-columns: minmax(0, 1fr); }
  .ftr-right { justify-self: start; }
  .hdr-tag { display: none; }
  .masthead { padding: 24px 0 18px; }
  .letters { gap: 5px; }
  .letter { box-shadow: 4px 4px 0 var(--ink); }
  .spot-body { padding: 22px 20px 20px; }
  .grid { gap: 14px; }
}

@media (max-width: 700px) {
  /* One clause per line reads better than a four-way wrap at this width, and
     the separators are what a line break already communicates. */
  .small-print { flex-direction: column; align-items: flex-start; gap: 7px; }
  .small-print .sep { display: none; }

  .ftr-in { padding: 34px var(--gut) 28px; gap: 24px; }
  /* min-width reserves room for the longest bleat on desktop, where the word
     sits right-aligned against the button. Stacked and left-aligned, that
     reservation is just a hole between the two. */
  .bleat-word { min-width: 0; text-align: left; }
  .ftr-right { gap: 16px; align-items: center; }

  .ftr-in-b { flex-direction: column; align-items: stretch; gap: 18px; padding: 18px var(--gut) 24px; }
  .btn-top { align-self: flex-start; padding: 9px 15px; }
}

@media (max-width: 560px) {
  .herd-bar { align-items: flex-start; }
  .spot-bar-key { width: 84px; font-size: 13px; }
  .bleat-word { min-width: 92px; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }
}
