/* Museum of Clear Themes — shared production stylesheet.
   Ported from the locked Phase-1 deck direction (_build/deck/dark-museum/,
   see _build/deck/decision.md): -apple-system type, museum-placard grid,
   spotlit vault-glow detail hero. Single flat red surface (#DC2C2C, the
   Heat Map red) — the earlier visitor-selectable dark/light surfaces and
   their picker were removed 2026-07-27. */

@font-face {
  font-family: "color-emoji";
  src: local("Apple Color Emoji"), local("Segoe UI Emoji"), local("Noto Color Emoji");
}

* { box-sizing: border-box; }

/* Chrome typographic system — style-guide pass (see plan):
   1.2 modular scale on the UA-default 16px root (no stylesheet sets a root
   size on these pages — documented reliance); leading inversely proportional
   to size; tracking −0.02em on display, ≤0.05em only on small uppercase
   labels; measures in em targeting 45–75ch; hierarchy via the ink tone ramp
   (the style guide's #222→#999 importance ramp, inverted for dark ground).
   Card internals (.piece__screen etc.) follow the separate app-fidelity
   contract and do not use these tokens. */
:root {
  --fs-2: 0.694rem;  /* 11.1px — kickers, badges, chips, smallest labels */
  --fs-1: 0.833rem;  /* 13.3px — captions, footer, pagination, CTA */
  --fs0:  1rem;      /* 16px  — body/UI base, search input, placard notes */
  --fs1:  1.2rem;    /* 19.2px — lead/blurbs */
  --fs2:  1.44rem;   /* 23px — reserved */
  --fs3:  1.728rem;  /* 27.6px — reserved */
  --fs4:  2.074rem;  /* 33.2px — mobile display step */
  --fs5:  2.488rem;  /* 39.8px — collection/detail h1 */
  --fs6:  2.986rem;  /* 47.8px — museum display h1 */

  /* The one museum surface: flat, literal Clear red (#DC2C2C), inherited
     from the Heat Map theme. Compressed white ink ramp — a wide
     0.92→0.28 alpha spread collapses on a midtone background. (The
     earlier visitor-selectable dark/light surfaces were removed
     2026-07-27; red is the sole background.) */
  --bg: #DC2C2C;
  --ink: rgba(255, 255, 255, 0.97);
  --ink-heading: #fff;
  --ink-secondary: rgba(255, 255, 255, 0.88);
  --ink-caption: rgba(255, 255, 255, 0.80);
  --ink-muted: rgba(255, 255, 255, 0.74);
  --ink-faint: rgba(255, 255, 255, 0.55);
  /* black scrim: white washes go milky on saturated red */
  --surface-raise: rgba(0, 0, 0, 0.14);
  --surface-raise-hover: rgba(0, 0, 0, 0.22);
  --border-hair: rgba(255, 255, 255, 0.30);
  --border-hair-strong: rgba(255, 255, 255, 0.55);
  --ring: rgba(0, 0, 0, 0.30);
  --fill-invert-bg: #fff;
  --fill-invert-fg: #8c1414;
  --shadow-depth: rgba(0, 0, 0, 0.30);
  --shadow-depth-hero: rgba(0, 0, 0, 0.40);
  --phone-shadow-depth: rgba(0, 0, 0, 0.35);
  /* Font-picker dropdown panel (solid — floats over the phone demo);
     dark neutral, a red-tinted panel would fight the option faces */
  --menu-bg: #1c1c1c;
  --menu-ink: rgba(244, 242, 238, 0.92);
  --menu-raise: rgba(255, 255, 255, 0.10);
  --menu-border: rgba(255, 255, 255, 0.20);
}

html, body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  min-height: 100%;
}

body {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif, color-emoji;
  font-size: var(--fs0);
  font-weight: 300;
  line-height: 1.6;
  color: var(--ink);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

a { color: inherit; }

/* ---------- gallery bar ---------- */

.gallery-bar {
  position: relative;
  z-index: 3;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 2rem;
  max-width: 75em;
  margin: 0 auto;
}

.back-link {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-size: var(--fs-1);
  font-weight: 500;
  line-height: 1.4;
  color: var(--ink-secondary);
  text-decoration: none;
  transition: color 200ms ease;
}

.back-link:hover { color: var(--ink); }

/* ---------- museum header ---------- */

.museum-header {
  position: relative;
  z-index: 1;
  max-width: 45em;
  margin: 0 auto;
  padding: 2.5rem 2rem;
  text-align: center;
}

.museum-header .kicker {
  font-size: var(--fs-2);
  font-weight: 600;
  line-height: 1.4;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--ink-secondary);
  margin-bottom: 1rem;
}

.museum-header h1 {
  font-size: var(--fs6);
  line-height: 1.05;
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--ink-heading);
  margin: 0 0 1rem;
}

.museum-header--collection h1 { font-size: var(--fs5); }

@media (max-width: 620px) {
  .museum-header h1 { font-size: var(--fs5); }
  .museum-header--collection h1 { font-size: var(--fs4); }
}

.museum-header p {
  font-size: var(--fs1);
  font-weight: 300;
  line-height: 1.5;
  color: var(--ink-secondary);
  max-width: 28em;
  margin: 0 auto;
}

.museum-header .count {
  margin-top: 2rem;
  font-size: var(--fs-2);
  font-weight: 600;
  line-height: 1.4;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--ink-caption);
}

/* ---------- search bar ---------- */

.search-bar {
  position: relative;
  z-index: 1;
  max-width: 56em;
  margin: 0 auto 2.5rem;
  padding: 1rem 1.5rem;
  background: var(--surface-raise);
  border: 1px solid var(--border-hair);
  border-radius: 1rem;
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
}

.search-bar__row {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

.search-input {
  flex: 1;
  appearance: none;
  border: none;
  background: transparent;
  color: var(--ink);
  font-family: inherit;
  font-size: var(--fs0);
  font-weight: 400;
  line-height: 1.4;
  padding: 0.375rem 0.125rem;
  outline: none;
}

.search-input::placeholder { color: var(--ink-muted); }

.search-count {
  font-size: var(--fs-1);
  font-weight: 400;
  line-height: 1.4;
  color: var(--ink-caption);
  white-space: nowrap;
}

.search-bar__facets {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem 1rem;
  margin-top: 0.75rem;
  padding-top: 0.75rem;
  border-top: 1px solid var(--border-hair);
}

.facet-group {
  display: flex;
  align-items: center;
  gap: 0.375rem;
  flex-wrap: wrap;
}

/* Guide .tag adapted; pill radius kept as the recorded museum variant. */
.facet-chip {
  appearance: none;
  border: 1px solid var(--border-hair-strong);
  background: var(--surface-raise);
  color: var(--ink-secondary);
  border-radius: 999px;
  padding: 0.3em 0.9em;
  font-size: var(--fs-2);
  font-weight: 500;
  line-height: 1.4;
  cursor: pointer;
  transition: background 150ms ease, color 150ms ease, border-color 150ms ease;
}

/* :not(--active) so hover can never clobber the active inverted fill. */
.facet-chip:hover:not(.facet-chip--active) { background: var(--surface-raise-hover); }

.facet-chip--active {
  background: var(--fill-invert-bg);
  color: var(--fill-invert-fg);
  border-color: var(--fill-invert-bg);
}

.facet-chip--reset {
  border-style: dashed;
  color: var(--ink-caption);
}

.hue-picker {
  gap: 7px;
}

.hue-swatch {
  appearance: none;
  border: 2px solid var(--border-hair-strong);
  width: 22px;
  height: 22px;
  border-radius: 50%;
  padding: 0;
  cursor: pointer;
  background: hsl(var(--sw-hue, 0), 68%, 55%);
  transition: transform 150ms ease, border-color 150ms ease;
}

.hue-swatch:hover { transform: scale(1.15); }

.hue-swatch--active {
  border-color: var(--fill-invert-bg);
  transform: scale(1.2);
}

/* ---------- gallery grid ---------- */

.gallery-wrap {
  position: relative;
  z-index: 1;
  max-width: 90em;
  margin: 0 auto;
  padding: 0 2rem 6rem;
}

.gallery-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  grid-auto-rows: 130px;
  grid-auto-flow: dense;
  gap: 1.5rem;
}

.gallery-empty {
  text-align: center;
  padding: 4rem 0;
  color: var(--ink-caption);
  font-size: var(--fs-1);
  font-weight: 400;
  line-height: 1.4;
}

.piece {
  position: relative;
  display: block;
  border-radius: 10px;
  overflow: hidden;
  text-decoration: none;
  color: inherit;
  outline: none;
  transform: translateZ(0);
  transition: transform 420ms cubic-bezier(0.16, 1, 0.3, 1);
  /* Melt-fix hairline: keeps near-surface screenBg themes (e.g. Heatmap's
     near-black bottom) from dissolving into the page on either surface. */
  box-shadow: 0 0 0 1px var(--ring);
}

.piece.size-hero { grid-column: span 3; grid-row: span 3; }
.piece.size-wide { grid-column: span 2; grid-row: span 1; }
.piece.size-tall { grid-column: span 1; grid-row: span 2; }
.piece.size-small { grid-column: span 1; grid-row: span 1; }
.piece.size-medium { grid-column: span 2; grid-row: span 2; }

@media (max-width: 900px) {
  .piece.size-hero { grid-column: span 2; grid-row: span 2; }
}

@media (max-width: 620px) {
  .gallery-grid { grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); grid-auto-rows: 100px; gap: 0.75rem; }
  .piece.size-hero { grid-column: span 2; grid-row: span 2; }
  .piece.size-wide { grid-column: span 2; grid-row: span 1; }
  .piece.size-tall { grid-column: span 1; grid-row: span 2; }
}

/* Spotlighting stays (inside the card), but far subtler than the swatch-era
   value — the card now carries readable text rows that a heavy multiply
   vignette would murk. */
.piece__vignette {
  position: absolute;
  inset: 0;
  background:
    radial-gradient(ellipse 120% 90% at 50% -10%, rgba(255,255,255,0.10), transparent 45%),
    radial-gradient(ellipse 140% 110% at 50% 120%, rgba(0,0,0,0.30), transparent 55%),
    linear-gradient(rgba(0,0,0,0.02), rgba(0,0,0,0.14));
  mix-blend-mode: multiply;
  opacity: 0.5;
  pointer-events: none;
}

.piece__sheen {
  position: absolute;
  inset: 0;
  background: radial-gradient(circle at 50% 0%, rgba(255,255,255,0.22), transparent 55%);
  opacity: 0;
  transition: opacity 420ms ease;
  mix-blend-mode: screen;
}

/* ---- mini app screen: header (theme name as list title) + real lerped rows.
   All 6 rows are always in the markup; the card's geometry decides how many
   are visible — rows are FIXED height, never stretched. A short list leaves
   the theme's screen background below; a long list crops the last row at the
   card edge, exactly like a real phone viewport crops a long list.

   Proportionality contract (app-exact ratios, per the approved plan):
   row = the unit; header band = 1.208×row (87/72pt); row text = 0.347×row
   (25/72); title = 0.417×row (30/72, a 1.2 type-scale step over row text);
   left pad = 0.208×row (15/72); overlay = 1.806×row (130/72).

   Base px rules below are the no-container-query fallback; the real
   proportional metrics live in the @supports block. */

.piece__screen {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  isolation: isolate;
  font-family: var(--card-font, -apple-system, BlinkMacSystemFont, sans-serif);
  font-synthesis: none;
}

/* Explicit paint order for image-backed cards: photo (z0) -> scrim (z1) ->
   header/rows (z2, in normal flow) -> overlay (z3). Opaque cards never emit
   .piece__photo/.piece__scrim, so this is a no-op for them. */
.piece__photo {
  position: absolute;
  inset: 0;
  z-index: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.piece__scrim {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
}

.piece__header {
  position: relative;
  z-index: 2;
  flex: 0 0 auto;
  display: flex;
  align-items: flex-end;
  height: 33px;
  padding: 0 10px 5px;
  font-size: 11.5px;
  font-weight: 700;
  line-height: 1.1;
  letter-spacing: -0.01em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.piece__rows {
  position: relative;
  z-index: 2;
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
  overflow: hidden;
}

.piece__row {
  flex: 0 0 auto;
  height: 27.5px;
  display: flex;
  align-items: center;
  padding: 0 10px;
  font-size: 9.5px;
  font-weight: 600;
  line-height: 1.2;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.piece__overlay {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 3;
  height: 50px;
  pointer-events: none;
}

@supports (container-type: size) {
  .piece { container-type: size; }

  .piece__screen {
    /* Row unit: width-true phone scale (72/393 = 18.32cqw), clamped so
       header (1.208u) + at least 2 full rows always fit the card height. */
    --u: min(18.32cqw, 31cqh);
  }

  .piece__header {
    height: calc(1.208 * var(--u));
    padding: 0 calc(0.222 * var(--u)) calc(0.194 * var(--u)) calc(0.208 * var(--u));
    font-size: calc(0.417 * var(--u));
  }

  .piece__row {
    height: calc(var(--u));
    padding: 0 calc(0.222 * var(--u)) 0 calc(0.208 * var(--u));
    font-size: calc(0.347 * var(--u));
  }

  .piece__overlay {
    height: calc(1.806 * var(--u));
  }
}

.piece:hover,
.piece:focus-visible {
  transform: translateY(-4px) scale(1.02);
  z-index: 2;
}

.piece:hover .piece__sheen,
.piece:focus-visible .piece__sheen {
  opacity: 1;
}

.piece:hover .piece__vignette,
.piece:focus-visible .piece__vignette {
  opacity: 0.55;
}

/* No color aura outside card borders (removed per Cherian's review) —
   hover/hero shadows are neutral depth only. The --ring layer is repeated in
   every stack so the melt-fix hairline survives all states. */
.piece:hover,
.piece:focus-visible {
  box-shadow:
    0 0 0 1px var(--ring),
    0 30px 60px -20px var(--shadow-depth);
}

.piece.size-hero {
  box-shadow:
    0 0 0 1px var(--ring),
    0 40px 80px -30px var(--shadow-depth-hero);
}

/* ---------- pagination ---------- */

.pagination {
  position: relative;
  z-index: 1;
  max-width: 75em;
  margin: 0 auto;
  padding: 0 2rem 4rem;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 1.5rem;
  font-size: var(--fs-1);
  line-height: 1.4;
}

.page-link {
  font-weight: 500;
  color: var(--ink-secondary);
  text-decoration: none;
  transition: color 200ms ease;
}

.page-link:hover { color: var(--ink); }

.page-current {
  font-weight: 400;
  color: var(--ink-muted);
}

/* ---------- footer ---------- */

.museum-footer {
  position: relative;
  z-index: 1;
  text-align: center;
  padding: 0 2rem 6rem;
  color: var(--ink-caption);
  font-size: var(--fs-1);
  font-weight: 300;
  line-height: 1.5;
}

.museum-footer strong {
  color: var(--ink-secondary);
  font-weight: 600;
}

.footer-store-link {
  display: inline-block;
  margin-left: 0.6em;
  color: var(--ink-secondary);
  text-decoration: none;
  border-bottom: 1px solid var(--ink-faint);
}

.footer-store-link:hover { color: var(--ink); }

/* ---------- detail: the vault room ---------- */

/* No overflow clip: the blurred glows must finish their fade PAST the
   section boundary — clipping them mid-intensity printed a straight seam
   where the vault meets the next section (designer round 3c). The spill
   paints under .related (z-index 1) and body's overflow-x:hidden absorbs
   the 900px floor glow on narrow viewports. */
.vault {
  position: relative;
  min-height: 92vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 2.5rem 2rem 4rem;
}

.vault__glow {
  position: absolute;
  inset: 0;
  z-index: 0;
  background: radial-gradient(ellipse 60% 55% at 50% 42%, var(--g-start), transparent 68%);
  opacity: 0.28;
  filter: blur(10px);
  pointer-events: none;
  transition: opacity 600ms ease, background 600ms ease;
}

.vault__floor-glow {
  position: absolute;
  left: 50%;
  bottom: -10%;
  /* clamped to the viewport: with .vault no longer clipping, a fixed 900px
     would create horizontal scroll range on narrow screens */
  width: min(900px, 100vw);
  height: 320px;
  transform: translateX(-50%);
  background: radial-gradient(ellipse 50% 100% at 50% 100%, var(--g-end), transparent 70%);
  opacity: 0.35;
  filter: blur(20px);
  pointer-events: none;
  z-index: 0;
}

.vault__stage {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: minmax(300px, 460px) minmax(280px, 420px);
  gap: 4rem;
  align-items: center;
  max-width: 65em;
  width: 100%;
}

@media (max-width: 860px) {
  .vault__stage { grid-template-columns: 1fr; justify-items: center; text-align: center; gap: 2.5rem; }
}

.phone-wrap {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 18px;
}

/* Immersive scale: the phone dominates the vault. Uniform transform of the
   true 393×852 frame — every internal typographic ratio is preserved by
   construction. Height steps keep the whole phone in view on short windows.
   (drop-shadow() takes no spread value — the old 4-length glow was invalid
   CSS and browsers discarded the whole filter.) */
.demo-mount {
  --ctd-scale: 0.92;
  /* Reserves the exact box theme-demo.js will fill (.ctd-phone-scale is
     413x872 * var(--ctd-scale) in theme-demo.css) so the empty mount
     doesn't cause a layout shift when the phone mockup mounts. */
  width: calc(413px * var(--ctd-scale));
  height: calc(872px * var(--ctd-scale));
  filter: drop-shadow(0 60px 100px var(--phone-shadow-depth))
          drop-shadow(0 0 90px color-mix(in srgb, var(--g-start) 45%, transparent));
}

/* Melt-fix ring + tokenized depth for the phone itself (this page-scoped
   rule replaces theme-demo.css's box-shadow entirely, so the full stack is
   restated: ring, depth, inset bezel ring). */
.demo-mount .ctd-phone {
  box-shadow:
    0 0 0 1px var(--ring),
    0 40px 80px var(--phone-shadow-depth),
    inset 0 0 0 1px rgba(255, 255, 255, 0.12);
}

@media (max-height: 1000px) {
  .demo-mount { --ctd-scale: 0.8; }
}

@media (max-height: 840px) {
  .demo-mount { --ctd-scale: 0.68; }
}

@media (max-width: 860px) {
  .demo-mount { --ctd-scale: 0.72; }
}

.demo-hint {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 0.75rem 1.25rem;
}

/* Demo shelf: frameless control cluster under the phone — kicker-labeled
   groups with pill-style segmented controls and a font dropdown (designer
   feedback round 3, superseding the earlier framed plain-text/stacked-sizer
   design; see docs/superpowers/specs/2026-07-23-demo-controls-shelf-design.md).
   Active pill fills use the --fill-invert tokens (white fill, dark-red
   text on the red surface). */
.demo-shelf {
  display: inline-flex;
  align-items: flex-start;
  gap: 2.5rem;
  padding: 0.7rem 0 0.8rem;
}

.shelf-group {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.35rem;
}

.shelf-kicker {
  font-size: var(--fs-2);
  font-weight: 600;
  letter-spacing: 0.10em;
  text-transform: uppercase;
  color: var(--ink-caption);
}

/* Segmented pill track (Screen + Sound groups; the font group uses
   .shelf-picker below). */
.shelf-choices {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  padding: 2px;
  border-radius: 999px;
  background: var(--surface-raise);
}

.shelf-choices button {
  appearance: none;
  border: none;
  background: none;
  padding: 0.22em 0.95em;
  border-radius: 999px;
  font-family: inherit;
  font-size: var(--fs-1);
  font-weight: 500;
  line-height: 1.4;
  color: var(--ink-secondary);
  cursor: pointer;
  transition: color 150ms ease, background-color 150ms ease;
}

.shelf-choices button:hover { color: var(--ink-heading); }
.shelf-choices button.is-active {
  background: var(--fill-invert-bg);
  color: var(--fill-invert-fg);
}

/* Font picker: select-only combobox. Trigger is pill-shaped like the
   segmented tracks; the listbox opens UPWARD (the shelf sits at the bottom
   of the vault) as a solid panel floating over the phone demo. */
.shelf-picker {
  position: relative;
  display: inline-flex;
}

.shelf-select {
  appearance: none;
  border: none;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
  padding: calc(0.22em + 2px) 1em;
  border-radius: 999px;
  background: var(--surface-raise);
  font-family: inherit;
  font-size: var(--fs-1);
  font-weight: 500;
  line-height: 1.4;
  color: var(--ink);
  max-width: 13em;
  transition: background-color 150ms ease;
}

.shelf-select:hover { background: var(--surface-raise-hover); }

.shelf-select__label {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.shelf-select__caret {
  font-size: 0.833em; /* one 1.2 modular step below the trigger */
  color: var(--ink-caption);
  transition: transform 150ms ease;
}

.shelf-select[aria-expanded="true"] .shelf-select__caret { transform: rotate(180deg); }

.shelf-menu {
  position: absolute;
  bottom: calc(100% + 0.5rem);
  left: 50%;
  transform: translateX(-50%);
  z-index: 30;
  margin: 0;
  padding: 0.35rem;
  list-style: none;
  min-width: 13em;
  max-height: 300px;
  overflow-y: auto;
  background: var(--menu-bg);
  color: var(--menu-ink);
  border: 1px solid var(--menu-border);
  border-radius: 10px;
  box-shadow: 0 12px 40px var(--shadow-depth);
  text-align: left;
}

.shelf-menu [role="option"] {
  padding: 0.4em 0.75em;
  border-radius: 6px;
  font-size: var(--fs-1);
  line-height: 1.35;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  cursor: pointer;
}

.shelf-menu [role="option"]:hover { background: var(--menu-raise); }

/* Keyboard active-descendant: distinct from the selected state below. */
.shelf-menu [role="option"].is-focused {
  background: var(--menu-raise);
  outline: 1px solid var(--border-hair-strong);
  outline-offset: -1px;
}

/* Selected: checkmark in a system face — options render in their own
   (glyph-gated-for-the-label) fonts, which may not carry U+2713. */
.shelf-menu [role="option"][aria-selected="true"]::after {
  content: " \2713";
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  opacity: 0.7;
}

.shelf-menu__sep {
  border-top: 1px solid var(--menu-border);
  margin: 0.35rem 0.25rem;
}

@media (max-width: 620px) {
  .demo-shelf { flex-direction: column; align-items: center; gap: 1rem; }
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* ---------- placard ---------- */

.placard-title {
  display: flex;
  align-items: center;
  gap: 0.85rem;
  margin: 0 0 0.75rem;
}

.placard h1 {
  font-size: var(--fs5);
  font-weight: 600;
  line-height: 1.05;
  letter-spacing: -0.02em;
  color: var(--ink-heading);
  margin: 0;
}

/* App icon (square, staged at 132px = 44px @3x); radius approximates the iOS
   squircle at this size. */
.placard-icon {
  height: 44px;
  width: 44px;
  border-radius: 10px;
  box-shadow: 0 0 0 1px var(--ring);
  flex: none;
}

@media (max-width: 860px) {
  .placard-title { justify-content: center; }
}

@media (max-width: 620px) {
  .placard h1 { font-size: var(--fs4); }
  .placard-icon { height: 36px; width: 36px; }
}

.placard-meta {
  display: flex;
  align-items: center;
  gap: 0.6em;
  font-size: var(--fs-2);
  font-weight: 600;
  line-height: 1.4;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--ink-caption);
  margin-bottom: 1rem;
}

.placard-meta .dot {
  width: 3px;
  height: 3px;
  border-radius: 50%;
  background: currentColor;
  opacity: 0.6;
}

@media (max-width: 860px) {
  .placard-meta { justify-content: center; }
}

/* ---------- provenance badge ---------- */

.provenance-badge {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin-bottom: 1rem;
}

@media (max-width: 860px) {
  .provenance-badge { justify-content: center; }
}

/* Guide badge spec: smallest label, 600, 0.05em, tight radius. */
.provenance-badge__rarity {
  display: inline-block;
  font-size: var(--fs-2);
  font-weight: 600;
  line-height: 1;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  padding: 0.25em 0.65em;
  border-radius: 3px;
  background: var(--surface-raise);
  border: 1px solid var(--border-hair-strong);
  color: var(--ink);
}

/* Rarity tints, tuned for the flat #DC2C2C surface: the original
   dark-surface pastels dropped below 3:1 composited over red (Legendary
   ~2.9:1, Pro ~2.65:1) — lighter fg + lower bg alpha restores the floor
   without changing hue. */
.provenance-badge__rarity[data-rarity="Legendary"] {
  background: rgba(255, 200, 87, 0.10);
  border-color: rgba(255, 200, 87, 0.4);
  color: #ffe6b0;
}

.provenance-badge__rarity[data-rarity="Rare"] {
  background: rgba(126, 218, 199, 0.14);
  border-color: rgba(126, 218, 199, 0.4);
  color: #a4e8d6;
}

.provenance-badge__rarity[data-rarity="Pro"] {
  background: rgba(200, 185, 255, 0.10);
  border-color: rgba(180, 160, 255, 0.4);
  color: #efe9ff;
}

.provenance-badge__artist {
  font-size: var(--fs-1);
  font-weight: 500;
  line-height: 1.4;
  color: var(--ink-caption);
}

/* One prose tier: unlock-copy, placard-note, and placard-about share a
   single spec (fs0 / 300 / 1.6 / 34em / 1.5rem gap) — adjacent prose at
   mismatched scale steps read as an accident, not hierarchy. Enforced by
   _build/checks/type-scale-check.mjs (prose-parity assertion). */
.unlock-copy {
  font-size: var(--fs0);
  font-weight: 300;
  line-height: 1.6;
  color: var(--ink-secondary);
  max-width: 34em;
  margin: 0 0 1.5rem;
}

@media (max-width: 860px) {
  .unlock-copy { margin-left: auto; margin-right: auto; }
}

.placard-note {
  font-size: var(--fs0);
  font-weight: 300;
  line-height: 1.6;
  color: var(--ink-secondary);
  max-width: 34em;
  margin: 0 0 1.5rem;
}

@media (max-width: 860px) {
  .placard-note { margin-left: auto; margin-right: auto; }
}

.placard-about {
  font-size: var(--fs0);
  font-weight: 300;
  line-height: 1.6;
  color: var(--ink-secondary);
  max-width: 34em;
  margin: 0 0 1.5rem;
}

.placard-about p {
  margin: 0 0 0.75em;
}

.placard-about p:last-child {
  margin-bottom: 0;
}

.placard-about code {
  font-family: ui-monospace, 'SF Mono', Menlo, monospace;
  font-size: 0.833em; /* one 1.2 modular step below the parent (1/1.2) */
  color: var(--ink-secondary); /* caption ink is <AA on light/red */
}

@media (max-width: 860px) {
  .placard-about { margin-left: auto; margin-right: auto; }
}

.placard-links {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  margin-bottom: 1.5rem;
}

.placard-link {
  font-size: var(--fs-1);
  font-weight: 500;
  line-height: 1.5;
  color: var(--ink);
  text-decoration: none;
  border-bottom: 1px solid var(--ink-faint);
  align-self: flex-start;
  transition: color 150ms ease;
}

@media (max-width: 860px) {
  .placard-links { align-items: center; }
  .placard-link { align-self: center; }
}

.placard-link:hover { color: var(--ink-heading); }

.placard-ctas {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.75rem;
}

/* Secondary CTA: outlined ghost pill, deliberately quieter than the App Store
   pill (the page's one loud element). Visual placeholder — inert until the
   Clear deep-link plumbing exists. */
.apply-cta {
  display: inline-block;
  font-family: inherit;
  font-size: var(--fs-1);
  font-weight: 600;
  line-height: 1;
  color: var(--ink);
  background: none;
  border: 1px solid var(--border-hair-strong);
  padding: 0.8em 1.6em;
  border-radius: 999px;
  cursor: pointer;
  transition: color 150ms ease, border-color 150ms ease;
}

.apply-cta:hover { color: var(--ink-heading); border-color: var(--ink); }

@media (max-width: 860px) {
  .placard-ctas { align-items: center; }
}

/* Recorded exception: the CTA keeps its pill + inverted fill — the page's
   one deliberately loud element. Type follows the system. */
.app-store-cta {
  display: inline-block;
  font-size: var(--fs-1);
  font-weight: 600;
  line-height: 1;
  color: #0a0a0a;
  background: #f4f2ee;
  padding: 0.8em 1.6em;
  border-radius: 999px;
  text-decoration: none;
  transition: transform 150ms ease, box-shadow 150ms ease;
}

.app-store-cta:hover {
  transform: translateY(-1px);
  box-shadow: 0 8px 20px -6px var(--ink-muted);
}

/* ---------- related ---------- */

.related {
  position: relative;
  z-index: 1;
  max-width: 65em;
  margin: 0 auto;
  padding: 2.5rem 2rem 6rem;
}

.related h2 {
  font-size: var(--fs-2);
  font-weight: 600;
  line-height: 1.4;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--ink-caption);
  margin: 0 0 1.5rem;
}

/* Compact-accent mosaic: a 2×2 feature card leading, the rest small — with 6
   related picks this fills exactly a 3×3 block. Dense flow packs the smalls
   around the accent. Same mini-app-screen card renderer as the gallery. */
.related-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-auto-rows: 150px;
  grid-auto-flow: dense;
  gap: 1.5rem;
}

.related-grid .piece.size-related {
  grid-column: span 1;
  grid-row: span 1;
}

.related-grid .piece.size-related-accent {
  grid-column: span 2;
  grid-row: span 2;
}

@media (max-width: 640px) {
  .related-grid { grid-template-columns: repeat(2, 1fr); }
  /* Accent stays 2-wide (full row) but only 1 tall so the strip doesn't
     tower on narrow screens. */
  .related-grid .piece.size-related-accent { grid-column: span 2; grid-row: span 1; }
}

