/* ==========================================================================
   Design tokens
   ========================================================================== */
:root {
  --paper:      #FAFAF8;
  --paper-raised: #F2F0E8;
  --ink:        #1F241F;
  --ink-soft:   #565A50;
  --line:       #E2DFD3;
  --pine:       #33604D;
  --pine-soft:  #E9EFE9;
  --gold:       #A97C22;
  --gold-soft:  #F5EDDC;
  --rose:       #A15E52;
  --rose-soft:  #F3E9E5;

  /* Heat-map ramp — cold blue to hot red, six steps, at Paul's request
     (17 Aug 2026 build shipped a single-hue rose ramp; this replaces it).

     Two hues means lightness has to carry the ordering on its own, so it does:
     every step is darker than the one before it, monotonically, and greyscaled
     the ramp still reads in the right order. Measured, not eyeballed —
     verify/heat_palette.js re-checks all three properties against the real
     surface and fails the build if a step is edited out of line:

       step  contrast vs --paper-raised   OKLab dE to previous step
         0   2.02:1                       —      (no sightings)
         1   2.79:1                       11.2
         2   3.60:1                       10.2
         3   4.78:1                       13.6
         4   6.20:1                       13.7
         5   8.75:1                        9.5   (hottest)

     Step 0 is the floor: below about 2:1 a blob dissolves into the paper, which
     is how an earlier ramp starting at #F0DCD7 (1.16:1) failed. Don't lighten
     it. Colour is never the only encoding here anyway — zero-sighting spots are
     drawn as hollow rings, and every map is followed by a ranked list and a
     table of the raw counts. */
  --heat-0: #65B3E4;
  --heat-1: #5F8DF3;
  --heat-2: #8B69D8;
  --heat-3: #AC3D94;
  --heat-4: #AD1936;
  --heat-5: #890900;

  --display: "Fraunces", "Iowan Old Style", Georgia, serif;
  --body:    "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --mono:    "IBM Plex Mono", "SFMono-Regular", Consolas, monospace;

  --max: 46rem;
  --max-wide: 64rem;
}

@media (prefers-reduced-motion: reduce) {
  * { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
  /* Not covered by the rule above — scroll-behavior is neither an animation
     nor a transition, but smooth scrolling is exactly what this preference
     is asking us to stop. cats.js scrolls the answer panel into view. */
  html { scroll-behavior: auto !important; }
}

* { box-sizing: border-box; }
html { scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--body);
  font-size: 17px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

img, svg { max-width: 100%; display: block; }

a {
  color: var(--pine);
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}
a:hover { color: var(--ink); }

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

h1, h2, h3 {
  font-family: var(--display);
  font-weight: 600;
  line-height: 1.15;
  margin: 0 0 0.5em;
  letter-spacing: -0.01em;
}

.eyebrow {
  font-family: var(--mono);
  font-size: 0.72rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-soft);
  display: block;
  margin-bottom: 0.6em;
}

p { margin: 0 0 1em; color: var(--ink-soft); }

/* ==========================================================================
   Layout shell
   ========================================================================== */
.wrap { max-width: var(--max); margin: 0 auto; padding: 0 1.5rem; }
.wrap-wide { max-width: var(--max-wide); margin: 0 auto; padding: 0 1.5rem; }

header.site {
  border-bottom: 1px solid var(--line);
  background: var(--paper);
}

.site-bar {
  max-width: var(--max-wide);
  margin: 0 auto;
  padding: 1.15rem 1.5rem;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 0.75rem 1.5rem;
}

.wordmark {
  font-family: var(--display);
  font-style: italic;
  font-weight: 600;
  font-size: 1.25rem;
  color: var(--ink);
  text-decoration: none;
}

nav.site-nav {
  display: flex;
  gap: 1.5rem;
  font-family: var(--mono);
  font-size: 0.8rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

nav.site-nav a {
  color: var(--ink-soft);
  text-decoration: none;
  padding-bottom: 2px;
  border-bottom: 2px solid transparent;
}

nav.site-nav a:hover,
nav.site-nav a[aria-current="page"] {
  color: var(--ink);
  border-bottom-color: var(--pine);
}

main { padding: 3.5rem 0 5rem; }

.page-head { max-width: var(--max); margin: 0 auto 2.75rem; padding: 0 1.5rem; }
.page-head p { font-size: 1.05rem; }

footer.site {
  border-top: 1px solid var(--line);
  padding: 2rem 1.5rem;
  text-align: center;
  font-family: var(--mono);
  font-size: 0.75rem;
  color: var(--ink-soft);
}

/* ==========================================================================
   Home
   ========================================================================== */
.hero {
  max-width: var(--max);
  margin: 0 auto;
  padding: 2rem 1.5rem 3.5rem;
}
.hero h1 { font-size: clamp(2.1rem, 5vw, 3rem); max-width: 16ch; }
.hero .lede { font-size: 1.15rem; max-width: 42ch; }

.index-list { list-style: none; margin: 3rem 0 0; padding: 0; }
.index-list li { border-top: 1px solid var(--line); }
.index-list li:last-child { border-bottom: 1px solid var(--line); }

.index-item {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1.5rem;
  padding: 1.5rem 0;
  text-decoration: none;
  color: var(--ink);
}
.index-item:hover .index-title { color: var(--pine); }
.index-item:hover { color: var(--ink); }

.index-num {
  font-family: var(--mono);
  font-size: 0.8rem;
  color: var(--ink-soft);
  width: 2.5rem;
  flex-shrink: 0;
}
.index-title {
  font-family: var(--display);
  font-size: 1.5rem;
  flex-grow: 1;
}
.index-desc {
  font-size: 0.92rem;
  color: var(--ink-soft);
  text-align: right;
  max-width: 24ch;
}

/* ==========================================================================
   Letters (accordion)
   ========================================================================== */
.letters-list { max-width: var(--max); margin: 0 auto; padding: 0 1.5rem; }

details.letter {
  border-top: 1px solid var(--line);
}
details.letter:last-child { border-bottom: 1px solid var(--line); }

details.letter summary {
  list-style: none;
  cursor: pointer;
  padding: 1.4rem 0;
  display: flex;
  align-items: center;
  gap: 1rem;
  font-family: var(--display);
  font-size: 1.4rem;
}
details.letter summary::-webkit-details-marker { display: none; }

.letter-toggle {
  font-family: var(--mono);
  font-size: 1rem;
  color: var(--pine);
  border: 1px solid var(--line);
  border-radius: 50%;
  width: 1.6rem;
  height: 1.6rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  transition: transform 0.2s ease;
}
details.letter[open] .letter-toggle { transform: rotate(45deg); }

.letter-body {
  padding: 0 0 1.75rem 2.6rem;
  max-width: 34rem;
}
.letter-body p { color: var(--ink); }

/* ==========================================================================
   Games
   ========================================================================== */
.games-grid {
  max-width: var(--max-wide);
  /* The side gutter has to sit OUTSIDE the border, not as padding: this
     element's background IS the hairline between cards, so padding paints a
     thick beige bar down each edge. width caps at 100% - gutter on narrow
     screens; max-width takes over once there's room. */
  width: calc(100% - 3rem);
  margin: 0 auto;
  display: grid;
  /* auto-FIT, not auto-fill. The grid paints --line behind a 1px gap, so an
     empty track isn't invisible here — it renders as a solid beige block
     beside the real cards. auto-fit collapses it; the cards share the width. */
  grid-template-columns: repeat(auto-fit, minmax(15.5rem, 1fr));
  gap: 1px;
  background: var(--line);
  border: 1px solid var(--line);
}

.game-card {
  background: var(--paper);
  padding: 1.75rem;
  display: flex;
  flex-direction: column;
  gap: 0.9rem;
}

.game-tag {
  font-family: var(--mono);
  font-size: 0.68rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--gold);
  background: var(--gold-soft);
  align-self: flex-start;
  padding: 0.25rem 0.55rem;
  border-radius: 2px;
}

.game-card h3 { font-size: 1.3rem; margin: 0; }
.game-card p { font-size: 0.92rem; margin: 0; flex-grow: 1; }

.game-link {
  font-family: var(--mono);
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  text-decoration: none;
  color: var(--ink);
  border-top: 1px solid var(--line);
  padding-top: 0.9rem;
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.game-link:hover { color: var(--pine); }

/* ==========================================================================
   Cats page
   ========================================================================== */
.cats-layout {
  max-width: var(--max-wide);
  margin: 0 auto;
  padding: 0 1.5rem;
  display: grid;
  grid-template-columns: 1.1fr 0.9fr;
  gap: 3rem;
  align-items: start;
}
@media (max-width: 860px) {
  .cats-layout { grid-template-columns: 1fr; }
}

/* The heat view takes the whole page, the prediction view doesn't.
   Two maps side by side is the entire point of giving them a shared colour
   scale — a shade has to mean the same thing in both, and that's only worth
   anything if you can see both at once. The map column is ~27rem, which fits
   one map; forcing two into it puts each at ~172px, where a 6.9-unit furniture
   label renders at about 4px. So the layout drops to one column while the heat
   map is open and the panel takes the full 64rem, giving ~456px per map —
   larger than the prediction map, not smaller.

   The question panel keeps its reading measure instead of stretching to 64rem;
   long lines of prose and a 60rem-wide probability bar are both worse.

   Only above the breakpoint: below it the layout is already one column, and
   .heat-grid's auto-fit puts the maps side by side on its own wherever there's
   room for two 18rem tracks (down to ~620px) and stacks them below that. */
@media (min-width: 861px) {
  .cats-layout.map-wide { grid-template-columns: 1fr; }
  .cats-layout.map-wide > section:first-child { max-width: var(--max); }
}

.panel-label {
  font-family: var(--mono);
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--ink-soft);
  margin-bottom: 0.9rem;
  display: block;
}

/* The map panel's header row: the label and the view switch on one line, so
   the switch reads as a property of the map below it rather than as a second
   navigation. It wraps to two lines rather than shrinking the buttons. */
.map-switch {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem 1rem;
  margin-bottom: 0.9rem;
}
.map-switch .panel-label { margin-bottom: 0; }

/* Only one view is in the document flow at a time. Both are built on load and
   kept in the DOM, so switching is instant and the heat map never redraws for
   a reason the reader didn't ask for. */
.map-view[hidden] { display: none; }

/* Floor plan */
.floorplan-frame {
  border: 1px solid var(--line);
  background: var(--paper-raised);
  padding: 1.25rem;
}
.room-rect {
  fill: none;
  stroke: var(--ink);
  stroke-opacity: 0.35;
  stroke-width: 1.25;
}
/* Circulation space, drawn but deliberately quiet — no cat is ever logged
   there, so it shouldn't read as loudly as the four real rooms. */
.hallway { stroke-opacity: 0.18; }

.room-label {
  font-family: var(--mono);
  font-size: 9px;
  letter-spacing: 0.05em;
  fill: var(--ink-soft);
  text-transform: uppercase;
}

/* Furniture: fainter than the walls, so the room shapes still read first. */
.furn {
  fill: var(--ink);
  fill-opacity: 0.035;
  stroke: var(--ink);
  stroke-opacity: 0.2;
  stroke-width: 1;
}
.furn-label {
  font-family: var(--mono);
  font-size: 5.5px;
  letter-spacing: 0.04em;
  fill: var(--ink-soft);
  fill-opacity: 0.85;
  text-anchor: middle;
  text-transform: uppercase;
}
.cat-dot {
  transition: transform 2.2s cubic-bezier(0.65, 0, 0.35, 1);
}
.cat-dot circle {
  fill: var(--rose);
  /* The dot now sits on top of furniture rects, so a paper-coloured ring
     keeps its edge legible against a filled shape. */
  stroke: var(--paper);
  stroke-width: 1.5;
}
.cat-dot text {
  font-family: var(--mono);
  font-size: 8px;
  fill: var(--paper);
  text-anchor: middle;
  dominant-baseline: central;
  font-weight: 600;
}

.cat-status {
  margin-top: 1rem;
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}
.status-line {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  font-family: var(--mono);
  font-size: 0.78rem;
  color: var(--ink-soft);
}
.status-line strong { color: var(--rose); font-weight: 600; }
.status-room { color: var(--ink); }
.status-tag { font-style: italic; opacity: 0.75; }
.status-pct { margin-left: auto; }

/* Ask panel */
.chip-row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-bottom: 1rem;
}
.chip-row button {
  font-family: var(--mono);
  font-size: 0.72rem;
  background: none;
  border: 1px solid var(--line);
  color: var(--ink-soft);
  padding: 0.4rem 0.7rem;
  cursor: pointer;
  border-radius: 2px;
  text-align: left;
}
.chip-row button:hover { border-color: var(--rose); color: var(--rose); }

.ask-form {
  display: flex;
  border: 1px solid var(--line);
}
.ask-form input {
  flex-grow: 1;
  min-width: 0;
  border: none;
  background: transparent;
  padding: 0.9rem 1.1rem;
  font-family: var(--body);
  font-size: 0.95rem;
  color: var(--ink);
}
.ask-form input:focus { outline: none; }
.ask-form button {
  border: none;
  border-left: 1px solid var(--line);
  background: var(--rose-soft);
  color: var(--rose);
  font-family: var(--mono);
  font-size: 0.78rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  padding: 0 1.4rem;
  cursor: pointer;
}
.ask-form button:hover { background: var(--rose); color: var(--paper); }

.answer-panel {
  margin-top: 1.5rem;
  border-top: 1px solid var(--line);
  padding-top: 1.25rem;
}
.answer-heading {
  font-family: var(--mono);
  font-size: 0.72rem;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink-soft);
  margin: 0 0 1rem;
}
.answer-block { margin-bottom: 1.5rem; }
.answer-block:last-of-type { margin-bottom: 0; }
.answer-lead {
  margin: 0 0 0.8rem;
  font-size: 1rem;
  color: var(--ink);
}
.answer-note {
  margin: 1.25rem 0 0;
  font-size: 0.82rem;
  line-height: 1.55;
  color: var(--ink-soft);
  border-left: 2px solid var(--line);
  padding-left: 0.85rem;
}

/* One prediction: label, optional specific spot, bar, percentage */
.pred-row {
  display: grid;
  grid-template-columns: 7.5rem 1fr 4.5rem 2.5rem;
  align-items: center;
  gap: 0.6rem;
  padding: 0.3rem 0;
  font-family: var(--mono);
  font-size: 0.75rem;
}
.pred-name { color: var(--ink); }
.pred-tag {
  color: var(--ink-soft);
  font-style: italic;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.pred-pct { text-align: right; color: var(--ink-soft); }
.prob-bar {
  height: 6px;
  background: var(--paper-raised);
  border: 1px solid var(--line);
}
.prob-bar span {
  display: block;
  height: 100%;
  background: var(--rose);
  opacity: 0.75;
}

@media (max-width: 520px) {
  .pred-row { grid-template-columns: 6rem 1fr 2.5rem; }
  .pred-tag { display: none; }
}

/* Methodology disclosure */
.method {
  margin-top: 1.5rem;
  border-top: 1px solid var(--line);
  padding-top: 1rem;
}
.method summary {
  font-family: var(--mono);
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink-soft);
  cursor: pointer;
}
.method p {
  font-size: 0.85rem;
  line-height: 1.6;
  color: var(--ink-soft);
  margin: 0.9rem 0 0;
}
.data-meta { font-family: var(--mono); font-size: 0.72rem; }

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

/* ==========================================================================
   Cats page — sightings heat map
   ==========================================================================
   A second, deliberately different view of the same house, sharing the map
   panel with the prediction and reached by the switch above it. The other view
   is the *model*: where a cat probably is right now. This is the *data*: every
   sighting ever logged, dropped onto the same floor plan. They are allowed to
   disagree — the model discounts anything older than a few half-lives, the raw
   counts do not — and offering both is the honest version.

   Because the two views share one slot, this section is laid out for the
   column it sits in and carries no width, margin or rule of its own: the panel
   owns those, so the page doesn't shift when the switch is pressed.

   The two maps are small multiples, one per cat, on one shared scale. That is
   the whole reason this isn't a per-cat colour: comparing Bean to Toffee means
   comparing like with like, so colour has to mean "how often" in both maps and
   nothing else. Identity is carried by the caption, never by hue. */
.heat-section { margin: 0; }
/* Prose keeps its reading measure when the panel goes full width. The maps
   want all 64rem; a 0.85rem paragraph across 64rem is ~120 characters a line.
   Below the breakpoint the column is narrower than --max, so this does
   nothing there. */
.heat-head, #heatNote {
  font-size: 0.85rem;
  line-height: 1.6;
  color: var(--ink-soft);
  max-width: var(--max);
}
.heat-head p { margin: 0; }

/* Controls sit in one row above both maps, so it reads as one filter applied
   to the pair rather than two independent widgets. */
.heat-controls {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem 1.5rem;
  margin: 1.25rem 0;
}
.heat-control {
  display: flex;
  align-items: center;
  gap: 0.6rem;
}
.heat-control > span {
  font-family: var(--mono);
  font-size: 0.68rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--ink-soft);
}
.heat-seg { display: flex; border: 1px solid var(--line); }
.heat-seg button {
  font-family: var(--mono);
  font-size: 0.72rem;
  background: none;
  border: none;
  border-left: 1px solid var(--line);
  color: var(--ink-soft);
  padding: 0.5rem 0.85rem;
  cursor: pointer;
}
.heat-seg button:first-child { border-left: none; }
.heat-seg button:hover { color: var(--rose); }
.heat-seg button[aria-pressed="true"] {
  background: var(--rose-soft);
  color: var(--rose);
}

.heat-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(18rem, 1fr));
  gap: 2rem;
}
.heat-card { margin: 0; }
.heat-caption {
  display: flex;
  align-items: baseline;
  gap: 0.6rem;
  font-family: var(--mono);
  font-size: 0.78rem;
  margin-bottom: 0.7rem;
}
.heat-caption strong { color: var(--rose); font-weight: 600; }
.heat-caption span { color: var(--ink-soft); font-size: 0.72rem; }

.heat-frame {
  position: relative;
  border: 1px solid var(--line);
  background: var(--paper-raised);
  padding: 1.25rem;
}
.heat-plan { display: block; width: 100%; height: auto; }

/* The blobs are drawn over the room and furniture outlines but under the
   labels, which are then re-stacked on top with a paper outline behind the
   glyphs. Without that halo, --ink-soft over the darkest step measures 1.09:1
   and the bed and the couch stop being readable exactly where the map is
   busiest. */
.heat-plan .room-label,
.heat-plan .furn-label {
  paint-order: stroke;
  stroke: var(--paper-raised);
  stroke-width: 2px;
  stroke-linejoin: round;
  stroke-opacity: 0.85;
}
.heat-blob { transition: opacity 0.35s ease; }
/* "Logged here, but never by this cat in this period." Deliberately quiet — a
   thin ring, no fill — so the absences annotate the map without competing with
   the places she actually sleeps. */
.heat-blob-zero { stroke-width: 1.5px; stroke-opacity: 0.85; }
.heat-hit { fill: transparent; cursor: default; }
.heat-hit:focus { outline: none; }
.heat-hit:focus-visible { outline: 2px solid var(--pine); }

/* Tooltip. Positioned as a percentage of the frame, which works because the
   SVG scales to the frame width and keeps its aspect ratio. */
.heat-tip {
  position: absolute;
  transform: translate(-50%, -115%);
  background: var(--ink);
  color: var(--paper);
  font-family: var(--mono);
  font-size: 0.68rem;
  line-height: 1.5;
  padding: 0.45rem 0.6rem;
  border-radius: 2px;
  pointer-events: none;
  white-space: nowrap;
  z-index: 2;
}
.heat-tip[hidden] { display: none; }
.heat-tip b { font-weight: 500; display: block; }
.heat-tip span { opacity: 0.75; }

/* Top spots, listed rather than labelled on the map: the furniture labels
   already own the middle of every rect, so a percentage drawn there would
   land on top of one. */
.heat-rank {
  margin-top: 0.9rem;
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
}
.heat-rank-row {
  display: grid;
  grid-template-columns: 0.7rem 1fr 2.6rem;
  align-items: center;
  gap: 0.6rem;
  font-family: var(--mono);
  font-size: 0.72rem;
  color: var(--ink-soft);
}
.heat-swatch { width: 0.7rem; height: 0.7rem; border-radius: 1px; }
.heat-rank-name {
  color: var(--ink);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.heat-rank-pct { text-align: right; }

.heat-legend {
  display: flex;
  align-items: flex-end;
  gap: 0.75rem;
  flex-wrap: wrap;
  margin-top: 1.75rem;
  font-family: var(--mono);
  font-size: 0.68rem;
  color: var(--ink-soft);
}
.heat-scale { display: flex; gap: 2px; }
.heat-scale-step { width: 2.6rem; }
.heat-scale-step i { display: block; height: 0.55rem; }
/* The cold end is a ring, matching how a never-seen-here spot is drawn on the
   map, and is separated by a gap so it reads as "off the scale" rather than as
   the first bin. */
.heat-scale-zero { margin-right: 0.5rem; }
.heat-scale-zero i {
  background: none;
  border: 1.5px solid var(--heat-0);
  height: 0.55rem;
  box-sizing: border-box;
}
.heat-scale-zero em { text-align: left; }
.heat-scale-step em {
  display: block;
  font-style: normal;
  text-align: right;
  margin-top: 0.3rem;
  font-size: 0.62rem;
}
.heat-legend-note { max-width: 22rem; line-height: 1.5; }

.heat-table { width: 100%; border-collapse: collapse; margin-top: 0.9rem; }
.heat-table th,
.heat-table td {
  font-family: var(--mono);
  font-size: 0.72rem;
  text-align: right;
  padding: 0.3rem 0.5rem;
  border-bottom: 1px solid var(--line);
  color: var(--ink-soft);
}
.heat-table th { color: var(--ink); font-weight: 500; }
/* Room and spot are words, the rest are numbers. */
.heat-table th:first-child,
.heat-table td:first-child,
.heat-table th:nth-child(2),
.heat-table td:nth-child(2) { text-align: left; }
.heat-table td.heat-room { color: var(--ink); }
.heat-table-wrap { overflow-x: auto; }

/* ==========================================================================
   Content slots — the "put your text here" markers
   ==========================================================================
   These only appear while <body> carries class="drafting". Delete that one
   word from letters.html and games.html and every marker on the site
   disappears at once, without having to hunt down and remove each block.
   Hidden is the DEFAULT, so forgetting to tidy up can't leak editing notes
   onto the live site — the class has to be present for them to show. */
.slot { display: none; }

.drafting .slot {
  display: block;
  border: 1px dashed var(--rose);
  background: var(--rose-soft);
  padding: 0.85rem 1.05rem;
  margin: 0 0 1.25rem;
  font-family: var(--mono);
  font-size: 0.74rem;
  line-height: 1.65;
  color: var(--rose);
}
.slot b {
  display: block;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  font-size: 0.68rem;
  opacity: 0.75;
  margin-bottom: 0.35rem;
}
.slot code {
  background: rgba(31, 36, 31, 0.06);
  padding: 0.05em 0.3em;
  border-radius: 2px;
}
.slot p { margin: 0; color: inherit; font-size: inherit; line-height: inherit; }
.slot p + p { margin-top: 0.5rem; }

/* Games cards are a flex column with the link pinned to the bottom, so the
   slot needs to sit above it rather than stretch. */
.game-card .slot { margin-bottom: 0; }

/* ==========================================================================
   Mobile
   ==========================================================================
   Four specific problems, not general polish:
   1. An input under 16px makes iOS Safari zoom the page on focus and never
      zoom back out. 16px exactly is the threshold.
   2. Nav links and chips were ~15px and ~24px tall — well under a fingertip.
   3. Furniture labels are 5.5px in a 300-unit viewBox, and at phone width the
      SVG used to render near 1:1, so they turned to fuzz. They were hidden
      outright; that was the wrong fix, because an unlabelled bed and an
      unlabelled couch cushion are just grey boxes. See the 520px block.
   4. Long room names in the answer rows need the extra width back. */
@media (max-width: 620px) {
  .ask-form input { font-size: 16px; }

  /* Nav words like "Home" are only ~34px wide — that's the word, not a
     mistake. WCAG 2.5.8 is satisfied by the 40px height plus the gap, which
     keeps a 24px circle on one link clear of its neighbours. */
  nav.site-nav { gap: 1.25rem; }
  nav.site-nav a { padding: 0.55rem 0; }

  .chip-row button { padding: 0.85rem 0.85rem; font-size: 0.74rem; }
  .ask-form button { padding: 0 1.1rem; }

  /* The only real call to action on the games page — worth a full thumb. */
  .game-link { padding: 1.1rem 0 0.5rem; }

  /* Same WCAG 2.5.8 reasoning as the chips above — these were ~28px tall. */
  .heat-seg button { padding: 0.85rem 0.9rem; }

  main { padding: 2.5rem 0 3.5rem; }
}

@media (max-width: 520px) {
  /* The furniture labels used to be display:none here. The real problem was
     never the type size — it was that 88px of a 390px phone went to padding
     (1.5rem a side on .cats-layout, 1.25rem a side on the frame), leaving the
     SVG at exactly 300px against a 300-unit viewBox. Reclaiming most of that
     takes it to 337px, and with the bump below the labels land at an effective
     7.3px, i.e. bigger than they render on desktop.

     6.5px is a measured ceiling, not a taste call: at 7px "Climb Wall" is 45.3
     units wide inside a 46-unit rect and spills. Re-measure before raising it. */
  .cats-layout { padding: 0 1rem; }
  .floorplan-frame { padding: 0.6rem; }
  .furn-label { font-size: 6.5px; }

  /* The heat maps are the same 300-unit viewBox and need the same width back.
     The section sits inside .cats-layout now, which has already clawed back the
     outer padding above, so the frame is the only thing left to trim. */
  .heat-frame { padding: 0.6rem; }

  /* Measured, not precautionary: "Counting  Every sighting | Recent ones more"
     is ~338px on one line and a 360px phone has 328px of content width, so the
     row overflowed the page. Putting the label above its buttons drops it to
     ~267px. Wrapping .heat-seg itself would have broken its shared borders. */
  .heat-control {
    flex-direction: column;
    align-items: flex-start;
    gap: 0.4rem;
  }
}
