/* ───────────────────────────────────────────────────────────────
   PARANOID AND READY — gear category pages

   Loaded after base.css. These pages scroll normally: no deck, no snap.
   Three blocks under the title: a reel of picked products, the list of
   groups to consider, and the guides that actually relate.
   ─────────────────────────────────────────────────────────────── */

.wrap { width: 100%; max-width: var(--maxw); margin: 0 auto; padding: 0 var(--gutter); }

/* ── Title ──────────────────────────────────────────────────────
   The category name and nothing else. No standfirst, no intro paragraph:
   the rows below say what is in it. */
.cat-head { padding: clamp(96px, 16vh, 180px) 0 clamp(28px, 5vh, 56px); }

/* Own stacking context and a real hit area. Anton at 128px has a line box
   shorter than its glyphs, so the h1 below was catching clicks meant for
   this link. */
.cat-crumb {
  position: relative;
  z-index: 2;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-bottom: clamp(10px, 1.6vh, 18px);
  padding: 8px 10px 8px 0;
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 2.5px;
  text-transform: uppercase;
  color: rgba(239, 235, 228, 0.5);
}

.cat-crumb:hover { color: var(--signal); }
.cat-title { position: relative; font-size: clamp(38px, 9vw, 128px); }

/* ── Product reel ───────────────────────────────────────────────*/
.picks { --card: clamp(220px, 24vw, 320px); padding-bottom: clamp(28px, 5vh, 56px); }
.picks .reel-wrap { margin: 0 calc(var(--gutter) * -1); }

/* The storage groups run four of these down one page: each name is its own
   section rather than a caption over the last one, which is why it is set
   large and centred instead of as a small-caps eyebrow. */
.picks-title { text-align: center; font-size: clamp(24px, 3.4vw, 46px); margin-bottom: clamp(16px, 2.6vh, 26px); }

.pick { display: flex; flex-direction: column; gap: 12px; }
.pick-shot { height: clamp(170px, 26vh, 280px); display: flex; align-items: center; justify-content: center; background: var(--bone); }
.pick-shot img { max-height: 100%; max-width: 100%; width: auto; object-fit: contain; mix-blend-mode: multiply; }
.pick-name { font-family: 'Anton', 'Arial Narrow', Impact, sans-serif; font-size: clamp(14px, 1.5vw, 19px); text-transform: uppercase; letter-spacing: 0.01em; line-height: 1.06; }
.pick-price { font-size: 11px; font-weight: 700; color: var(--signal); }

/* Shown until products are chosen. A stated gap rather than a fake card. */
/* ── The metals card grid ───────────────────────────────────────
   Twelve columns with one pixel gaps over a hair background, so nine cards
   read as one mosaic rather than nine boxes. It is the same trick as the
   skills grid, given explicit spans. Grid stretches every card in a row to
   the tallest, which is why the chart has to grow rather than sit at its
   iframe height. Below 1000px every span collapses: a four column card is
   two words wide on a laptop and unreadable on a phone. */
.mgrid {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: 1px;
  margin-bottom: clamp(30px, 5vh, 60px);
  background: var(--hair);
  border: 1px solid var(--hair);
}

.mcard {
  display: flex;
  flex-direction: column;
  gap: clamp(12px, 1.8vh, 18px);
  padding: clamp(20px, 2.6vw, 34px);
  background: var(--void);
  grid-column: span 12;
}

.mcard-t { font-size: clamp(16px, 1.9vw, 26px); }
.mcard-p { font-size: clamp(11px, 1.05vw, 13px); line-height: 1.65; color: rgba(239, 235, 228, 0.66); }

@media (min-width: 1000px) {
  .mcard[data-span="4"] { grid-column: span 4; }
  .mcard[data-span="6"] { grid-column: span 6; }
  .mcard[data-span="8"] { grid-column: span 8; }
}

/* The chart fills whatever height its row neighbour dictates. */
.mcard-chart { flex: 1; min-height: 430px; }
.mcard-chart iframe { display: block; width: 100%; height: 100%; min-height: 430px; border: 0; }

/* A chart with the whole row to itself is the page's one figure, so it is
   given the height its own controls need: the widget puts the range buttons
   and the drag handles below the plot, and they are the point of it. */
.mcard[data-span="12"] .mcard-chart,
.mcard[data-span="12"] .mcard-chart iframe { min-height: clamp(420px, 62vh, 640px); }

.mcard-tick { border: 1px solid var(--hair); background: rgba(239, 235, 228, 0.04); }
.mcard-tick iframe { display: block; width: 100%; border: 0; }

/* On the red card the hairline border disappears into the ground. */
.mcard-cta .mcard-tick { border-color: rgba(12, 12, 12, 0.22); background: rgba(12, 12, 12, 0.06); }

.mdate { display: grid; grid-template-columns: 5ch minmax(0, 1fr); gap: clamp(10px, 1.2vw, 16px); padding: clamp(9px, 1.3vh, 13px) 0; border-top: 1px solid var(--hair); }
.mdate:first-child { border-top: none; padding-top: 0; }
.mdate dt { font-size: 11px; font-weight: 700; color: var(--signal); }
.mdate dd { font-size: clamp(11px, 1.02vw, 13px); line-height: 1.55; color: rgba(239, 235, 228, 0.66); }

.mlist li { position: relative; padding: 7px 0 7px 20px; font-size: clamp(11px, 1.02vw, 13px); line-height: 1.6; color: rgba(239, 235, 228, 0.7); }
.mlist li::before { content: '+'; position: absolute; left: 0; color: var(--signal); font-weight: 700; }

.mrank li { display: grid; grid-template-columns: 3.5ch minmax(0, 1fr); gap: 12px; padding: clamp(8px, 1.2vh, 12px) 0; border-top: 1px solid var(--hair); font-size: clamp(11px, 1.02vw, 13px); line-height: 1.55; color: rgba(239, 235, 228, 0.7); }
.mrank li:first-child { border-top: none; padding-top: 0; }
.mrank-n { font-weight: 700; color: var(--signal); }

.mstat { margin-top: auto; font-family: 'Anton', 'Arial Narrow', Impact, sans-serif; font-size: clamp(52px, 7.5vw, 104px); line-height: 0.86; letter-spacing: 0.01em; color: var(--signal); }
.mstat-u { display: block; margin-top: 10px; font-family: 'JetBrains Mono', ui-monospace, monospace; font-size: 9px; font-weight: 700; letter-spacing: 2px; text-transform: uppercase; color: rgba(239, 235, 228, 0.5); }

/* The one card that is an advert. Inverted so it reads as a different kind
   of object from the data around it, and it appears exactly once. */
.mcard-cta { background: var(--signal); color: var(--void); }
.mcard-cta .mcard-t { color: var(--void); }
.mcard-cta .mcard-p { color: rgba(12, 12, 12, 0.78); }

.mcta-go {
  margin-top: auto;
  align-self: flex-start;
  padding: 15px 26px;
  background: var(--void);
  color: var(--bone);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 2px;
  text-transform: uppercase;
  transition: background 0.2s, color 0.2s;
}

.mcta-go:hover { background: var(--bone); color: var(--void); }

/* ── Safes reel ─────────────────────────────────────────────────
   A product pick with two lines added, because a safe is chosen on its
   rating and on the job it does rather than on the photo. Wider card to
   carry them. A pick with no product behind it yet renders as a div, so it
   is dimmed and takes no pointer instead of looking clickable. */
.safes { --card: clamp(240px, 27vw, 350px); padding-bottom: clamp(28px, 5vh, 56px); }

/* .picks pulls the reel out of the wrap it normally sits in. This section is
   already full width, so that negative gutter would push it past the viewport
   and scroll the whole page sideways. */
.safes .reel-wrap { margin: 0; }

.safe { gap: 10px; }
.safe-shot { height: clamp(150px, 22vh, 240px); display: flex; align-items: center; justify-content: center; background: var(--bone); }
.safe-shot img { max-height: 100%; max-width: 100%; width: auto; object-fit: contain; mix-blend-mode: multiply; }

.safe-plate {
  display: flex;
  align-items: flex-end;
  width: 100%;
  height: 100%;
  padding: clamp(12px, 1.4vw, 18px);
  font-family: 'Anton', 'Arial Narrow', Impact, sans-serif;
  font-size: clamp(13px, 1.3vw, 18px);
  line-height: 1.04;
  text-transform: uppercase;
  letter-spacing: 0.01em;
  color: rgba(12, 12, 12, 0.35);
  border-bottom: 3px solid var(--signal);
}

.safe-spec { font-size: clamp(11px, 1.05vw, 13px); line-height: 1.6; color: rgba(239, 235, 228, 0.62); }
.safe-use { font-size: 9px; font-weight: 700; letter-spacing: 1.6px; text-transform: uppercase; color: rgba(239, 235, 228, 0.42); }
.safe.is-placeholder { cursor: default; }
.safe.is-placeholder .pick-price { color: rgba(239, 235, 228, 0.3); }

.picks-empty {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: clamp(22px, 4vh, 40px) 0;
  border-top: 1px solid var(--hair);
  border-bottom: 1px solid var(--hair);
  font-size: 11px;
  letter-spacing: 1px;
  color: rgba(239, 235, 228, 0.45);
}

.picks-empty b { font-family: 'Anton', 'Arial Narrow', Impact, sans-serif; font-weight: 400; font-size: 15px; letter-spacing: 0.01em; text-transform: uppercase; color: rgba(239, 235, 228, 0.7); }

/* ── Rows: the groups worth considering ─────────────────────────
   The row names the actual thing. Opening it gives one short reason and
   one link to the whole group on Amazon, so nothing here depends on
   hand-picking individual products. */
/* One indent value, used by the trigger gap and by the body padding, so the
   description starts under the row name rather than under the number. */
.rows { --row-gap: clamp(14px, 2.5vw, 32px); --row-num: 24px; border-top: 1px solid var(--hair); }
.row { border-bottom: 1px solid var(--hair); }

.row-trigger {
  width: 100%;
  display: flex;
  align-items: center;
  gap: var(--row-gap);
  padding: clamp(18px, 2.8vh, 28px) 0;
  text-align: left;
  transition: color 0.2s;
}

.row-trigger:hover { color: var(--signal); }
.row-num { width: var(--row-num); font-size: 10px; font-weight: 700; color: var(--signal); flex-shrink: 0; }

/* A row that goes straight to a guide, with nothing to open. */
.row-link {
  display: flex;
  align-items: center;
  gap: var(--row-gap);
  padding: clamp(18px, 2.8vh, 28px) 0;
  transition: color 0.2s;
}

.row-link:hover { color: var(--signal); }
.row-hint { margin-left: auto; font-size: 9px; font-weight: 700; letter-spacing: 2px; text-transform: uppercase; color: var(--signal); flex-shrink: 0; }
.row-link .row-icon { transform: none; }
.row-name { flex: 1; font-family: 'Anton', 'Arial Narrow', Impact, sans-serif; font-size: clamp(17px, 2.6vw, 34px); text-transform: uppercase; letter-spacing: 0.01em; line-height: 1.05; }
.row-icon { font-size: 18px; font-weight: 800; flex-shrink: 0; transition: transform 0.3s ease; }
.row.open .row-icon { transform: rotate(45deg); }

.row-body { max-height: 0; overflow: hidden; transition: max-height 0.4s ease; }

/* Generous enough for the longest shelf on the books page (twelve volumes,
   about 1440px). A max-height transition needs a fixed target, and clipping a
   list is a worse failure than an animation that finishes slightly early. */
.row.open .row-body { max-height: 3000px; transition: max-height 0.6s ease; }

/* Reason left, the single Amazon link right. */
/* Grid, not flex. As a flex row the left column was sized by its widest
   child, so a group with long type chips pushed the Amazon button hundreds
   of pixels further right than the row above it. minmax(0,1fr) pins the
   button to the right edge on every row. */
.row-content {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: start;
  column-gap: clamp(20px, 4vw, 60px);
  padding: 0 0 clamp(22px, 3.5vh, 36px) calc(var(--row-num) + var(--row-gap));
}

.row-main { min-width: 0; }
.row-blurb { font-size: clamp(12px, 1.3vw, 15px); line-height: 1.65; color: rgba(239, 235, 228, 0.72); max-width: 74ch; }
.row-go { justify-self: end; }

/* One line by design. Below the fold of the widest screens it scrolls
   sideways rather than wrapping into a second row of chips. */
/* One line, always. It scrolls rather than wrapping, and .is-scrollable
   (set by js/inner.js when the content actually overflows) fades the right
   edge so the run reads as continuing rather than as cut off. */
.row-types { display: flex; align-items: center; gap: 8px; margin-top: 18px; overflow-x: auto; scrollbar-width: none; -webkit-overflow-scrolling: touch; }
.row-types::-webkit-scrollbar { display: none; }
.row-types.is-scrollable { -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 44px), transparent 100%); mask-image: linear-gradient(to right, #000 calc(100% - 44px), transparent 100%); }
.row-types-label { flex-shrink: 0; font-size: 9px; font-weight: 700; letter-spacing: 2px; text-transform: uppercase; color: var(--signal); margin-right: 4px; }
.row-type { flex-shrink: 0; white-space: nowrap; font-size: 10px; letter-spacing: 1px; padding: 6px 10px; border: 1px solid var(--hair); color: rgba(239, 235, 228, 0.6); }

/* ── Books page: The Essential Shelf ────────────────────────────*/
.ess-section { --card: clamp(280px, 34vw, 500px); padding-bottom: clamp(32px, 6vh, 64px); }
.ess { display: grid; grid-template-columns: clamp(100px, 11vw, 170px) minmax(0, 1fr); gap: clamp(16px, 1.8vw, 28px); align-items: center; }
.ess-cover { height: clamp(160px, 26vh, 250px); display: flex; align-items: center; justify-content: center; }
.ess-cover img { max-width: 100%; max-height: 100%; width: auto; height: auto; object-fit: contain; filter: drop-shadow(0 16px 30px rgba(0,0,0,0.55)); }
.ess-meta { display: flex; flex-direction: column; gap: 8px; }
.ess-name { font-family: 'Anton', 'Arial Narrow', Impact, sans-serif; font-weight: 400; font-size: clamp(15px, 1.3vw, 22px); text-transform: uppercase; letter-spacing: 0.01em; line-height: 1.05; }
.ess-by { font-size: 10px; color: rgba(239, 235, 228, 0.5); }
.ess-note { font-size: clamp(11px, 0.95vw, 13px); line-height: 1.6; color: rgba(239, 235, 228, 0.7); display: -webkit-box; -webkit-line-clamp: 5; -webkit-box-orient: vertical; overflow: hidden; }

.book-buy { align-self: flex-start; margin-top: 4px; padding: 8px 15px; 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); }

/* A set title page stands in wherever the cover artwork does not exist. */
.book-plate { width: 100%; height: 100%; aspect-ratio: 2 / 3; display: flex; flex-direction: column; justify-content: space-between; gap: 10px; padding: clamp(12px, 1.4vw, 18px); background: var(--bone); color: var(--void); box-shadow: 0 16px 30px rgba(0,0,0,0.55); }
.book-plate-t { font-family: 'Anton', 'Arial Narrow', Impact, sans-serif; font-size: clamp(12px, 1.2vw, 17px); line-height: 1.02; text-transform: uppercase; letter-spacing: 0.01em; }
.book-plate-b { font-size: 8px; letter-spacing: 1px; color: rgba(12, 12, 12, 0.6); border-top: 2px solid var(--signal); padding-top: 6px; }

/* ── Books page: the shelves ────────────────────────────────────*/
.row-count { font-size: 9px; font-weight: 700; color: var(--signal); flex-shrink: 0; margin-left: auto; margin-right: 16px; }

.vols { display: flex; flex-direction: column; padding: 0 0 clamp(20px, 3vh, 34px) calc(var(--row-num) + var(--row-gap)); }

.vol {
  display: grid;
  grid-template-columns: clamp(56px, 6vw, 88px) minmax(0, 1fr) auto;
  align-items: center;
  gap: clamp(14px, 2vw, 30px);
  padding: clamp(14px, 2vh, 20px) 0;
  border-bottom: 1px solid var(--hair);
}

.vol:last-child { border-bottom: none; }
.vol-cover { height: clamp(72px, 9vh, 110px); display: flex; align-items: center; justify-content: center; }
.vol-cover img { max-width: 100%; max-height: 100%; width: auto; height: auto; object-fit: contain; }
.vol-cover.is-plate .book-plate { box-shadow: none; }
.vol-meta { min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.vol-name { font-family: 'Anton', 'Arial Narrow', Impact, sans-serif; font-weight: 400; font-size: clamp(13px, 1.2vw, 18px); text-transform: uppercase; letter-spacing: 0.01em; line-height: 1.05; }
.vol-by { font-size: 9px; color: rgba(239, 235, 228, 0.5); }
.vol-note { font-size: clamp(11px, 1vw, 13px); line-height: 1.55; color: rgba(239, 235, 228, 0.68); }
.vol-go { justify-self: end; }

/* ── Books page: the hinge ──────────────────────────────────────
   Everything above it costs money, everything below it does not. The band
   states the instruction rather than announcing a section. */
.hinge { background: var(--signal); color: var(--void); padding: clamp(40px, 8vh, 90px) 0; margin: clamp(30px, 6vh, 70px) 0 0; }
.hinge-line { font-size: clamp(20px, 3.4vw, 46px); color: var(--void); }

/* ── Books page: free documents ─────────────────────────────────*/
.docs-section { padding: clamp(40px, 7vh, 80px) 0 0; }
.docs { border-top: 1px solid var(--hair); }

.doc {
  display: flex;
  align-items: baseline;
  gap: clamp(14px, 2.5vw, 32px);
  padding: clamp(16px, 2.4vh, 24px) 0;
  border-bottom: 1px solid var(--hair);
  transition: color 0.2s;
}

.doc:hover { color: var(--signal); }
.doc-num { width: var(--row-num, 24px); font-size: 10px; font-weight: 700; color: var(--signal); flex-shrink: 0; }
.doc-main { display: flex; flex-direction: column; gap: 5px; min-width: 0; }
.doc-name { font-family: 'Anton', 'Arial Narrow', Impact, sans-serif; font-size: clamp(14px, 1.6vw, 22px); text-transform: uppercase; letter-spacing: 0.01em; line-height: 1.06; }
.doc-src { font-size: clamp(10px, 1vw, 12px); line-height: 1.55; color: rgba(239, 235, 228, 0.6); }
.doc-go { margin-left: auto; font-size: 9px; font-weight: 700; letter-spacing: 2px; text-transform: uppercase; color: var(--signal); flex-shrink: 0; }

/* ── Guides ─────────────────────────────────────────────────────*/
/* scroll-margin-top so a #guides jump from the homepage does not land the
   heading flush under the fixed wordmark. */
.cat-guides { --card: clamp(240px, 28vw, 380px); padding: clamp(44px, 8vh, 90px) 0 clamp(28px, 5vh, 48px); scroll-margin-top: 60px; }
.cat-guides .reel-wrap { margin: 0 calc(var(--gutter) * -1); }
.section-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px 20px; padding-bottom: clamp(14px, 2.4vh, 24px); }
/* One line under the eyebrow, for a run that needs saying what it is for.
   Wraps under it rather than beside it once the two cannot share a line. */
.section-note { flex: 1 1 30ch; min-width: 0; font-size: clamp(11px, 1.05vw, 13px); line-height: 1.6; color: rgba(239, 235, 228, 0.6); }

.guide-card { display: flex; flex-direction: column; gap: 10px; padding: clamp(20px, 3vh, 30px); border: 1px solid var(--hair); min-height: clamp(150px, 22vh, 210px); }
.guide-card:hover { border-color: var(--signal); }
.guide-tag { font-size: 8px; font-weight: 700; letter-spacing: 1.6px; text-transform: uppercase; color: var(--signal); }

/* A paid card reads differently at a glance, before the eye even reaches the
   title: the tag is the price, not a category, so it earns the fill the
   free and reading tags don't get. */
.guide-tag--paid { display: inline-block; padding: 2px 6px; background: var(--signal); color: var(--void); }
.guide-tag--free { color: rgba(239, 235, 228, 0.5); }

/* ── The email gate ────────────────────────────────────────────── */
.unlock-form { display: flex; flex-wrap: wrap; gap: clamp(10px, 1.6vw, 16px); max-width: 520px; }
.unlock-input {
  flex: 1 1 260px;
  padding: 15px 18px;
  background: transparent;
  border: 1px solid var(--hair);
  color: var(--bone);
  font-family: inherit;
  font-size: 13px;
}
.unlock-input::placeholder { color: rgba(239, 235, 228, 0.4); }
.unlock-input:focus { outline: none; border-color: var(--signal); }
.unlock-go { flex: 0 0 auto; }
.unlock-note { margin-top: clamp(12px, 2vh, 18px); font-size: 11px; color: rgba(239, 235, 228, 0.5); }
.guide-name { font-family: 'Anton', 'Arial Narrow', Impact, sans-serif; font-size: clamp(16px, 1.8vw, 23px); text-transform: uppercase; letter-spacing: 0.01em; line-height: 1.06; }
.guide-go { margin-top: auto; font-size: 9px; font-weight: 700; letter-spacing: 2px; text-transform: uppercase; color: var(--signal); }

/* ── Articles ───────────────────────────────────────────────────
   The long-form pages behind rows no product search can answer. One
   measure, generous leading: these are read, not scanned. */
.art-series { display: block; margin-bottom: clamp(10px, 1.6vh, 16px); font-size: 9px; font-weight: 700; letter-spacing: 4px; text-transform: uppercase; color: var(--signal); }
.art-title { font-size: clamp(30px, 6.4vw, 84px); max-width: 20ch; }

/* A title that has to stay on one line. The measure comes off and the size
   is capped a second time against the viewport, because nowrap alone would
   push a 24 character title straight off a phone screen. Anton runs about
   0.42em per character, so 24 characters need roughly 8.5vw to fit inside
   the gutters. */
.art-title--one-line { max-width: none; white-space: nowrap; font-size: min(clamp(30px, 6.4vw, 84px), 8.4vw); }
.art-lede { margin-top: clamp(18px, 3vh, 32px); max-width: 62ch; font-size: clamp(13px, 1.4vw, 17px); line-height: 1.6; color: rgba(239, 235, 228, 0.78); }

.art-body { max-width: 78ch; padding-bottom: clamp(40px, 7vh, 90px); }
.art-h2 { margin: clamp(34px, 6vh, 64px) 0 clamp(12px, 2vh, 20px); font-size: clamp(19px, 2.4vw, 32px); }
.art-p { margin-bottom: 16px; font-size: clamp(13px, 1.2vw, 16px); line-height: 1.75; color: rgba(239, 235, 228, 0.8); }

.art-list { margin: 4px 0 18px; }
.art-list li { position: relative; padding: 7px 0 7px 22px; font-size: clamp(12px, 1.15vw, 15px); line-height: 1.65; color: rgba(239, 235, 228, 0.76); }
.art-list li::before { content: '+'; position: absolute; left: 0; color: var(--signal); font-weight: 700; }

/* Anything the reader should not skim past: the disclaimer, the caveat. */
.art-note {
  margin: clamp(18px, 3vh, 30px) 0;
  padding: clamp(16px, 2.4vh, 22px) clamp(16px, 2vw, 24px);
  border-left: 3px solid var(--signal);
  background: rgba(239, 235, 228, 0.05);
  font-size: clamp(11px, 1.05vw, 13px);
  line-height: 1.7;
  color: rgba(239, 235, 228, 0.7);
}

/* Label and value on one hairline row. For a page that answers with a number
   instead of an argument, so there is nothing to read past. */
.art-spec { margin: clamp(4px, 1vh, 10px) 0 clamp(20px, 3.4vh, 34px); border-top: 1px solid var(--hair); }

.art-spec-row {
  display: grid;
  grid-template-columns: minmax(0, 0.34fr) minmax(0, 1fr);
  gap: clamp(10px, 2vw, 28px);
  padding: clamp(11px, 1.7vh, 16px) 0;
  border-bottom: 1px solid var(--hair);
}

.art-spec dt { font-size: 9px; font-weight: 700; letter-spacing: 2px; text-transform: uppercase; color: var(--signal); padding-top: 3px; }
.art-spec dd { font-size: clamp(13px, 1.35vw, 17px); line-height: 1.5; color: var(--bone); }

/* A contact row's value is the link. Underlined rather than coloured: on a
   page that is nothing but four rows, four red lines would be the loudest
   thing on it. */
.chan { text-decoration: underline; text-underline-offset: 3px; text-decoration-color: var(--hair); transition: color 0.2s, text-decoration-color 0.2s; }
.chan:hover { color: var(--signal); text-decoration-color: var(--signal); }

@media (max-width: 700px) {
  .art-spec-row { grid-template-columns: 1fr; gap: 5px; }
}

.art-embed { margin: clamp(18px, 3vh, 30px) 0; border: 1px solid var(--hair); background: rgba(239, 235, 228, 0.04); }
.art-embed iframe { display: block; width: 100%; border: 0; }

.art-banner { display: block; margin: clamp(24px, 4vh, 46px) 0; }
.art-banner img { width: 100%; height: auto; max-width: 728px; }

.art-cta { margin: clamp(10px, 2vh, 18px) 14px clamp(10px, 2vh, 18px) 0; }

/* ── The split card ─────────────────────────────────────────────
   Key facts on the left, one product sample on the right, pointing at the
   page that carries the whole shelf. It sits outside .art-body because two
   columns in a 78ch measure are two very narrow columns; the generator gives
   it its own full-width wrap.

   Only the heading links out. The shot and the buy button are their own
   targets (a product photo and an Amazon link mean two different things),
   so the card cannot be one big anchor the way it was before it carried a
   picture. */
.asplit {
  display: grid;
  grid-template-columns: minmax(0, 1.35fr) minmax(0, 1fr);
  gap: clamp(18px, 2.6vw, 40px);
  margin: clamp(10px, 2vh, 20px) 0 clamp(30px, 5vh, 60px);
  align-items: start;
}

.asplit-l .art-h2 { margin-top: 0; }
.asplit-l .art-list { margin-bottom: 0; }

.asplit-r {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(14px, 2vh, 20px);
  padding: clamp(22px, 3vw, 36px);
  border: 1px solid var(--hair);
  background: rgba(239, 235, 228, 0.04);
  text-align: center;
}

.asplit-title-link {
  font-size: clamp(22px, 2.8vw, 38px);
  line-height: 1.02;
  color: var(--bone);
  transition: color 0.2s;
}

.asplit-title-link:hover { color: var(--signal); }

/* Bone, same reason a safe or a bag shot is bone anywhere else on the site:
   a product photo on white needs a light ground to multiply into. */
.asplit-shot {
  width: 100%;
  aspect-ratio: 4 / 3;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--bone);
  overflow: hidden;
}

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

.asplit-go.is-placeholder,
.asplit-go.is-placeholder:hover { opacity: 0.4; background: var(--void); color: var(--bone); cursor: default; }

@media (max-width: 800px) {
  .asplit { grid-template-columns: 1fr; }
}

/* ── Guides: list first ─────────────────────────────────────────
   No intro and no standfirst. One dry spec line under the title says how
   big the thing is, and everything below it is the list. */
.gspec { margin-top: clamp(16px, 2.6vh, 26px); font-size: clamp(11px, 1.1vw, 13px); letter-spacing: 1px; text-transform: uppercase; color: rgba(239, 235, 228, 0.55); }
.cat-head .gspec + .btn { margin-top: clamp(18px, 3vh, 28px); }

/* The number column and the gap after it are one variable, because the open
   list has to start exactly under the section name and there is no shared
   ancestor to align them with. Change either here and both move together. */
.guide-body { --gnum: 14px; --ggap: clamp(12px, 2vw, 24px); padding-bottom: clamp(30px, 5vh, 60px); }
.gsec { border-bottom: 1px solid var(--hair); }
.gsec:first-child { border-top: 1px solid var(--hair); }

.gsec-head { font-weight: inherit; }

.gsec-trigger {
  width: 100%;
  display: flex;
  align-items: center;
  gap: var(--ggap);
  padding: clamp(16px, 2.6vh, 26px) 0;
  text-align: left;
  transition: color 0.2s;
}

.gsec-trigger:hover { color: var(--signal); }
.gsec-num { width: var(--gnum); font-size: 10px; font-weight: 700; color: var(--signal); flex-shrink: 0; }
.gsec-name { flex: 1; font-size: clamp(17px, 2.4vw, 30px); }
.gsec-count { font-size: 9px; font-weight: 700; color: var(--signal); flex-shrink: 0; }
.gsec-icon { font-size: 17px; font-weight: 800; flex-shrink: 0; transition: transform 0.3s ease; }
.gsec.open .gsec-icon { transform: rotate(45deg); }

.gsec-body { max-height: 0; overflow: hidden; transition: max-height 0.45s ease; }
.gsec.open .gsec-body { max-height: 2400px; transition: max-height 0.65s ease; }
.gsec-list { padding-left: calc(var(--gnum) + var(--ggap)); padding-bottom: clamp(16px, 2.6vh, 26px); }

.gitem {
  display: grid;
  grid-template-columns: minmax(0, 0.42fr) minmax(0, 1fr);
  gap: clamp(10px, 2vw, 28px);
  padding: clamp(9px, 1.4vh, 13px) 0;
  border-bottom: 1px solid rgba(239, 235, 228, 0.09);
}

.gitem:last-child { border-bottom: none; }
.gitem-name { font-size: clamp(12px, 1.2vw, 15px); font-weight: 600; color: var(--bone); }
.gitem-note { font-size: clamp(11px, 1.1vw, 14px); line-height: 1.6; color: rgba(239, 235, 228, 0.62); }

@media (max-width: 700px) {
  .gitem { grid-template-columns: 1fr; gap: 4px; }
}

/* ── Skills grid ────────────────────────────────────────────────
   The bridge from "what to trade" to "how to learn it". Each tile ends in
   a real book from books.json, so the page hands off to the shelf rather
   than repeating it. */
.skills { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 1px; margin: clamp(20px, 3.4vh, 34px) 0; background: var(--hair); border: 1px solid var(--hair); }

.skill { display: flex; flex-direction: column; gap: 10px; padding: clamp(18px, 2.6vh, 26px); background: var(--void); }
.skill-name { font-size: clamp(16px, 1.9vw, 24px); color: var(--bone); }
.skill-why { font-size: clamp(11px, 1.05vw, 13px); line-height: 1.6; color: rgba(239, 235, 228, 0.66); }

.skill-book { display: flex; align-items: center; gap: 12px; margin-top: auto; padding-top: 14px; border-top: 1px solid var(--hair); transition: color 0.2s; }
.skill-book:hover { color: var(--signal); }
.skill-cover { flex: 0 0 auto; width: 46px; display: flex; align-items: center; }
.skill-cover img { width: 100%; height: auto; }
.skill-cover .book-plate { aspect-ratio: 2 / 3; padding: 5px; box-shadow: none; }
.skill-cover .book-plate-t { font-size: 7px; }
.skill-cover .book-plate-b { display: none; }
.skill-meta { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.skill-learn { font-size: 8px; font-weight: 700; letter-spacing: 1.6px; text-transform: uppercase; color: var(--signal); }
.skill-title { font-size: 11px; line-height: 1.35; }

/* ── Footer ─────────────────────────────────────────────────────*/
.foot {
  display: flex;
  flex-wrap: wrap;
  gap: 14px 32px;
  align-items: center;
  margin-top: clamp(30px, 5vh, 60px);
  padding: clamp(18px, 2.6vh, 28px) 0 clamp(28px, 4vh, 48px);
  border-top: 1px solid var(--hair);
  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); }

@media (max-width: 860px) {
  .row-content { grid-template-columns: 1fr; row-gap: 18px; }
  .row-go { justify-self: start; }
  .ess { grid-template-columns: 1fr; gap: 14px; }
  .ess-cover { height: clamp(140px, 20vh, 190px); }
  .vol { grid-template-columns: clamp(52px, 14vw, 72px) minmax(0, 1fr); row-gap: 12px; }
  .vol-go { grid-column: 1 / -1; justify-self: start; }
  .doc-go { display: none; }
}

/* ── The product page ───────────────────────────────────────────
   One page, one thing to buy. The title carries the same red accent the
   printed sheets use for their own titles, so the product and the thing
   you get out of it are visibly the same object. */
.prod-title em { font-style: normal; color: var(--signal); }

.prod-buy { display: flex; flex-wrap: wrap; align-items: center; gap: clamp(12px, 2vw, 20px); margin-top: clamp(20px, 3.4vh, 34px); }
.prod-buy-note { font-size: 11px; color: rgba(239, 235, 228, 0.5); }

/* The five sheets as a numbered run, not cards: it is a list of what is in
   a box, and a list is what says that fastest. */
.prod-sheets { padding-bottom: clamp(30px, 5vh, 60px); }
.sheets { border-top: 1px solid var(--hair); }

.sheet-row {
  display: grid;
  grid-template-columns: 3.5ch minmax(0, 1fr) auto;
  align-items: baseline;
  gap: clamp(12px, 2vw, 24px);
  padding: clamp(14px, 2.2vh, 20px) 0;
  border-bottom: 1px solid var(--hair);
}

.sheet-n { font-size: 10px; font-weight: 700; color: var(--signal); }
.sheet-t { font-size: clamp(15px, 2vw, 26px); color: var(--bone); }
.sheet-note { font-size: 10px; letter-spacing: 1px; text-transform: uppercase; color: rgba(239, 235, 228, 0.45); }

@media (max-width: 640px) {
  .sheet-row { grid-template-columns: 3.5ch minmax(0, 1fr); }
  .sheet-note { grid-column: 2; }
}

/* A button with nothing behind it yet. Not a link, so it cannot be clicked
   into a dead checkout, and dimmed so it reads as pending rather than as a
   control that failed. */
.btn.is-soon { background: rgba(239, 235, 228, 0.12); color: rgba(239, 235, 228, 0.55); cursor: default; }
