/* ============================================================
   Hidden Temple - set-page "composition" redesign (shared)
   ------------------------------------------------------------
   Generalized from the approved Daiichi Pan sample
   (<style id="daiichi-redesign-v1">). Linked LAST on every set
   page, after banner.css and mobile.css, so it wins the cascade
   (with !important where the page's inline block or mobile.css
   would otherwise take it).

   Nothing in any page's markup is added, removed or reworded.
   This file only decides where the words sit, how large they are
   and what marks them - carrying the approved composition:

     - one shared page axis (1200px measure, 32px inset) that the
       masthead, both section marks and the grid all hang on,
       left-ranged rather than centred. 1200px is the site-wide
       grid width used by ~630 set pages (the sample's own value);
       a handful of 1100px grids sit only ~50px inside it, so the
       masthead still ranges left directly over the grid;
     - the eyebrow becomes an engraved SECTION MARK: a short heavy
       bronze rule, the words in Plex Mono, then a stacked
       double-rule running out to the right edge;
     - Cinzel for the name, a Cormorant italic teal <em> for the
       descriptive part, a bronze drop-cap opening the standfirst;
     - three type voices, three jobs - Cinzel names, Cormorant
       prose, Plex Mono labels;
     - hover in which nothing moves: a bronze rule draws in - no
       lift, no scale, no shadow.

   SCOPING
   -------
   * Every body-level selector is prefixed
       html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page)
     so the three bespoke pages (Hyper Sticker Collection 1 and the
     two Topsun 3 pages) stay completely untouched even if the link
     is present.
   * The card restyle targets .set-tile:not(.pack-art-tile) only, so
     pack-art / product-shot tiles keep their .ph-f/.ph-b photo-slot
     layout; only standard grid tiles become engraved plates.
   ============================================================ */

:root {
  /* 2026-09-12 root-cause fix RC1. This was a flat 1200px, which fights the
     tiered desktop body zoom in banner.css (0.85 from 600px, 0.8 from 1300px).
     `zoom` scales painted pixels but the body's LAYOUT width becomes
     viewport/zoom, so a 1280px window lays out at 1506 CSS px and a 1900px
     window at 2375: a 1200px measure painted 1020 visual px (80% of the screen)
     at 1280 and 960 (51%) at 1900. The wider the monitor, the smaller the share
     of it the page used - the opposite of what a max-width is for.
     The value below is not invented: it is the measure the pages Chris has
     already approved carry in their own stylesheets, read off the rendered
     pages (relics `min(1600px, 100%)`, codex and market `1600px`). Adopting it
     puts every page on the approved pages' own axis: 100% of a 1280px screen
     and 67.4% of a 1900px one, matching relics/codex/market exactly, and it
     stops growing at 1600 CSS px so a 2560 monitor does not inflate the page
     (htc-compact-not-oversized). Below ~1200px of layout width the 100% arm
     wins and nothing changes, so phones and tablets are untouched.
     --dc-max is consumed by the masthead (:54), the standfirst/about band
     (:207) and the checklist wrapper (:341), so one value re-ranges all three
     together and the page keeps a single left edge. */
  --dc-max: min(1600px, 100%);
  --dc-inset: 32px;
  --dc-bronze: #d9b877;
  --dc-teal: #bfeeea;
  --dc-ink: #b9c8c6;
  --dc-rule: rgba(139, 115, 68, 0.34);
  --dc-rule-strong: rgba(139, 115, 68, 0.56);
}

/* ---------- 1. the shared page axis + masthead ---------- */
html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) .page-head {
  max-width: var(--dc-max) !important;
  margin: 0 auto !important;
  /* 2026-09-12 root-cause fix RC3, part 2 of 2 (part 1 is the hero pull-up in
     section 13). The head spent clamp(10px,1.6vw,18px) of its own padding plus
     the back-link and eyebrow rows - 108px above the title at 1280 against 41px
     on the approved pages. The padding tightens here; the two row margins
     tighten at :74 and :109. Measured, not guessed: the stack is
     padding-top + back-link box + its margin + eyebrow box + its margin. */
  padding: clamp(8px, 1.1vw, 14px) var(--dc-inset) clamp(20px, 2.4vw, 28px) !important;
  text-align: left !important;
  position: relative;
  z-index: 2;
}

/* the back-link: a quiet Plex Mono label with a rule that draws
   in on hover - it never boxes itself in */
html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) .page-head .relics-back {
  display: inline-flex !important;
  align-items: center !important;
  gap: 8px !important;
  font-family: 'IBM Plex Mono', monospace !important;
  font-size: 10px !important;
  letter-spacing: 0.3em !important;
  text-transform: uppercase !important;
  color: #8a9896 !important;
  text-decoration: none !important;
  /* 2026-09-12 RC3: was clamp(18px, 2.2vw, 26px). The back-link owns a row of
     its own on ~2,500 pages and that row plus its margin was 52 of the 108 CSS
     px above the title. The row is kept (it is the page's only way back up the
     archive) and the air under it is cut to the eyebrow's rhythm. */
  margin: 0 0 clamp(10px, 1.1vw, 14px) !important;
  padding: 5px 0 !important;
  border: 0 !important;
  position: relative !important;
}
html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) .page-head .relics-back::after {
  content: '' !important;
  position: absolute !important;
  left: 0 !important;
  bottom: 0 !important;
  width: 100% !important;
  height: 1px !important;
  background: linear-gradient(90deg, #c9a968, rgba(201, 169, 104, 0.05)) !important;
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 0.4s cubic-bezier(0.22, 0.8, 0.3, 1) !important;
}
html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) .page-head .relics-back:hover {
  color: var(--dc-teal) !important;
  border-color: transparent !important;
}
html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) .page-head .relics-back:hover::after { transform: scaleX(1); }

/* the eyebrow becomes the engraved section mark:
   short heavy rule -> the words -> stacked double rule to edge */
html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) .page-head .eyebrow {
  display: flex !important;
  align-items: center !important;
  gap: clamp(11px, 1.3vw, 18px) !important;
  font-family: 'IBM Plex Mono', monospace !important;
  font-size: 13px !important;
  font-weight: 500 !important;
  letter-spacing: 0.42em !important;
  text-transform: uppercase !important;
  color: var(--dc-bronze) !important;
  /* 2026-09-12 RC3: was clamp(16px, 2vw, 22px), the last of the three
     declarations that put 108px between the head's top and the title. */
  margin: 0 0 clamp(11px, 1.2vw, 15px) !important;
  line-height: 1.35 !important;
  white-space: normal !important;
  text-shadow: 0 1px 6px rgba(0, 0, 0, 0.9) !important;
}
html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) .page-head .eyebrow::before {
  content: '' !important;
  flex: none !important;
  width: clamp(20px, 2.6vw, 38px) !important;
  height: 2px !important;
  margin: 0 !important;
  background: var(--dc-bronze) !important;
  font-size: 0 !important;
}
html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) .page-head .eyebrow::after {
  content: '' !important;
  flex: 1 1 auto !important;
  height: 7px !important;
  margin: 0 !important;
  font-size: 0 !important;
  background:
    linear-gradient(90deg, var(--dc-rule-strong), rgba(139, 115, 68, 0.06)) top left / 100% 1px no-repeat,
    linear-gradient(90deg, rgba(139, 115, 68, 0.30), rgba(139, 115, 68, 0.03)) bottom left / 100% 1px no-repeat !important;
}

/* the name: Cinzel, with the descriptive part in Cormorant italic teal */
html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) .page-head .page-title {
  font-family: 'Cinzel', serif !important;
  font-weight: 900 !important;
  font-size: clamp(26px, 3.4vw, 40px) !important;
  line-height: 0.98 !important;
  letter-spacing: 0.02em !important;
  color: #e6efed !important;
  margin: 0 0 clamp(16px, 2vw, 22px) !important;
  text-shadow: 0 2px 18px rgba(0, 0, 0, 0.9) !important;
}
html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) .page-head .page-title em {
  font-family: 'Cormorant Garamond', serif !important;
  font-style: italic !important;
  font-weight: 400 !important;
  color: var(--dc-teal) !important;
  text-shadow: 0 0 46px rgba(109, 181, 176, 0.28) !important;
}

/* the standfirst: Cormorant prose, opened by a bronze drop-cap */
html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) .page-head .page-sub {
  font-family: 'Cormorant Garamond', serif !important;
  font-size: clamp(15px, 1.15vw, 18px) !important;
  line-height: 1.5 !important;
  font-weight: 500 !important;
  color: #d5e0de !important;
  max-width: 66ch !important;
  margin: 0 !important;
  text-align: left !important;
  text-wrap: pretty;
}
html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) .page-head .page-sub::first-letter {
  float: left;
  font-family: 'Cinzel', serif;
  font-weight: 900;
  font-size: 2.3em;
  line-height: 0.82;
  margin: 0.05em 0.16em 0 0;
  color: var(--dc-bronze);
  text-shadow: 0 2px 16px rgba(0, 0, 0, 0.95), 0 0 30px rgba(201, 169, 104, 0.20);
}
html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) .page-head .page-sub strong {
  color: var(--dc-bronze) !important;
  font-weight: 600 !important;
}

/* ---------- 2. meta-badges -> engraved chips ---------- */
html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) .page-head .meta-badges {
  display: flex !important;
  flex-wrap: wrap !important;
  justify-content: flex-start !important;
  gap: 8px !important;
  margin-top: clamp(16px, 2vw, 22px) !important;
}
html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) .page-head .meta-badges .meta-badge {
  display: inline-flex !important;
  align-items: center !important;
  gap: 8px !important;
  padding: 6px 12px !important;
  border: 1px solid var(--dc-rule) !important;
  border-radius: 0 !important;
  background: rgba(10, 20, 22, 0.55) !important;
  font-family: 'IBM Plex Mono', monospace !important;
  font-size: 10px !important;
  letter-spacing: 0.22em !important;
  text-transform: uppercase !important;
  color: #8a9896 !important;
}
html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) .page-head .meta-badges .meta-badge .k { color: var(--dc-bronze) !important; }
html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) .page-head .meta-badges .meta-badge .v { color: var(--dc-teal) !important; font-weight: 600 !important; }

/* ---------- 3. section headers -> engraved section marks ---------- */
html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) .sticker-head {
  max-width: var(--dc-max) !important;
  margin: clamp(36px, 4.5vw, 56px) auto clamp(14px, 1.8vw, 20px) !important;
  padding: 0 var(--dc-inset) !important;
}
html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) .sticker-head h2 {
  display: flex !important;
  align-items: center !important;
  gap: clamp(11px, 1.3vw, 18px) !important;
  font-family: 'IBM Plex Mono', monospace !important;
  font-weight: 500 !important;
  font-size: 13px !important;
  letter-spacing: 0.32em !important;
  text-transform: uppercase !important;
  color: var(--dc-bronze) !important;
  padding: 0 !important;
  border: 0 !important;
  line-height: 1.35 !important;
  white-space: normal !important;
}
html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) .sticker-head h2::before {
  content: '' !important;
  flex: none !important;
  width: clamp(20px, 2.6vw, 38px) !important;
  height: 2px !important;
  background: var(--dc-bronze) !important;
}
html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) .sticker-head h2::after {
  content: '' !important;
  flex: 1 1 auto !important;
  height: 7px !important;
  background:
    linear-gradient(90deg, var(--dc-rule-strong), rgba(139, 115, 68, 0.06)) top left / 100% 1px no-repeat,
    linear-gradient(90deg, rgba(139, 115, 68, 0.30), rgba(139, 115, 68, 0.03)) bottom left / 100% 1px no-repeat !important;
}
html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) .sticker-head .sh-sub {
  font-family: 'IBM Plex Mono', monospace !important;
  font-size: 10px !important;
  letter-spacing: 0.22em !important;
  color: #8a9896 !important;
  text-transform: uppercase !important;
  margin-top: 8px !important;
}

/* ---------- 4. grid cards -> engraved plates, hover draws a rule ----------
   sharp corners, a thin bronze border, a dark fill; on hover
   nothing moves - a bronze rule draws in along the bottom edge.

   SCOPE (two selector forms, see below):
     F1  .set-tile:not(.pack-art-tile)
         - standard grid tiles: plain checklists AND families whose
           tiles carry per-sticker .ph-f/.ph-b photo slots
           (ensky / merlin / carddass etc.). These are NEVER given
           the pack-art-tile class by parent-pack-art.js.
     F2  .set-tile.pack-art-tile.has-parent-thumb
         - grid tiles that parent-pack-art.js enriched with an
           injected parent thumbnail (.set-tile-thumb) and tagged
           pack-art-tile + has-parent-thumb. This is EVERY tile on
           the approved Daiichi sample, so it must be engraved to
           match the signed-off look.

   What stays UNTOUCHED: the real product-shot tiles
   (.set-tile.pack-art-tile WITHOUT has-parent-thumb, i.e. the
   static .ph-f/.ph-b photo-slot product shots). Those live in the
   separate .pack-art section outside .sets-wrap, and the extra
   has-parent-thumb guard protects them even if one ever sits in a
   grid. This is a deliberate refinement of the sample's requested
   ":not(.pack-art-tile)": that literal form would have stripped the
   engraving from the entire Daiichi grid, because the sample page's
   tiles are all runtime pack-art-tiles. */
html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) .sets-wrap .set-tile:not(.pack-art-tile),
html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) .sets-wrap .set-tile.pack-art-tile.has-parent-thumb {
  position: relative !important;
  border: 1px solid var(--dc-rule) !important;
  border-radius: 0 !important;
  background: rgba(10, 20, 22, 0.5) !important;
  padding: 14px !important;
  overflow: hidden !important;
  transition: border-color 0.25s ease, background 0.3s ease, color 0.25s ease !important;
}
html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) .sets-wrap .set-tile:not(.pack-art-tile)::after,
html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) .sets-wrap .set-tile.pack-art-tile.has-parent-thumb::after {
  content: '' !important;
  position: absolute !important;
  left: 0 !important;
  bottom: 0 !important;
  width: 100% !important;
  height: 2px !important;
  background: linear-gradient(90deg, var(--dc-bronze) 0%, rgba(201, 169, 104, 0.06) 100%) !important;
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 0.42s cubic-bezier(0.22, 0.8, 0.3, 1) !important;
  z-index: 2 !important;
}
html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) .sets-wrap .set-tile:not(.pack-art-tile):hover,
html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) .sets-wrap .set-tile.pack-art-tile.has-parent-thumb:hover {
  border-color: var(--dc-rule-strong) !important;
  background: rgba(15, 28, 30, 0.72) !important;
  transform: none !important;
  box-shadow: none !important;
}
html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) .sets-wrap .set-tile:not(.pack-art-tile):hover::after,
html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) .sets-wrap .set-tile.pack-art-tile.has-parent-thumb:hover::after { transform: scaleX(1); }

/* ---------- 5. the checklist grid joins the page axis ----------
   The masthead, both section marks and the pack-art block all hang on the
   1200px measure above, but the numbered checklist did not: an auto-generated
   <style id="AUTO-checklist-width"> block on ~1430 pages releases .sets-wrap to
   max-width:none with a clamp(20px,2.5vw,48px) inset, so above ~1264px the grid
   ran full-bleed from x32 to x1568 while the h1 above it started at x345. Three
   competing left edges on one page.

   These two rules put the grid back on the shared axis, and the three bespoke
   pages stay exempt through the same html body:not(...) prefix as everything
   else here.

   About `:is(#ht-set-axis, .sets-wrap)`: 1146 of the 1431 AUTO blocks scope
   themselves by the section's id (`html body.<page> #<slug>-checklist`), which
   no id-free selector can out-rank however many classes it names. `:is()`
   takes the specificity of its most specific argument, so naming a sentinel id
   alongside the real class lifts these rules to (1,3,2) - above the AUTO
   block's (1,1,2) - while still matching on `.sets-wrap` alone. #ht-set-axis
   is not an element on any page and is not meant to become one; it exists only
   to carry that weight. The remaining 285 AUTO blocks use the plain
   `.sets-wrap` form and were already out-ranked.

   The column count has to come with it. The AUTO block asks for six columns
   above 1300px, which was already tight at full bleed (the two photo wells in
   a tile wrap onto separate lines rather than sitting side by side) and would
   be ~181px per tile inside a 1200px measure. Four columns give each tile
   ~276px on the axis - wider than the six-up tiles were before - so the change
   buys legibility as well as alignment. Widths below 1301px are untouched:
   there the viewport inset and the axis inset resolve within a few px of each
   other anyway. */
html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) :is(#ht-set-axis, .sets-wrap) {
  max-width: var(--dc-max) !important;
  margin-left: auto !important;
  margin-right: auto !important;
  padding-left: var(--dc-inset) !important;
  padding-right: var(--dc-inset) !important;
}
@media (min-width: 1301px) {
  html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) :is(#ht-set-axis, .sets-wrap) .sets-grid {
    grid-template-columns: repeat(4, minmax(0, 1fr)) !important;
  }
}

/* ---------- 6. the pack-art block names itself once ----------
   A .pack-art section prints its own heading ("Pack Art") and then a single
   product tile whose .sn / .snm carry the same words. Every page therefore
   hides that tile's labels in its own inline block - and mobile.css undid it
   below 600px with `.set-tile .snm{display:block !important}`, so phones got
   the heading twice: the eyebrow at the top of the block and a second, larger
   "Pack Art" sitting under the wells.

   Re-assert the page's intent, scoped two ways so it can only ever hit the
   duplicate: the section must already carry a .pack-art-head (no heading, no
   duplication, labels stay), and the tile must be a real product pack-art tile
   rather than a checklist tile that parent-pack-art.js tagged (those live in
   .sets-wrap, never in .pack-art). HSC1's promo-tile is excluded twice over -
   by the body prefix and by class. */
html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) .pack-art:has(> .pack-art-head) .set-tile.pack-art-tile:not(.promo-tile) > .sn,
html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) .pack-art:has(> .pack-art-head) .set-tile.pack-art-tile:not(.promo-tile) > .snm {
  display: none !important;
}

/* ---------- 7. a meta chip that holds a sentence reads as a note ----------
   The chips are built for a word or two ("Year: 1998"), but some pages put a
   whole sentence in one ("Distribution: Booster packs and lottery packs, 1
   promo holo with the Perfect Album 3"). Unwrapped, that chip ran ~900px on
   its own row at desktop and stacked four lines of centred pill at 390px.
   Cap the measure and let a long value wrap as prose inside the chip: short
   chips are shorter than the cap and do not move at all. */
html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) .page-head .meta-badges .meta-badge {
  max-width: min(100%, 420px) !important;
  align-items: flex-start !important;
  white-space: normal !important;
  line-height: 1.55 !important;
  text-align: left !important;
  padding: 7px 12px !important;
}
html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) .page-head .meta-badges .meta-badge .k {
  flex: none !important;
}

/* ---------- mobile: hold the grid's 18px inset, ease spacing ---------- */
@media (max-width: 600px) {
  html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) .page-head {
    padding-left: 18px !important;
    padding-right: 18px !important;
  }
  html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) .sticker-head {
    padding-left: 18px !important;
    padding-right: 18px !important;
  }
  /* the checklist keeps the same 18px inset as the masthead and the section
     marks (mobile.css gives it 11px, which left the grid a few px outside
     every heading above it) */
  html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) :is(#ht-set-axis, .sets-wrap) {
    padding-left: 18px !important;
    padding-right: 18px !important;
  }
  html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) .page-head .eyebrow {
    font-size: 11px !important;
    letter-spacing: 0.28em !important;
    gap: 10px !important;
  }
  html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) .sticker-head h2 {
    font-size: 11px !important;
    letter-spacing: 0.26em !important;
    gap: 10px !important;
  }
  /* A phone has no width to spare, and 0.22em between every letter of a
     sentence-length chip value is what turned it into a four-line slab. Close
     the tracking up for the value only: short chips are a word or two and
     barely move, a long one reads as a note. */
  html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) .page-head .meta-badges .meta-badge .v {
    letter-spacing: 0.08em !important;
  }
}

/* ============================================================
   9. PHONES: the checklist plate at half height
   ------------------------------------------------------------
   A checklist tile measured 372-410px on a 390px phone: one card
   filled the screen and a 194-entry set ran 86 screens. The height
   was not the picture - it was everything around it. Two ~156px
   square wells, a ~50px strip reserved under each for the
   contributor credit, the item reference and the name on two
   full-width rows at 13/18px, a like row, and then a
   clamp(60px,16vw,70px) - 62px - dead band at the foot reserved for
   a 44px anvil icon that only needed the corner. Roughly 44 pages
   also pin their tiles to a min-height floor (352px is the common
   value in the astryx card blocks), so trimming content alone would
   have changed nothing on them.

   This block halves the plate: wells capped and centred in their
   columns, the credit strip cut to the line it holds, the reference
   chip shrunk to its words, the name at 15px, and the anvil icon
   moved into the like row's own band so the 62px reserve goes away.
   Everything an eye or a finger needs is kept - the anvil icon
   still carries a 44px hit area through a transparent ::after, and
   the like chip keeps the one it already had.

   SPECIFICITY
   -----------
   mobile.css's phone locks reach (0,9,1) and ~44 page blocks add
   their own !important floors, so these rules borrow the
   `:is(#ht-set-axis, .sets-wrap)` device documented in section 5:
   the sentinel id (which is on no page and is not meant to become
   an element) lifts every selector here into id territory, above
   both. It also scopes the whole block to the numbered checklist -
   pack-art and product-shot grids live outside .sets-wrap and are
   untouched.

   The three bespoke pages keep the same html body:not(...) prefix
   used by every other rule in this file, so HSC1 and the two
   Topsun 3 pages never see any of it.

   2026-08-26 outlier sweep: a handful of checklist pages hold their
   .sets-grid in a wrapper other than .sets-wrap, so this phone block
   never reached them and their tiles stayed 318-671px. The narrow,
   checklist-only wrappers are folded into the :is() list for THIS
   block only (not section 5's base rules nor section 10's tablet
   block, so >=601px is left exactly as it was): .intake-wrap
   (kakumen retsuden part 1/2) and .verified-list (kakumen retsuden
   kai 1/2). The playing-cards decks and amada-accessories carry a
   bare .sets-grid with no safe wrapper and are shrunk by their own
   page-scoped <slug>-shrink-20260826 blocks. Bear Walker COA
   (.coa-wrap) is deliberately left out: its own inline style records
   that the shared sheet was measured and rejected there because it
   collapses the landscape COA photo slots and truncates ~37 labels,
   so that page keeps its bespoke layout like the hsc1/tg3/tsg3 set.
   ============================================================ */
@media (max-width: 600px) {

  /* --- the grid: tiles sit closer together --- */
  html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) :is(#ht-set-axis, .sets-wrap, .intake-wrap, .verified-list) .sets-grid {
    gap: 8px !important;
  }

  /* --- the plate: no artificial floor, tighter inset and rows --- */
  html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) :is(#ht-set-axis, .sets-wrap, .intake-wrap, .verified-list) .sets-grid > .set-tile {
    /* one dial for every photo well on the plate; it tracks the
       viewport so a 600px phone is not left with capped wells and a
       lake of empty plate beside them */
    --tm-well: clamp(84px, 26vw, 150px);
    min-height: 0 !important;
    height: auto !important;
    padding: 6px 7px 8px !important;
    row-gap: 3px !important;
    column-gap: 6px !important;
  }
  /* the 62px band that only existed to hold a 44px icon */
  html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) :is(#ht-set-axis, .sets-wrap, .intake-wrap, .verified-list) .sets-grid > .set-tile:has(.anvil-toggle.anvil-img) {
    padding-bottom: 8px !important;
  }
  html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) :is(#ht-set-axis, .sets-wrap, .intake-wrap, .verified-list) .sets-grid > .set-tile.ht-anvil-pad {
    padding-right: 7px !important;
  }

  /* --- the wells: square, capped, centred in their column ---
     Capping the width rather than squashing the box keeps the well
     square, so a portrait card and a landscape sticker are both
     shown whole (background-size:contain) at the new height. Empty
     wells take exactly the same size as filled ones. */
  html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) :is(#ht-set-axis, .sets-wrap, .intake-wrap, .verified-list) .sets-grid > .set-tile > .ph-f,
  html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) :is(#ht-set-axis, .sets-wrap, .intake-wrap, .verified-list) .sets-grid > .set-tile > .ph-b,
  html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) :is(#ht-set-axis, .sets-wrap, .intake-wrap, .verified-list) .sets-grid > .set-tile > .ph-f1,
  html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) :is(#ht-set-axis, .sets-wrap, .intake-wrap, .verified-list) .sets-grid > .set-tile > .ph-f2,
  html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) :is(#ht-set-axis, .sets-wrap, .intake-wrap, .verified-list) .sets-grid > .set-tile > .body > .ph-f,
  html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) :is(#ht-set-axis, .sets-wrap, .intake-wrap, .verified-list) .sets-grid > .set-tile > .body > .ph-b {
    width: 100% !important;
    max-width: var(--tm-well) !important;
    height: auto !important;
    min-height: 0 !important;
    aspect-ratio: 1 / 1 !important;
    justify-self: center !important;
    margin-left: auto !important;
    margin-right: auto !important;
    margin-top: 0 !important;
    padding: 3px !important;
  }
  html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) :is(#ht-set-axis, .sets-wrap, .intake-wrap, .verified-list) .sets-grid > .set-tile > .ph-f.has-img,
  html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) :is(#ht-set-axis, .sets-wrap, .intake-wrap, .verified-list) .sets-grid > .set-tile > .ph-b.has-img,
  html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) :is(#ht-set-axis, .sets-wrap, .intake-wrap, .verified-list) .sets-grid > .set-tile > .ph-f1.has-img,
  html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) :is(#ht-set-axis, .sets-wrap, .intake-wrap, .verified-list) .sets-grid > .set-tile > .ph-f2.has-img {
    padding: 0 !important;
  }
  /* the strip under a filled well is the credit line, not a margin:
     one 10px line plus air, in place of clamp(48px,13vw,56px) */
  html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) :is(#ht-set-axis, .sets-wrap, .intake-wrap, .verified-list) .sets-grid > .set-tile > .ph-f.has-img,
  html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) :is(#ht-set-axis, .sets-wrap, .intake-wrap, .verified-list) .sets-grid > .set-tile > .ph-b.has-img,
  html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) :is(#ht-set-axis, .sets-wrap, .intake-wrap, .verified-list) .sets-grid > .set-tile > .ph-f1.has-img,
  html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) :is(#ht-set-axis, .sets-wrap, .intake-wrap, .verified-list) .sets-grid > .set-tile > .ph-f2.has-img {
    margin-bottom: 15px !important;
  }
  html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) :is(#ht-set-axis, .sets-wrap, .intake-wrap, .verified-list) .sets-grid > .set-tile > .ph-f:not(.has-img),
  html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) :is(#ht-set-axis, .sets-wrap, .intake-wrap, .verified-list) .sets-grid > .set-tile > .ph-b:not(.has-img),
  html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) :is(#ht-set-axis, .sets-wrap, .intake-wrap, .verified-list) .sets-grid > .set-tile > .ph-f1:not(.has-img),
  html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) :is(#ht-set-axis, .sets-wrap, .intake-wrap, .verified-list) .sets-grid > .set-tile > .ph-f2:not(.has-img) {
    margin-bottom: 0 !important;
  }

  /* --- captioned photo columns (the ht-card fp2/fp3/fp4 family) ---
     Front / 1st Back / 2nd Back sit in a single row of small wells;
     the caption becomes a label again rather than a headline. */
  html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) :is(#ht-set-axis, .sets-wrap, .intake-wrap, .verified-list) .sets-grid .set-tile .fp-cols {
    gap: 5px !important;
    margin-bottom: 0 !important;
  }
  html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) :is(#ht-set-axis, .sets-wrap, .intake-wrap, .verified-list) .sets-grid .set-tile .fp-col {
    gap: 2px !important;
  }
  html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) :is(#ht-set-axis, .sets-wrap, .intake-wrap, .verified-list) .sets-grid .set-tile .fp-col > .ph-f,
  html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) :is(#ht-set-axis, .sets-wrap, .intake-wrap, .verified-list) .sets-grid .set-tile .fp-col > .ph-b {
    max-width: var(--tm-well) !important;
    height: auto !important;
    min-height: 0 !important;
    margin-bottom: 0 !important;
  }
  html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) :is(#ht-set-axis, .sets-wrap, .intake-wrap, .verified-list) .sets-grid .set-tile .fp-cl {
    font-size: 8px !important;
    line-height: 1.15 !important;
    letter-spacing: 0.03em !important;
  }
  html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) :is(#ht-set-axis, .sets-wrap, .intake-wrap, .verified-list) .sets-grid .set-tile .fp-meta {
    gap: 2px !important;
  }

  /* --- one contributor-credit voice, at label size --- */
  html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) :is(#ht-set-axis, .sets-wrap, .intake-wrap, .verified-list) .sets-grid .set-tile .ht-credit,
  html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) :is(#ht-set-axis, .sets-wrap, .intake-wrap, .verified-list) .sets-grid .set-tile .ph-f .ht-credit,
  html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) :is(#ht-set-axis, .sets-wrap, .intake-wrap, .verified-list) .sets-grid .set-tile .ph-b .ht-credit,
  html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) :is(#ht-set-axis, .sets-wrap, .intake-wrap, .verified-list) .sets-grid .set-tile .fp-col > .ht-credit {
    font-size: 10px !important;
    line-height: 1.2 !important;
    min-height: 0 !important;
    padding: 1px 2px !important;
    letter-spacing: 0 !important;
  }

  /* --- the reference chip shrinks to its words --- */
  html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) :is(#ht-set-axis, .sets-wrap, .intake-wrap, .verified-list) .sets-grid > .set-tile > .sn,
  html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) :is(#ht-set-axis, .sets-wrap, .intake-wrap, .verified-list) .sets-grid > .set-tile > .num,
  html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) :is(#ht-set-axis, .sets-wrap, .intake-wrap, .verified-list) .sets-grid > .set-tile > .body .sn,
  html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) :is(#ht-set-axis, .sets-wrap, .intake-wrap, .verified-list) .sets-grid .set-tile .fp-nl .sn {
    font-size: 10px !important;
    line-height: 1.2 !important;
    padding: 2px 6px !important;
    letter-spacing: 0.1em !important;
    width: auto !important;
    max-width: 100% !important;
    justify-self: start !important;
  }

  /* --- the name --- */
  html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) :is(#ht-set-axis, .sets-wrap, .intake-wrap, .verified-list) .sets-grid > .set-tile > .snm,
  html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) :is(#ht-set-axis, .sets-wrap, .intake-wrap, .verified-list) .sets-grid > .set-tile > .body .snm,
  html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) :is(#ht-set-axis, .sets-wrap, .intake-wrap, .verified-list) .sets-grid .set-tile .fp-nl .snm {
    font-size: 15px !important;
    line-height: 1.15 !important;
  }

  /* --- the type / print pill and any Japanese line --- */
  html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) :is(#ht-set-axis, .sets-wrap, .intake-wrap, .verified-list) .sets-grid > .set-tile > .sty,
  html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) :is(#ht-set-axis, .sets-wrap, .intake-wrap, .verified-list) .sets-grid > .set-tile > .jp,
  html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) :is(#ht-set-axis, .sets-wrap, .intake-wrap, .verified-list) .sets-grid > .set-tile > .body .sty,
  html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) :is(#ht-set-axis, .sets-wrap, .intake-wrap, .verified-list) .sets-grid > .set-tile > .body .jp,
  html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) :is(#ht-set-axis, .sets-wrap, .intake-wrap, .verified-list) .sets-grid .set-tile .fp-type {
    font-size: 9px !important;
    line-height: 1.25 !important;
  }
  html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) :is(#ht-set-axis, .sets-wrap, .intake-wrap, .verified-list) .sets-grid > .set-tile > .body {
    gap: 3px !important;
    margin-top: 0 !important;
  }

  /* --- the like chip and the anvil share one band at the foot ---
     The chip keeps the invisible ::after that already grows it to a
     44px target; the row simply reserves the corner the icon sits in. */
  html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) :is(#ht-set-axis, .sets-wrap, .intake-wrap, .verified-list) .sets-grid .set-tile .ht-like-row {
    margin-top: 1px !important;
    padding-right: 40px !important;
    min-height: 26px !important;
    align-items: center !important;
  }
  html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) :is(#ht-set-axis, .sets-wrap, .intake-wrap, .verified-list) .sets-grid .set-tile .ht-like-chip {
    font-size: 10px !important;
    letter-spacing: 0.06em !important;
    padding: 3px 8px !important;
    min-height: 22px !important;
    gap: 5px !important;
  }
  html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) :is(#ht-set-axis, .sets-wrap, .intake-wrap, .verified-list) .sets-grid .set-tile .ht-like-chip .ht-like-heart {
    font-size: 11px !important;
  }

  /* the anvil icon reads at 30px and is hit at 44px */
  html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) :is(#ht-set-axis, .sets-wrap, .intake-wrap, .verified-list) .sets-grid .set-tile .anvil-ctl .anvil-toggle.anvil-img.anvil-img {
    width: 30px !important;
    height: 30px !important;
    min-width: 30px !important;
    min-height: 30px !important;
    padding: 1px !important;
    right: 6px !important;
    bottom: 6px !important;
  }
  html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) :is(#ht-set-axis, .sets-wrap, .intake-wrap, .verified-list) .sets-grid .set-tile .anvil-ctl .anvil-toggle.anvil-img.anvil-img::after {
    content: '' !important;
    position: absolute !important;
    inset: -7px !important;
  }

  /* --- the "+ Photo" invitation, sized for the smaller well ---
     On TCG pages the well already holds the official card scan and the
     button sits over its foot, so at 44px it would have covered nearly
     half the art once the well came down to ~100px. 36px keeps a
     comfortable thumb target and gives the card back its face. */
  html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page):not([class*="karuta-"]) :is(#ht-set-axis, .sets-wrap, .intake-wrap, .verified-list) .sets-grid .set-tile .ht-addphoto {
    font-size: 10px !important;
    min-height: 36px !important;
    width: min(100%, 86px) !important;
    padding: 5px 2px !important;
    letter-spacing: 0.04em !important;
    line-height: 1.1 !important;
  }
}

/* ---------- 10. small tablets / narrow windows (601-760px) ----------
   The phone block stops at 600px, and above it the same ~44 page
   min-height floors were holding a 2-up tile at 357px around an 85px
   pair of wells - most of the plate was reserved emptiness. Release
   the floor and close the rows up; the wells are already trimmed to
   100px here by ht-set-grid.css, so they are left alone. */
@media (min-width: 601px) and (max-width: 760px) {
  html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) :is(#ht-set-axis, .sets-wrap) .sets-grid > .set-tile {
    min-height: 0 !important;
    height: auto !important;
    padding: 10px 10px 12px !important;
    row-gap: 6px !important;
  }
  html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) :is(#ht-set-axis, .sets-wrap) .sets-grid > .set-tile > .snm,
  html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) :is(#ht-set-axis, .sets-wrap) .sets-grid > .set-tile > .body .snm {
    font-size: 17px !important;
    line-height: 1.2 !important;
  }
  html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) :is(#ht-set-axis, .sets-wrap) .sets-grid .set-tile .ht-credit {
    font-size: 10px !important;
    line-height: 1.2 !important;
    min-height: 0 !important;
  }
  /* 44px was reserved under every filled well for a caption that is one
     10px line tall */
  html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) :is(#ht-set-axis, .sets-wrap) .sets-grid > .set-tile > .ph-f.has-img,
  html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) :is(#ht-set-axis, .sets-wrap) .sets-grid > .set-tile > .ph-b.has-img,
  html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) :is(#ht-set-axis, .sets-wrap) .sets-grid > .set-tile > .ph-f1.has-img,
  html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) :is(#ht-set-axis, .sets-wrap) .sets-grid > .set-tile > .ph-f2.has-img {
    margin-bottom: 18px !important;
  }
  html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) :is(#ht-set-axis, .sets-wrap) .sets-grid > .set-tile > .ph-f:not(.has-img),
  html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) :is(#ht-set-axis, .sets-wrap) .sets-grid > .set-tile > .ph-b:not(.has-img) {
    margin-bottom: 0 !important;
  }
}

/* ============================================================
   11. EMPTY / LOADING PHOTO-WELL PLACEHOLDER  (shared)
   ------------------------------------------------------------
   Kills the "wall of black empty tiles". A photo well with no
   photo yet used to be a flat near-black void; every genuinely
   empty or still-loading well now reads as a mounted, empty plate
   - a subtle teal / near-black mat (the same tone filled wells use
   behind a letterboxed photo, HT_PHOTO_MAT) with a faint centred
   temple (torii) mark, and, WHILE a photo is actively loading, a
   soft bronze shimmer sweep.

   STATE MODEL (judged entirely from markup the producers set, so
   no page needs editing):
     - painted photo        -> .ph-*.has-img (neither ph class)
                               : the real photo, no placeholder.
     - deferred, queued but
       not yet painted      -> .ph-*.has-img.ht-ph-load
                               (banner-anvil-cart.js htLazyPaint adds it,
                                htPaintSlot drops it) : STATIC mat +
                                ghost, no animation - so a set with
                                hundreds of below-the-fold wells never
                                runs hundreds of shimmers.
     - actively downloading -> .ph-*.has-img.ht-ph-fetch
                               (htPaintSlot adds it while the real bytes
                                load, and clears it when the <img> decodes
                                or fails) : mat + ghost + shimmer sweep.
     - genuine empty void   -> .ph-*:not(.has-img) with no injected
                               image and no "+ Photo" button
                               : mat + ghost, no shimmer.
     - "+ PHOTO" affordance  -> .ph-*:not(.has-img):has(.ht-addphoto)
                               : gets the SAME quiet mat + ghost so it
                               is no longer a black void, but the "+
                               Photo" button is never removed, hidden,
                               or obscured - it keeps sitting clearly
                               on top, so the contributor affordance is
                               fully preserved (only the black fill
                               behind it changes). The active shimmer is
                               reserved for genuinely loading wells, so
                               a +photo slot never animates.
     - inline fallback art   -> .ph-*:has(img) (e.g. the TCG
                               pokemontcg.io .ht-apifb card scan on
                               Crown Zenith) : LEFT UNTOUCHED - it
                               already shows art, it is not a void.

   SCOPE: standard grid tiles only (.set-tile:not(.pack-art-tile)),
   never the bespoke hand-drawn pages (hsc1 / tg3 / tsg3 - the Topsun
   puzzle wells each paint a slice of ONE image, so a ghost there
   would be wrong) and never the decochara pokedex checklist, which
   frames and paints its own wells. Reduced-motion drops the shimmer
   and leaves only the static ghost.
   ============================================================ */

/* one place for the three background pieces; defining them on every
   well is inert until a state rule below actually paints them. */
html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page):not(.decochara-pokedex-page)
  .set-tile:not(.pack-art-tile) :is(.ph-f, .ph-b, .ph-f1, .ph-f2) {
  --ht-ph-mat: linear-gradient(160deg, rgba(22, 40, 42, 0.90), rgba(9, 19, 21, 0.96));
  --ht-ph-mark: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 viewBox=%270 0 100 100%27%3E%3Cg fill=%27none%27 stroke=%27%23c9a968%27 stroke-opacity=%270.15%27 stroke-width=%276%27 stroke-linecap=%27round%27 stroke-linejoin=%27round%27%3E%3Cpath d=%27M13 32 H87%27/%3E%3Cpath d=%27M21 46 H79%27/%3E%3Cpath d=%27M31 32 V80%27/%3E%3Cpath d=%27M69 32 V80%27/%3E%3C/g%3E%3C/svg%3E");
  --ht-ph-shimmer: linear-gradient(100deg, rgba(201, 169, 104, 0) 40%, rgba(201, 169, 104, 0.13) 50%, rgba(201, 169, 104, 0) 60%);
}

/* JOB 2 - reserve the box before the image lands. A defensive square
   fallback: wells that already carry an explicit height (nearly all,
   on desktop) keep it because a set height wins over aspect-ratio; a
   well left at auto height gets a reserved square so the grid never
   reflows as async photos arrive. No !important, so no page is
   overridden. */
html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page):not(.decochara-pokedex-page)
  .set-tile:not(.pack-art-tile) > :is(.ph-f, .ph-b, .ph-f1, .ph-f2) {
  aspect-ratio: 1 / 1;
}

/* Empty well (a genuine void OR a "+ Photo" slot): mat + ghost, no shimmer
   (it is not loading). Wells that already carry inline fallback art - the
   TCG API card scan (.ht-apifb) - are excluded with :not(:has(img)); they
   are not voids. The "+ Photo" button, when present, is a child that keeps
   painting on top of this background untouched. */
html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page):not(.decochara-pokedex-page)
  .set-tile:not(.pack-art-tile) :is(.ph-f, .ph-b, .ph-f1, .ph-f2):not(.has-img):not(:has(img)) {
  background-image: var(--ht-ph-mark), var(--ht-ph-mat) !important;
  background-repeat: no-repeat !important;
  background-position: center, center !important;
  background-size: 44% auto, cover !important;
}

/* Deferred (queued, below the fold): the SAME static mat + ghost as an
   empty well, so a not-yet-painted photo slot is never a black void while
   the visitor scrolls toward it. No animation - hundreds of these can exist
   at once on a big set. */
html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page):not(.decochara-pokedex-page)
  .set-tile:not(.pack-art-tile) :is(.ph-f, .ph-b, .ph-f1, .ph-f2).ht-ph-load {
  background-image: var(--ht-ph-mark), var(--ht-ph-mat) !important;
  background-repeat: no-repeat !important;
  background-position: center, center !important;
  background-size: 44% auto, cover !important;
}

/* Actively downloading: the same mat + ghost, plus the bronze shimmer
   sweep on top. htPaintSlot clears .ht-ph-fetch the instant the photo
   decodes, so only the handful of wells genuinely fetching at once
   animate, and the real photo then replaces the placeholder cleanly. */
html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page):not(.decochara-pokedex-page)
  .set-tile:not(.pack-art-tile) :is(.ph-f, .ph-b, .ph-f1, .ph-f2).ht-ph-fetch {
  background-image: var(--ht-ph-shimmer), var(--ht-ph-mark), var(--ht-ph-mat) !important;
  background-repeat: no-repeat !important;
  background-position: 150% 0, center, center !important;
  background-size: 200% 100%, 44% auto, cover !important;
  animation: ht-ph-shimmer 1.35s ease-in-out infinite !important;
}
@keyframes ht-ph-shimmer {
  0%   { background-position: 150% 0, center, center; }
  100% { background-position: -150% 0, center, center; }
}

/* Soft fade as the real photo (the SEO <img class="ph-img">) arrives
   over the retained plate mat, so the placeholder does not snap. */
html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page):not(.decochara-pokedex-page)
  .set-tile:not(.pack-art-tile) :is(.ph-f, .ph-b, .ph-f1, .ph-f2) > img.ph-img {
  animation: ht-ph-imgin 0.45s ease both;
}
@keyframes ht-ph-imgin { from { opacity: 0; } to { opacity: 1; } }

/* Reduced motion: no shimmer, no fade - just the static ghost. The
   shimmer highlight is parked off the well so no bright band is frozen
   mid-sweep. */
@media (prefers-reduced-motion: reduce) {
  html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page):not(.decochara-pokedex-page)
    .set-tile:not(.pack-art-tile) :is(.ph-f, .ph-b, .ph-f1, .ph-f2).ht-ph-fetch {
    animation: none !important;
    background-position: 150% 0, center, center !important;
  }
  html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page):not(.decochara-pokedex-page)
    .set-tile:not(.pack-art-tile) :is(.ph-f, .ph-b, .ph-f1, .ph-f2) > img.ph-img {
    animation: none !important;
  }
}

/* ============================================================
   12. LABEL CONTAINMENT  (shared, every width)   2026-08-26
   ------------------------------------------------------------
   Two label boxes are capped to the box they belong to - the
   "+ Photo" chip inside a captioned photo column is held to
   max-width:calc(100% - Npx) of its slot, and the .fp-cl print
   caption is as wide as the column it labels - yet both were
   also set white-space:nowrap. The words were then wider than
   the box that draws their border: "+ Photo" crossed the
   chip's own border on both sides, and "1st Print" ran out of
   its plate into the next column's caption, so the row read
   "1ST PRINT2ND PRINT".
   Allowing them to wrap is containment only. A label that
   already fits is unaffected - nowrap and normal render the
   same when there is room - and a label that does not fit
   takes a second line INSIDE its own box. No tile, well, grid
   or column changes size, and the three bespoke pages keep
   their own rules.
   Deliberately NOT applied to the plain `.ph-f > .ht-addphoto`
   chip: that one is auto-width and hangs under its well, where
   wrapping would break a line that fits today.
   ============================================================ */
html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) :is(#ht-set-axis, .sets-wrap, .intake-wrap, .verified-list) .sets-grid .set-tile .fp-col .ht-addphoto,
html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) :is(#ht-set-axis, .sets-wrap, .intake-wrap, .verified-list) .sets-grid .set-tile .fp-cl {
  white-space: normal !important;
}

/* Same fault, second home: on the product-shot and pack-art bands the
   generated page blocks seat the chip INSIDE the well with
   width:max-content capped by max-width:100%, and pin white-space:nowrap
   at (0,11,2). On a narrow phone well the cap bites and "+ Photo" paints
   past the chip's border and the well's. width:max-content means a chip
   with room still never wraps, so this only ever acts where the cap bites.
   The repeated class is the house trick (see .anvil-img.anvil-img above)
   for outranking those page blocks without inventing a page id. */
html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) :is(section.sticker-head, .pack-art) .sets-grid .set-tile :is(.ph-f, .ph-b, .ph-f1, .ph-f2) .ht-addphoto.ht-addphoto.ht-addphoto.ht-addphoto {
  white-space: normal !important;
}

/* ============================================================
   13. THE SHARED-LAYER ROOT-CAUSE FIXES            2026-09-12
   ------------------------------------------------------------
   The 2026-09-12 sitewide design audit
   (data/research/draft-sitewide-design-audit-2026-09-12.json)
   measured all 2,562 built pages in a real browser and found that
   three defects in THIS layer and in the two injected runtime
   controls account for nearly every polish failure on the site.
   Two of the three are answered above, in place, where the faulty
   declaration lived (RC1 at :43, RC3's head stack at :56, :74 and
   :109). The rest are new rules and live here.

   The shape of every fix below is the one the Tretta family refit
   shipped and Chris verified live on 2026-09-12: the same axis for
   the masthead, both runtime disclosures and the checklist; the gap
   between the two disclosures DECLARED, twice, so margin collapse
   cannot close it; and the neon arcade heading replaced by the
   archive's engraved section mark. That block is scoped
   body[class*="tretta"] and out-ranks everything here by one
   class-level term, so the 23 Tretta pages keep their own shipped
   handling untouched and this layer carries the same treatment to
   the rest of the archive.

   NOT touched by this batch, deliberately:
     * the desktop body zoom in banner.css (it is the reason the
       measure had to change, not a fault of its own; Chris settled
       the tiers on 2026-08-05 and the hero band on 2026-08-21),
     * every checklist tile rule and the grid's own column counts -
       the 4-column rule in section 5 and each page's own grid are
       left exactly as they are, so no tile, well, credit or Anvil
       control moves,
     * the three bespoke pages, excluded here by the same
       html body:not(...) prefix used by every rule in this file.
   ============================================================ */

/* ---------- 13a. RC3 part 1: the masthead comes up under the banner ----------
   The approved pages overlap the hero band by ~20 painted px
   (relics: head top 317.5 against a banner bottom of 337.1 at
   1280); set pages began at exactly banner-bottom because the
   shared rule at :55 hard-sets `margin: 0 auto !important`, which
   no page could override. The pull-up is the recorded masthead
   recipe's own value (htc-astryx-composition-rollout /
   htc-compact-not-oversized) and it is desktop-only, as the recipe
   states. It is scoped to a head that actually FOLLOWS the hero
   band - 2,523 of the 2,561 built pages, plus the nine that wrap it
   in <main> - so a head with other content above it can never be
   dragged up over that content. Nothing here re-enables the
   banner-wrap ::after dissolve (banner.css:61), and nothing needs
   it: .page-head already carries position:relative and z-index:2
   from :58, so it simply paints over the band's bottom edge. */
@media (min-width: 1101px) {
  html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) .banner-wrap + .page-head,
  html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) .banner-wrap + main > .page-head {
    margin-top: clamp(-26px, -1.8vw, -16px) !important;
  }
}

/* ---------- 13b. RC2: one owner for the gap, one axis for both disclosures ----------
   Two runtime controls sit between the masthead and the checklist:
   the ABOUT fold that collapse-page-intros.js lifts out of the page
   description, and the MISSING AN ITEM chip that missing-item.js
   mounts as the first child of the checklist wrapper. Each assumed
   the other supplied the space between them - the fold declared
   `margin:16px auto 0`, the chip `margin:0 auto 14px` - so their
   borders landed on the same line at every width on 1,501 pages,
   which is the collision Chris screenshotted. The fold also centred
   itself on its own 820px measure while the masthead ranged left on
   the page measure, so the composition broke its left edge mid-page
   (audit class D4b, 1,501 pages).

   The gap now has ONE declared owner and is declared TWICE:
     1. assets/js/collapse-page-intros.js declares the fold's own
        bottom margin (`margin:16px auto 18px`). That is the owner,
        and it is the guarantee on the 45 pages that inject the fold
        without linking this sheet.
     2. this rule re-declares it on .ht-info-fold, and the checklist
        wrapper carries the same value as padding-top. With space on
        both sides of the boundary no margin collapse can close it.
   assets/js/missing-item.js is NOT an owner: .htmi-wrap keeps
   margin-top:0, and tools/shared-layout-contract-regression.cjs
   asserts that, so the "each assumes the other" ambiguity cannot
   come back through either file. */
html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) .ht-info-fold {
  max-width: var(--dc-max) !important;
  margin: clamp(10px, 1.2vw, 14px) auto clamp(16px, 1.9vw, 22px) !important;
  padding-left: var(--dc-inset) !important;
  padding-right: var(--dc-inset) !important;
  text-align: left !important;
}
/* A fold lifted out of a .page-intro / .page-sub is inserted INSIDE .page-head
   (1,216 pages), which already supplies the axis inset, so the rule above would
   indent it twice: box 32px inside the masthead, summary 64px in. Pull its box
   back out to the head's own edges and keep the inset as padding, so the summary
   ranges on exactly the h1's left edge and the box shares the masthead's measure
   like every other fold. --dc-inset is redefined to the phone inset at <=600px
   below, so this arithmetic is correct at every width and can never push the box
   outside the viewport. */
html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) :is(.page-head, #ht-set-axis, .sets-wrap, .sticker-head) .ht-info-fold {
  max-width: none !important;
  margin-left: calc(-1 * var(--dc-inset)) !important;
  margin-right: calc(-1 * var(--dc-inset)) !important;
}
/* The in-set search input is the third injected control in this stack
   (banner-anvil-cart.js declares `.ht-set-search-wrap{width:100%;margin-top:14px}`
   - a top margin and no bottom one, the same half-a-gap that caused RC2), and on
   the pages where it lands directly above the chip the two butt together at 0px.
   Same principle, same shape: the control that ends declares the space below
   itself. Measured on pokemon-amada-accessories and pokemon-bandai-pokemon-kids,
   where the search input and the chip shared an edge before this rule. */
html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) .ht-set-search-wrap {
  margin-bottom: clamp(12px, 1.5vw, 18px) !important;
}
html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) :is(#ht-set-axis, .sets-wrap) {
  padding-top: clamp(16px, 1.9vw, 22px) !important;
}
/* The chip when it is NOT mounted inside .sets-wrap: missing-item.js gives it
   .htmi-inset-none in the wrap (where the wrap already supplies the inset and
   releases the cap), and on every other mount it keeps its own `max-width:1200px`
   - the same stale measure RC1 replaced. Put that mount on the page axis too,
   and leave .htmi-inset-none exactly as the script sets it. */
html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) .htmi-wrap:not(.htmi-inset-none) {
  max-width: var(--dc-max) !important;
  margin-left: auto !important;
  margin-right: auto !important;
  padding-left: var(--dc-inset) !important;
  padding-right: var(--dc-inset) !important;
}

/* ---------- 13c. the legacy neon section heading becomes the engraved mark ----------
   149 pages painted their section headings with a five-colour arcade
   neon cycle (teal / hot pink / yellow / blue / red in Bungee
   Outline, each with a four-layer glow), declared in each page's own
   inline <style> as `.series-head:nth-of-type(5n+1..5)`. It is the
   loudest thing on those pages and it is off the Temple palette
   entirely - "a bare TRETTA CHECKLIST neon heading instead of the
   redesign masthead", in Chris's words. The treatment below is the
   archive's own engraved section mark, identical to the one section
   3 gives .sticker-head h2 and to the one the Tretta refit shipped:
   a short heavy bronze rule, the words in Plex Mono, then a stacked
   double rule running out to the measure.

   It reads no text: the mark is drawn entirely with ::before and
   ::after, so a heading that says "Series 2" or "Uncut Sheets"
   rather than "CHECKLIST" gets the same treatment and degrades to
   exactly the same composition. All 155 pages that use .series-head
   link this sheet, so none is left half-treated. The 64px top margin
   the neon rule carried is cut with it - that margin is also what
   widened the gap under the about band.

   On the face: the font-family below is declared for consistency with
   every other section mark in this file, and like all of them it is
   superseded at runtime. assets/css/temple-typography.css carries
   Chris's site-wide "no monospace type" rule inside
   `@layer ht-typography` as `html body * { font-family:
   var(--ht-font-body) !important }`, and an !important declaration in
   a layer out-ranks every unlayered !important on the site, so the
   archive's labels all render in the body face by his own directive.
   What actually retires the neon look is everything else here: the
   bronze colour, no glow shadow, no outline stroke, ranging left, and
   the engraved rules. Those are what the render proof measures. */
/* THE GUARD, and why it is one :not(:has(a, b)) and not two :not()s.
   The mark makes the heading a flex container, which is how every section mark
   in this file draws its rules. On two TCG promo pages the markup leaves the
   heading unclosed, so the browser's corrected tree puts the whole checklist
   INSIDE the heading element: flex then laid 68 tiles out in one row, squeezed
   to 30px, and pushed them past a 390px viewport. Mobile has to stay
   overflow-clean, so a heading that wraps checklist content is left exactly as
   it is (evidence/root-cause-20260912/headwrap.json enumerates them: 2 of 166).
   The two exclusions are collapsed into ONE :not(:has(.set-tile, .sets-grid))
   deliberately: :has() takes the specificity of its most specific argument, so
   this form keeps the selector at (0,5,2) - equal to the shipped Tretta refit
   block and earlier in the cascade - where two separate :not()s would have
   reached (0,6,2) and started overriding that family's own shipped handling. */
html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) .series-head:not(:has(.set-tile, .sets-grid)),
html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) .group-label:not(:has(.set-tile, .sets-grid)) {
  display: flex !important;
  align-items: center !important;
  gap: clamp(11px, 1.3vw, 18px) !important;
  font-family: 'IBM Plex Mono', monospace !important;
  font-weight: 500 !important;
  font-size: 13px !important;
  letter-spacing: 0.32em !important;
  line-height: 1.35 !important;
  text-transform: uppercase !important;
  text-align: left !important;
  color: var(--dc-bronze) !important;
  text-shadow: none !important;
  -webkit-text-stroke: 0 !important;
  border-bottom: 0 !important;
  margin: clamp(20px, 2.3vw, 28px) 0 8px !important;
  padding: 0 !important;
}
html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) .series-head:not(:has(.set-tile, .sets-grid))::before,
html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) .group-label:not(:has(.set-tile, .sets-grid))::before {
  content: '' !important;
  flex: none !important;
  width: clamp(20px, 2.6vw, 38px) !important;
  height: 2px !important;
  margin: 0 !important;
  background: var(--dc-bronze) !important;
  font-size: 0 !important;
}
html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) .series-head:not(:has(.set-tile, .sets-grid))::after,
html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) .group-label:not(:has(.set-tile, .sets-grid))::after {
  content: '' !important;
  flex: 1 1 auto !important;
  height: 7px !important;
  margin: 0 !important;
  font-size: 0 !important;
  background:
    linear-gradient(90deg, var(--dc-rule-strong), rgba(139, 115, 68, 0.06)) top left / 100% 1px no-repeat,
    linear-gradient(90deg, rgba(139, 115, 68, 0.30), rgba(139, 115, 68, 0.03)) bottom left / 100% 1px no-repeat !important;
}
/* the count a .group-label carries stays a label, not a headline */
html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) .group-label .gcount {
  flex: none !important;
  margin: 0 !important;
  color: #8a9896 !important;
  font-size: 10px !important;
  letter-spacing: 0.22em !important;
}
html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) .series-sub {
  font-family: 'IBM Plex Mono', monospace !important;
  font-size: 10px !important;
  letter-spacing: 0.22em !important;
  color: #8a9896 !important;
  text-align: left !important;
  text-transform: uppercase !important;
  margin: 0 0 clamp(12px, 1.5vw, 18px) !important;
}

/* ---------- 13d. phones ----------
   Mobile is overflow-clean today (audit D6 = 0) and every rule above is either
   a no-op at 390 (the measure resolves to 100%, the pull-up is >=1101px only)
   or a margin. These two keep the disclosure on the same 18px inset the
   masthead and the grid use below 600px, and hold the section mark to the phone
   label size the rest of this file uses. */
@media (max-width: 600px) {
  /* The phone inset, stated once. Every rule in this file that uses
     var(--dc-inset) - the masthead padding, the section marks, the checklist
     wrapper - already overrides itself to this exact 18px below 600px, so this
     declaration changes none of them; it exists so the negative-margin
     arithmetic on an in-head fold resolves to the phone inset rather than the
     desktop one, which is what keeps that box inside a 390px viewport. */
  :root { --dc-inset: 18px; }
  html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) .ht-info-fold {
    padding-left: 18px !important;
    padding-right: 18px !important;
  }
  html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) .series-head:not(:has(.set-tile, .sets-grid)),
  html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) .group-label:not(:has(.set-tile, .sets-grid)) {
    font-size: 11px !important;
    letter-spacing: 0.24em !important;
    gap: 10px !important;
    margin-top: clamp(16px, 4vw, 22px) !important;
  }
  /* RC3 on a phone. There is no pull-up below 1101px (the recipe's own rule), so
     the whole distance from the hero band to the title is head chrome: 103px
     against 37 on the approved pages. The three margins above come down again
     here, and the breadcrumb's tracking closes from 0.28em to 0.20em with a
     tighter line box - which is what lets a two-line breadcrumb fit one line on
     the ~250 pages measured carrying one, and costs a one-line breadcrumb
     nothing. 11px is the archive's label floor and it is kept. */
  /* The head's own padding-top is deliberately NOT tightened again here. It was
     taken to 6px in a first pass and measured: it bought nothing (0 pages moved
     under the ceiling at 390, because the eyebrow's line box is what decides
     that) and it shifted the-crier's page-owned back-link 2px into a 1.7px
     overlap with its own search field. A change that buys no polish and costs a
     hairline collision is not worth making, so the base clamp stands. */
  html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) .page-head .relics-back {
    margin-bottom: 8px !important;
  }
  html body:not(.hsc1-page):not(.tg3-page):not(.tsg3-page) .page-head .eyebrow {
    letter-spacing: 0.20em !important;
    line-height: 1.2 !important;
    /* 11px, not the 9px a first pass used. Measured both ways: the 2px bought
       nothing at all (0 of 814 pages crossed the D1 ceiling either way, because
       the breadcrumb's line COUNT is what decides that, and the tracking above is
       what changes it) and it pulled everything below the masthead up far enough
       to close the-crier's own back-link against its own search field. The 2px
       stays spent on the rhythm. */
    margin-bottom: 11px !important;
  }
}
