/* ───────────────────────────────────────────────────────────────
   PARANOID AND READY — homepage deck

   Loaded by index.html only. The homepage runs a different design system
   from the rest of the site: full-screen snapping panels, a display face,
   and a hot signal red instead of the concrete grey and dried blood the
   category pages still use. Keeping it in its own file makes the migration
   of the inner pages legible instead of tangling two systems in style.css.

   Two recurring devices:
     the BAND  — a full-width row that is entirely a link (scenarios, gear,
                 guides: the same object at three different counts)
     the REEL  — a horizontal run where the centre item is the live one and
                 its neighbours sit back (books, bags)
   ─────────────────────────────────────────────────────────────── */

:root {
  --void: #0C0C0C;
  --bone: #EFEBE4;
  --signal: #E8321E;
  --hair: rgba(239, 235, 228, 0.18);
  --hair-dark: rgba(12, 12, 12, 0.16);
  /* svh so mobile browser chrome never clips a bottom-anchored block */
  --h: 100svh;
  --gutter: clamp(20px, 5vw, 72px);
}

/* This page does not load style.css, so it carries its own reset. Without it
   the default body margin gives the document its own scrollbar, and the deck's
   snap points end up fighting a second scroller. */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

.home,
.home body { height: 100%; overflow: hidden; }

.home {
  background: var(--void);
  color: var(--bone);
  font-family: 'JetBrains Mono', ui-monospace, monospace;
  -webkit-font-smoothing: antialiased;
}

.home img { max-width: 100%; display: block; }
.home a { color: inherit; text-decoration: none; }
.home ul, .home ol { list-style: none; }
.home button { font: inherit; color: inherit; background: none; border: none; cursor: pointer; }

/* The deck scrolls rather than the document, so fixed chrome never fights
   the snap points. */
.deck {
  height: var(--h);
  overflow-y: scroll;
  scroll-snap-type: y mandatory;
  scroll-behavior: smooth;
  scrollbar-width: none;
}

.deck::-webkit-scrollbar { display: none; }

.panel {
  position: relative;
  height: var(--h);
  scroll-snap-align: start;
  overflow: hidden;
  isolation: isolate;
  display: flex;
  flex-direction: column;
}

.panel-inner {
  width: 100%;
  max-width: 1400px;
  margin: 0 auto;
  padding: clamp(64px, 10vh, 120px) var(--gutter) clamp(36px, 6vh, 64px);
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

/* A head or foot that brackets a full-bleed block rather than centring in
   the panel. Doubled class so it outranks the .panel-inner flex below. */
/* No max-width on either: the block between them (bands, reels) runs edge to
   edge on --gutter alone, so a 1400px cap would centre the head and leave it
   drifting right of the band names on anything wider than 1400px. */
.panel-inner.panel-inner--head { flex: 0 0 auto; justify-content: flex-start; padding-bottom: 0; max-width: none; }
.panel-inner.panel-inner--foot { flex: 0 0 auto; padding-top: clamp(16px, 2.4vh, 28px); max-width: none; }
.panel-inner--centre { align-items: center; text-align: center; }

/* ── Display type ───────────────────────────────────────────────
   Anton carries every headline. It is a single heavy condensed weight,
   which is why a long phrase can run large without wrapping into mush.
   Everything that is not a headline stays in JetBrains Mono, so the site
   still reads as a document underneath the poster type. */
.display {
  font-family: 'Anton', 'Arial Narrow', Impact, sans-serif;
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: 0.01em;
  line-height: 0.92;
}

.eyebrow {
  font-size: clamp(9px, 1.1vw, 11px);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 4px;
  color: var(--signal);
}

.lede {
  font-size: clamp(12px, 1.4vw, 14px);
  line-height: 1.65;
  color: rgba(239, 235, 228, 0.66);
  max-width: 58ch;
}

.panel-head { display: flex; flex-direction: column; gap: clamp(12px, 2.2vh, 24px); }
.panel-title { font-size: clamp(30px, 6vw, 84px); color: var(--bone); }
.panel-title em { font-style: normal; color: var(--signal); }

.btn {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  padding: 14px 24px;
  background: var(--signal);
  color: var(--void);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 2px;
  text-transform: uppercase;
  transition: background 0.2s, color 0.2s;
}

.btn:hover { background: var(--bone); color: var(--void); }
.btn--ghost { background: transparent; color: var(--bone); border: 1px solid var(--hair); }
.btn--ghost:hover { background: var(--bone); color: var(--void); }

/* ── Chrome: wordmark and menu ──────────────────────────────────*/
.mark {
  position: fixed;
  top: clamp(16px, 3vh, 30px);
  left: var(--gutter);
  z-index: 30;
  font-size: 10px;
  font-weight: 800;
  letter-spacing: 3px;
  text-transform: uppercase;
  color: var(--bone);
  opacity: 0;
  transition: opacity 0.4s ease;
  pointer-events: none;
}

.mark.show { opacity: 1; pointer-events: auto; }
.mark:hover { color: var(--signal); }

.burger {
  position: fixed;
  top: clamp(14px, 2.8vh, 28px);
  right: var(--gutter);
  z-index: 31;
  width: 30px;
  height: 22px;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding: 4px 0;
}

.burger span { display: block; height: 2px; background: var(--bone); transition: transform 0.3s ease, opacity 0.2s ease; }
.burger[aria-expanded='true'] span:nth-child(1) { transform: translateY(6px) rotate(45deg); }
.burger[aria-expanded='true'] span:nth-child(2) { opacity: 0; }
.burger[aria-expanded='true'] span:nth-child(3) { transform: translateY(-6px) rotate(-45deg); }

/* No panel, no overlay, no fill: the menu is text arriving on whatever is
   already behind it. That is why it needs a shadow rather than a backdrop. */
.menu {
  position: fixed;
  top: calc(clamp(14px, 2.8vh, 28px) + 42px);
  right: var(--gutter);
  z-index: 30;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 10px;
  text-align: right;
  opacity: 0;
  transform: translateY(-8px);
  pointer-events: none;
  transition: opacity 0.28s ease, transform 0.28s ease;
}

.menu[data-open='true'] { opacity: 1; transform: none; pointer-events: auto; }

/* Mono rather than Anton: the display face at menu size shouts, and six heavy
   condensed lines take over the corner of the screen. */
.menu a {
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 2.5px;
  color: var(--bone);
  text-shadow: 0 1px 12px rgba(12, 12, 12, 0.8);
  transition: color 0.2s;
}

.menu a:hover { color: var(--signal); }

/* On the bone and red panels the chrome has to flip or it disappears. The
   class is set on the root by the deck observer. */
.home.on-light .mark,
.home.on-light .menu a { color: var(--void); }
.home.on-light .menu a { text-shadow: 0 1px 14px rgba(239, 235, 228, 0.75); }
.home.on-light .burger span { background: var(--void); }

/* ── Ticks ─────────────────────────────────────────────────────
   One short mark per panel, the current one longer and red. Deliberately
   quieter than a scrollbar: it is there when you look for it and invisible
   when you are reading. */
.ticks {
  position: fixed;
  right: clamp(14px, 2vw, 30px);
  top: 50%;
  transform: translateY(-50%);
  z-index: 32;
  display: flex;
  flex-direction: column;
  gap: 11px;
  align-items: flex-end;
}

.ticks button {
  width: 16px;
  height: 2px;
  padding: 0;
  background: rgba(239, 235, 228, 0.3);
  transition: width 0.3s cubic-bezier(.16,.84,.36,1), background 0.3s ease;
}

.ticks button:hover { background: rgba(239, 235, 228, 0.65); width: 24px; }
.ticks button[aria-current='true'] { width: 32px; height: 3px; background: var(--signal); }

.on-light .ticks button { background: rgba(12, 12, 12, 0.28); }
.on-light .ticks button:hover { background: rgba(12, 12, 12, 0.6); }
.on-light .ticks button[aria-current='true'] { background: var(--void); }

@media (max-width: 860px) { .ticks { display: none; } }

/* ── 01 Cover ───────────────────────────────────────────────────*/
.hero-panel { justify-content: center; align-items: center; }

.hero-shot {
  position: absolute;
  inset: -2%;
  background-image: url('../assets/banner.jpg');
  background-size: cover;
  background-position: center 32%;
  filter: grayscale(0.25) contrast(1.12) saturate(0.95) brightness(0.72);
  transform: scale(1.06);
  transition: transform 2.6s cubic-bezier(.16,.84,.36,1);
  z-index: -2;
}

.panel.is-live .hero-shot { transform: scale(1); }

.hero-panel::after {
  content: '';
  position: absolute;
  inset: 0;
  background: radial-gradient(ellipse at 50% 45%, rgba(12,12,12,0.30) 0%, rgba(12,12,12,0.72) 70%, rgba(12,12,12,0.92) 100%);
  z-index: -1;
}

.masthead {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(12px, 2vh, 22px);
  text-align: center;
  padding: 0 var(--gutter);
}

.masthead-pre {
  font-size: clamp(10px, 1.3vw, 13px);
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 8px;
  text-indent: 8px;
  color: var(--signal);
}

.masthead-main { font-size: clamp(44px, 12vw, 168px); color: var(--bone); }
.masthead-main .amp { color: var(--signal); }

/* ── Bands: scenarios, gear, guides ─────────────────────────────*/
.bands { flex: 1; display: flex; flex-direction: column; border-top: 1px solid var(--hair); }

.band {
  flex: 1;
  display: flex;
  align-items: center;
  gap: clamp(14px, 3vw, 44px);
  padding: 0 var(--gutter);
  border-bottom: 1px solid var(--hair);
  color: var(--bone);
  position: relative;
  overflow: hidden;
  transition: color 0.35s ease;
}

/* Wipe rather than a background swap, so the fill reads as deliberate. */
.band::before {
  content: '';
  position: absolute;
  inset: 0;
  background: var(--signal);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.45s cubic-bezier(.16,.84,.36,1);
  z-index: -1;
}

.band:hover::before,
.band:focus-visible::before { transform: scaleX(1); }
.band:hover .band-num,
.band:focus-visible .band-num { color: var(--void); }

.band-num { font-size: clamp(9px, 1.1vw, 12px); font-weight: 700; color: var(--signal); flex-shrink: 0; transition: color 0.35s ease; }
.band-name { font-size: clamp(20px, 4.6vw, 58px); }

/* Rows in a half-width column, or a lot of rows in one screen: shorter rows,
   so the type comes down with them. */
.bands--tight .band-name { font-size: clamp(14px, 2.6vw, 32px); }

/* ── Gear: three levels in one panel ────────────────────────────
   Level 1 keeps the dark band. Levels 2 and 3 flip to bone with black
   type: that is where the reading happens, and small light-on-dark text
   is hard work. Each level steps further right so the hierarchy is legible
   without rules or bullets. */
.gear-scroll {
  /* The indent is derived from the same values that place the category name,
     so the group names sit a fixed step to its right at every width instead
     of drifting into line with it on small screens. */
  --num-w: 26px;
  --gear-gap: clamp(14px, 3vw, 44px);
  --gear-step: clamp(24px, 4.4vw, 64px);
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  scrollbar-width: none;
  border-top: 1px solid var(--hair);
}

.gear-scroll::-webkit-scrollbar { display: none; }

.gear-cat { border-bottom: 1px solid var(--hair); }

.gear-trigger {
  width: 100%;
  display: flex;
  align-items: center;
  gap: var(--gear-gap);
  padding: clamp(14px, 2.4vh, 24px) var(--gutter);
  color: var(--bone);
  text-align: left;
  position: relative;
  overflow: hidden;
  transition: color 0.3s ease;
}

.gear-trigger::before {
  content: '';
  position: absolute;
  inset: 0;
  background: var(--signal);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.45s cubic-bezier(.16,.84,.36,1);
  z-index: -1;
}

.gear-trigger:hover::before { transform: scaleX(1); }
.gear-trigger:hover .band-num { color: var(--void); }

.gear-trigger .band-num { width: var(--num-w); flex-shrink: 0; }
.gear-trigger .band-name { flex: 1; font-size: clamp(14px, 2.6vw, 32px); }
.gear-icon { font-size: 17px; font-weight: 800; flex-shrink: 0; transition: transform 0.3s ease; }
.gear-cat.open > .gear-trigger .gear-icon,
.gear-sub.open > .gear-sub-trigger .gear-icon { transform: rotate(45deg); }

/* Direct-child selectors: an open group must not drag its category open. */
.gear-body,
.gear-sub-body { max-height: 0; overflow: hidden; transition: max-height 0.45s ease; }
.gear-cat.open > .gear-body { max-height: 2200px; transition: max-height 0.7s ease; }
.gear-sub.open > .gear-sub-body { max-height: 700px; transition: max-height 0.6s ease; }

/* The bone slab. Indented past the category name so the nesting reads. */
.gear-subs {
  background: var(--bone);
  color: var(--void);
  padding: 4px 0 8px;
  padding-left: calc(var(--gutter) + var(--num-w) + var(--gear-gap) + var(--gear-step));
}

.gear-sub { border-bottom: 1px solid rgba(12, 12, 12, 0.14); }
.gear-sub:last-of-type { border-bottom: none; }

.gear-sub-trigger,
.gear-sub-link {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 16px;
  padding: clamp(11px, 1.7vh, 16px) var(--gutter) clamp(11px, 1.7vh, 16px) 0;
  color: var(--void);
  text-align: left;
  transition: color 0.2s;
}

.gear-sub-trigger:hover,
.gear-sub-link:hover { color: var(--signal); }
.gear-sub-name { flex: 1; font-family: 'Anton', 'Arial Narrow', Impact, sans-serif; font-size: clamp(13px, 1.5vw, 19px); text-transform: uppercase; letter-spacing: 0.02em; }
.gear-hint { font-size: 9px; font-weight: 700; letter-spacing: 2px; text-transform: uppercase; color: var(--signal); flex-shrink: 0; }

/* Level 3: the one-liner, the types and the single Amazon link. Stepped in
   again from the group name. Grid rather than a stack, so the button sits at
   the right edge of every group instead of under the text, and the sentence
   gets the whole remaining column instead of a character cap that broke it
   halfway across a wide screen. */
.gear-detail {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: start;
  column-gap: clamp(20px, 3vw, 52px);
  padding: 0 var(--gutter) clamp(16px, 2.4vh, 24px) clamp(14px, 2vw, 28px);
}

.gear-detail-main { min-width: 0; }
.gear-blurb { font-size: clamp(11px, 1.15vw, 14px); line-height: 1.6; color: rgba(12, 12, 12, 0.75); }
.gear-detail .row-types { display: flex; align-items: center; gap: 8px; margin-top: 14px; overflow-x: auto; scrollbar-width: none; }
.gear-detail .row-types::-webkit-scrollbar { display: none; }
.gear-detail .row-types-label { flex-shrink: 0; font-size: 9px; font-weight: 700; letter-spacing: 2px; text-transform: uppercase; color: var(--signal); margin-right: 4px; }
.gear-detail .row-type { flex-shrink: 0; white-space: nowrap; font-size: 10px; letter-spacing: 1px; padding: 5px 9px; border: 1px solid rgba(12, 12, 12, 0.2); color: rgba(12, 12, 12, 0.62); }
.gear-go { justify-self: end; margin-top: 0; white-space: nowrap; }
.gear-go:hover { background: var(--void); color: var(--bone); }


/* The books panel title is a link to its own page. */
.panel-title-link { display: inline-block; transition: color 0.2s; }
.panel-title-link:hover { color: var(--signal); }

@media (max-width: 860px) {
  /* Still an indent, just a smaller step. Replacing the gutter here put the
     group names to the LEFT of the category they sit under. */
  .gear-sub-trigger, .gear-sub-link { padding-right: var(--gutter); }
  .gear-detail { grid-template-columns: 1fr; row-gap: 14px; padding-left: 14px; }
  .gear-go { justify-self: start; }
}

.band-go {
  margin-left: auto;
  font-size: clamp(9px, 1.1vw, 11px);
  font-weight: 700;
  letter-spacing: 2px;
  text-transform: uppercase;
  opacity: 0;
  transform: translateX(-8px);
  transition: opacity 0.35s ease, transform 0.35s ease;
  flex-shrink: 0;
}

.band:hover .band-go,
.band:focus-visible .band-go { opacity: 1; transform: translateX(0); }

/* ── Reel: the centre item is live, neighbours sit back ─────────
   Card widths are fixed and emphasis is done with transform, never with
   width. A width transition would move every later card mid-animation and
   the centring maths would chase a target that keeps moving. */
.reel-wrap { position: relative; flex: 1; display: flex; align-items: center; min-height: 0; }

.reel {
  display: flex;
  align-items: center;
  gap: clamp(16px, 2vw, 32px);
  height: 100%;
  width: 100%;
  /* Side padding lets the first and last card reach the centre. */
  padding: clamp(10px, 2vh, 24px) max(var(--gutter), calc(50% - var(--card) / 2));
  overflow-x: auto;
  overflow-y: hidden;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  scroll-behavior: smooth;
}

.reel::-webkit-scrollbar { display: none; }
.reel:focus-visible { outline: 1px solid var(--signal); outline-offset: -4px; }

.reel-item {
  flex: 0 0 auto;
  width: var(--card);
  scroll-snap-align: center;
  transform: scale(0.82);
  opacity: 0.4;
  transition: transform 1.05s cubic-bezier(.16,.84,.36,1), opacity 1.05s ease;
  will-change: transform;
}

.reel-item.is-active { transform: scale(1); opacity: 1; }

.reel-btn {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  z-index: 3;
  width: 42px;
  height: 42px;
  border: 1px solid var(--hair);
  color: var(--bone);
  font-size: 20px;
  line-height: 1;
  background: rgba(12, 12, 12, 0.6);
  transition: background 0.2s, color 0.2s, opacity 0.2s;
}

.reel-btn:hover { background: var(--signal); color: var(--void); }
.reel-btn:disabled { opacity: 0.2; cursor: default; }
.reel-btn:disabled:hover { background: rgba(12, 12, 12, 0.6); color: var(--bone); }
.reel-prev { left: clamp(6px, 1.2vw, 18px); }
.reel-next { right: clamp(6px, 1.2vw, 18px); }

/* ── 06 Books ───────────────────────────────────────────────────
   Cover left, everything else right. No plate behind the cover: the
   artwork is the object, a framed box around it is just furniture. */
/* Sized so three whole books, descriptions included, are on screen at once
   rather than one large card with slivers either side. 32vw x 3 plus the gaps
   always clears the viewport. */
.books-panel { --card: clamp(280px, 32vw, 470px); }
.books-panel .reel { gap: clamp(10px, 1vw, 16px); }

/* The centre book is still favoured, but only just: at 0.82 the neighbours
   were too faint to read, and reading all three is the point. */
.books-panel .reel-item { transform: scale(0.86); opacity: 0.5; }
.books-panel .reel-item.is-active { transform: scale(1.1); opacity: 1; z-index: 2; }

/* The cover column is fixed rather than fractional so the text gets every
   pixel the card gains: widening the card spreads the description, it does
   not just inflate the artwork. */
.book { display: grid; grid-template-columns: clamp(92px, 10vw, 150px) minmax(0, 1fr); gap: clamp(14px, 1.4vw, 22px); align-items: center; }

/* The container carries a definite height so the row does not collapse while
   a lazy cover is still loading, and the image is sized to fit inside it.
   Covers vary in proportion, so nothing is cropped and nothing is stretched. */
.book-cover { height: clamp(150px, 32vh, 280px); display: flex; align-items: center; justify-content: center; }
.book-cover img { max-width: 100%; max-height: 100%; width: auto; height: auto; object-fit: contain; filter: drop-shadow(0 18px 34px rgba(0,0,0,0.55)); }

/* Stand-in for the titles OpenLibrary has no artwork for. A set title page
   rather than a grey placeholder: it reads as a decision, not as a gap. */
.book-cover--plate { padding: 0 6%; }

.book-plate {
  width: 100%;
  height: 100%;
  aspect-ratio: 2 / 3;
  max-width: 100%;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 12px;
  padding: clamp(14px, 1.6vw, 22px);
  background: var(--bone);
  color: var(--void);
  box-shadow: 0 18px 34px rgba(0, 0, 0, 0.55);
}

.book-plate-t {
  font-family: 'Anton', 'Arial Narrow', Impact, sans-serif;
  font-size: clamp(13px, 1.5vw, 20px);
  line-height: 1.02;
  text-transform: uppercase;
  letter-spacing: 0.01em;
}

.book-plate-b { font-size: 9px; letter-spacing: 1px; color: rgba(12, 12, 12, 0.6); border-top: 2px solid var(--signal); padding-top: 8px; }

.book-meta { display: flex; flex-direction: column; gap: 9px; }
.book-cat { font-size: 8px; font-weight: 700; letter-spacing: 1.6px; text-transform: uppercase; color: var(--signal); }
/* Sized so almost every title holds one line in the space next to the cover.
   The handful that are genuinely too long still wrap rather than get cut,
   because a truncated book title is worse than a second line. */
.book-name { font-family: 'Anton', 'Arial Narrow', Impact, sans-serif; font-weight: 400; font-size: clamp(14px, 1.2vw, 20px); text-transform: uppercase; letter-spacing: 0.01em; line-height: 1.06; color: var(--bone); }
.book-by { font-size: 10px; color: rgba(239, 235, 228, 0.5); }

/* Clamped rather than cut by width, so every card keeps the same block and
   the row of buttons stays level. */
.book-note {
  font-size: clamp(11px, 0.95vw, 14px);
  line-height: 1.6;
  color: rgba(239, 235, 228, 0.7);
  display: -webkit-box;
  -webkit-line-clamp: 6;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.book-buy {
  align-self: flex-start;
  margin-top: 6px;
  padding: 9px 16px;
  border: 1px solid var(--signal);
  color: var(--signal);
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 2px;
  text-transform: uppercase;
  transition: background 0.2s, color 0.2s;
}

.book-buy:hover { background: var(--signal); color: var(--void); }

/* ── 03 Grab and go ─────────────────────────────────────────────
   The panel is bone rather than void for one concrete reason: the product
   shots are Amazon JPEGs on white. On a dark ground they read as white
   boxes. On bone, mix-blend-mode: multiply drops the background for real
   instead of faking a cutout. */
.bags-panel { --card: clamp(260px, 30vw, 400px); background: var(--bone); color: var(--void); }
.bags-panel .panel-title { color: var(--void); }
.bags-panel .reel-btn { background: rgba(239, 235, 228, 0.7); border-color: var(--hair-dark); color: var(--void); }
.bags-panel .reel-btn:hover { background: var(--signal); color: var(--bone); }
.bags-panel .reel-btn:disabled:hover { background: rgba(239, 235, 228, 0.7); color: var(--void); }

.bag { display: flex; flex-direction: column; gap: 12px; text-align: center; }
.bag-shot { height: clamp(160px, 30vh, 300px); display: flex; align-items: center; justify-content: center; }
.bag-shot img { max-height: 100%; max-width: 100%; width: auto; object-fit: contain; mix-blend-mode: multiply; }

/* Same reasoning as the book plate: until a real product shot is dropped into
   assets/bags/, a set name reads as a decision rather than a broken image. */
.bag-plate {
  height: 100%;
  aspect-ratio: 3 / 4;
  display: flex;
  align-items: flex-end;
  padding: clamp(14px, 1.6vw, 22px);
  background: var(--void);
  color: var(--bone);
  border-bottom: 3px solid var(--signal);
}

.bag-plate-t {
  font-family: 'Anton', 'Arial Narrow', Impact, sans-serif;
  font-size: clamp(15px, 1.7vw, 24px);
  line-height: 1.02;
  text-transform: uppercase;
  letter-spacing: 0.01em;
  text-align: left;
}

.bag-tag { font-size: 8px; font-weight: 700; letter-spacing: 1.6px; text-transform: uppercase; color: var(--signal); }
.bag-name { font-size: clamp(17px, 2vw, 26px); color: var(--void); }
.bag-note { font-size: 11px; line-height: 1.55; color: rgba(12, 12, 12, 0.62); }
.bag-foot { display: flex; align-items: center; justify-content: center; gap: 14px; font-size: 11px; font-weight: 700; }
.bag-go { color: var(--signal); font-size: 9px; letter-spacing: 2px; text-transform: uppercase; }

/* The two build-it-yourself guides, under the reel. */
.bag-guides { display: flex; flex-wrap: wrap; gap: 0; border-top: 1px solid var(--hair-dark); }

.bag-guide {
  flex: 1 1 300px;
  display: flex;
  align-items: center;
  gap: 14px;
  padding: clamp(14px, 2.2vh, 22px) 0;
  border-bottom: 1px solid var(--hair-dark);
  color: var(--void);
  transition: color 0.2s;
}

.bag-guide + .bag-guide { border-left: 1px solid var(--hair-dark); padding-left: clamp(16px, 2.5vw, 40px); }
.bag-guide:hover { color: var(--signal); }
.bag-guide .n { font-size: 9px; font-weight: 700; color: var(--signal); flex-shrink: 0; }
.bag-guide .t { font-family: 'Anton', 'Arial Narrow', Impact, sans-serif; font-size: clamp(14px, 1.6vw, 20px); text-transform: uppercase; letter-spacing: 0.01em; }

/* ── 05 Guides and merch ────────────────────────────────────────
   Two halves of one panel. Only one of them is red.

   Both red would leave the guides with nowhere to go: the band device is a
   red wipe across black, and a red wipe across red is nothing at all. So the
   reading half keeps the void ground it needs to work, and the shop half
   takes the field the old shop panel used to hold on its own, which is what
   keeps the red in the rhythm of the deck now that the panel is shared.

   The chrome stays bone across the whole panel rather than flipping to ink
   on the red side. The wordmark sits over the void half and the burger over
   the red one, and there is no way to be both at once. */
.split { flex: 1; min-height: 0; display: grid; grid-template-columns: 1fr 1fr; }

.split-half {
  /* The inner edges meet at the divider, so they take half a gutter each
     rather than a full one, which would push the two columns apart at wide
     widths. Named because the band wipe below has to undo exactly it. */
  --pad-i: calc(var(--gutter) / 2);
  min-width: 0;
  min-height: 0;
  display: flex;
  flex-direction: column;
  gap: clamp(16px, 3vh, 34px);
  padding: clamp(56px, 9vh, 104px) var(--gutter) clamp(28px, 4.5vh, 52px);
}

/* The title carries the panel, centred, exactly as Books and Knowledge does
   at the foot of the deck. Nothing above it: an eyebrow and a standfirst on
   a half-width column is three sizes of type before the first link. */
.split-half .panel-title { flex: 0 0 auto; text-align: center; font-size: clamp(26px, 3.4vw, 56px); }

.split-guides { padding-right: var(--pad-i); }
.split-merch { padding-left: var(--pad-i); background: var(--signal); color: var(--void); }
.split-merch .panel-title { color: var(--void); }

/* The half already carries a gutter, so the band drops its own. The wipe is
   pulled back out to both edges of the half: a red fill stopping short of the
   panel edge on one side and the red half on the other reads as a misaligned
   box rather than a row lighting up. */
.split-guides .bands { min-height: 0; }
/* Four rows, not nine: they hold a floor once the panel stops being exactly
   one screen and stretch stops doing the work. */
.split-guides .band { padding: 0; gap: clamp(12px, 1.6vw, 24px); min-height: clamp(56px, 8.5vh, 82px); }
.split-guides .band-name { font-size: clamp(15px, 2.4vw, 30px); }
.split-guides .band::before { left: calc(var(--gutter) * -1); right: calc(var(--pad-i) * -1); }

/* The title carries the link out of the panel now (guides.html, the shop),
   the same device Books and Knowledge uses at the foot of the deck, so
   neither half needs a button of its own any more. The base hover turns the
   link signal red, which on the red half is the background colour, so the
   merch title needs its own hover to stay visible. */
.split-merch .panel-title-link:hover { color: var(--void); opacity: 0.7; }

.merch-grid {
  flex: 1;
  min-height: 0;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  /* The cards keep their own proportions and the shelf centres in whatever
     the panel has left. Stretched to fill, a three-up run in a half-width
     column turns every shot into a slab twice as tall as it is wide. */
  align-content: center;
  gap: clamp(10px, 1.2vw, 18px);
}

/* No run yet, so one frame across the whole shelf rather than three invented
   products. Drawn in ink on the red rather than filled: an empty frame reads
   as a space held open, a filled one reads as a card that failed to load. */
.merch-grid:has(.merch-empty) { grid-template-columns: 1fr; align-content: stretch; }

.merch-empty {
  display: block;
  min-height: clamp(120px, 22vh, 300px);
  border: 1px solid rgba(12, 12, 12, 0.28);
}

.merch {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
  color: var(--void);
  transition: opacity 0.2s;
}

a.merch:hover { opacity: 0.72; }
.merch.is-placeholder { cursor: default; }
.merch.is-placeholder .merch-price { color: rgba(12, 12, 12, 0.4); }

/* The tile is bone inside the red half for the same reason the whole Grab
   and Go panel is bone: a product shot on white needs a light ground to
   multiply into, and red is not one. */
.merch-shot {
  aspect-ratio: 3 / 4;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--bone);
  overflow: hidden;
}

.merch-shot img { max-height: 100%; max-width: 100%; width: auto; object-fit: contain; mix-blend-mode: multiply; }

.merch-plate {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: flex-end;
  padding: clamp(10px, 1.2vw, 16px);
  background: var(--void);
  color: var(--bone);
  border-bottom: 3px solid var(--signal);
}

.merch-plate-t {
  font-family: 'Anton', 'Arial Narrow', Impact, sans-serif;
  font-size: clamp(13px, 1.4vw, 19px);
  line-height: 1.02;
  text-transform: uppercase;
  letter-spacing: 0.01em;
}

.merch-tag { font-size: 8px; font-weight: 700; letter-spacing: 1.6px; text-transform: uppercase; color: var(--void); }
.merch-name { font-size: clamp(13px, 1.3vw, 19px); }
.merch-note { font-size: 10px; line-height: 1.5; color: rgba(12, 12, 12, 0.68); }
.merch-price { font-size: 10px; font-weight: 700; color: rgba(12, 12, 12, 0.8); }

/* ── Footer ─────────────────────────────────────────────────────*/
.foot {
  flex: 0 0 auto;
  display: flex;
  flex-wrap: wrap;
  gap: 14px 32px;
  align-items: center;
  padding: clamp(16px, 2.4vh, 26px) var(--gutter);
  font-size: 10px;
  letter-spacing: 1px;
  color: rgba(239, 235, 228, 0.55);
}

.foot a { color: rgba(239, 235, 228, 0.75); text-transform: uppercase; font-weight: 500; }
.foot a:hover { color: var(--signal); }
.foot .spacer { flex: 1; }
.foot-note { flex-basis: 100%; font-size: 9px; line-height: 1.7; color: rgba(239, 235, 228, 0.4); }

/* Print grain: the one texture that ties the photograph to the flat panels. */
.home::before {
  content: '';
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 9999;
  opacity: 0.32;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='0.42'/%3E%3C/svg%3E");
}

@media (max-width: 860px) {
  .book { grid-template-columns: 1fr; gap: 14px; }
  .book-cover img { max-height: 26vh; }
  .band-go { display: none; }
  .reel-btn { display: none; }
  .bag-guide + .bag-guide { border-left: none; padding-left: 0; }
  /* Panels stop being a strict screen each once the content stacks. */
  .panel--stack { height: auto; min-height: var(--h); }
  /* The split becomes two stacked halves and both edges go back to a full
     gutter. No divider is needed once they are stacked: the change of ground
     from void to red is the edge. */
  .split { grid-template-columns: 1fr; }
  .split-half { --pad-i: var(--gutter); }
  /* Three across at 375px leaves no room for the note. Two, and the third
     wraps: still a shelf, still readable. */
  .merch-grid { grid-template-columns: 1fr 1fr; }
}

@media (prefers-reduced-motion: reduce) {
  .deck, .reel { scroll-behavior: auto; }
  .hero-shot, .band::before, .band-go, .reel-item { transition: none; }
}
