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

   Loaded after category.css by every inner page that runs as a deck of
   full-screen snapping panels rather than as a document: the Books and
   Knowledge category, and the four checklist guides. The homepage keeps its
   own copy of these rules in home.css, because it is the only page that
   locks the document without ever loading category.css, and because its
   panels carry a different structure inside each one.

   Two halves, and only the first is generic:

     .deck / .deck-panel / .panel-head / .panel-body
       the mechanics, identical wherever a deck is used

     .gd-panel--*
       what a checklist guide's four panels do with them. The books page's
       own five panels live in books.css, which loads after this file.

   The rule that makes any of it survivable: a panel is exactly one viewport
   tall and never grows. Anything that does not fit scrolls inside the panel,
   in .panel-body, which is also what stops an opening accordion from
   dragging the deck to a different panel underneath the reader.
   ─────────────────────────────────────────────────────────────── */

/* The deck scrolls, not the document, so the fixed wordmark and menu never
   fight the snap points. */
.deck-doc,
.deck-doc body { height: 100%; overflow: hidden; }

.deck {
  height: var(--h);
  overflow-y: scroll;
  scroll-snap-type: y mandatory;
  scroll-behavior: smooth;
  scrollbar-width: none;
}

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

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

/* The part of a panel that holds still: title, eyebrow, the red seam. */
.panel-head { flex: 0 0 auto; }

/* The part that gives way. Its own scroller, so a long shelf or a run of
   documents is reachable without the deck moving off the panel, and so the
   accordion below can grow without the page under it sliding. */
.panel-body {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  overflow-y: auto;
  overflow-x: hidden;
  scrollbar-width: none;
  overflow-anchor: none;
  -webkit-overflow-scrolling: touch;
}

/* A scroller inside a snap target of a `y mandatory` deck is a gesture
   conflict on a touch screen: the drag meant for the panel body is routinely
   taken by the deck, which snaps to the next panel instead. The
   recommended-gear panel of the evacuation-bags guide holds 811px below the
   fold of a 640px screen, and a phone could not reliably reach it.

   Both conditions matter. Unconditional, `contain` blocks chaining even where
   this box has nothing to scroll — which is most panels — and a wheel over
   one then moves nothing at all. And a pointer never had the problem in the
   first place: it cannot hand a drag to the wrong scroller, and a wheel has
   no gesture boundary at which a contained scroller could release it. The
   reasoning is written out once over .gear-scroll in home.css. */
@media (pointer: coarse) {
  .panel-body.is-scrollable-y { overscroll-behavior-y: contain; }
}

.panel-body::-webkit-scrollbar { display: none; }

/* The scrollbar is hidden, so with the panel exactly one screen tall there
   was nothing at all to say the content continued. Set by inner.js on the
   panels whose content actually overflows; the mask fades the last 28px, the
   same device .row-types uses sideways. */
.panel-body.is-scrollable-y {
  -webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - 28px), transparent 100%);
  mask-image: linear-gradient(to bottom, #000 calc(100% - 28px), transparent 100%);
}
.panel-body > .wrap { flex: 1 0 auto; display: flex; flex-direction: column; }

/* ── A checklist guide, as a deck ───────────────────────────────
   Four panels, in the order a reader needs them:

     01  the title and the list        what you came for
     02  the Paranoid Action Plan      what the whole set is
     03  the books                     where to read further
     04  where it goes                 documents only: safes and bags

   The four checklist guides run the same four (three, for the three that
   have nothing to store) so that moving between them is moving through the
   same page with different contents, which is the whole argument for a deck
   over a document. */

/* On a deck the title is the top of a panel rather than the top of a
   document, and the list underneath needs the room more than the white
   space above it does.

   The title also gains a ceiling in vh. Everywhere else on the site a
   headline is sized against the width of the screen, because width is what
   it has to fit across. Here it shares one panel with a list of up to
   twelve sections, so the thing it is really competing for is height, and
   on a 620px laptop window a 77px headline was taking the twelfth section
   off the bottom of the screen. */
/* The bottom padding is not decoration: the list's first section carries a
   hairline across the top, and with nothing under the button the two met
   exactly, which reads as a button sitting on a rule rather than above one.
   Small, because every pixel here is a pixel the twelve-section list does
   not get, but never zero. */
.gd .cat-head { padding: max(calc(clamp(38px, 6.5vh, 74px) + var(--ticker-band)), var(--chrome-h)) 0 clamp(16px, 2.6vh, 30px); }
.gd .cat-head .art-title { font-size: min(var(--t-page), 12vh); }
.gd .cat-head .art-lede { margin-bottom: 0; }
.gd .cat-head .btn { margin-top: clamp(11px, 2vh, 26px); }

/* ── 01 The title and the list ──────────────────────────────────
   The whole list on one screen with the title above it. A checklist whose
   sections have to be scrolled to be counted is not a checklist, it is the
   first two thirds of one, and the longest of the four runs to twelve
   sections. */
.gd-panel--list .guide-body,
.gd-panel--list .guide-body > .wrap {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
}

.gd-panel--list .guide-body { padding-bottom: clamp(14px, 2.6vh, 30px); }

/* While everything is closed the sections divide the panel between them, so
   the list is the screen rather than a short stack with dead air under it.
   The moment one opens, its own contents need the room more than the closed
   rows below it do, and the stretching stops — at which point .panel-body
   is the scroller and the deck stays where it is. */
/* The ceiling is what stops the stretch turning into an argument. Dividing a
   panel between twelve sections gives a row of 45px and between three gives
   one of 210px, and at 210 the reader is not looking at a list any more, they
   are looking at three headings a long way apart. The cap is set just above
   the tallest row a full list produces — the seven-section guide sits at 88 —
   so every list that fills the screen is untouched and only the short ones
   stop short, which is what a short list should look like. */
.gd-panel--list .wrap:not(:has(.gsec.open)) .gsec { flex: 1 1 auto; max-height: clamp(64px, 11vh, 108px); display: flex; flex-direction: column; }
.gd-panel--list .wrap:not(:has(.gsec.open)) .gsec-head { flex: 1 1 auto; display: flex; }
.gd-panel--list .wrap:not(:has(.gsec.open)) .gsec-trigger { flex: 1 1 auto; }

/* And when the stretch stops, the rows keep the height it gave them. That
   sentence used to end the other way: the stretch stopped and every closed
   row in the list snapped back to the height of its own type, so opening one
   section redrew all seven, and the list the reader clicked at was not the
   list they were looking at a frame later. The row heights are the page's
   rhythm; a row opening is not a reason to change them.

   The floor is a pixel value because that is the only kind flex can be held
   to: grow only ever divides space that is free, and once a body is open
   there is none. inner.js measures a row at the click, while everything is
   still closed and still stretched, and writes it here. Closing the last one
   drops the selector and the stretch takes over again. */
.gd-panel--list .wrap:has(.gsec.open) .gsec { min-height: var(--gsec-row, 0px); display: flex; flex-direction: column; }
.gd-panel--list .wrap:has(.gsec.open) .gsec-head { flex: 1 1 auto; display: flex; }
.gd-panel--list .wrap:has(.gsec.open) .gsec-trigger { flex: 1 1 auto; min-height: var(--gsec-row, 0px); }

/* ── 01 on paper ────────────────────────────────────────────────
   A list panel can run on bone. The guides that lead with the list have a
   shelf under them and a shelf of books under that, both already light, and
   a void list at the top of three bone screens reads as the page changing
   its mind rather than as one page.

   data-chrome="light" is the panel saying what it stands on. inner.js reads
   the same attribute to flip the fixed wordmark and burger to void while the
   panel is in view — the ground and the chrome standing on it are one fact
   and are written once.

   Only the greys are restated. The reds carry on the bone slab as they do
   on the void one, which is the whole reason they are the accent, and the
   type colour arrives by inheritance from the panel. */
.gd-panel--list[data-chrome='light'] { background: var(--bone); color: var(--void); }
.gd-panel--list[data-chrome='light'] .cat-crumb { color: rgba(var(--rgb-void), 0.5); }
.gd-panel--list[data-chrome='light'] .gsec,
.gd-panel--list[data-chrome='light'] .gsec:first-child { border-color: var(--hair-dark); }

/* Opened, a section on the void deck flips to bone, because that is where
   the reading happens. On bone there is nothing to flip to and nothing to
   announce: the reading was always going to happen on this ground. A fill a
   shade down was tried and read as a panel dropped into the list rather than
   as the list opening, so the body keeps the page's own paper and the open
   section is marked the way it is on every other page — by the name turning
   red and the + turning into a cross. */
.gd-panel--list[data-chrome='light'] .gsec-body { background: none; }

/* The two guides with no shelves keep their title and their Action Plan
   button on the list panel, so the button lands on bone as well. It is a
   red block either way; only the hover had a ground to lose, since bone on
   bone is a button that disappears under the cursor. */
.gd-panel--list[data-chrome='light'] .btn:hover { background: var(--void); color: var(--bone); }

/* ── A whole deck on paper ──────────────────────────────────────
   `ground: "bone"` in guides.json says the page is paper rather than one
   panel of it, and lands as .gd--paper on the html tag. The shelves, the
   books and the picks were bone already and the list has data-chrome; the
   Action Plan panel is the one left.

   It keeps its red slab and loses the black around it. The slab was drawn to
   be the one loud screen in a dark deck, and on a page with no dark screens
   left the black margin round it was the only thing still arguing for the
   old ground.

   A class and not the attribute, because they answer different questions.
   data-chrome says what the fixed wordmark is standing on, and over this
   panel that is the slab — full-bleed to the top of the screen, and read
   against bone chrome since the day it was drawn. The ground behind it
   changes; what stands on it does not. */
.gd--paper .gd-panel--plan { background: var(--bone); color: var(--void); }

/* Sized for the twelve-section guide rather than the six-section one: the
   flex stretch above spreads a short list back out, so the type only has to
   be small enough that the longest list fits, not small enough to look
   mean on the shortest.

   Capped in vh for the same reason the title above is: twelve rows of type
   sized only against the width of the screen do not know how much height
   they have been given, and on a short window they overrun it together.

   The + is given a line-height because it is what a row is actually as tall
   as. At 17px on the default normal leading its line box is 22px, taller
   than the section name beside it, so every row in the list was being sized
   by the smallest thing in it and shrinking the name changed nothing. */
.gd-panel--list .gsec-trigger { padding: clamp(5px, 0.9vh, 14px) 0; }
.gd-panel--list .gsec-name { font-size: min(var(--t-row), 3.4vh); }
.gd-panel--list .gsec-icon { line-height: 1; }

/* ── 02 The Action Plan ─────────────────────────────────────────
   Centred in the panel rather than pinned under its own heading: it is the
   one panel on the page that is an argument rather than a list, and it is
   the full-bleed red slab, so it should sit in the middle of the screen it
   has taken over. */
.gd-panel--plan .panel-body { justify-content: safe center; }

/* The band's own top margin is the gap it needs when it follows a reel down
   a document. It has a whole panel to itself here, and nothing above it to
   be separated from, so the margin is only height taken away from the one
   thing on the screen. */
.gd-panel--plan .plan-band { flex: 0 0 auto; margin-top: 0; }

/* ── 03 and 04 The reels ────────────────────────────────────────
   Same treatment for both: the heading holds the top of the panel and the
   cards take the whole of what is left, centred in it.

   Centring the section's contents as a group was the obvious thing and the
   wrong one. A reel section is a heading and a row of cards, and centring
   both together puts the heading in the middle of the screen with the cards
   hanging off the bottom of it — measured on the first aid guide, that was
   14px of air above the covers and 131px below them. The heading is a
   label; labels belong at the top. Only the thing being labelled gets
   centred. */
.gd-panel--books .ess-section,
.gd-panel--picks .picks {
  flex: 1 1 auto;
  min-height: 0;
  display: flex;
  flex-direction: column;
  padding-bottom: 0;
}

/* The heading's own .wrap, which is inside the section rather than beside
   it — a detail worth naming, because the same rule written against
   .panel-body > .wrap silently matches nothing. */
.gd-panel--books .ess-section > .wrap,
.gd-panel--picks .picks > .wrap { flex: 0 0 auto; }

/* .reel-wrap is already align-items: center, so giving it the rest of the
   column is all the vertical centring the cards need. */
.gd-panel--books .reel-wrap,
.gd-panel--picks .reel-wrap { flex: 1 1 auto; min-height: 0; }

/* The heading's own bottom margin comes off inside a panel. It sits outside
   .reel-wrap, so it is space the flex centring never sees: the cards end up
   exactly centred in what is left, which is 20px lower than the middle of
   the area the reader is actually looking at. There is no shortage of air
   between a heading and a row of cards that share a whole screen. */
.gd-panel--books .picks-title,
.gd-panel--picks .picks-title { margin-bottom: 0; }
/* Both reel headings clear the top edge by at least a centimetre. The books
   heading was landing flush against it — the panel starts, and the first
   thing on the screen is a 43px headline touching the boundary with nothing
   above it. The floor is 38px rather than a proportion, because on a short
   window a vh-based value collapses to nothing exactly where the crowding
   is worst. Same figure on both so the two panels agree. */
.gd-panel--books .picks-title,
.gd-panel--picks .picks-title { padding-top: clamp(38px, 6vh, 72px); }

/* ── The footer ─────────────────────────────────────────────────
   Pinned to the foot of the last panel rather than scrolling inside it. On
   a deck the last panel IS the bottom of the page, so a footer that has to
   be scrolled to inside it is a footer the reader never reaches. */
.gd-panel:last-child > .foot-wrap { flex: 0 0 auto; }

@media (max-width: 860px) {
  /* Nothing about the deck itself changes: a panel is still one screen and
     still scrolls inside itself, the same as the books page. What stops is
     the stretch — twelve sections divided into a phone screen is twelve
     rows of type with no room around any of them. Below this width the
     sections keep their own height and .panel-body carries the overflow. */
  .gd .cat-head { padding-top: calc(clamp(40px, 6vh, 62px) + var(--ticker-band)); }
  /* Both halves of the stretch go, the growth and the ceiling with it: a
     section name that wraps to two lines on a phone is taller than the cap,
     and a cap on a row that is not being stretched can only clip it. */
  .gd-panel--list .wrap:not(:has(.gsec.open)) .gsec { display: block; max-height: none; }
  .gd-panel--list .wrap:has(.gsec.open) .gsec { display: block; }
  .gd-panel--list .wrap:has(.gsec.open) .gsec-trigger { min-height: 0; }
  .gd-panel--list .gsec-trigger { padding: clamp(9px, 1.5vh, 16px) 0; }

  /* Stacked, the band's two columns run one under the other and it stops
     fitting the panel it is the only thing in. It still scrolls inside
     .panel-body if it has to, but a sales panel the reader has to scroll
     to see the button on is a sales panel with a button nobody presses. */
  .gd-panel--plan .plan-band { padding: clamp(26px, 4vh, 44px) 0 clamp(22px, 3.4vh, 38px); }
  .gd-panel--plan .plan-band-grid { margin-top: clamp(16px, 2.6vh, 26px); gap: clamp(16px, 2.6vh, 24px); }
  .gd-panel--plan .plan-band-note { margin-top: clamp(8px, 1.4vh, 14px); }
  .gd-panel--plan .plan-foot { margin-top: clamp(14px, 2.4vh, 24px); }
}

@media (prefers-reduced-motion: reduce) {
  .deck { scroll-behavior: auto; }
}

/* ── The shelves go light ───────────────────────────────────────
   Any panel carrying products is bone, and always was: a product shot cut
   out on a transparent background needs a light ground to sit on — on void
   the dark half of every object disappears into the panel and the shelf
   reads as a row of holes. The list panel used to be the counterweight, void
   because reading is what this site does on black; `listGround` and `ground`
   in guides.json have since taken every guide's list onto paper too, and
   these rules are what the shelves brought to that.

   The ink flips with the ground. .on-light does this for the fixed chrome
   already; these are the page's own elements, which that class never
   reached because the guide decks had no light panel until now. */
.gd-panel--gear,
.gd-panel--books,
.gd-panel--picks {
  background: var(--bone);
  color: var(--void);
}

.gd-panel--gear .picks-title,
.gd-panel--books .picks-title,
.gd-panel--picks .picks-title,
.gd-panel--gear .pick-name,
.gd-panel--picks .pick-name,
.gd-panel--books .ess-name { color: var(--void); }

.gd-panel--gear .pick-spec,
.gd-panel--gear .safe-spec,
.gd-panel--picks .safe-spec,
.gd-panel--books .ess-note { color: rgba(var(--rgb-void), 0.66); }

.gd-panel--gear .safe-key,
.gd-panel--picks .safe-key {
  border-color: rgba(var(--rgb-void), 0.22);
  color: rgba(var(--rgb-void), 0.62);
}

/* The pick line is the product's own name — the one thing on the card that
   says what a reader is about to spend money on — and on these panels it has
   been invisible since the shelves went light. It is set bone at 78% over a
   bone hairline, which on the void is a quiet line under the keywords and on
   bone is nothing at all.

   It read as a hand's width of empty card between the keywords and the buy
   line. It was never empty; it was a sentence nobody could see. */
.gd-panel--gear .safe-pick {
  color: rgba(var(--rgb-void), 0.62);
  border-top-color: rgba(var(--rgb-void), 0.16);
}

.gd-panel--books .ess-by { color: rgba(var(--rgb-void), 0.5); }

/* And so does the shadow under a cover. The base rule in category.css drops
   0.6 black at 44px, which is the right shadow on the void the books page and
   the articles run on — invisible against black, and doing its work only at
   the edges. On bone the same shadow is a grey smear the width of the cover
   again, and every title on a guide deck was wearing one.

   Same values the other two light grounds already use: .books-panel on the
   homepage and .bk-panel--ess on the books page both lightened it, and this
   panel is simply the one that arrived after them. */
.gd-panel--books .ess-cover img { filter: var(--cover-shadow-bone); }

/* The reel arrows were drawn for a dark panel. */
.gd-panel--gear .reel-btn,
.gd-panel--books .reel-btn,
.gd-panel--picks .reel-btn {
  background: rgba(var(--rgb-bone), 0.7);
  border-color: rgba(var(--rgb-void), 0.18);
  color: var(--void);
}
.gd-panel--gear .reel-btn:hover,
.gd-panel--books .reel-btn:hover,
.gd-panel--picks .reel-btn:hover { background: var(--signal); color: var(--bone); }

/* ── The display scale on a deck ─────────────────────────────────
   The steps and the two laws they follow are set out over the tokens in
   base.css. This is where a deck adds the one thing a document does not
   need: a ceiling in vh on every step. A panel is exactly one screen, so a
   heading sized off the width alone can push its own content off the bottom
   of a short laptop window, and the title is not the part that should win.

   The alignment classes are what the two laws look like in markup. .t-page
   is written on the one heading that names the page; .t-panel on a heading
   that owns a screen. Only the shelf-first guides carry them, because they
   are the only pages with both on the same page. */
.cat-head .art-title.t-page {
  font-size: min(var(--t-page), 12vh);
  text-align: left;
}

/* 02, and the reason the page name above it can be this close in size: they
   are never on the same screen. */
.cat-head .art-title.t-panel {
  font-size: min(var(--t-panel), 9vh);
  text-align: center;
}

/* 03. Several of these stack inside the shelves panel, so they are a step
   below a title that owns a screen on its own. */
.gd .gd-panel--gear .picks-title { font-size: var(--t-group); }

/* Read further is the only heading on its screen, which makes it an 02 and
   not an 03, whatever it is called. */
.gd .gd-panel--books .picks-title { font-size: min(var(--t-panel), 9vh); }

/* 02, and the same ceiling: the band carries a title, a list and a button on
   one screen. */
.gd-panel--plan .plan-band-title { font-size: min(var(--t-panel), 9vh); }

/* 05. */
.gd .pick-name { font-size: var(--t-card); }

/* ── Shelf-first: the name of the thing, over the shelves ───────
   Two guides open on their shelves rather than on their list, because they
   are reached from Grab and Go by a reader who has already decided to buy a
   bag. The head that carries the page name therefore sits on the bone panel
   instead of the void one, and the crumb has to flip with it: rgba(bone, 0.5)
   on bone is nothing at all. */
.gd-panel--gear .cat-crumb { color: rgba(var(--rgb-void), 0.5); }
.gd-panel--gear .cat-crumb:hover { color: var(--signal); }

/* ── The products float ─────────────────────────────────────────
   .safe-shot used to paint a bone tile behind every shot, which put a frame
   round each product and made the shelf a row of cards. The scenario decks do
   not do that: the shot sits on the panel's own ground under a drop shadow,
   so the object reads as an object rather than as a picture of one. Now that
   the panel is bone, the tile was the only thing separating the two, and it
   was separating them for no reason.

   Bigger, too. The old box topped out at 240px on a panel that gives it more
   than twice that: these are the products the page is recommending and they
   were the smallest thing on the screen. */
.gd-panel--gear .safe-shot,
.gd-panel--picks .safe-shot {
  height: clamp(220px, 34vh, 420px);
  background: none;
}

.gd-panel--gear .safe-shot img,
.gd-panel--picks .safe-shot img {
  max-height: 100%;
  max-width: 100%;
  width: auto;
  object-fit: contain;
  /* The same shadow the scenario cards give a floating product. It falls on
     the panel's own colour, which is why the shots must not carry a baked
     one. */
  filter: drop-shadow(0 22px 30px rgba(var(--rgb-void), 0.28));
}

/* The card widens with the shot, or a 420px picture sits in a 240px column. */
.gd-panel--gear .reel { --card: clamp(240px, 30vw, 400px); }
.gd-panel--gear .reel-item { width: var(--card); }

/* ── Air above the shelf title ──────────────────────────────────
   The list panel ends on a rule and Ready Bags began immediately under it,
   so the two read as one run rather than as a list and then a shelf. */
.gd-panel--gear .picks-title { padding-top: clamp(48px, 8vh, 104px); }

/* ── Always scrollable ──────────────────────────────────────────
   A guide panel was exactly one screen and never grew, so anything past the
   fold lived in .panel-body's own scroller — which is a scroller inside a
   mandatory snap container, the one combination a touch screen handles
   worst, and the reason 800px of the evacuation-bag shelf was unreachable on
   a phone. The panels grow now and the deck scrolls through them.

   proximity rather than mandatory, for the same reason: mandatory fights a
   panel taller than the screen, pulling the reader back to the top of it
   every time they try to read the bottom. */
.gd .deck { scroll-snap-type: y proximity; }
/* min-height: var(--h) used to sit here too, flooring every panel at one
   screen. That only ever mattered for the overflow case above; for a panel
   shorter than a screen it forced .gd-panel--plan's `justify-content: safe
   center` (and .gd-panel--books' equivalent) to centre a much shorter block
   in the rest, and since .plan-band supplies its own red background rather
   than the panel doing it, the leftover space showed the page's own ground
   through as a band of colour that did not belong to either neighbour.
   height: auto alone already covers the underflow case: a panel with
   nothing to add just sizes to its content. */
.gd .deck-panel { height: auto; }
.gd .panel-body { overflow: visible; }

/* ── A slot with no photograph yet ──────────────────────────────
   Taking the bone tile off .safe-shot was right for a product — the object
   floats on the panel's own ground — and wrong for a slot that has no object
   yet. The plate lost the only thing that framed it and became faint caption
   text on a bone panel: five of the six first aid kits were on the page and
   read as one product and a lot of empty space.

   A slot held open should look held open. The outline says a picture is
   coming, which is true, rather than saying nothing, which reads as a shelf
   with one thing on it. Only where there is no image: a real product still
   floats. */
.gd-panel--gear .safe-shot:has(.safe-plate),
.gd-panel--picks .safe-shot:has(.safe-plate) {
  border: 1px solid rgba(var(--rgb-void), 0.18);
}

.gd-panel--gear .safe-plate,
.gd-panel--picks .safe-plate {
  color: rgba(var(--rgb-void), 0.5);
  font-size: clamp(13px, 1.3vw, 17px);
  padding: 0 12px;
  text-align: center;
}

/* ── The phone scrolls the document ─────────────────────────────
   The reasoning is the one written out at "A guide panel was exactly one
   screen" above, and at greater length in home.css. What changed is the
   scope. That fix answered the clipping and the nested scroller on .gd and
   left two things standing: it kept the document locked, so the address bar
   stayed pinned on every deck page, and it never reached .bk, which was
   still a mandatory snap deck 4.7 screens long.

   Below 860px every deck page is an ordinary document. No snap: these pages
   open on a title and a list rather than on a photograph, so there is no
   cover worth holding a reader on and nothing for an attractor to do. The
   homepage keeps one, because it has one. Past that, all 28 pages on the
   site now scroll the same way, which is the part a thumb actually learns. */
@media (max-width: 860px) {
  .deck-doc,
  .deck-doc body { height: auto; overflow: visible; }

  .deck-doc .deck {
    height: auto;
    overflow: visible;
    scroll-snap-type: none;
    scroll-behavior: auto;
  }

  .deck-doc { scroll-behavior: smooth; scroll-padding-top: var(--chrome-h); }

  .deck-doc .deck-panel {
    height: auto;
    min-height: 0;
    overflow: visible;
    scroll-snap-align: none;
  }

  /* Chrome clearance for the panel a reader actually lands on, rhythm for
     the rest. .gd .cat-head reserves the band on every panel that has a
     head, which is right while each one is a screen the reader arrives at.
     Stacked and scrolled, only the first panel on the page is ever parked
     under the fixed row; Safes and Secure Storage was paying 107px for it
     twice, on the shelf and again on the list below it. */
  .gd .deck-panel:not(:first-child) .cat-head {
    padding-top: clamp(38px, 6vh, 58px);
  }

  /* The panel's inner scroller hands its content back to the page. */
  .deck-doc .panel-body {
    overflow: visible;
    min-height: 0;
    flex: 0 1 auto;
  }

  /* base.css takes every reel on the site to one card width at this
     breakpoint, by setting --card on .reel itself so it resolves nearer to
     the item than any section does. This one selector outranks it: the gear
     panel of a guide deck names .reel directly, with a class in front of it,
     and deck.css is the last sheet these pages load. Without this line the
     safes shelf stayed at its 240px floor, 64% of a 375px screen, while
     every other shelf the same reader meets is at 86%. */
  .gd-panel--gear .reel { --card: min(86vw, 420px); }

  /* Nothing scrolls inside a panel any more, so the fade marks an edge that
     is not there and the containment guards a gesture that cannot happen. */
  .deck-doc .panel-body.is-scrollable-y {
    -webkit-mask-image: none;
    mask-image: none;
    overscroll-behavior-y: auto;
  }
}
