/* ============================================================
   Hidden Temple — Top Nav Bar + Banner Below (v15 — bulletproof)

   Design rules (do not break):
   - Every color is a literal hex/rgb. NO var() references.
     Pages have inline <style> blocks with their own :root vars,
     and those vars cascade through everything. Using var() here
     makes the nav look different on every page. Hardcoding
     guarantees a single, consistent nav.
   - Every property uses !important so inline page styles can't win.
   - Solid dropdown bg (multiple background-* declarations defeat
     any inherited transparency, blur, filter, opacity.)
   - The hover-bridge ::after never receives pointer-events:auto,
     so it can never swallow clicks meant for menu items.
   - z-index on .tools-menu is 9999 to win against page chrome.
   ============================================================ */

/* ===== Hide the duplicate text logo ===== */
.banner-nav .nav-brand,
.banner-nav a.nav-brand { display: none !important; }

/* ===== BANNER + NAV: full page width ===== */
.banner-wrap {
  display: flex !important;
  flex-direction: column !important;
  position: relative !important;
  width: 100% !important;
  max-width: 100% !important;
  margin-left: 0 !important;
  margin-right: 0 !important;
  background: #0a1416 !important;
  /* .banner-wrap is a <section>, and pages that style bare `section`
     (about.html sets a 1px border on all of them) were insetting the
     whole nav by a pixel. The bar's container is not the page's to
     dress. */
  border: 0 !important;
  aspect-ratio: auto !important;
  height: auto !important;
  max-height: none !important;
  min-height: 0 !important;
  overflow: visible !important;
  z-index: 1 !important;
  padding: 0 !important;
}
.banner-wrap .banner-nav { order: -1; }
.banner-wrap img.banner-img {
  order: 1;
  position: relative !important;
  inset: auto !important;
  width: 100% !important;
  height: auto !important;
  aspect-ratio: auto !important;
  object-fit: contain !important;
  object-position: center center !important;
  opacity: 1 !important;
  z-index: 1 !important;
  display: block !important;
  max-height: 360px;
  margin: 0 !important;
}
.banner-wrap::after,
.banner-wrap::before { display: none !important; }
.banner-fallback { display: none !important; }

/* ===== NAV BAR ===== */
.banner-nav {
  position: relative !important;
  top: auto !important; left: auto !important;
  right: auto !important; bottom: auto !important;
  width: 100% !important;
  max-width: 100% !important;
  margin: 0 !important;
  background: rgba(10, 20, 22, 0.97) !important;
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border-bottom: 1px solid #1f2e30 !important;
  border-top: none !important;
  padding: 14px 32px !important;
  z-index: 500 !important;
  box-sizing: border-box !important;
  /* CONSTANT HEIGHT — same on every page */
  min-height: 64px !important;

  /* ---- the bar's own tokens ----------------------------------------
     Astryx's first discipline is semantic tokens instead of raw colour
     inside a component. This file's oldest rule is the opposite - no
     var() anywhere - because pages declare their own :root palettes and
     an inherited var made the nav a different colour on every page.
     Both hold at once when the tokens are declared HERE, on the bar
     itself, under names no page uses: a declaration on the element
     always beats an inherited one, so the bar carries its palette with
     it and the palette is still written down in one place.
     Three ramps of the Temple's own colour - neutral, bronze, aged
     teal - and the roles composed out of them. Spacing is deliberately
     NOT tokenised: nearly all of it lives inside clamp(), where a token
     hides the 4px step instead of naming it, so the steps are stated at
     the point of use and every one of them is a multiple of 4.
     ---------------------------------------------------------------- */
  --ht-nav-ink:         #8fa4a1;   /* a link at rest                  */
  --ht-nav-ink-hover:   #e2ecea;   /* a link you could go to          */
  --ht-nav-bronze:      #c9a968;
  --ht-nav-bronze-lit:  #d9b877;
  --ht-nav-bronze-hi:   #f2dcab;
  --ht-nav-teal-lit:    #8ed4cf;
  --ht-nav-teal-hi:     #bfeeea;
  --ht-nav-star:        #a93942;

  /* the two rules a link can wear. Bronze says "this is the page you
     are on"; dim teal says "you could go here". Selected is the louder
     of the two - it used to be the quieter one, which is why the
     current page did not stand out from whatever the cursor was over. */
  --ht-nav-rule-here:   #c9a968;
  --ht-nav-rule-hover:  rgba(109, 181, 176, 0.55);
  --ht-nav-wash-here:   rgba(201, 169, 104, 0.10);

  /* the three controls on the right are one family: same border weight,
     same alpha, same fill, same 44px box. Only the hue changes, and it
     changes for one reason - to say which of them is you. */
  --ht-nav-ctl-line:    rgba(139, 115, 68, 0.62);
  --ht-nav-ctl-fill:    rgba(139, 115, 68, 0.05);
  --ht-nav-ctl-fill-hi: rgba(139, 115, 68, 0.20);
  --ht-nav-you-line:    rgba(109, 181, 176, 0.55);
  --ht-nav-you-fill:    rgba(109, 181, 176, 0.06);
  --ht-nav-you-fill-hi: rgba(109, 181, 176, 0.14);
}

.banner-nav .banner-nav-inner {
  max-width: 1600px !important;
  margin: 0 auto !important;
  display: grid !important;
  grid-template-columns: minmax(0,1fr) auto minmax(0,1fr) !important;
  align-items: center !important;
  gap: clamp(10px, 1.6vw, 20px) !important;
  padding: 0 !important;
  width: 100% !important;
  box-sizing: border-box !important;
}
.banner-nav .banner-nav-inner::before {
  content: '';
  display: block;
}

.banner-nav .nav-links {
  display: flex !important;
  gap: 6px !important;
  align-items: center !important;
  flex-wrap: wrap !important;
  justify-content: center !important;
  white-space: normal !important;
  overflow: visible !important;
  margin: 0 !important;
  padding: 0 !important;
  min-width: 0 !important;
  max-width: 100% !important;
}

/* ===== Nav buttons — uniform across every page ===== */
.banner-nav .nav-links > a,
.banner-nav .nav-links > .tools-dropdown > .tools-trigger {
  font-family: 'Cinzel', serif !important;
  color: #d6e2e0 !important;
  text-decoration: none !important;
  font-size: 12px !important;
  letter-spacing: 0.2em !important;
  font-weight: 500 !important;
  text-transform: uppercase !important;
  padding: 8px 14px !important;
  border: 1px solid transparent !important;
  border-radius: 0 !important;
  transition: all 0.2s ease !important;
  white-space: nowrap !important;
  text-shadow: none !important;
  cursor: pointer !important;
  display: inline-block !important;
  line-height: 1.4 !important;
  background: transparent !important;
  margin: 0 !important;
  /* Lock height so font-size from inline styles can't change it */
  height: auto !important;
  min-height: 0 !important;
}
/* 2026-08-25 button refit (Chris-approved mockup): hover draws a
   bronze-to-teal underline instead of boxing the link. Painted as a
   background layer, not a pseudo-element, so the dropdown's ::after
   caret and every existing pseudo stay untouched. */
.banner-nav .nav-links > a,
.banner-nav .nav-links > .tools-dropdown > .tools-trigger {
  background-image: linear-gradient(90deg, #c9a968, #8ed4cf) !important;
  background-repeat: no-repeat !important;
  background-position: left calc(100% - 4px) !important;
  background-size: 0% 1px !important;
  transition: color 0.25s ease, background-size 0.3s cubic-bezier(0.22, 0.8, 0.3, 1) !important;
}
.banner-nav .nav-links > a:hover,
.banner-nav .nav-links > .tools-dropdown > .tools-trigger:hover {
  color: #8ed4cf !important;
  border-color: transparent !important;
  background-size: 100% 1px !important;
}
.banner-nav .nav-links > a.active {
  color: #d6e2e0 !important;
  border-color: transparent !important;
  background-size: 100% 1px !important;
}

/* Visited-link override — kill purple/underlined Contact, etc. */
.banner-nav .nav-links > a:visited,
.banner-nav .nav-links > .tools-dropdown > .tools-trigger:visited,
.banner-nav .nav-auth a:visited {
  color: inherit !important;
  text-decoration: none !important;
}

/* ===== Tools Dropdown ===== */
.tools-dropdown {
  position: relative !important;
  display: inline-block !important;
  z-index: 600 !important;
}

/* INVISIBLE BRIDGE — keeps :hover active across the gap from
   trigger to menu. pointer-events flips to auto WHILE hovered/open,
   so the cursor can cross the 8px margin without dropping :hover.
   The bridge sits BELOW menu items in z-index, so menu links still
   receive their own clicks. */
.tools-dropdown::after {
  content: '' !important;
  position: absolute !important;
  top: 100% !important;
  left: -10px !important;
  right: -10px !important;
  height: 14px !important;
  background: transparent !important;
  pointer-events: none !important;
  z-index: 1 !important;
}
.tools-dropdown:hover::after,
.tools-dropdown.open::after {
  pointer-events: auto !important;
}

.tools-dropdown .caret {
  font-size: 0.8em !important;
  margin-left: 0.25em !important;
  display: inline-block !important;
  transition: transform 0.2s ease !important;
}
.tools-dropdown.open .caret,
.tools-dropdown:hover .caret {
  transform: rotate(180deg) !important;
}

/* ===== The actual menu — solid bg, hidden by default ===== */
.tools-dropdown .tools-menu {
  display: none !important;
  position: absolute !important;
  top: 100% !important;
  left: 50% !important;
  transform: translateX(-50%) !important;
  margin-top: 8px !important;
  min-width: 240px !important;
  /* SOLID BACKGROUND — multiple declarations defeat any
     inherited transparency, blur, filter, opacity, or
     backdrop-filter from inline page styles. */
  background: #050a0b !important;
  background-color: #050a0b !important;
  background-image: none !important;
  opacity: 1 !important;
  filter: none !important;
  -webkit-filter: none !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
  isolation: isolate !important;
  border: 1px solid #1f2e30 !important;
  border-top: 2px solid #2d5654 !important;
  box-shadow: 0 14px 36px rgba(0, 0, 0, 0.95) !important;
  padding: 8px 0 !important;
  z-index: 9999 !important;
  /* Ensure clicks land on the items, not anything underneath */
  pointer-events: auto !important;
}

/* SHOW menu on hover OR when explicitly toggled open via click */
.tools-dropdown:hover > .tools-menu,
.tools-dropdown.open > .tools-menu,
body .banner-nav .tools-dropdown:hover > .tools-menu,
body .banner-nav .tools-dropdown.open > .tools-menu,
body .nav-links .tools-dropdown:hover > .tools-menu,
body .nav-links .tools-dropdown.open > .tools-menu,
html body .tools-dropdown:hover .tools-menu,
html body .tools-dropdown.open .tools-menu {
  display: block !important;
}

.tools-dropdown .tools-menu a {
  display: block !important;
  padding: 12px 18px !important;
  text-decoration: none !important;
  border: none !important;
  border-bottom: 1px solid rgba(31, 46, 48, 0.5) !important;
  background: transparent !important;
  text-align: left !important;
  white-space: nowrap !important;
  transition: background 0.15s ease !important;
  letter-spacing: normal !important;
  text-transform: none !important;
  /* Ensure links are clickable, not blocked by the bridge or anything else */
  pointer-events: auto !important;
  cursor: pointer !important;
  position: relative !important;
  z-index: 10000 !important;
  color: #d6e2e0 !important;
}
.tools-dropdown .tools-menu a:visited { color: #d6e2e0 !important; }
.tools-dropdown .tools-menu a:last-child { border-bottom: none !important; }
.tools-dropdown .tools-menu a:hover {
  background: rgba(109, 181, 176, 0.10) !important;
}
.tools-dropdown .tools-menu a strong {
  display: block !important;
  font-family: 'Cinzel', serif !important;
  font-weight: 700 !important;
  font-size: 12px !important;
  letter-spacing: 0.18em !important;
  text-transform: uppercase !important;
  color: #8ed4cf !important;
  margin-bottom: 3px !important;
}
.tools-dropdown .tools-menu a em {
  display: block !important;
  font-family: 'Cormorant Garamond', serif !important;
  font-style: italic !important;
  font-size: 13px !important;
  letter-spacing: 0.02em !important;
  color: #8a9896 !important;
}

/* ===== Sign-in stays right ===== */
.banner-nav .nav-auth {
  display: flex !important;
  justify-content: flex-end !important;
  align-items: center !important;
  flex-wrap: wrap !important;
  gap: 8px !important;
  margin: 0 !important;
  padding: 0 !important;
  min-width: 0 !important;
  max-width: 100% !important;
}
/* 2026-08-25 button refit (Chris-approved mockup): the auth links are
   pills with a bronze-to-teal gradient hairline border and a soft glow
   on hover — the site's CTA button voice. */
.banner-nav .nav-auth a {
  font-family: 'Cinzel', serif !important;
  color: #c9a968 !important;
  text-decoration: none !important;
  font-size: 11px !important;
  letter-spacing: 0.18em !important;
  text-transform: uppercase !important;
  font-weight: 500 !important;
  padding: 6px 12px !important;
  border: 1px solid transparent !important;
  border-radius: 999px !important;
  transition: color 0.25s ease, box-shadow 0.3s ease !important;
  white-space: normal !important;
  overflow-wrap: anywhere !important;
  word-break: normal !important;
  max-width: 100% !important;
  text-shadow: none !important;
  background: linear-gradient(180deg, rgba(20,35,38,0.85), rgba(10,20,22,0.65)) padding-box,
              linear-gradient(120deg, rgba(201,169,104,0.55), rgba(109,181,176,0.45)) border-box !important;
  display: inline-block !important;
  line-height: 1.4 !important;
  margin: 0 !important;
}
.banner-nav .nav-auth a:hover {
  color: #d9b877 !important;
  background: linear-gradient(180deg, rgba(20,35,38,0.85), rgba(10,20,22,0.65)) padding-box,
              linear-gradient(120deg, rgba(201,169,104,0.75), rgba(109,181,176,0.65)) border-box !important;
  border-color: transparent !important;
  box-shadow: 0 0 18px rgba(201, 169, 104, 0.2), inset 0 0 12px rgba(201, 169, 104, 0.07) !important;
}

/* ============================================================
   THE NAV BAR - one definition, every page, every state
   ------------------------------------------------------------
   This block is the site's ONLY desktop nav layout. It replaced
   fourteen page-level copies of it (index, relics, about, market,
   codex, contact, contributors, login, the-anvil, the-crier, the
   two sticker set pages and the two long-form codex pages), which
   had drifted into three different vintages and were the reason
   the same bar looked different on different pages and the same
   overlap bug had to be fixed three times.

   Do not re-add a `.banner-nav` rule to a page. A page's own
   <style> block is parsed after this file and, at equal weight,
   wins on source order - so one copy anywhere puts the drift back.
   If a page genuinely needs something here changed, change it
   here, and measure 320-1920 in every signed-in state.

   The four things it guarantees, in order of how loudly they were
   asked for:

   1. THE LINKS ARE CENTRED ON THE PAGE. Not centred on what is
      left over beside the account cluster - centred on the page,
      which is what "it should always stay centered" means. The
      bar is three grid tracks and the outer two are one `1fr`
      each, so track 1 grows by exactly as much as track 3 does
      and the middle track's centre is the page's centre in every
      signed-in state. It was a flex row with the links packed to
      `flex-start` and the cluster pushed over by `margin-left:
      auto`, and an admin's bar additionally carried ~360px of
      one-sided padding to stand HOME on the page axis; between
      them the row sat 161-190px left of centre at 1900px. The
      1180px page measure had to go with them - a centred bar
      needs room for two of the account cluster, and the measure
      did not have it.

   2. THE BAR IS ONE LINE. A grid with an explicit track list has
      no second line to wrap onto, so the track list is the
      guarantee `flex-wrap: nowrap` used to be. The previous fix
      let the account cluster wrap to its own line when the row
      was crowded; that is what "THE NAV BAR IS MESSED UP AGAIN"
      was. What gives instead is the display name - see 4.

   3. NOTHING IS PAINTED OVER ANYTHING. The links row may not be
      laid out narrower than its own words (`min-width: auto`
      against banner.css's `min-width: 0`, which is what let the
      row be squeezed and then painted over the mail square and
      SIGN IN), and track 3 may not be laid out narrower than the
      cluster in it - that is why the outer tracks are `1fr` and
      not `minmax(0, 1fr)`: an fr track's automatic minimum is its
      content's min-content. So the two clusters cannot occupy the
      same pixels.

   4. THE NAME IS THE ONE THING THAT GIVES. Track 3's floor is the
      cluster's min-content, so a long display name can never push
      the row over; while there is free space the track is the
      same width as track 1 and the name renders on one line, and
      past that point the name reads down inside its own button
      instead of the bar breaking in two. Nothing is truncated.
      When even that is not enough - a very long name at 1101px -
      track 1 is what gives next: it shrinks below track 3 and the
      whole composition slides left rather than overflowing.
   ============================================================ */
@media (min-width: 1241px) {
  .banner-nav {
    /* the bar's own inset. Every page used to declare its own copy of
       this and of a 1180px page measure (--hmax/--hx, --cmax/--cx,
       --rmax/--rx); the measure is gone - see the inner container - so
       the inset is all that is left of the pair. */
    --ht-nav-x: clamp(16px, 4.2vw, 40px);

    display: flex !important;
    align-items: stretch !important;
    padding: 0 !important;
    min-height: 64px !important;
    background: linear-gradient(180deg, #070f10 0%, #050a0b 100%) !important;
    border-bottom: 1px solid rgba(139, 115, 68, 0.34) !important;
  }

  .banner-nav .banner-nav-inner {
    /* NO PAGE MEASURE. A bar centred in three tracks costs twice the
       width of the account cluster, and inside a 1180px measure there
       was not that much room: the fr share came out under the cluster's
       max-content, the grid starved track 3 down to its min-content -
       one character, because .nav-auth links carry
       overflow-wrap:anywhere - and a signed-in visitor's display name
       came out as a 173px-tall column of stacked letters. An admin's
       bar already ran the full width of the window (its :has() rule
       below set max-width:none for exactly this reason); this is the
       same bar for everyone else, which is also why the account cluster
       now sits at the window's edge in every state instead of only in
       an admin's. */
    max-width: none !important;
    width: 100% !important;
    margin: 0 auto !important;
    padding: 0 var(--ht-nav-x) !important;
    display: grid !important;
    /* THREE TRACKS, AND THE OUTER TWO ARE THE SAME WIDTH. That is the
       whole centring mechanism. Track 1 is the empty ::before below,
       track 2 holds the links, track 3 holds the account cluster; the
       two `1fr` tracks resolve equal whenever there is free space, so
       whatever track 3 takes for the cluster, track 1 takes the same
       on the other side and the middle track stays centred on the
       page. It keeps holding as the cluster grows, which is the part
       the old flex row could not do.
       `1fr`, not `minmax(0, 1fr)`: an fr track's automatic minimum is
       its content's min-content, so track 3 can never be laid out
       narrower than the cluster standing in it.
       A grid with an explicit track list cannot wrap, so this is also
       where the one-line guarantee now lives. */
    grid-template-columns: 1fr auto 1fr !important;
    column-gap: clamp(16px, 1.8vw, 32px) !important;   /* 4px grid */
    row-gap: 0 !important;
    align-items: stretch !important;
    box-sizing: border-box !important;
  }
  /* THE COUNTERWEIGHT. banner.css puts an empty ::before at the front
     of the bar; it is track 1, and it is the only reason the links can
     be centred on the page without a wrapper element in 1,578 pages of
     markup. It has to stay in flow. */
  .banner-nav .banner-nav-inner::before { display: block !important; }

  .banner-nav .nav-links {
    /* the middle track. `auto` sizes the track to the row's own words,
       and centring inside it costs nothing but means the row stays
       centred even if the track is ever handed more than that. */
    justify-self: center !important;
    /* banner.css pins this to 0, which is what allowed the row to be
       squeezed narrower than its own words and then painted over.
       Its words are its floor. */
    min-width: auto !important;
    max-width: none !important;
    justify-content: center !important;
    align-items: stretch !important;
    flex-wrap: nowrap !important;
    gap: 0 clamp(12px, 1.5vw, 28px) !important;   /* 4px grid */
    overflow: visible !important;
    margin: 0 !important;
    padding: 0 !important;
  }

  /* a link is a word on a rule, not a bordered box */
  .banner-nav .nav-links > a,
  .banner-nav .nav-links > .tools-dropdown > .tools-trigger {
    display: flex !important;
    align-items: center !important;
    /* the row stretches to the bar height; this is the floor that
       keeps each link a 44px target in its own right */
    min-height: 56px !important;
    position: relative !important;
    font-family: 'Cinzel', serif !important;
    font-size: 13px !important;
    letter-spacing: 0.24em !important;
    font-weight: 500 !important;
    text-transform: uppercase !important;
    color: var(--ht-nav-ink) !important;
    background: transparent !important;
    backdrop-filter: none !important;
    border: 0 !important;
    border-radius: 0 !important;
    padding: 0 !important;
    margin: 0 !important;
    white-space: nowrap !important;
    text-shadow: none !important;
    transition: color 0.22s ease !important;
  }
  /* the marker is a rule that draws itself in from the left, sitting
     on the nav's own bottom edge - not another bordered box. This one
     is hover's: thin, and the dimmer of the bar's two rules. */
  .banner-nav .nav-links > a::after {
    content: '';
    position: absolute;
    left: 0; right: 0; bottom: -1px;
    height: 2px;
    background: var(--ht-nav-rule-hover);
    transform: scaleX(0);
    transform-origin: left center;
    transition: transform 0.32s cubic-bezier(0.22, 0.8, 0.3, 1);
  }
  .banner-nav .nav-links > a:hover {
    color: var(--ht-nav-ink-hover) !important;
    background: transparent !important;
    border: 0 !important;
  }
  .banner-nav .nav-links > a:hover::after { transform: scaleX(1); }
  /* THE PAGE YOU ARE ON, said three ways so it is not carried by hue
     alone: bronze ink, a rule half again as thick as hover's, and light
     gathering at the foot of the word as if it came off that rule. A
     wash that fades out upward, not a filled box - the bar's own rule
     is that a link is a word on a rule. Declared after :hover, at equal
     specificity, so hovering the current page cannot dim its own mark. */
  .banner-nav .nav-links > a.active {
    color: var(--ht-nav-bronze-hi) !important;
    background: linear-gradient(180deg,
      rgba(201, 169, 104, 0) 44%, var(--ht-nav-wash-here) 100%) !important;
    border: 0 !important;
  }
  .banner-nav .nav-links > a.active::after {
    transform: scaleX(1);
    height: 3px;
    background: var(--ht-nav-rule-here);
  }

  /* -- the cluster stands at the end of track 3 --
     It used to be pushed over by `margin-left: auto`, which is the
     declaration that made the links row everything-that-was-left
     rather than a centred track. The grid places it now: it is the
     third track's only occupant, held to that track's end, and the
     track's floor is its own min-content - so it may narrow, never
     squash, and the links can never be painted over it.
     max-content stops it claiming a pixel more than it needs, so every
     bar that already fitted is laid out to the same width it was. */
  .banner-nav .banner-nav-inner > .nav-auth {
    justify-self: end !important;
    max-width: max-content !important;
    min-width: auto !important;
    /* the pair is a pair: the name gives, the squares never drop
       below it. (Wrapping here is what put the mail and tools
       squares on a line of their own above the account button.) */
    flex-wrap: nowrap !important;
    justify-content: flex-end !important;
    align-items: center !important;
    gap: 8px !important;
    padding: 0 !important;
  }
  .banner-nav .banner-nav-inner > .nav-auth > a.ht-msg-bell,
  .banner-nav .banner-nav-inner > .nav-auth > a.ht-anvil-cart {
    flex: 0 0 auto !important;
  }
  /* the name is the one thing here that can give, so it reads down
     inside its own button instead of the bar breaking in two.
     THE FLOOR IS WHAT KEEPS IT TO ONE LINE. Centring the bar costs
     twice the width of this cluster, and under about 1265px there is
     not that much free space going. With no floor the button's own
     minimum was its min-content, and .nav-auth links carry
     overflow-wrap:anywhere, so min-content is ONE CHARACTER: the grid
     was free to hand track 3 the small share it could afford, and the
     name came down a letter at a time - a 237px-tall bar for an email
     address as a display name, 486px for a 33-character name.
     A floor turns that around. Once the share drops below it track 3
     stops flexing, and track 1 - the empty one - is what gives
     instead, so the bar slides a little off centre and stays ONE LINE
     at its 64px. Past the floor the name still wraps rather than
     truncate, but inside a 128px button, which is a couple of lines
     and not a column of letters.
     128px is the widest floor that still fits the worst bar there is,
     an admin's nine links at 1101px, without overflowing it. */
  .banner-nav .banner-nav-inner > .nav-auth > a.user-chip {
    flex: 0 1 auto !important;
    min-width: 128px !important;                       /* 4px grid */
    line-height: 1.2 !important;
    text-align: center !important;
  }

  /* -- the mail square, the anvil and SIGN IN as one matched set --
     The bell's and the anvil's own styles are injected into <head>
     at runtime, so they land after this file; these selectors
     out-specify them. */
  .banner-nav .nav-auth > a,
  .banner-nav .nav-auth > a.ht-msg-bell,
  .banner-nav .nav-auth > a.ht-anvil-cart {
    box-sizing: border-box !important;
    display: inline-flex !important;
    align-items: center !important;
    justify-content: center !important;
    /* min-height, not height: a display name long enough to wrap
       inside the button has to make the button taller rather than
       spill out through the top and bottom of it. */
    height: auto !important;
    min-height: 44px !important;
    padding: 0 16px !important;                        /* 4px grid */
    margin: 0 !important;
    font-family: 'Cinzel', serif !important;
    font-size: 13px !important;
    font-weight: 500 !important;
    letter-spacing: 0.22em !important;
    line-height: 1 !important;
    text-transform: uppercase !important;
    color: var(--ht-nav-bronze) !important;
    border: 1px solid var(--ht-nav-ctl-line) !important;
    border-radius: 0 !important;
    background: var(--ht-nav-ctl-fill) !important;
    backdrop-filter: none !important;
    text-shadow: none !important;
    transition: background 0.22s ease, border-color 0.22s ease,
      color 0.22s ease !important;
  }
  .banner-nav .nav-auth > a.ht-msg-bell,
  .banner-nav .nav-auth > a.ht-anvil-cart {
    width: 44px !important;
    padding: 0 !important;
    font-size: 16px !important;
    letter-spacing: 0 !important;
  }
  .banner-nav .nav-auth > a:hover,
  .banner-nav .nav-auth > a.ht-msg-bell:hover,
  .banner-nav .nav-auth > a.ht-anvil-cart:hover {
    background: var(--ht-nav-ctl-fill-hi) !important;
    border-color: var(--ht-nav-bronze-lit) !important;
    color: var(--ht-nav-bronze-hi) !important;
  }
  /* the account button reads as yours, not as one more bronze
     control: teal, marked with the site's star. Carried here from
     the seven page copies that had it, so the rest of the site
     gains it rather than those seven losing it. The space after the
     star is non-breaking, so the mark can never be left alone at
     the end of a line when a long name reads down. */
  .banner-nav .nav-auth > a.user-chip {
    color: var(--ht-nav-teal-lit) !important;
    /* the same border weight and the same alpha as the two squares
       beside it - the hue is the only thing that differs, and it
       differs to say this one is you. */
    border-color: var(--ht-nav-you-line) !important;
    background: var(--ht-nav-you-fill) !important;
  }
  .banner-nav .nav-auth > a.user-chip::before {
    content: '\2726\00a0';
    color: var(--ht-nav-star);
  }
  .banner-nav .nav-auth > a.user-chip:hover {
    color: var(--ht-nav-teal-hi) !important;
    border-color: var(--ht-nav-teal-lit) !important;
    background: var(--ht-nav-you-fill-hi) !important;
  }
  /* keyboard focus is a bronze ring, on every control in the bar */
  .banner-nav .nav-links > a:focus-visible {
    outline: 2px solid var(--ht-nav-bronze-lit) !important;
    outline-offset: 4px !important;
  }
  .banner-nav .nav-auth > a:focus-visible {
    outline: 2px solid var(--ht-nav-bronze-lit) !important;
    outline-offset: 3px !important;
  }

  /* -- the states that carry more than the composition was drawn on
     An admin's bar holds two more links and an account button as
     wide as the name: about 300px more than a visitor's. All that is
     left for those states to do is close the rhythm up, because the
     width the page measure used to hold back is now given to every
     state - see the inner container above.
     What this rule mostly does now is NOT do something. It used to
     read `padding: 0 var(--ht-nav-x) 0 var(--ht-nav-axis)`, standing
     the left edge of the bar on the page's 1180px axis so that HOME
     lined up with the page under it: about 360px of padding on the
     left against 40px on the right at 1900px. A track centred inside a
     box that is itself pushed 320px to the right is not centred on the
     page, so the axis trick had to go - `--ht-nav-axis` is gone with
     it, the padding is symmetric, and HOME now sits wherever the
     centred row puts it. That is the second half of the centring fix.
     Where :has() is unsupported none of this applies and the bar is
     still one line and still centred - the account cluster simply
     narrows sooner. */
  .banner-nav .banner-nav-inner:has(.nav-links .nav-admin-link),
  .banner-nav .banner-nav-inner:has(.nav-links .nav-seeker-link) {
    padding: 0 var(--ht-nav-x) !important;
    column-gap: clamp(12px, 1.1vw, 16px) !important;   /* 4px grid */
  }
  .banner-nav .banner-nav-inner:has(.nav-links .nav-admin-link) .nav-links,
  .banner-nav .banner-nav-inner:has(.nav-links .nav-seeker-link) .nav-links {
    gap: 0 clamp(12px, 1.6vw - 7px, 16px) !important;  /* 4px grid */
  }
  .banner-nav .banner-nav-inner:has(.nav-links .nav-admin-link) .nav-links > a,
  .banner-nav .banner-nav-inner:has(.nav-links .nav-seeker-link) .nav-links > a {
    letter-spacing: 0.18em !important;
  }
  .banner-nav .banner-nav-inner:has(.nav-links .nav-admin-link) .nav-auth > a.user-chip,
  .banner-nav .banner-nav-inner:has(.nav-links .nav-seeker-link) .nav-auth > a.user-chip {
    padding: 0 12px !important;
  }
}

/* ===== Compact: hamburger nav overlaid ON the banner ===== */

/* Hamburger button — hidden on desktop, injected by banner-anvil-cart.js */
.mnav-toggle { display: none !important; }

/* Complementary to the desktop block above, not `max-width: 1240px`:
   a viewport width is a fractional CSS length on any display whose device
   pixel ratio is not a whole number (1.25 is the common Windows case), and
   `1240 < width < 1241` matched NEITHER query - the bar fell all the way back
   to its base rules, with no hamburger and no desktop composition.
   The 1241px boundary is measured from the full signed-in Admin + Seeker +
   inbox + Anvil + account state. At 1178px the old 1101px boundary painted
   Seeker over the inbox; at 1241px the desktop row has a real clear gap.
   `not all and (min-width: 1241px)` is exactly everything the block above
   does not take. */
@media not all and (min-width: 1241px) {
  /* The banner image is the top element; the nav floats ON it.
     No separate nav bar above the banner. High z-index so the
     open dropdown paints above every page section below it. */
  .banner-wrap { position: relative !important; z-index: 9000 !important; }

  .banner-nav {
    position: absolute !important;
    top: 0 !important;
    left: 0 !important;
    right: 0 !important;
    bottom: auto !important;
    z-index: 600 !important;
    background: transparent !important;
    background-color: transparent !important;
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;
    border: none !important;
    border-bottom: none !important;
    padding: 0 !important;
    margin: 0 !important;
    min-height: 0 !important;
    pointer-events: none !important;   /* taps fall through to the banner */
  }

  .banner-nav .banner-nav-inner {
    display: flex !important;
    flex-wrap: wrap !important;
    align-items: flex-start !important;
    justify-content: flex-end !important;
    gap: 0 !important;
    padding: 0 !important;
    max-width: 100% !important;
  }
  .banner-nav .banner-nav-inner::before { display: none !important; }

  /* Banner art already carries the wordmark — hide the text brand */
  body .banner-nav .nav-brand,
  body .banner-nav a.nav-brand { display: none !important; }

  /* --- Hamburger: floats in the top-right corner of the banner --- */
  .mnav-toggle {
    order: 1 !important;
    margin: 12px 12px 0 auto !important;
    display: flex !important;
    align-items: center !important;
    justify-content: center !important;
    width: 48px !important;
    height: 48px !important;
    background: rgba(5,10,11,0.74) !important;
    border: 1px solid rgba(201,169,104,0.6) !important;
    color: #c9a968 !important;
    font-size: 21px !important;
    line-height: 1 !important;
    cursor: pointer !important;
    padding: 0 !important;
    pointer-events: auto !important;
    box-shadow: 0 2px 10px rgba(0,0,0,0.55) !important;
    -webkit-backdrop-filter: blur(4px);
    backdrop-filter: blur(4px);
    -webkit-tap-highlight-color: transparent;
  }
  .mnav-toggle::before { content: '\2630'; }
  .banner-nav.mnav-open .mnav-toggle::before { content: '\2715'; font-size: 18px !important; }
  .mnav-toggle:hover, .mnav-toggle:focus {
    color: #e6c688 !important;
    border-color: #c9a968 !important;
    outline: none !important;
  }

  /* --- Links + auth: collapsed by default --- */
  body .banner-nav .nav-links,
  body .banner-nav .nav-auth {
    order: 2 !important;
    flex-basis: 100% !important;
    width: 100% !important;
    display: none !important;
    margin: 0 !important;
    padding: 0 !important;
    pointer-events: auto !important;
  }
  body .banner-nav .nav-auth { order: 3 !important; }

  /* --- Open: the dropdown drops down over the banner --- */
  body .banner-nav.mnav-open .nav-links {
    display: flex !important;
    flex-direction: column !important;
    flex-wrap: nowrap !important;
    flex-basis: calc(100% - 24px) !important;
    width: auto !important;
    margin: 4px 12px 0 !important;
    background: rgba(5,10,11,0.98) !important;
    border: 1px solid #2d5654 !important;
    box-shadow: 0 16px 40px rgba(0,0,0,0.7) !important;
  }
  body .banner-nav.mnav-open .nav-auth {
    display: flex !important;
    flex-direction: row !important;
    justify-content: center !important;
    align-items: center !important;
    gap: 14px !important;
    flex-basis: calc(100% - 24px) !important;
    width: auto !important;
    margin: 0 12px !important;
    padding: 14px !important;
    background: rgba(5,10,11,0.98) !important;
    border: 1px solid #2d5654 !important;
    border-top: none !important;
    box-shadow: 0 16px 40px rgba(0,0,0,0.7) !important;
  }

  /* Each link = full-width tappable row */
  .banner-nav.mnav-open .nav-links > a {
    display: block !important;
    width: 100% !important;
    box-sizing: border-box !important;
    font-size: 13px !important;
    letter-spacing: 0.14em !important;
    text-align: left !important;
    padding: 15px 20px !important;
    margin: 0 !important;
    border: none !important;
    border-bottom: 1px solid rgba(31,46,48,0.7) !important;
  }
  .banner-nav.mnav-open .nav-links > a:last-child { border-bottom: none !important; }
  .banner-nav.mnav-open .nav-links > a:hover,
  .banner-nav.mnav-open .nav-links > a.active {
    background: rgba(109,181,176,0.08) !important;
  }

  /* Tools dropdown flows inline inside the open menu */
  .banner-nav.mnav-open .nav-links > .tools-dropdown {
    display: block !important;
    width: 100% !important;
  }
  .banner-nav.mnav-open .nav-links > .tools-dropdown > .tools-trigger {
    display: block !important;
    width: 100% !important;
    box-sizing: border-box !important;
    font-size: 13px !important;
    letter-spacing: 0.14em !important;
    text-align: left !important;
    padding: 15px 20px !important;
    border: none !important;
    border-bottom: 1px solid rgba(31,46,48,0.7) !important;
  }
  .banner-nav.mnav-open .tools-dropdown .tools-menu {
    position: static !important;
    transform: none !important;
    width: 100% !important;
    min-width: 0 !important;
    margin: 0 !important;
    box-shadow: none !important;
    border: none !important;
  }

  /* Sign In stretches; anvil icon stays compact */
  .banner-nav.mnav-open .nav-auth a:not(.ht-anvil-cart):not(.ht-msg-bell) {
    flex: 1 1 auto !important;
    text-align: center !important;
  }

  /* -- the open menu's account strip --
     The same rule the closed bar follows, restated for the panel:
     the name is never clipped and never ellipsised, it wraps inside
     its own button and the button grows downward to hold every line
     it makes, while the mail and tools squares are a fixed pair that
     never gives. Needs .mnav-open, so the closed bar cannot be
     reached by any of it. */
  .banner-nav.mnav-open .nav-auth {
    flex-wrap: wrap !important;
  }
  .banner-nav.mnav-open .nav-auth > a {
    height: auto !important;
    min-height: 44px !important;
    line-height: 1.2 !important;
    white-space: normal !important;
    overflow-wrap: anywhere !important;
    max-width: 100% !important;
  }
  .banner-nav.mnav-open .nav-auth > a.ht-msg-bell,
  .banner-nav.mnav-open .nav-auth > a.ht-anvil-cart {
    flex: 0 0 44px !important;
    width: 44px !important;
    height: 44px !important;
  }
}

/* === Homepage portal tiles — approved relic frame, scaled to nav-tile + 4-across responsive === */
/* Image-sliced frame (border-image 88 fill) + CSS depth/glow. Smaller than feature cards.
   Four tiles stay in ONE row at every width; descriptions/CTA hidden; compact mobile labels
   mapped by href (full title stays in the DOM for accessibility). Text is live HTML. */
.gates{
  display:grid !important;
  grid-template-columns:repeat(4, minmax(0,1fr)) !important;
  gap:clamp(7px,1.3vw,18px) !important;
  max-width:1180px !important; margin-left:auto !important; margin-right:auto !important;
}
.gates .gate{
  border-style:solid !important; border-color:transparent !important;
  border-width:clamp(14px,3vw,30px) !important;
  border-image:url('../ui/ht-relic-frame.png') 88 fill stretch !important;
  background:transparent !important; border-radius:0 !important;
  box-shadow:0 18px 40px -14px rgba(0,0,0,.9) !important;
  min-height:0 !important; aspect-ratio:1.7 / 1;
  padding:clamp(6px,1vw,14px) !important; box-sizing:border-box; container-type:inline-size;
  position:relative; overflow:visible;
  display:flex !important; flex-direction:column !important;
  justify-content:center !important; align-items:center !important; text-align:center !important;
}
.gates .gate::after{ content:''; position:absolute; inset:0; z-index:0; pointer-events:none;
  background:radial-gradient(130% 95% at 50% 40%, rgba(0,0,0,0) 44%, rgba(1,6,7,.55) 100%); }
.gates .gate::before{ content:''; position:absolute; inset:0; z-index:0; pointer-events:none; mix-blend-mode:screen;
  background:radial-gradient(50% 26% at 50% 3%, rgba(120,244,232,.50), transparent 72%),
            radial-gradient(50% 26% at 50% 97%, rgba(120,244,232,.42), transparent 72%); }
.gates .gate > *{ position:relative; z-index:1; }
.gates .gate-desc, .gates .gate-enter{ display:none !important; }
.gates .gate-num{ font-size:clamp(2px,4.4cqi,11px) !important; color:#ee6a77 !important; letter-spacing:0.03em !important; white-space:nowrap; overflow:hidden; max-width:96%; margin:0 0 clamp(3px,1.4cqi,9px) !important; }
.gates .gate-title{ font-size:clamp(3px,6.8cqi,22px) !important; max-width:100%; overflow:hidden; white-space:nowrap; line-height:1.05 !important; letter-spacing:0.02em !important; margin:0 !important; }
.gates .gate:hover{ transform:translateY(-3px); box-shadow:0 24px 50px -12px rgba(0,0,0,.95) !important; }
.gates .gate:hover::before{ background:radial-gradient(55% 30% at 50% 3%, rgba(150,255,244,.70), transparent 72%),
            radial-gradient(55% 30% at 50% 97%, rgba(150,255,244,.58), transparent 72%); }
@media (max-width:600px){
  .gates{ gap:clamp(4px,1.2vw,8px) !important; }
  .gates .gate{ aspect-ratio:1.05 / 1; border-width:clamp(8px,2.6vw,15px) !important; padding:clamp(3px,1vw,8px) !important; }
  .gates .gate::before{ opacity:.82; }
  /* Mobile labels: drop "The", size each word to fill its tile without spilling.
     Hide the real title/eyebrow text and swap in a short ::after label. */
  .gates .gate-title{ font-size:0 !important; max-width:100% !important; overflow:hidden; }
  /* Uniform size across all four tiles, sized so the longest word
     (CONTRIBUTORS) fits — the others match it exactly. */
  .gates .gate-title::after{ display:block; white-space:nowrap; line-height:1.04;
    font-family:'Cinzel',serif; font-weight:700; letter-spacing:0.01em;
    color:#cfe9e6; text-shadow:0 1px 2px rgba(0,0,0,.7);
    font-size:clamp(5px,10.6cqi,15px); }
  .gates .gate[href="relics.html"] .gate-title::after{ content:'RELICS'; }
  .gates .gate[href="contributors.html"] .gate-title::after{ content:'CONTRIBUTORS'; }
  .gates .gate[href="the-anvil.html"] .gate-title::after{ content:'ANVIL'; }
  .gates .gate[href="market.html"] .gate-title::after{ content:'MARKET'; }
  /* Eyebrow: just the numeral so the red stays large enough to read. */
  .gates .gate-num{ font-size:0 !important; margin:0 0 clamp(2px,1cqi,6px) !important; }
  .gates .gate-num::after{ display:block; white-space:nowrap; color:#ff7d88 !important;
    font-family:'Cinzel',serif; font-weight:700; letter-spacing:0.06em;
    text-shadow:0 1px 2px rgba(0,0,0,.6); font-size:clamp(6px,9cqi,12px); }
  .gates .gate[href="relics.html"] .gate-num::after{ content:'I'; }
  .gates .gate[href="contributors.html"] .gate-num::after{ content:'II'; }
  .gates .gate[href="the-anvil.html"] .gate-num::after{ content:'III'; }
  .gates .gate[href="market.html"] .gate-num::after{ content:'IV'; }
}

/* ===== Temple Announcements — framed with the approved relic frame =====
   Same real frame image (assets/ui/ht-relic-frame.png) and 9-slice border-image
   as the portal tiles. NOT a CSS recreation. The box grows with content; keep
   the announcement within the character budget so it stays a tidy plaque on
   both phone and desktop. */
.ht-home-card{
  border:0 !important; border-style:solid !important;
  border-image:url('../ui/ht-relic-frame.png') 88 fill stretch !important;
  border-width:clamp(20px,3.4vw,46px) !important;
  background:transparent !important; border-radius:0 !important;
  box-shadow:0 22px 50px -16px rgba(0,0,0,.85) !important;
  padding:clamp(12px,1.8vw,26px) clamp(16px,2.4vw,40px) !important;
  box-sizing:border-box; position:relative; isolation:isolate;
  min-height:clamp(180px,22vw,240px);
}
/* ===== the relic frame's own light, breathing =========================
   ht-relic-frame.png carries a teal light on its top and bottom edges,
   brightest at the middle and falling away to the corners. A border-image
   cannot be animated, so every box wearing the frame gets one extra layer
   that echoes that light - same colour, same two places - and swells very
   slightly into it. 20s for a full breath; you only see it if you look.

   The layer RESTS AT OPACITY 0. That is the whole point: with the
   animation switched off (reduced motion, an old engine, this rule
   deleted) the box is pixel-for-pixel what it was before. Only opacity
   moves, so nothing lays out and nothing outside the box repaints. No
   will-change: mix-blend-mode already gives the layer its own compositing
   group, and pinning a permanent layer for an animation that never ends
   costs phone memory for nothing.

   The keyframes are declared once, here, and reused by the framed plates
   in pages/index.html, pages/about.html and pages/contact.html - banner.css
   is loaded by all of them.
   ==================================================================== */
@keyframes ht-frame-glow-breathe{
  from{ opacity:0; }
  to{ opacity:.24; }
}
.ht-home-card::before{
  content: '';
  position: absolute;
  /* out over the border box: the frame is painted in the border band, so a
     layer at inset:0 starts where the frame ends and leaves a visible gap */
  inset: calc(-1 * clamp(20px, 3.4vw, 46px));
  /* above the border, so screen-blending brightens the frame's own light */
  z-index: 1;
  pointer-events: none;
  mix-blend-mode: screen;
  /* vertical radius IS the frame band, anchored on the edge, so the lit
     area covers the frame and does not reach into the box */
  background:
    radial-gradient(46% clamp(20px, 3.4vw, 46px) at 50% 0%, rgba(120, 244, 232, 0.55), transparent 78%),
    radial-gradient(46% clamp(20px, 3.4vw, 46px) at 50% 100%, rgba(120, 244, 232, 0.48), transparent 78%);
  opacity: 0;
  animation:ht-frame-glow-breathe 10s ease-in-out 3.5s infinite alternate;
}
@media (prefers-reduced-motion:reduce){
  .ht-home-card::before{ animation:none !important; }
}
.ht-ann.is-featured{
  border:1px solid #c9a968 !important;
  padding:16px 20px !important;
  background:linear-gradient(180deg,rgba(68,52,18,.32),rgba(10,20,22,.72)) !important;
  text-align:center;
  box-shadow:inset 0 0 32px rgba(201,169,104,.1);
  max-height:min(560px,62vh);
  overflow-y:auto;
  overscroll-behavior:contain;
}
.ht-ann.is-featured .ht-ann-title{
  font-size:clamp(22px,3vw,38px) !important;
  font-weight:900 !important;
  line-height:1.15 !important;
  color:#f4d98d !important;
  text-shadow:0 0 18px rgba(230,198,136,.32);
}
.ht-ann.is-featured .ht-ann-body{
  font-family:'IBM Plex Mono',monospace !important;
  font-size:13px !important;
  font-weight:700 !important;
  line-height:1.65 !important;
  color:#f0f5f4 !important;
}
@media (max-width:600px){
  .ht-home-card{ border-width:clamp(11px,4vw,18px) !important;
    padding:8px 9px !important;
    min-height:0; }
  .ht-home-sec{ margin:7px auto !important; padding:0 11px !important; }
  .ht-home-h{
    font-size:9px !important;
    letter-spacing:0.14em !important;
    margin:0 0 7px !important;
    line-height:1.25 !important;
  }
  #ht-ann-list{
    height:auto !important;
    max-height:none !important;
    overflow-y:auto !important;
    overscroll-behavior:contain !important;
    padding-right:4px !important;
  }
  .ht-ann{ padding:0 0 0 8px !important; margin-bottom:6px !important; }
  .ht-ann-date{ font-size:6.5px !important; letter-spacing:0.12em !important; margin-bottom:2px !important; }
  .ht-ann-title{ font-size:8px !important; letter-spacing:0.02em !important; line-height:1.12 !important; margin-bottom:2px !important; }
  .ht-ann-body{ font-size:8.5px !important; line-height:1.18 !important; }
  .ht-ann.is-featured{
    padding:12px 10px !important;
    max-height:min(430px,54vh) !important;
    overflow-y:auto !important;
  }
  .ht-ann.is-featured .ht-ann-date{
    font-size:7px !important;
  }
  .ht-ann.is-featured .ht-ann-title{
    font-size:clamp(16px,4.8vw,20px) !important;
    font-weight:900 !important;
    line-height:1.12 !important;
    letter-spacing:.03em !important;
    margin:2px 0 8px !important;
  }
  .ht-ann.is-featured .ht-ann-body{
    font-size:clamp(10px,2.85vw,11px) !important;
    font-weight:700 !important;
    line-height:1.35 !important;
    text-align:left !important;
  }
  .ht-ann-toggle{
    display:none !important;
  }
}

/* ===== Hero banner/video on mobile: crop to COVER a top strip that fits the
   screen (centered on the logo/figure) instead of showing the whole wide image.
   Applies to both the static .banner-img fallback and the .ht-hero-media video. */
@media (max-width:700px){
  .banner-wrap img.banner-img,
  .banner-wrap .ht-hero-media{
    height:clamp(140px,42vw,185px) !important;
    max-height:none !important;
    object-fit:cover !important;
    object-position:center center !important;
  }
}

/* ===== Checklist tiles: stop the Pokémon name from overflowing into the type
   label (Holo / Non Holo / Promo). The name's flex box can shrink narrower than
   the text, so the name spilled over the type. Pull the type label out of the
   row to the tile's top-right corner so they can never collide. ===== */
.sets-wrap .set-tile{ position:relative; }
.sets-wrap .set-tile > .sty{ position:absolute !important; top:10px; right:14px; max-width:42%; text-align:right; }
.sets-wrap .set-tile .body .sty{ position:static !important; max-width:100% !important; text-align:left !important; }
.sets-wrap .set-tile .snm{ min-width:0 !important; }

/* ===== Responsive set-description grids =====
   Browser zoom can enlarge headings enough that fixed 4/5-column description
   grids spill outside their sections. Keep the approved card/list design, but
   let these shared grids reduce columns whenever their container is too narrow. */
.set-grid,
.set-grid-3,
.set-grid-4,
.set-grid-5{
  min-width:0 !important;
  max-width:100% !important;
}
.set-grid-3{ grid-template-columns:repeat(auto-fit,minmax(min(100%,220px),1fr)) !important; }
.set-grid-4{ grid-template-columns:repeat(auto-fit,minmax(min(100%,200px),1fr)) !important; }
.set-grid-5{ grid-template-columns:repeat(auto-fit,minmax(min(100%,180px),1fr)) !important; }
.set-grid > *{
  min-width:0 !important;
  max-width:100% !important;
  overflow-wrap:anywhere !important;
}

/* ===== Set index tiles: pack art above copy =====
   Maker/index pages used a float-left pack-art thumbnail with copy beside it,
   wasting horizontal space and forcing wide two-column rows. Limit this to
   linked index tiles that contain .set-tile-thumb so checklist item tiles,
   HSC1, and dedicated set layouts keep their own rules. */
.sets-wrap .sets-grid > a.set-tile:has(> .set-tile-thumb){
  display:flex !important;
  flex-direction:column !important;
  align-items:stretch !important;
  gap:8px !important;
  min-height:0 !important;
  padding:10px !important;
  overflow:hidden;
}
/* Pack-art box takes the photo's own aspect ratio (--ht-art-ar, written by
   assets/js/parent-pack-art.js) so `contain` fills it exactly and the tile is
   never wider than its photo. Falls back to 4/5 before the image loads. */
.sets-wrap .sets-grid > a.set-tile:has(> .set-tile-thumb) > .set-tile-thumb{
  float:none !important;
  width:100% !important;
  height:auto !important;
  aspect-ratio:var(--ht-art-ar, 4 / 5) !important;
  max-height:none;
  margin:0 !important;
  flex:0 0 auto;
}
.sets-wrap .sets-grid > a.set-tile:has(> .set-tile-thumb) .set-name{
  margin:2px 0 0 !important;
  line-height:1.25 !important;
  min-height:0;
  overflow-wrap:break-word;
  hyphens:auto;
}
.sets-wrap .sets-grid > a.set-tile:has(> .set-tile-thumb) .set-meta{
  margin:0 !important;
  line-height:1.35 !important;
  overflow-wrap:break-word;
}
@media (min-width:701px){
  .sets-wrap .sets-grid:has(> a.set-tile > .set-tile-thumb){
    grid-template-columns:repeat(4,minmax(0,220px)) !important;
    justify-content:center;
    align-items:start;
  }
}
@media (max-width:700px){
  .sets-wrap .sets-grid:has(> a.set-tile > .set-tile-thumb){
    grid-template-columns:repeat(3,minmax(0,1fr)) !important;
    align-items:start;
    gap:8px !important;
  }
  .sets-wrap .sets-grid > a.set-tile:has(> .set-tile-thumb){
    padding:6px !important;
    gap:6px !important;
  }
  .sets-wrap .sets-grid > a.set-tile:has(> .set-tile-thumb) > .set-tile-thumb{
    max-height:none;
  }
}
@media (max-width:359px){
  .sets-wrap .sets-grid:has(> a.set-tile > .set-tile-thumb){
    grid-template-columns:repeat(2,minmax(0,1fr)) !important;
  }
}

/* BANNER COMPACT 2026-08-04 — shrink the hero band on all pages (desktop/tablet); keep
   the logo (top) and the hooded figure (centre), trim empty sky/rubble.
   Mobile keeps the full panorama (this is scoped >=701px). */
@media (min-width: 701px){
  .banner-wrap .banner-img,
  .banner-wrap .ht-hero-media{
    height: clamp(92px, 9vw, 164px) !important;
    max-height: none !important;
    object-fit: contain !important;
    object-position: center !important;
  }
}

/* NAV COMPACT 2026-08-04 — ~half the previous bar height + button sizes */
.banner-nav{ padding:6px 18px !important; min-height:34px !important; }
.banner-nav .nav-links>a,
.banner-nav .nav-links>.tools-dropdown>.tools-trigger{ font-size:10.5px !important; padding:4px 9px !important; letter-spacing:0.12em !important; }
.banner-nav .nav-auth a{ font-size:10.5px !important; padding:5px 11px !important; letter-spacing:0.12em !important; }
.banner-nav .nav-links{ gap:4px !important; }
.banner-nav .banner-nav-inner{ gap:clamp(6px,1vw,12px) !important; }

/* HERO OVERLAY 2026-08-04 — banner fills edge-to-edge; nav floats over it,
   translucent, with a top-down scrim so the links stay readable and the
   'Hidden Temple' logo in the art shows through/just below the bar. */
.banner-wrap{ position:relative !important; overflow:hidden !important; }
/* MOBILE MENU FIX 2026-08-09 — the hero overlay's overflow:hidden crops the
   banner, but on mobile the hamburger dropdown is an absolutely-positioned child
   of .banner-wrap, so overflow:hidden also clipped every nav item past the
   ~200px banner (only HOME/ABOUT/half of RELICS showed). When the menu is open,
   restore overflow so the panel paints down over the page; .banner-wrap's mobile
   z-index (9000) keeps it above the page content below. Reverts to the crop the
   moment the menu closes. (0,3,0) + !important beats the rule above. */
.banner-wrap:has(.banner-nav.mnav-open){ overflow:visible !important; }
/* MOBILE MENU FILL 2026-08-10 — the mobile banner is short, so the page sits
   directly behind the open dropdown; the side/inter-panel margins + near-transparent
   fill let page text bleed THROUGH the menu, so it read as half-rendered. Make the
   open menu one solid, edge-to-edge block (no gaps, fully opaque). */
.banner-nav.mnav-open{ background:#050a0b !important; }
.banner-nav.mnav-open .banner-nav-inner{ align-content:flex-start !important; row-gap:0 !important; }
.banner-nav.mnav-open .nav-links,
.banner-nav.mnav-open .nav-auth{
  background:#050a0b !important;
  margin-left:0 !important; margin-right:0 !important;
}
.banner-nav.mnav-open .nav-links{ margin-top:0 !important; }
.banner-nav.mnav-open .nav-auth{ margin-top:0 !important; border-top:0 !important; }
.banner-wrap .banner-img,
.banner-wrap .ht-hero-media{
  width:100% !important; max-width:100% !important;
  aspect-ratio:1536 / 320 !important; height:auto !important; max-height:none !important;
  object-fit:cover !important; object-position:center !important;
  display:block !important; margin:0 !important;
}
.banner-wrap .banner-nav{
  position:absolute !important; top:0 !important; left:0 !important; right:0 !important;
  z-index:6 !important; min-height:0 !important;
  background:transparent !important;
  border:0 !important;
}
/* keep every nav label legible over the art */
.banner-wrap .banner-nav .nav-links>a,
.banner-wrap .banner-nav .nav-links>.tools-dropdown>.tools-trigger,
.banner-wrap .banner-nav .nav-auth a{
  text-shadow:0 1px 5px rgba(0,0,0,0.95), 0 0 2px rgba(0,0,0,0.8) !important;
}
/* HERO MOBILE — full banner, never cropped (Chris, 2026-08-21). Phones play the
   full 21:9 scene file; show ALL of it at its natural ratio (height auto, no cap,
   contain) so the whole composition is visible on mobile too, same as desktop. */
@media (max-width:700px){
  .banner-wrap .banner-img,
  .banner-wrap .ht-hero-media{ aspect-ratio:auto !important; height:auto !important; max-height:none !important; object-fit:contain !important; object-position:center !important; }
}
/* NAV CLEAR + ONE ROW 2026-08-04 — truly transparent nav (remove the frosted-glass
   blur that made it look solid) and force the links to ONE row so the
   logged-in extras (Admin/Seeker/name) can't wrap down onto the logo.
   Pin the bar to the very top so the buttons clear 'Hidden Temple'. */
.banner-wrap .banner-nav{
  background:transparent !important; background-color:transparent !important;
  backdrop-filter:none !important; -webkit-backdrop-filter:none !important;
  padding-top:2px !important; padding-bottom:4px !important;
  align-items:flex-start !important; min-height:0 !important;
}
.banner-wrap .banner-nav .banner-nav-inner{ background:transparent !important; align-items:flex-start !important; }
.banner-wrap .banner-nav .banner-nav-inner::before{ display:none !important; }
.banner-wrap .banner-nav .nav-links{ flex-wrap:nowrap !important; }
.banner-wrap .banner-nav .nav-auth{ flex-wrap:nowrap !important; }
/* NAV CENTER 2026-08-04 — desktop: center the nav links as one row, sign-in pinned right. */
@media (min-width:1241px){
  .banner-wrap .banner-nav .banner-nav-inner{
    display:flex !important; grid-template-columns:none !important;
    justify-content:center !important; align-items:center !important;
    position:relative !important; max-width:100% !important; gap:0 !important;
  }
  .banner-wrap .banner-nav .banner-nav-inner::before{ display:none !important; }
  .banner-wrap .banner-nav .nav-links{ flex:0 1 auto !important; justify-content:center !important; }
  .banner-wrap .banner-nav .nav-auth{
    position:absolute !important; right:18px !important; top:50% !important;
    transform:translateY(-50%) !important; margin:0 !important;
  }
}
/* GLOBAL DESKTOP SCALE 2026-08-05 — the site scales UP with viewport width (vw units), so on
   wide desktop monitors everything reads oversized. Zoom the whole page
   down on desktop so the full layout is compact ("everything smaller").
   Desktop only (>=1300px); phones/tablets keep their own compact sizing.
   Single dial: change the 0.7 to taste (lower = smaller). */
@media (min-width: 600px){ body{ zoom: 0.85; } }
@media (min-width: 1300px){ body{ zoom: 0.8; } }

/* ===== HERO BAND - ONE SIZE ON EVERY PAGE 2026-08-17 =====
   Chris's Seedance loop, band-cut to the real composition, run with the nav
   ON the art. This block is the ONLY thing that sizes the desktop banner:
   every page used to be free to cap the masthead itself, and they all picked
   different numbers, so the same banner was 451px tall on home, 161px on
   relics/contributors/about/codex/contact and 277px on the Astryx hubs (all
   visual px @1900). The selector below is deliberately over-specific -
   (0,4,2), higher than the `html body .banner-wrap img.banner-img` (0,2,3)
   the pages use - so the page <style> blocks, which load AFTER this file and
   would otherwise win on source order, can no longer move the banner. Their
   content compaction below the banner is untouched.

   It sizes the VIDEO and the still `img.banner-img` fallback together
   (`.banner-img.banner-img` matches both: the video is created with
   class="banner-img ht-hero-media"), so reduced-motion users get exactly the
   same banner height as everyone else.

   ---- The band's own geometry (rows of the 2206x524 file, re-measured off
        hidden-temple-hero-loop-band-524-poster.jpg, not inherited) ----------
     row 103  tip of the sign's crown spire
     row 196  bottom of the logo's flourish
     row 344  top of the figure's hood
     row 435  the glowing orb in its hand
     row 470  bottom of the coat
     row 509  bottom of the boots
     row 524  the wet path - bottom of the file

   ---- What the numbers below are for -----------------------------------
   Measured, not assumed (headless Chrome, /assets/css only): at a 1900px
   window the page is zoom:0.7, so the banner's LAYOUT width is 1900/0.7 =
   2714 CSS px and the band is upscaled x1.2303. The floating nav's lowest
   link sits 58 CSS px below the top of the banner at every desktop width
   (its font sizes are fixed px, so it does not scale with the viewport).

   Two constraints fix the shortest honest banner:
     - the crown (row 103) must clear that nav: >= 58 + ~6 CSS px
     - the boots (row 509) must stay in frame, with a few rows of path under
       them so the figure is standing on something
   Window = rows 51..514 = 463 of the 524 rows -> 463 * 1.2303 = 570 CSS px,
   i.e. 399 visual px at 1900 (was 451 on home). Anything shorter than this
   starts cutting the composition - see the dial.

   object-position 84% puts that window as LOW as the nav allows, so no cloud
   is wasted above the links: 0.84 * (524 - 570/1.2303) = row 50.99, crown
   lands 64.0 CSS px down (6.0 CSS / 4.2 visual px clear of the nav), boots
   land 563 CSS px down inside the 570 box with ~6 CSS px of path below.

   Why max(570px, 30vw) and not a plain 570px: vw resolves against the
   UNZOOMED viewport (30vw = 570px at exactly 1900), so above 1900 the vw arm
   grows the cap at the same rate the band upscales and the visible window
   stays locked on rows 51..514 - on a 2560 monitor a flat 570px cap would
   have sliced the figure off at the knees. Below ~1680 the natural aspect
   height is already under the cap, the cap and object-position go inert, and
   the banner behaves exactly as it does today (nav clearance at 1500/1300/
   1101 is therefore unchanged: 42.1 / 28.7 / 6.3 CSS px, all measured).

   Phones (<=700px) are NOT touched by any of this - they keep the 200px
   cover slice and the separate ...-loop-scene-1470x630 files. */
@media (min-width:701px){
  html body .banner-wrap.banner-wrap .banner-img.banner-img{
    /* FULL BANNER, NEVER CROPPED (Chris, 2026-08-21). The band file is shown
       whole at its own 2206:524 ratio: width 100%, height auto, NO max-height
       cap, object-fit contain. Nothing is ever cut regardless of window width -
       the height simply scales with the width (~448 CSS px at a full-width
       1900px monitor, proportionally less as the window narrows). This replaces
       the earlier crop "dials"; a full-width image at this ratio cannot be made
       shorter without either cropping it or letterboxing, so height follows
       width by design. */
    aspect-ratio: 2206/524 !important;
    width: 100% !important;
    max-width: 100% !important;
    height: auto !important;
    max-height: none !important;
    display: block !important;
    object-fit: contain !important;
    object-position: center center !important;
    margin: 0 !important;

    /* ---- SHORT DIAL - uncomment the ONE line below to flip ---------------
       440 CSS px / 308 visual px @1900 (vs 570/399 above). Window becomes
       rows 50..407 of 524. KEPT: the whole sign/logo, the temple, the
       lightning, both mountain walls, the path receding, and the figure's
       hood + shoulders + upper chest (the hood starts at row 344).
       CUT: everything below row 407 - the glowing orb in the figure's hand
       (row 435), the bottom of the coat (470), the boots (509) and the wet
       path they stand on. The figure reads as a small silhouette at the
       bottom edge rather than a full figure on a road.
       Nav clearance is re-checked and SAFE at this setting: window top =
       0.30 * (524 - 440/1.2303) = row 49.9, so the crown lands 65.3 CSS px
       below the banner top = 7.3 CSS / 5.1 visual px clear of the nav's
       58 CSS px - slightly MORE headroom than the default.
       Re-comment this line to go back to the full composition. */
    /* max-height:max(440px,23.16vw)!important; object-position:center 30%!important; */

    /* ---- MIDDLE SETTING, if 440 cuts too much and 570 is still too tall:
       515 CSS px / 360 visual px @1900, window rows 51..470 - keeps the
       figure down to the bottom of its coat and the orb, cuts only the boots
       and the path. Same flip, uncomment the one line:
       max-height:max(515px,27.11vw)!important; object-position:center 48%!important; */
  }
}

/* ============================================================
   2026-08-25 signed-in cluster centering (Chris): the round icon
   buttons (inbox, anvil) and the account pill center their glyphs
   dead-center at EVERY width, at pill radius, and the pill refit's
   11px text sizing never shrinks an icon again. Appended last so
   it outranks both the pill block and the desktop matched-set
   block above. Badges keep their corner post untouched.
   ============================================================ */
.banner-nav .nav-auth > a {
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  text-align: center !important;
  line-height: 1 !important;
  border-radius: 999px !important;
}
.banner-nav .nav-auth > a.ht-msg-bell,
.banner-nav .nav-auth > a.ht-anvil-cart {
  width: 40px !important;
  height: 40px !important;
  min-height: 40px !important;
  padding: 0 !important;
  font-size: 17px !important;
  letter-spacing: 0 !important;
}
.banner-nav .nav-auth > a.user-chip {
  padding: 8px 18px !important;
  line-height: 1.2 !important;
}
@media (max-width: 720px) {
  .banner-nav .nav-auth > a.ht-msg-bell,
  .banner-nav .nav-auth > a.ht-anvil-cart {
    width: 32px !important;
    height: 32px !important;
    min-height: 32px !important;
    font-size: 14px !important;
  }
}

/* ============================================================
   SITE CHROME UNIFICATION - 2026-08-26
   id: ht-chrome-unify-20260826
   ------------------------------------------------------------
   Design-audit fix wave (defects #3 #4 #8 #9 #10 #20 #21 #23).
   CSS only: not one character of markup, copy or script is
   touched by this block.

   banner.css loads on every page, so this is the ONE place the
   whole site's footer, its floating controls, its nav cluster
   and its page-title scale can be said once. Page-level style
   blocks live at the end of each document and therefore come
   AFTER this file in source order, so every selector here is
   deliberately out-specified past them:

     - footer rules carry :not(#ht-none) on the footer element.
       The :not() argument is an id, so the selector picks up
       id-level weight (1,0,x) while still matching every
       footer. The strongest page-level footer selector in the
       site is  html body footer p[style*="border-top"] a  at
       (0,1,5); ours land at (1,1,5)+ and settle over all of them.
     - nav / title rules add "html body" plus a class the page
       blocks do not use.
     - the float controls are styled in JS-injected style tags
       with NO !important, so a single !important here wins.

   WHAT IT SETS
   1. FOOTER (#3 #4 #20 #21) - one footer everywhere: ranged
      left on a 1216px axis centred in the band, IBM Plex Mono
      13px #8b9997 prose, the Cinzel bronze mark, #8fbfba links
      that inherit their paragraph's size, and the policy row as
      small bronze ghost pills. The literal middle-dot
      separators between the policy links are display:none, so a
      wrapped row can never orphan one.
   2. MOBILE DEAD BAND (#8) - mobile.css reserves 120px of body
      padding-bottom for the float rail, which reads as a 120px
      strip of page background BELOW the footer. The reserve
      moves into the footer's own padding, so the band keeps its
      colour and the floats still clear the last line.
   3. NAV MAIL BELL (#9) - radius 999 at every width.
   4. FLOATING CONTROLS (#10) - one shape (pill / circle), one
      bronze scheme, one baseline.
   5. PAGE TITLE SCALE (#23) - one h1 clamp for the non-set
      pages (set pages are excluded by :has(.meta-badges); they
      run their own fitted-title regime).
   ============================================================ */

/* ------------------------------------------------------------
   1. FOOTER - the band
   ------------------------------------------------------------ */
html body footer:not(#ht-none) {
  display: block !important;
  box-sizing: border-box !important;
  text-align: left !important;
  /* content axis: 1216px, centred inside a full-bleed band */
  padding-top: clamp(30px, 3.2vw, 46px) !important;
  /* the bottom pad is the float rail's clearance: back-to-top is a
     48px circle sitting 18px off the bottom of the viewport and the
     policy row is the last thing on the page, so without this the
     centre float lands on top of a pill. Inside the band it costs
     nothing - it is the footer's own ground, not a strip of page
     background (see #8 below). */
  padding-bottom: clamp(56px, 4.6vw, 76px) !important;
  /* The side pads below are percentages of the CONTAINING BLOCK, not of the
     footer, so the band has to be full bleed for them to mean "centre a
     1216px axis". A page that caps its own footer (the-crier ships
     `footer{max-width:1200px;margin:auto}`) kept the wide pad against a
     narrow box and squeezed the text column to ~60px, one word per line.
     Pin the band open so the axis maths always holds. */
  max-width: none !important;
  width: auto !important;
  margin-left: 0 !important;
  margin-right: 0 !important;
  padding-left: max(18px, calc((100% - 1216px) / 2)) !important;
  padding-right: max(18px, calc((100% - 1216px) / 2)) !important;
  border-top: 1px solid #1f2e30 !important;
  font-family: 'IBM Plex Mono', monospace !important;
  font-size: 13px !important;
  font-weight: 400 !important;
  line-height: 1.65 !important;
  letter-spacing: 0.02em !important;
  color: #8b9997 !important;
}

/* the mark - the one Cinzel bronze line in the whole footer */
html body footer:not(#ht-none) .mark,
html body footer:not(#ht-none) > span.mark {
  display: block !important;
  font-family: 'Cinzel', serif !important;
  font-weight: 500 !important;
  font-size: clamp(12px, 1vw, 14px) !important;
  letter-spacing: 0.42em !important;
  line-height: 1.4 !important;
  text-transform: none !important;
  text-align: left !important;
  color: #c9a968 !important;
  margin: 0 0 clamp(14px, 1.6vw, 20px) !important;
}

/* legal prose - never the 9-10px #4a5856 full-bleed setting */
html body footer:not(#ht-none) p {
  font-family: 'IBM Plex Mono', monospace !important;
  font-size: 13px !important;
  font-weight: 400 !important;
  line-height: 1.65 !important;
  letter-spacing: 0.02em !important;
  color: #8b9997 !important;
  text-align: left !important;
  max-width: 82ch !important;
  margin: 0 0 11px !important;
}

/* #21: an inline citation link is part of its sentence, so it
   takes the paragraph's type, not a size of its own. The
   attribute qualifier is what beats the pages' own
   "footer p a[style]" rules. */
html body footer:not(#ht-none) a { color: #8fbfba !important; }
html body footer:not(#ht-none) p a,
html body footer:not(#ht-none) p a[style] {
  font-family: inherit !important;
  font-size: inherit !important;
  font-weight: inherit !important;
  line-height: inherit !important;
  letter-spacing: inherit !important;
  text-transform: none !important;
  color: #8fbfba !important;
  text-decoration: underline !important;
  text-underline-offset: 2px !important;
  /* a bigger hit box without disturbing the line box it sits in */
  padding-block: 12px !important;
}
html body footer:not(#ht-none) p a:hover { color: #8ed4cf !important; }
html body footer:not(#ht-none) a:focus-visible {
  outline: 2px solid #c9a968 !important;
  outline-offset: 3px !important;
}

/* index keeps its two columns - it just joins the type system */
html body footer:not(#ht-none) .f-cols {
  max-width: none !important;
  margin: 0 !important;
  gap: clamp(24px, 3.4vw, 64px) !important;
}

/* ------------------------------------------------------------
   2. FOOTER - the policy row as ghost pills (the codex setting)
   p[style*="border-top"] is the row on every page but index,
   which calls it .f-policy.
   ------------------------------------------------------------ */
html body footer:not(#ht-none) p[style*="border-top"],
html body footer:not(#ht-none) p.f-policy {
  display: flex !important;
  flex-wrap: wrap !important;
  align-items: center !important;
  justify-content: flex-start !important;
  gap: 8px !important;
  max-width: none !important;
  margin: clamp(18px, 2vw, 26px) 0 0 !important;
  padding: clamp(12px, 1.4vw, 18px) 0 0 !important;
  border-top: 1px solid #1f2e30 !important;
  border-bottom: 0 !important;
  text-align: left !important;
}

/* the orphaned middle dot: the separators are literal spans
   between the links, and a row that wraps leaves one stranded at
   the head of the new line. The pills do the separating now. */
html body footer:not(#ht-none) p[style*="border-top"] > span,
html body footer:not(#ht-none) p.f-policy > span { display: none !important; }

html body footer:not(#ht-none) p[style*="border-top"] a[href],
html body footer:not(#ht-none) p.f-policy a[href] {
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  min-height: 34px !important;
  margin: 0 !important;
  padding: 6px 14px !important;
  border: 1px solid rgba(139, 115, 68, 0.42) !important;
  border-radius: 999px !important;
  background: rgba(201, 169, 104, 0.05) !important;
  font-family: 'IBM Plex Mono', monospace !important;
  font-size: 10px !important;
  font-weight: 500 !important;
  line-height: 1 !important;
  letter-spacing: 0.16em !important;
  text-transform: uppercase !important;
  text-decoration: none !important;
  color: #c9a968 !important;
  white-space: nowrap !important;
  transition: color 0.22s ease, border-color 0.22s ease,
    background 0.22s ease !important;
}
html body footer:not(#ht-none) p[style*="border-top"] a[href]:hover,
html body footer:not(#ht-none) p.f-policy a[href]:hover {
  color: #d9b877 !important;
  border-color: #c9a968 !important;
  background: rgba(201, 169, 104, 0.1) !important;
}

/* ------------------------------------------------------------
   3. #8 - the 120px strip of page background under the footer.
   Two sources reserve it:
     assets/css/mobile.css:461  @media (max-width:600px)
                                body{padding-bottom:120px !important}
     pages/the-anvil.html:62    body{padding-bottom:120px}  (all widths)
   The reserve exists so the fixed float rail never permanently
   covers the last cards. It does not have to be page background
   BELOW the footer to do that: carried in the footer's own
   padding-bottom (section 1, plus the phone bump here) it does
   the same job, and the band simply runs to the bottom of the
   document instead of stopping 120px short of it. Every real
   floating control still gets its clearance - it is the same
   number of pixels, just painted footer instead of page.
   ------------------------------------------------------------ */
html body:not(#ht-none) { padding-bottom: 0 !important; }

@media (max-width: 600px) {
  /* phones carry the rail lower and tighter, so the band needs a
     little more than the desktop clamp gives it */
  html body:not(#ht-none) footer {
    padding-bottom: calc(84px + env(safe-area-inset-bottom, 0px)) !important;
  }
  /* phone: the pills stay a real tap target */
  html body footer:not(#ht-none) p[style*="border-top"] a[href],
  html body footer:not(#ht-none) p.f-policy a[href] {
    min-height: 40px !important;
    padding: 8px 14px !important;
    font-size: 9.5px !important;
  }
}

/* ------------------------------------------------------------
   4. #9 - the mail bell is a circle, like everything else in the
   signed-in cluster. The desktop "matched set" block above sets
   border-radius:0 at (0,3,1) on .ht-msg-bell / .ht-anvil-cart
   specifically, which out-ranked the 999px on the plain
   ".nav-auth > a" beside it - that is why the bell rendered as a
   square next to a radius-999 SIGN IN. Adding "html body" lifts
   these to (0,3,3) so the round shape holds at every width.
   ------------------------------------------------------------ */
html body .banner-nav .nav-auth > a.ht-msg-bell,
html body .banner-nav .nav-auth > a.ht-anvil-cart,
html body .banner-nav.mnav-open .nav-auth > a.ht-msg-bell,
html body .banner-nav.mnav-open .nav-auth > a.ht-anvil-cart {
  border-radius: 999px !important;
  aspect-ratio: 1 / 1 !important;
  overflow: visible !important;
}

/* ------------------------------------------------------------
   5. #10 - the float rail: one shape, one palette, one baseline.
   These three controls are drawn by shared scripts
   (banner-anvil-cart.js, set-jump-nav.js, back-to-top.js) whose
   styles are injected without !important, so this block is the
   shared place to shape them and every page that renders them
   gains the fix.
     - .ht-report-btn  radius 4 + crimson  -> pill + bronze
     - .htjn-tab       radius 26           -> pill
     - #ht-back-to-top stays a circle
   ------------------------------------------------------------ */
html body .ht-report-btn {
  border-radius: 999px !important;
  border: 1px solid #8b7344 !important;
  background: rgba(20, 35, 38, 0.9) !important;
  color: #d9b877 !important;
  font-family: 'IBM Plex Mono', monospace !important;
  font-weight: 500 !important;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.55) !important;
  transition: color 0.22s ease, border-color 0.22s ease,
    background 0.22s ease !important;
}
html body .ht-report-btn:hover,
html body .ht-report-btn:focus-visible {
  background: rgba(201, 169, 104, 0.14) !important;
  border-color: #c9a968 !important;
  color: #e6c688 !important;
}
html body .htjn-tab {
  border-radius: 999px !important;
  border: 1px solid #8b7344 !important;
  background: rgba(20, 35, 38, 0.9) !important;
  color: #d9b877 !important;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.55) !important;
}
html body .htjn-tab:hover,
html body .htjn-tab:focus-visible {
  background: rgba(201, 169, 104, 0.14) !important;
  border-color: #c9a968 !important;
  color: #e6c688 !important;
}
html body #ht-back-to-top { border-radius: 50% !important; }

/* one shared baseline, and clear of the content edges on the
   narrowest phones */
@media (max-width: 430px) {
  html body .ht-report-btn {
    left: 12px !important;
    right: auto !important;
    bottom: calc(12px + env(safe-area-inset-bottom, 0px)) !important;
  }
  html body .htjn-tab {
    right: 12px !important;
    left: auto !important;
    bottom: calc(12px + env(safe-area-inset-bottom, 0px)) !important;
    min-height: 44px !important;
    padding: 0 14px !important;
    font-size: 11px !important;
  }
  html body #ht-back-to-top {
    bottom: calc(12px + env(safe-area-inset-bottom, 0px)) !important;
  }
}

/* ------------------------------------------------------------
   6. #23 - one page-title scale. 28px at the top end everywhere,
   instead of 28 on some pages and 30 on others.
   Set / checklist pages are excluded: their .page-head carries
   .meta-badges and their titles are fitted by
   htc-ornate-buttons.js.
   ------------------------------------------------------------ */
html body .page-head:not(:has(.meta-badges)) > h1.page-title,
html body .page-header:not(:has(.meta-badges)) > h1.page-title {
  font-size: clamp(20px, 2vw, 28px) !important;
}

/* Mobile hero fallback parity, 2026-08-30.
   mobile.css still carries an older, more-specific rule for img.banner-img
   that forced a 210px cover crop. The animated video was already showing the
   complete scene, but reduced-motion, autoplay failure, and data-saving paths
   fell back to that cropped still. Keep both the video and its still fallback
   fluid and uncropped so every phone sees the same full composition. */
@media (max-width: 700px) {
  html body .banner-wrap.banner-wrap .banner-img.banner-img {
    width: 100% !important;
    max-width: 100% !important;
    height: auto !important;
    max-height: none !important;
    aspect-ratio: auto !important;
    object-fit: contain !important;
    object-position: center center !important;
    display: block !important;
    margin: 0 !important;
  }
}
