/* ==========================================================================
   SupDucks — home page
   Palette + shapes pulled from the SupDucks Public Figma board:
   the boardwalk scene, the wordmark, and the 16 background traits.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Tokens
   -------------------------------------------------------------------------- */
:root {
  /* Core brand colors, sampled off the boardwalk illustration */
  --sup-sky:        #6FE0F5;
  --sup-sky-deep:   #3FC6E8;
  /* Sampled from the top row of boardwalk-strip.webp. The hero sky must end
     on exactly this value or a seam shows where the CSS sky meets the art. */
  --sky-art:        #78E0FF;
  --sup-sea:        #2E5FD9;
  --sup-sand:       #EBD7A6;
  --sup-road:       #8A8A8A;

  --sup-pink:       #FF5FA2;
  --sup-bubblegum:  #FF95D6;
  --sup-yellow:     #FFD23F;
  --sup-orange:     #FF8A3D;
  --sup-toxic:      #B6F24B;
  /* Only for destructive states -- currently the connected wallet pill on
     hover/press. Deliberately not one of the boardwalk colours: it has to
     read as "this undoes something" against a palette that is otherwise all
     candy brights. */
  --sup-danger:     #E5484D;
  --sup-green:      #5BD46B;
  --sup-purple:     #7B4BE8;
  --sup-deep:       #241748;

  --sup-ink:        #0D0D0D;
  --sup-cream:      #FFF7E9;
  --sup-paper:      #FFFFFF;

  /* The wordmark is a heavy black outline — that outline is the whole system */
  --line:           4px;
  --line-thick:     6px;
  --radius:         18px;
  --radius-lg:      28px;
  --radius-pill:    999px;

  /* Hard offset shadow, no blur — sticker look */
  --pop:            6px 6px 0 var(--sup-ink);
  --pop-sm:         4px 4px 0 var(--sup-ink);
  --pop-lg:         10px 10px 0 var(--sup-ink);

  --font-display:   "Sigmar", "Impact", system-ui, sans-serif;
  --font-body:      "Nunito", ui-rounded, "Segoe UI", system-ui, sans-serif;

  --shell:          1180px;
  --shell-narrow:   780px;
  --header-h:       76px;

  --ease-out:       cubic-bezier(0.16, 1, 0.3, 1);
}

/* --------------------------------------------------------------------------
   2. Reset / base
   -------------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

html {
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--header-h) + 16px);
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  font-family: var(--font-body);
  font-size: clamp(1rem, 0.96rem + 0.2vw, 1.075rem);
  line-height: 1.65;
  color: var(--sup-ink);
  background: var(--sup-cream);
  overflow-x: hidden;
}

img { max-width: 100%; display: block; height: auto; }
ul, ol { margin: 0; padding: 0; list-style: none; }
p { margin: 0 0 1.1em; }
a { color: inherit; }

h1, h2, h3, h4 {
  font-family: var(--font-display);
  font-weight: 400;
  line-height: 1.02;
  letter-spacing: 0.01em;
  margin: 0 0 0.4em;
}

.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;
}

.skip-link {
  position: absolute; left: 12px; top: -100px; z-index: 200;
  background: var(--sup-yellow); color: var(--sup-ink);
  padding: 12px 20px; border: var(--line) solid var(--sup-ink);
  border-radius: var(--radius); font-weight: 900; text-decoration: none;
  transition: top 0.2s var(--ease-out);
}
.skip-link:focus { top: 12px; }

:focus-visible {
  outline: 4px solid var(--sup-purple);
  outline-offset: 3px;
  border-radius: 4px;
}

/* --------------------------------------------------------------------------
   3. Layout primitives
   -------------------------------------------------------------------------- */
.shell {
  width: min(100% - 2.5rem, var(--shell));
  margin-inline: auto;
}
.shell--narrow { width: min(100% - 2.5rem, var(--shell-narrow)); }

.section { padding: clamp(4.5rem, 9vw, 7.5rem) 0; position: relative; }
.section--tight { padding-top: 0; }
.section--cream { background: var(--sup-cream); }
.section--sky {
  background: linear-gradient(180deg, var(--sup-sky) 0%, var(--sup-sky-deep) 100%);
  border-top: var(--line-thick) solid var(--sup-ink);
  border-bottom: var(--line-thick) solid var(--sup-ink);
}
.section--dark {
  background:
    radial-gradient(120% 90% at 80% 0%, rgba(123, 75, 232, 0.55), transparent 60%),
    radial-gradient(90% 80% at 10% 100%, rgba(255, 95, 162, 0.35), transparent 60%),
    var(--sup-deep);
  border-bottom: var(--line-thick) solid var(--sup-ink);
}

.section__head {
  max-width: 760px;
  margin: 0 auto clamp(2.5rem, 5vw, 4rem);
  text-align: center;
}
.section__head--left { margin-inline: 0; text-align: left; }
.section__sub { font-size: 1.1rem; opacity: 0.92; margin-bottom: 0; }

.h2 { font-size: clamp(2.1rem, 1.3rem + 3.4vw, 3.9rem); }
.h2--light { color: var(--sup-paper); text-shadow: 4px 4px 0 var(--sup-ink); }

.eyebrow {
  font-family: var(--font-display);
  font-size: 0.86rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--sup-paper);
  -webkit-text-stroke: 0.6px var(--sup-ink);
  margin-bottom: 0.9rem;
}
.eyebrow--dark { color: var(--sup-purple); -webkit-text-stroke: 0; }

/* On the pale hero sky the white-on-stroke treatment washes out, so the
   hero eyebrow runs dark with a light halo instead. */
.hero .eyebrow {
  color: var(--sup-deep);
  -webkit-text-stroke: 0;
  text-shadow: 0 1px 0 rgba(255, 255, 255, 0.65);
}

/* --------------------------------------------------------------------------
   4. Buttons
   -------------------------------------------------------------------------- */
.btn {
  --btn-bg: var(--sup-yellow);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  font-family: var(--font-display);
  font-size: 1.05rem;
  letter-spacing: 0.03em;
  text-decoration: none;
  padding: 0.85rem 1.75rem;
  background: var(--btn-bg);
  color: var(--sup-ink);
  border: var(--line) solid var(--sup-ink);
  border-radius: var(--radius-pill);
  box-shadow: var(--pop);
  cursor: pointer;
  transition: transform 0.14s var(--ease-out), box-shadow 0.14s var(--ease-out);
}
.btn:hover { transform: translate(3px, 3px); box-shadow: var(--pop-sm); }
.btn:active { transform: translate(6px, 6px); box-shadow: 0 0 0 var(--sup-ink); }

.btn--sm { font-size: 0.9rem; padding: 0.55rem 1.15rem; box-shadow: var(--pop-sm); }
.btn--pink   { --btn-bg: var(--sup-pink); color: var(--sup-paper); }
.btn--yellow { --btn-bg: var(--sup-yellow); }
.btn--ghost  { --btn-bg: var(--sup-paper); }
.btn--ghost-light { --btn-bg: var(--sup-sky); }

/* --------------------------------------------------------------------------
   5. Header
   -------------------------------------------------------------------------- */
.site-header {
  position: fixed;
  inset: 0 0 auto 0;
  z-index: 100;
  height: var(--header-h);
  display: flex;
  align-items: center;
  transition: background 0.25s var(--ease-out), box-shadow 0.25s var(--ease-out);
}
.site-header.is-stuck {
  background: var(--sup-cream);
  border-bottom: var(--line) solid var(--sup-ink);
  box-shadow: 0 6px 0 rgba(13, 13, 13, 0.08);
}

.header__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.5rem;
  width: min(100% - 2.5rem, 1320px);
}

.brand { display: block; flex: none; }
.brand__mark {
  height: 30px;
  width: auto;
  transition: transform 0.2s var(--ease-out);
}
.brand:hover .brand__mark { transform: rotate(-3deg) scale(1.04); }

.nav {
  display: flex;
  align-items: center;
  gap: clamp(1rem, 2vw, 1.9rem);
}
.nav > a {
  font-family: var(--font-display);
  font-size: 1rem;
  letter-spacing: 0.03em;
  text-decoration: none;
  color: var(--sup-ink);
  position: relative;
  padding: 4px 0;
}
.nav > a:not(.btn)::after {
  content: "";
  position: absolute;
  left: 0; right: 0; bottom: -2px;
  height: 4px;
  border-radius: 4px;
  background: var(--sup-pink);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 0.22s var(--ease-out);
}
.nav > a:not(.btn):hover::after { transform: scaleX(1); }

/* Hero sits on sky blue, so the un-stuck header needs light text */
.site-header:not(.is-stuck) .nav > a:not(.btn) {
  color: var(--sup-ink);
  text-shadow: 0 2px 0 rgba(255, 255, 255, 0.5);
}

.nav-toggle {
  display: none;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 48px; height: 44px;
  padding: 0 9px;
  background: var(--sup-yellow);
  border: var(--line) solid var(--sup-ink);
  border-radius: 12px;
  box-shadow: var(--pop-sm);
  cursor: pointer;
}
.nav-toggle__bar {
  display: block; height: 4px; width: 100%;
  background: var(--sup-ink); border-radius: 3px;
  transition: transform 0.22s var(--ease-out), opacity 0.15s linear;
}
.nav-toggle[aria-expanded="true"] .nav-toggle__bar:nth-child(1) { transform: translateY(9px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] .nav-toggle__bar:nth-child(2) { opacity: 0; }
.nav-toggle[aria-expanded="true"] .nav-toggle__bar:nth-child(3) { transform: translateY(-9px) rotate(-45deg); }

/* --------------------------------------------------------------------------
   6. Hero
   -------------------------------------------------------------------------- */
.hero {
  position: relative;
  min-height: min(100svh, 860px);
  padding-top: calc(var(--header-h) + clamp(1.25rem, 3.5vw, 2.75rem));
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  overflow: hidden;
  /* The flat --sky-art band has to reach the artwork's top edge, and where
     that edge lands is driven by WIDTH, not height: boardwalk-strip.webp is
     3000x991, always rendered at 100% width, so it is 33.03vw tall no matter
     how tall the hero is. Pinning the stop to a percentage of hero height
     (it was 55%) therefore only worked at some window sizes -- the scene top
     measures 79% of the hero at 375px wide but 37% at 2560px, so on wide
     screens the art butted into sky that had not finished fading and a hard
     line showed (#84E4FF against #78E0FF at 2560).

     Measured from the bottom instead, the flat band tracks the art exactly:
     33.03vw for the strip, rounded up to 34vw for slack, plus 3rem to clear
     .hero__scene's padding-top (max 2rem). vw counts the scrollbar the hero
     does not, which only over-covers -- the safe direction. */
  background: linear-gradient(
    to top,
    var(--sky-art) 0,
    var(--sky-art) calc(34vw + 3rem),
    #9DEDFF 100%
  );
  border-bottom: var(--line-thick) solid var(--sup-ink);
}

.hero__sky { position: absolute; inset: 0; pointer-events: none; }

/* The real cloud, lifted straight out of the boardwalk illustration */
.cloud {
  position: absolute;
  height: auto;
  pointer-events: none;
  filter: drop-shadow(0 4px 0 rgba(13, 13, 13, 0.07));
}
.cloud--1 { width: clamp(180px, 22vw, 340px); top: 15%; left: 4%;   animation: drift 34s ease-in-out infinite; }
.cloud--2 { width: clamp(130px, 16vw, 250px); top: 31%; right: 10%; animation: drift 46s ease-in-out infinite reverse; }
/* mirrored so the three do not read as the same stamp repeated */
.cloud--3 { width: clamp(100px, 12vw, 190px); top: 8%;  right: 31%; animation: drift 58s ease-in-out infinite; transform: scaleX(-1); }

/* Uses the standalone `translate` property, not `transform`, so the mirrored
   cloud keeps its scaleX(-1) while drifting. */
@keyframes drift {
  from { translate: -5vw 0; }
  to   { translate: 5vw 0; }
}

.sun {
  position: absolute;
  top: 8%; right: 8%;
  width: 120px; height: 120px;
  border-radius: 50%;
  background: var(--sup-yellow);
  border: var(--line) solid var(--sup-ink);
  box-shadow: 0 0 0 14px rgba(255, 210, 63, 0.28);
}

.hero__content {
  position: relative;
  z-index: 2;
  text-align: center;
  max-width: 860px;
}

.hero__title { margin: 0 0 1rem; }
.hero__logo {
  /* Scales with the viewport instead of sitting at a fixed 720px, which made
     the hero overrun a 720px-tall screen by ~40%. */
  width: min(100%, clamp(280px, 44vw, 600px));
  margin-inline: auto;
  filter: drop-shadow(8px 8px 0 rgba(13, 13, 13, 0.22));
  animation: bob 5s ease-in-out infinite;
}

@keyframes bob {
  0%, 100% { transform: translateY(0) rotate(-0.6deg); }
  50%      { transform: translateY(-12px) rotate(0.6deg); }
}

.hero__lede {
  font-size: clamp(1.05rem, 0.95rem + 0.55vw, 1.35rem);
  font-weight: 700;
  max-width: 620px;
  margin: 0 auto 1.6rem;
  color: var(--sup-ink);
  text-shadow: 0 2px 0 rgba(255, 255, 255, 0.45);
}

.hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  justify-content: center;
}

.hero__scene {
  position: relative;
  z-index: 1;
  margin-top: auto;
  width: 100%;
  padding-top: clamp(1rem, 2.5vw, 2rem);
  /* Same colour as the strip's own sky, so any sub-pixel gap is invisible */
  background: var(--sky-art);
}
.hero__boardwalk {
  /* Exactly full width. Any overscale pushed the end buildings off-canvas,
     and the crop now runs from clean sky down to the true artwork edge, so
     nothing needs hiding. */
  width: 100%;
  margin-left: 0;
  will-change: transform;
}

/* --------------------------------------------------------------------------
   7. Marquee
   -------------------------------------------------------------------------- */
.marquee {
  background: var(--sup-pink);
  border-bottom: var(--line-thick) solid var(--sup-ink);
  overflow: hidden;
  padding: 0.75rem 0;
}
.marquee__track {
  display: flex;
  gap: 2rem;
  width: max-content;
  font-family: var(--font-display);
  font-size: 1.35rem;
  letter-spacing: 0.08em;
  color: var(--sup-paper);
  -webkit-text-stroke: 1.5px var(--sup-ink);
  animation: scroll-x 26s linear infinite;
}
.marquee__track .dot { color: var(--sup-yellow); -webkit-text-stroke: 1.5px var(--sup-ink); }

@keyframes scroll-x {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}

/* --------------------------------------------------------------------------
   8. Stats
   -------------------------------------------------------------------------- */
.stats {
  background: var(--sup-cream);
  padding: clamp(3rem, 6vw, 4.5rem) 0;
}
.stats__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 1.25rem;
}
.stat {
  background: var(--sup-paper);
  border: var(--line) solid var(--sup-ink);
  border-radius: var(--radius-lg);
  box-shadow: var(--pop);
  padding: 1.6rem 1.25rem;
  text-align: center;
  transition: transform 0.18s var(--ease-out);
}
.stat:nth-child(1) { background: var(--sup-yellow); }
.stat:nth-child(2) { background: var(--sup-bubblegum); }
.stat:nth-child(3) { background: var(--sup-toxic); }
.stat:nth-child(4) { background: var(--sup-sky); }
.stat:hover { transform: translateY(-6px) rotate(-1.5deg); }

.stat__num {
  display: block;
  font-family: var(--font-display);
  font-size: clamp(2.1rem, 1.5rem + 2.2vw, 3rem);
  line-height: 1;
  color: var(--sup-paper);
  -webkit-text-stroke: 2.5px var(--sup-ink);
  paint-order: stroke fill;
}
.stat__label {
  display: block;
  margin-top: 0.5rem;
  font-weight: 900;
  font-size: 0.9rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

/* --------------------------------------------------------------------------
   9. Split (World)
   -------------------------------------------------------------------------- */
.split {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(2rem, 5vw, 4.5rem);
  align-items: center;
}
.split__text .h2 { margin-bottom: 0.6em; }

.ticks { margin-top: 1.75rem; display: grid; gap: 0.75rem; }
.ticks li {
  position: relative;
  padding-left: 2.4rem;
  font-weight: 700;
}
.ticks li::before {
  content: "";
  position: absolute;
  left: 0; top: 2px;
  width: 26px; height: 26px;
  border-radius: 50%;
  background: var(--sup-toxic);
  border: 3px solid var(--sup-ink);
}
.ticks li::after {
  content: "";
  position: absolute;
  left: 9px; top: 9px;
  width: 6px; height: 11px;
  border: solid var(--sup-ink);
  border-width: 0 3px 3px 0;
  transform: rotate(42deg);
}

.polaroid {
  margin: 0;
  background: var(--sup-paper);
  border: var(--line) solid var(--sup-ink);
  border-radius: var(--radius);
  box-shadow: var(--pop-lg);
  padding: 14px 14px 0;
  transform: rotate(-1.6deg);
  transition: transform 0.25s var(--ease-out);
}
.polaroid:hover { transform: rotate(0.8deg) scale(1.015); }
.polaroid img {
  border: 3px solid var(--sup-ink);
  border-radius: 10px;
}
.polaroid figcaption {
  font-family: var(--font-display);
  font-size: 1.05rem;
  text-align: center;
  padding: 0.7rem 0 0.9rem;
}

/* --------------------------------------------------------------------------
   10. Featured duck
   -------------------------------------------------------------------------- */
.duck-feature {
  display: grid;
  grid-template-columns: minmax(0, 420px) 1fr;
  gap: clamp(2rem, 5vw, 4rem);
  align-items: center;
}

.duck-feature__card {
  margin: 0;
  background: var(--sup-paper);
  border: var(--line) solid var(--sup-ink);
  border-radius: var(--radius-lg);
  box-shadow: var(--pop-lg);
  overflow: hidden;
}

.duck-feature__art {
  position: relative;      /* positioning context for the loading cover */
  aspect-ratio: 1;
  border-bottom: var(--line) solid var(--sup-ink);
  display: grid;
  place-items: end center;
  background-size: cover;
  background-position: center;
  transition: background-image 0.2s linear;
}
.duck-feature__art img {
  width: 88%;
  align-self: end;
}

/* Until the duck of the day resolves, cover the card.
   The markup ships the bundled sample duck -- small, bottom-aligned, on a
   trait tile -- and the live token replaces it full-bleed. Left uncovered,
   every visitor watched that swap happen, which looked like a bug. This is
   an ::after cover rather than a rule on the element because buildDuckFeature
   paints the trait tile as an INLINE style, and no stylesheet rule outranks
   that without !important.

   Gated on .js: with scripting off nothing will ever replace the sample duck,
   so it must stay visible. */
.js .duck-feature__art.is-loading::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    linear-gradient(100deg, var(--sup-sky) 30%, #CFF6FF 50%, var(--sup-sky) 70%)
    0 0 / 300% 100%;
  animation: duck-shimmer 1.4s ease-in-out infinite;
}
@keyframes duck-shimmer {
  from { background-position: 150% 0; }
  to   { background-position: -50% 0; }
}
@media (prefers-reduced-motion: reduce) {
  .js .duck-feature__art.is-loading::after { animation: none; background: var(--sup-sky); }
}
/* The picker only applies to the bundled duck, so it must not appear and then
   vanish when the live one arrives. */
.js #duckPicker.is-pending { display: none; }

/* A live collection token is a finished square with its own background, so
   it fills the card instead of sitting on a trait tile. */
.duck-feature__art.is-live { background: none; place-items: stretch; }
.duck-feature__art.is-live img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  align-self: stretch;
}

.duck-feature__cap {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 0.9rem 1.2rem 1rem;
}
.duck-feature__name { font-family: var(--font-display); font-size: 1.25rem; }
.duck-feature__bg {
  font-size: 0.78rem;
  font-weight: 900;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  padding: 0.28rem 0.7rem;
  border: 2.5px solid var(--sup-ink);
  border-radius: var(--radius-pill);
  background: var(--sup-yellow);
  white-space: nowrap;
}

.duck-feature__info { color: var(--sup-ink); }
.duck-feature__h3 {
  font-size: clamp(1.6rem, 1.2rem + 1.6vw, 2.4rem);
  color: var(--sup-paper);
  text-shadow: 3px 3px 0 var(--sup-ink);
}
.duck-feature__info p { font-weight: 700; }
.duck-feature__hint { margin-bottom: 0.85rem; }

/* Real trait layer names off the board */
.chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.55rem;
  margin: 0 0 1.6rem;
}
.chips li {
  font-family: var(--font-display);
  font-size: 0.92rem;
  letter-spacing: 0.02em;
  padding: 0.35rem 0.85rem;
  background: var(--sup-paper);
  border: 3px solid var(--sup-ink);
  border-radius: var(--radius-pill);
  box-shadow: 3px 3px 0 var(--sup-ink);
}

.swatch-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(46px, 1fr));
  gap: 0.55rem;
  max-width: 520px;
}
.swatch {
  aspect-ratio: 1;
  padding: 0;
  border: 3px solid var(--sup-ink);
  border-radius: 12px;
  background-size: cover;
  background-position: center;
  cursor: pointer;
  transition: transform 0.15s var(--ease-out), box-shadow 0.15s var(--ease-out);
}
.swatch:hover { transform: translateY(-4px) scale(1.06); }
.swatch.is-active {
  box-shadow: 0 0 0 4px var(--sup-yellow), 4px 4px 0 var(--sup-ink);
  transform: translateY(-4px) scale(1.06);
}

/* --------------------------------------------------------------------------
   11. Background trait grid
   -------------------------------------------------------------------------- */
.bg-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 1.15rem;
}

.bg-card {
  border: var(--line) solid var(--sup-ink);
  border-radius: var(--radius);
  box-shadow: var(--pop-sm);
  overflow: hidden;
  background: var(--sup-paper);
  transition: transform 0.18s var(--ease-out), box-shadow 0.18s var(--ease-out);
}
.bg-card:hover { transform: translateY(-6px) scale(1.03); box-shadow: var(--pop); }

.bg-card__swatch {
  aspect-ratio: 1;
  border-bottom: 3px solid var(--sup-ink);
  background-size: cover;
  background-position: center;
}
.bg-card__name {
  display: block;
  font-family: var(--font-display);
  font-size: 0.95rem;
  text-align: center;
  padding: 0.6rem 0.5rem 0.7rem;
  letter-spacing: 0.02em;
}

/* --------------------------------------------------------------------------
   12. FAQ
   -------------------------------------------------------------------------- */
.faq { display: grid; gap: 1rem; }

.faq__item {
  background: var(--sup-paper);
  border: var(--line) solid var(--sup-ink);
  border-radius: var(--radius);
  box-shadow: var(--pop-sm);
  overflow: hidden;
}
.faq__item[open] { background: var(--sup-yellow); }

.faq__item summary {
  list-style: none;
  cursor: pointer;
  padding: 1.15rem 3.5rem 1.15rem 1.4rem;
  font-family: var(--font-display);
  font-size: 1.2rem;
  position: relative;
}
.faq__item summary::-webkit-details-marker { display: none; }
.faq__item summary::after {
  content: "";
  position: absolute;
  right: 1.4rem; top: 50%;
  width: 14px; height: 14px;
  border: solid var(--sup-ink);
  border-width: 0 4px 4px 0;
  transform: translateY(-70%) rotate(45deg);
  transition: transform 0.22s var(--ease-out);
}
.faq__item[open] summary::after { transform: translateY(-25%) rotate(-135deg); }

.faq__answer { padding: 0 1.4rem 1.3rem; }
.faq__answer p { margin: 0; font-weight: 700; }

/* --------------------------------------------------------------------------
   13. Join CTA
   -------------------------------------------------------------------------- */
.join {
  background:
    radial-gradient(80% 120% at 50% 0%, rgba(255, 210, 63, 0.35), transparent 65%),
    linear-gradient(160deg, var(--sup-pink) 0%, var(--sup-purple) 100%);
  border-top: var(--line-thick) solid var(--sup-ink);
  border-bottom: var(--line-thick) solid var(--sup-ink);
  padding: clamp(4rem, 9vw, 7rem) 0;
}
.join__inner { text-align: center; }
.join__title { margin-bottom: 0.5em; }
.join__sub {
  color: var(--sup-paper);
  font-weight: 900;
  font-size: 1.15rem;
  text-shadow: 0 2px 0 rgba(13, 13, 13, 0.35);
  margin-bottom: 2rem;
}
.join__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  justify-content: center;
}

/* --------------------------------------------------------------------------
   14. Footer
   -------------------------------------------------------------------------- */
.site-footer {
  background: var(--sup-deep);
  color: var(--sup-cream);
  padding: clamp(3rem, 6vw, 4.5rem) 0 1.75rem;
}
.footer__inner {
  display: grid;
  grid-template-columns: minmax(220px, 1fr) 2fr;
  gap: clamp(2rem, 5vw, 4rem);
  padding-bottom: 2.5rem;
  border-bottom: 3px solid rgba(255, 247, 233, 0.18);
}
.footer__logo { height: 34px; width: auto; filter: invert(1); }
.footer__tag {
  margin: 1rem 0 0;
  font-family: var(--font-display);
  font-size: 1.1rem;
  color: var(--sup-sky);
}

.footer__nav {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 1.5rem;
}
.footer__col h4 {
  font-size: 1.05rem;
  color: var(--sup-yellow);
  margin-bottom: 0.8em;
}
.footer__col a {
  display: block;
  text-decoration: none;
  font-weight: 700;
  padding: 0.28rem 0;
  opacity: 0.85;
  transition: opacity 0.15s, transform 0.15s var(--ease-out);
}
.footer__col a:hover { opacity: 1; transform: translateX(4px); color: var(--sup-sky); }

.footer__base {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 0.5rem;
  padding-top: 1.75rem;
  font-size: 0.87rem;
  opacity: 0.7;
}
.footer__base p { margin: 0; }

/* --------------------------------------------------------------------------
   15. Scroll reveal
   -------------------------------------------------------------------------- */
/* Gated on .js so the page never ends up blank if the script fails to run */
.js .reveal {
  opacity: 0;
  transform: translateY(28px);
  transition: opacity 0.6s var(--ease-out), transform 0.6s var(--ease-out);
}
.js .reveal.is-visible { opacity: 1; transform: none; }

/* --------------------------------------------------------------------------
   16. Responsive
   -------------------------------------------------------------------------- */
@media (max-width: 900px) {
  .split { grid-template-columns: 1fr; }
  .split__media { order: -1; }
  .footer__inner { grid-template-columns: 1fr; }
  .duck-feature { grid-template-columns: 1fr; }
  .duck-feature__card { max-width: 420px; margin-inline: auto; }
}

@media (max-width: 780px) {
  .nav-toggle { display: flex; }

  .nav {
    position: fixed;
    inset: var(--header-h) 0 auto 0;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    background: var(--sup-cream);
    border-bottom: var(--line-thick) solid var(--sup-ink);
    padding: 0.5rem 1.25rem 1.5rem;
    transform: translateY(-130%);
    transition: transform 0.3s var(--ease-out);
    box-shadow: 0 14px 0 rgba(13, 13, 13, 0.1);
  }
  .nav.is-open { transform: translateY(0); }

  /* With the drawer open the header must match it. On the hero the header is
     transparent, which left a band of sky between the logo row and the cream
     drawer. */
  .site-header.is-nav-open {
    background: var(--sup-cream);
    border-bottom: none;
    box-shadow: none;
  }
  .nav > a {
    padding: 0.85rem 0;
    font-size: 1.3rem;
    border-bottom: 3px solid rgba(13, 13, 13, 0.1);
  }
  .nav > a:not(.btn)::after { display: none; }
  .nav__cta { margin-top: 1rem; border-bottom: var(--line) solid var(--sup-ink); }

  .sun { width: 80px; height: 80px; top: 6%; right: 6%; }
  /* The strip is cropped tight to the artwork, so it is full-width here too.
     The old 165%/-32% overscale dated from the uncropped image and shoved the
     boardwalk off to the left on phones. */
  .hero__boardwalk { width: 100%; margin-left: 0; }

}

@media (max-width: 480px) {
  .btn { width: 100%; }
  .hero__actions, .join__actions { flex-direction: column; }
  .bg-grid { grid-template-columns: repeat(2, 1fr); }
}

/* --------------------------------------------------------------------------
   17. Motion / print
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
  .js .reveal { opacity: 1; transform: none; }
}

/* --------------------------------------------------------------------------
   18. Resources page
   -------------------------------------------------------------------------- */
.page { padding-top: var(--header-h); }

.page__head {
  background: var(--sup-cream);
  padding: clamp(2.5rem, 6vw, 4.5rem) 0 clamp(1.5rem, 3vw, 2.5rem);
}
.page__lede {
  max-width: 620px;
  font-weight: 700;
  margin-top: 0.75rem;
}

.section--tight2 { padding: clamp(2.5rem, 5vw, 4rem) 0; }

.step__title {
  display: flex;
  align-items: center;
  gap: 0.85rem;
  font-family: var(--font-display);
  font-size: clamp(1.5rem, 1.1rem + 1.6vw, 2.2rem);
  margin-bottom: 1.75rem;
}
.step__title--light { color: var(--sup-paper); text-shadow: 3px 3px 0 var(--sup-ink); }
.step__num {
  flex: none;
  width: 46px; height: 46px;
  display: grid; place-items: center;
  border-radius: 50%;
  background: var(--sup-yellow);
  border: var(--line) solid var(--sup-ink);
  box-shadow: var(--pop-sm);
  color: var(--sup-ink);
  text-shadow: none;
  font-size: 1.35rem;
}

/* ---- step 1: picker ---- */
.picker {
  background: var(--sup-paper);
  border: var(--line) solid var(--sup-ink);
  border-radius: var(--radius-lg);
  box-shadow: var(--pop);
  padding: clamp(1.25rem, 3vw, 2rem);
}
.picker__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 1rem 1.25rem;
}
.picker__or {
  font-family: var(--font-display);
  padding-bottom: 0.6rem;
  opacity: 0.5;
}
.field { display: grid; gap: 0.35rem; }
.field__label {
  font-size: 0.78rem;
  font-weight: 900;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}
.field__label small {
  display: block;
  font-weight: 700;
  text-transform: none;
  letter-spacing: 0;
  opacity: 0.6;
}
.field__row { display: flex; gap: 0.5rem; }
.field input[type="number"] {
  width: 140px;
  font: inherit;
  font-weight: 700;
  padding: 0.6rem 0.8rem;
  border: 3px solid var(--sup-ink);
  border-radius: 12px;
  background: var(--sup-cream);
}

.picker__status {
  margin: 1rem 0 0;
  font-weight: 700;
  font-size: 0.92rem;
  min-height: 1.4em;
}
.picker__status.is-ok   { color: #1E7A34; }
.picker__status.is-warn { color: #B4232B; }

.duck-strip {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-top: 1rem;
  max-height: 190px;
  overflow-y: auto;
  /* The active chip casts a 3px offset shadow to the right and below, and
     overflow-y:auto forces overflow-x to clip too -- so without this the
     shadow is sliced off the selected duck on both edges. Pulled back out
     with margin so nothing shifts. */
  padding: 0 4px 5px 0;
  margin-right: -4px;
  margin-bottom: -5px;
}
.duck-chip {
  font-family: var(--font-display);
  font-size: 0.9rem;
  padding: 0.4rem 0.8rem;
  background: var(--sup-cream);
  border: 3px solid var(--sup-ink);
  border-radius: var(--radius-pill);
  cursor: pointer;
}
.duck-chip.is-active { background: var(--sup-yellow); box-shadow: 3px 3px 0 var(--sup-ink); }

/* ---- tabs ---- */
.tabs { display: flex; flex-wrap: wrap; gap: 0.6rem; margin-bottom: 1.5rem; }
.tab {
  font-family: var(--font-display);
  font-size: 1rem;
  padding: 0.6rem 1.3rem;
  background: var(--sup-paper);
  border: var(--line) solid var(--sup-ink);
  border-radius: var(--radius-pill);
  box-shadow: var(--pop-sm);
  cursor: pointer;
}
.tab.is-active { background: var(--sup-yellow); }

/* ---- studio ---- */
.studio {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: clamp(1.5rem, 4vw, 3rem);
  align-items: start;
}
/* Grid and flex children default to min-width:auto, which the 1200px canvas
   would otherwise use as a floor. */
.studio > * { min-width: 0; }

.stage {
  position: relative;
  background:
    repeating-conic-gradient(rgba(255,255,255,0.14) 0% 25%, transparent 0% 50%) 50%/22px 22px;
  border: var(--line) solid var(--sup-ink);
  border-radius: var(--radius-lg);
  box-shadow: var(--pop);
  overflow: hidden;
  display: grid;
  place-items: center;
  min-height: 260px;
}
.stage canvas { display: block; width: 100%; max-width: 100%; height: auto; }
/* Once there is art the canvas sets the height. Keeping the empty-state
   minimum would letterbox the wide membership card on a narrow screen. */
.stage.has-art { min-height: 0; }
.stage__empty {
  position: absolute;
  margin: 0;
  font-family: var(--font-display);
  font-size: 1.1rem;
  color: var(--sup-paper);
  text-shadow: 2px 2px 0 var(--sup-ink);
}
.stage__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1rem;
  margin-top: 1.1rem;
}
.stage__meta {
  font-size: 0.82rem;
  font-weight: 700;
  color: var(--sup-paper);
  opacity: 0.8;
}
.btn:disabled { opacity: 0.45; cursor: not-allowed; transform: none; box-shadow: var(--pop); }

.studio__controls {
  --panel-pad: clamp(1.1rem, 2.5vw, 1.75rem);
  background: rgba(255, 255, 255, 0.07);
  border: 3px solid rgba(255, 255, 255, 0.22);
  border-radius: var(--radius-lg);
  padding: var(--panel-pad);
}
.panel { display: none; }
.panel.is-active { display: block; }

.control { margin-bottom: 1.4rem; }
.control:last-child { margin-bottom: 0; }
.control__label {
  display: block;
  font-size: 0.78rem;
  font-weight: 900;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--sup-paper);
  margin-bottom: 0.6rem;
}
.control__label small {
  display: block;
  font-weight: 700;
  text-transform: none;
  letter-spacing: 0;
  opacity: 0.65;
}

/* The row scrolls edge to edge of the panel, not edge to edge of the panel's
   text column. Left inside the padding, a chip disappeared a whole gutter
   early and read as clipped by nothing at all. Negative margins pull the
   scroll port out to the border; the matching padding keeps the first and
   last chips off it when you reach either end. */
.chip-row {
  display: flex;
  gap: 0.5rem;
  overflow-x: auto;
  padding-bottom: 0.25rem;
  margin-inline: calc(-1 * var(--panel-pad, 0px));
  padding-inline: var(--panel-pad, 0px);
  scroll-padding-inline: var(--panel-pad, 0px);
  /* Same clipping trap vertically: :hover lifts a chip 2px and the active one
     drops a 3px shadow, both of which a scroll container cuts. */
  padding-top: 3px;
  margin-top: -3px;
  /* The chips have 3px outlines and a drop shadow; a scrollbar underneath
     them fights the artwork. */
  scrollbar-width: none;
  -ms-overflow-style: none;
}
.chip-row::-webkit-scrollbar { display: none; }
.chip-row--wrap {
  flex-wrap: wrap;
  overflow: visible;
  margin-inline: 0;
  padding-inline: 0;
}
.chip {
  flex: none;
  font-family: var(--font-display);
  font-size: 0.85rem;
  letter-spacing: 0.02em;
  padding: 0.42rem 0.9rem;
  background: var(--sup-paper);
  border: 3px solid var(--sup-ink);
  border-radius: var(--radius-pill);
  cursor: pointer;
  transition: transform 0.14s var(--ease-out);
}
.chip:hover { transform: translateY(-2px); }
.chip.is-active { background: var(--sup-yellow); box-shadow: 3px 3px 0 var(--sup-ink); }

.control input[type="range"] { width: 100%; accent-color: var(--sup-pink); }


/* ---- membership card tier strip ---- */
.card-tier {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem 1rem;
  align-items: center;
}
.card-tier__item {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  opacity: 0.42;                 /* tiers you have not reached */
  transition: opacity 0.14s var(--ease-out);
}
/* The one your holdings actually earn. */
.card-tier__item.is-active {
  opacity: 1;
  transform: scale(1.08);
}
.card-tier__item img { width: 34px; height: 34px; }
.card-tier__item em {
  font-family: var(--font-display);
  font-style: normal;
  font-size: 0.85rem;
  color: var(--sup-paper);
}

/* ---- rescan ---- */
.btn--rescan {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
}
.rescan__icon { flex: none; }
/* Spun only while a scan is running, so the button reads as busy rather than
   unresponsive -- an owner-scan sweeps the whole supply and takes seconds. */
.btn--rescan.is-busy .rescan__icon { animation: rescan-spin 0.9s linear infinite; }
@keyframes rescan-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .btn--rescan.is-busy .rescan__icon { animation: none; opacity: 0.6; }
}

/* ---- wallet button ---- */
[data-wallet-button] { font-family: var(--font-display); }
/* Drive --btn-bg, not `background`. Every .btn colour in this file works that
   way (.btn--pink, .btn--bungalow:hover), because .btn itself paints
   `background: var(--btn-bg)`. Setting `background` here instead meant two
   declarations competing for the same pixel, which is fragile and was the
   wrong idiom regardless of who won. */
[data-wallet-button].is-connected { --btn-bg: var(--sup-toxic); color: var(--sup-ink); }

/* Connected, the pill shows the address until you go to press it, then says
   what pressing it will do. Both labels occupy the same grid cell so the
   button is sized to the wider of the two and never resizes mid-hover --
   a pill that jumps as the cursor lands on it is easy to mis-click. */
[data-wallet-button].is-connected {
  display: inline-grid;
  grid-template-areas: "label";
  place-items: center;
  transition: background-color 0.14s var(--ease-out), color 0.14s var(--ease-out),
              transform 0.14s var(--ease-out), box-shadow 0.14s var(--ease-out);
}
[data-wallet-button].is-connected .wallet__label { grid-area: label; }
[data-wallet-button].is-connected .wallet__label--off { visibility: hidden; }

/* Desktop: on hover. Guarded so a touch device, where :hover can stick after
   a tap, does not leave the pill reading "Disconnect" indefinitely. */
@media (hover: hover) {
  [data-wallet-button].is-connected:hover,
  [data-wallet-button].is-connected:focus-visible {
    --btn-bg: var(--sup-danger);
    color: #fff;
  }
  [data-wallet-button].is-connected:hover .wallet__label--addr,
  [data-wallet-button].is-connected:focus-visible .wallet__label--addr { visibility: hidden; }
  [data-wallet-button].is-connected:hover .wallet__label--off,
  [data-wallet-button].is-connected:focus-visible .wallet__label--off { visibility: visible; }
}

/* Touch: while pressed. :active fires on touchstart, so the label confirms
   the action under the finger before it lifts. */
[data-wallet-button].is-connected:active {
  --btn-bg: var(--sup-danger);
  color: #fff;
}
[data-wallet-button].is-connected:active .wallet__label--addr { visibility: hidden; }
[data-wallet-button].is-connected:active .wallet__label--off { visibility: visible; }

@media (max-width: 900px) {
  /* minmax(0,…) not 1fr: a bare 1fr floors at the canvas's intrinsic width
     (1200px) and pushed the stage past the viewport on phones. */
  .studio { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 560px) {
  .picker__or { display: none; }
  .picker__actions { flex-direction: column; align-items: stretch; }
  .field input[type="number"] { width: 100%; }
}

.picker__gate {
  margin: 0 0 1.25rem;
  font-weight: 700;
  font-size: 0.95rem;
  padding-left: 0.9rem;
  border-left: 4px solid var(--sup-yellow);
}

/* ---- downloads grid ---- */
.dl-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 1.25rem;
  margin-top: 1.75rem;
}
.dl-card {
  margin: 0;
  background: var(--sup-paper);
  border: var(--line) solid var(--sup-ink);
  border-radius: var(--radius-lg);
  box-shadow: var(--pop-sm);
  overflow: hidden;
  transition: transform 0.18s var(--ease-out), box-shadow 0.18s var(--ease-out);
}
.dl-card:hover { transform: translateY(-5px); box-shadow: var(--pop); }
.dl-card img { border-bottom: 3px solid var(--sup-ink); width: 100%; }
.dl-card figcaption {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.75rem;
  padding: 0.8rem 1rem 0.9rem;
}
.dl-card__name { font-family: var(--font-display); font-size: 1rem; }

/* ---- collection tabs in the picker ---- */
.col-tabs { display: flex; flex-wrap: wrap; gap: 0.55rem; margin: 1.1rem 0 0; }
.col-tab {
  font-family: var(--font-display);
  font-size: 0.92rem;
  padding: 0.45rem 1rem;
  background: var(--sup-cream);
  border: 3px solid var(--sup-ink);
  border-radius: var(--radius-pill);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
}
.col-tab.is-active { background: var(--sup-yellow); box-shadow: 3px 3px 0 var(--sup-ink); }
.col-tab__n {
  font-family: var(--font-body);
  font-weight: 900;
  font-size: 0.72rem;
  background: var(--sup-ink);
  color: var(--sup-paper);
  border-radius: var(--radius-pill);
  padding: 0.05rem 0.45rem;
}

.control__note {
  margin: 0.25rem 0 0;
  font-size: 0.82rem;
  font-weight: 700;
  color: var(--sup-paper);
  opacity: 0.75;
}

/* --------------------------------------------------------------------------
   19. Mobile / PWA
   -------------------------------------------------------------------------- */
:root { --safe-t: env(safe-area-inset-top, 0px); --safe-b: env(safe-area-inset-bottom, 0px); }

/* Respect the notch when installed to the home screen */
.site-header { padding-top: var(--safe-t); height: calc(var(--header-h) + var(--safe-t)); }
.page { padding-top: calc(var(--header-h) + var(--safe-t)); }
.site-footer { padding-bottom: calc(1.75rem + var(--safe-b)); }

@media (max-width: 780px) {
  .nav { top: calc(var(--header-h) + var(--safe-t)); }

  /* Touch targets: 44px minimum */
  .chip, .duck-chip, .col-tab { min-height: 44px; padding-block: 0.6rem; }
  .tab { min-height: 46px; }
  .btn { min-height: 48px; }

  /* Horizontal chip rows should scroll cleanly under a thumb */
  .chip-row {
    scroll-snap-type: x proximity;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
  }
  .chip-row::-webkit-scrollbar { display: none; }
  .chip-row > .chip { scroll-snap-align: start; }

  /* The holdings strip can get long; cap it and let it scroll */
  .duck-strip { max-height: 168px; }

  .step__title { font-size: 1.4rem; }
  .step__num { width: 38px; height: 38px; font-size: 1.1rem; }
  .studio__controls { padding: 1rem; }
  .stage__actions { flex-direction: column; align-items: stretch; }
  .stage__meta { text-align: center; }
}

/* Installed standalone: the browser chrome is gone, so trim the top gap */
@media (display-mode: standalone) {
  .page__head { padding-top: 1.5rem; }
}

/* Stop iOS Safari inflating text in landscape */
@media screen and (max-device-width: 780px) {
  html { -webkit-text-size-adjust: 100%; }
}

/* ---- grouped downloads ---- */
/* The wrapper must not be a grid itself — each group carries its own, and
   nesting them turned the two groups into side-by-side columns. */
.dl-groups { display: block; }
.dl-group { margin-top: 2.25rem; }
.dl-group:first-child { margin-top: 1.5rem; }
.dl-group__title {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  font-size: 1.25rem;
  margin-bottom: 1rem;
}
.dl-group__n {
  font-family: var(--font-body);
  font-weight: 900;
  font-size: 0.72rem;
  background: var(--sup-ink);
  color: var(--sup-paper);
  border-radius: var(--radius-pill);
  padding: 0.1rem 0.5rem;
}
/* Wallpapers are tall phone art; headers are wide. Different grids. */
.dl-grid--wide { grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }
.dl-grid--tall { grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); }
.dl-grid--tall .dl-card img { aspect-ratio: 853 / 1844; object-fit: cover; }

@media (max-width: 560px) {
  .dl-grid--tall { grid-template-columns: repeat(2, 1fr); }
}

/* ---- Bungalow entry point ---- */
.btn--bungalow {
  --btn-bg: var(--sup-purple);
  color: var(--sup-paper);
  text-decoration: none;
  white-space: nowrap;
  letter-spacing: 0.02em;
}
/* Scoped to .nav on purpose: `.nav > a` sets `padding: 4px 0`, and being a
   class-plus-element selector it outranks a bare `.btn--bungalow`. The pill
   was rendering with 4px of end padding, which is what made the label look
   cramped against the edges. */
.nav > .btn--bungalow {
  /* `.nav > a` also overrides font-size (1rem vs the pill's 0.9rem), which is
     what left this button 10px taller than the wallet pill beside it. */
  font-size: 0.9rem;
  padding: 0.55rem 1.6rem;
  /* An <a> inherits the body's 1.65 line-height while the neighbouring
     <button> uses `normal`, which left the pill 5px taller. */
  line-height: 1.25;
}
.btn--bungalow:hover { --btn-bg: #8d5cff; }

@media (max-width: 780px) {
  /* In the drawer it reads as a nav item, so let it fill the width */
  .nav__bungalow { margin-top: 1rem; border-bottom: var(--line) solid var(--sup-ink); }
}

/* ---- sign-in chooser ---- */
.auth-menu {
  position: absolute;
  z-index: 200;
  min-width: 208px;
  background: var(--sup-paper);
  border: var(--line) solid var(--sup-ink);
  border-radius: var(--radius);
  box-shadow: var(--pop);
  padding: 0.4rem;
  display: grid;
  gap: 0.3rem;
}
.auth-menu__item {
  font-family: var(--font-display);
  font-size: 0.95rem;
  text-align: left;
  padding: 0.7rem 0.9rem;
  min-height: 44px;
  background: var(--sup-cream);
  border: 3px solid var(--sup-ink);
  border-radius: 12px;
  cursor: pointer;
}
.auth-menu__item:hover { background: var(--sup-yellow); }

/* --------------------------------------------------------------------------
   20. Bungalow page
   The React app is mounted under the shared header rather than owning the
   viewport, so it gets the remaining height and the header keeps its safe-area
   inset. --sup-header-h is what App.tsx subtracts from 100dvh.
   -------------------------------------------------------------------------- */
.bungalow-page {
  --sup-header-h: calc(var(--header-h) + var(--safe-t));
  margin: 0;
  background: var(--sup-deep);
}
/* The app itself does not scroll — it scales to fit — but the page does, so
   the shared footer is reachable below it like on every other page. */
.bungalow-page #root > div { overscroll-behavior: contain; }
.bungalow-page #root {
  margin-top: var(--sup-header-h);
}
/* The app draws its own dark scene; the site header stays cream above it. */
.bungalow-page .site-header { background: var(--sup-cream); }

/* The hook and the sign-off are their own lines so the middle sentence reads
   as the collection blurb rather than one long run-on. */
.hero__lede-hook,
.hero__lede-sign {
  display: block;
}
.hero__lede-hook { margin-bottom: 0.35em; }
.hero__lede-sign { margin-top: 0.35em; }
