/* =========================================================================
   NORTH STAR - waitlist deck
   Brand: Guidelines v2. The Table (off-black stage), dark cards, Cups accents
   (ember lines on dark, oxblood fills), bone type. Slack for ceremony,
   Geita for mechanics, DM Serif italic for the whisper.
   Motion engine values are decompiled from the reference deck - do not touch.
   ========================================================================= */

:root {
  /* Brand tokens */
  --canvas:    #0A0A0A;                  /* off-black stage (user call; brand canvas is #000) */
  --surface:   #111111;                  /* cards, panels */
  --surface-2: #1A1A1A;                  /* elevated */
  --bone:      #F8EDDB;
  --bone-dim:  #C7BBA3;
  --hairline:  rgba(248, 237, 219, 0.12);
  --ember:     #C8102E;                  /* cups line tier: lines + marks on dark */
  --oxblood:   #7A0A10;                  /* cups fill tier: fills only on dark */
  --cups-deep: #4A060A;                  /* pressed, recesses */

  --slack:  "Slack", Georgia, serif;
  --geita:  "Geita", system-ui, -apple-system, "Segoe UI", sans-serif;
  --whisper: "DM Serif Display", Georgia, serif;

  /* Motion (decompiled from the reference; keep) */
  --ease-out:   cubic-bezier(0.16, 1, 0.3, 1);
  --ease-inout: cubic-bezier(0.62, 0, 0.13, 1);
  --dur-move:   640ms;

  --card-h: clamp(400px, 66vh, 600px);
  --card-w: calc(var(--card-h) * 0.594);
  --radius: calc(var(--card-w) * 0.045);   /* tarot-card radius: 4.5% of width */

  color-scheme: dark;
}

* { box-sizing: border-box; }
html, body { height: 100%; margin: 0; }

body {
  font-family: var(--geita);
  color: var(--bone);
  background: var(--canvas);
  overflow: hidden;                       /* the page itself never scrolls */
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  min-height: 100dvh;
}

.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;
}
.svg-defs { position: absolute; width: 0; height: 0; overflow: hidden; }

/* ---- Grain: 5% over the dark field, felt not seen ---- */
.grain {
  position: fixed; inset: 0; z-index: 60; pointer-events: none;
  opacity: 0.05; mix-blend-mode: screen;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='0.6'/%3E%3C/svg%3E");
}

/* ---- Quiet frame ---- */
.frame {
  position: fixed; top: 0; left: 0; right: 0; z-index: 30;
  display: flex; align-items: center; justify-content: space-between;
  padding: 22px clamp(20px, 4vw, 48px); pointer-events: none;
}
.frame > * { pointer-events: auto; }
.wordmark {
  display: inline-flex; align-items: center; gap: 9px;
  font-family: var(--slack); font-weight: 300; font-size: 19px;
  letter-spacing: 0.04em; color: var(--bone); text-decoration: none;
}
.wordmark__stella { width: 13px; height: 13px; fill: var(--ember); }
.frame__tag {
  margin: 0; font-family: var(--geita); font-weight: 500;
  font-size: 11px; letter-spacing: 0.22em; text-transform: uppercase;
  color: var(--bone-dim);
}

/* =========================================================================
   STAGE + DECK  (geometry unchanged)
   ========================================================================= */
.stage {
  position: relative; z-index: 10; height: 100dvh;
  display: grid; grid-template-columns: 1fr auto 1fr; align-items: center;
  justify-items: center; gap: clamp(8px, 3vw, 56px);
}
.deck {
  position: relative; grid-column: 2;
  width: var(--card-w); height: var(--card-h);
  perspective: 1700px; perspective-origin: 50% 45%;
}
.ground-shadow {
  position: absolute; left: 50%; top: 56%;
  width: calc(var(--card-w) * 1.12); height: calc(var(--card-h) * 1.04);
  border-radius: 46% / 40%;
  background: radial-gradient(closest-side, rgba(0,0,0,0.55), rgba(0,0,0,0) 70%);
  transform: translate(-50%, -50%);
  opacity: 0.10; z-index: 0;
  pointer-events: none; will-change: transform, opacity;
}

/* ---- The card. No perimeter hairline, no edge-light: the ember frame and
   the drop shadow define the edge (fixes the white outline during motion) ---- */
.card {
  position: absolute;
  width: var(--card-w); height: var(--card-h);
  left: 50%; top: 50%;
  border-radius: var(--radius);
  transform-style: preserve-3d;
  transform: translate(-50%, -50%);
  cursor: pointer;
  will-change: transform;
  outline: none;
  transition:
    transform var(--dur-move) var(--ease-inout),
    opacity 420ms var(--ease-out),
    width var(--dur-move) var(--ease-out),
    height var(--dur-move) var(--ease-out),
    border-radius var(--dur-move) var(--ease-out);
}
.card:focus-visible { outline: 1.5px solid var(--bone); outline-offset: 6px; }

.card__face {
  position: absolute; inset: 0;
  border-radius: inherit;
  overflow: hidden;
  background: var(--surface);
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
  /* inset bone rim: defines the card's outline against the dark stage without
     the outer edge-light that bled white during the 3D motion */
  box-shadow: inset 0 0 0 1px rgba(248, 237, 219, 0.176);   /* card outline, -20% opacity */
}
.card__front { transform: rotateY(0deg); }
.card__back  { transform: rotateY(180deg); }

/* physical cards carry a true drop shadow (brand: they are objects) */
.card.is-active:not(.is-open) { box-shadow: 0 12px 32px rgba(0,0,0,0.5); }

/* card thickness: dark paper stock, no ring */
.card::before {
  content: ""; position: absolute; inset: 0; border-radius: inherit;
  background: linear-gradient(90deg, #1c1c1f, #26262a 30%, #26262a 70%, #191a1c);
  transform: translateZ(-11px);
  backface-visibility: hidden;
  -webkit-backface-visibility: hidden;
}
.card.is-open::before { display: none; }

/* =========================================================================
   FRONT: the framed face
   ========================================================================= */
.card__frame { position: absolute; inset: 0; width: 100%; height: 100%; color: var(--ember); opacity: 0.8; }
/* During the close reverse-motion the front face comes back into view while
   the card is still oversized: keep its frame + title hidden until the card
   has landed at deck size (.is-closing is held by JS through the close). */
.card__frame, .card__centre { transition: opacity 260ms var(--ease-out); }
.card.is-closing .card__frame, .card.is-closing .card__centre { opacity: 0; transition: none; }
.ns-line { fill: none; stroke: var(--ember); stroke-width: 1.25; stroke-linejoin: round; }
.ns-fill { fill: var(--ember); stroke: none; }
.ns-bay {
  font-family: var(--slack); font-size: 7.5px; letter-spacing: 0.18em;
  fill: var(--ember); stroke: none;
}
.card__centre {
  position: absolute; inset: 13%;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  text-align: center; gap: 18px;
  pointer-events: none;
}
.card__title {
  margin: 0; font-family: var(--slack); font-weight: 300;
  font-size: clamp(24px, 2.6vw, 33px); line-height: 1.18;
  letter-spacing: 0.05em; text-transform: uppercase; color: var(--bone);
}
.card__stella { width: 15px; height: 15px; fill: var(--ember); }
.card__whisper {
  margin: 0; font-family: var(--whisper); font-style: italic;
  font-size: 15px; color: var(--bone-dim);
}

/* =========================================================================
   BACK: the page (dark, scrollable once settled)
   ========================================================================= */
.card__back { background: var(--surface); }

/* The scroller is an INSET layer inside the card, so the subtle scrollbar
   floats within the face, clear of the rounded corners - never on the edge. */
.page-scroll {
  position: absolute;
  inset: 20px 8px 12px 8px;
  overflow: hidden;
  z-index: 2;                             /* reading surface sits above the face-down back pattern */
}
.card.is-settled .page-scroll {
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-width: none;                 /* native bar hidden: bar lives at screen edge */
}
.page-scroll::-webkit-scrollbar { display: none; }

/* Real, interactive scrollbar at the right edge of the SCREEN. The card is
   3D-transformed so a native bar there is unusable; this drives the card's
   inner scroller in screen space (wheel is JS-driven; thumb is draggable). */
.vscroll {
  position: fixed; right: 3px; top: 10px; bottom: 10px; width: 12px;
  z-index: 210; opacity: 0; pointer-events: none;
  transition: opacity 300ms var(--ease-out);
}
.vscroll.is-on { opacity: 1; pointer-events: auto; }
.vscroll__thumb {
  position: absolute; left: 3px; right: 3px; top: 0; min-height: 40px;
  border-radius: 999px; background: rgba(199,187,163,0.30);
  cursor: grab; will-change: transform, height;
  transition: background 160ms var(--ease-out);
}
@media (hover: hover) { .vscroll__thumb:hover { background: rgba(199,187,163,0.5); } }
.vscroll.is-dragging .vscroll__thumb { background: rgba(199,187,163,0.62); cursor: grabbing; }

/* content renders only once the card has landed (engine adds .is-settled) */
.page {
  position: relative;
  min-height: 100%;
  /* 15% left/right borders -> content sits in the central 70% of the card */
  padding: clamp(48px, 10vh, 110px) 15% clamp(48px, 8vh, 90px);
  display: flex; flex-direction: column; align-items: flex-start; gap: 18px;
  max-width: none; margin: 0;
  opacity: 0; visibility: hidden;
  transition: opacity 360ms var(--ease-out), visibility 0s linear 360ms;
}
.card.is-settled .page {
  opacity: 1; visibility: visible;
  transition: opacity 420ms var(--ease-out) 60ms, visibility 0s;
}

.page__eyebrow {
  margin: 0; font-family: var(--geita); font-weight: 500;
  font-size: 11px; letter-spacing: 0.22em; text-transform: uppercase;
  color: var(--bone-dim);
}
.page__title {
  margin: 0; font-family: var(--slack); font-weight: 300;
  font-size: clamp(28px, 4vw, 44px); line-height: 1.12;
  letter-spacing: 0.04em; text-transform: uppercase; color: var(--bone);
  max-width: 22ch;
}
.page__whisper {
  margin: 0; font-family: var(--whisper); font-style: italic;
  font-size: clamp(16px, 1.5vw, 19px); line-height: 1.5; color: var(--bone-dim);
  max-width: 46ch;
}
.page__head {
  margin: 6px 0 0; font-family: var(--slack); font-weight: 300;
  font-size: clamp(17px, 1.7vw, 21px); letter-spacing: 0.05em;
  text-transform: uppercase; color: var(--bone);
}
.page__body {
  margin: 0; font-family: var(--geita); font-size: 16px; line-height: 1.5;
  color: var(--bone-dim); max-width: 62ch;
}
.page__caption { margin: 0; font-family: var(--geita); font-size: 12px; line-height: 1.35; color: var(--bone-dim); opacity: 0.75; }
.page__note { margin: 2px 0 0; font-family: var(--whisper); font-style: italic; font-size: 14px; color: var(--bone-dim); }
.page__rule { width: 100%; border: none; border-top: 1px solid var(--hairline); margin: 28px 0 10px; }
.page__colophon {
  width: 100%; margin-top: 48px; padding-top: 28px;
  border-top: 1px solid var(--hairline);
  display: flex; flex-direction: column; align-items: center; gap: 10px;
}
.page__colophon svg { width: 13px; height: 13px; fill: var(--ember); }
.page__colophon p {
  margin: 0; font-family: var(--geita); font-weight: 500;
  font-size: 10px; letter-spacing: 0.22em; text-transform: uppercase;
  color: var(--bone-dim); opacity: 0.8;
}
.page__links { margin: 6px 0 0; display: flex; flex-wrap: wrap; gap: 10px 28px; }
.page__link {
  font-family: var(--geita); font-weight: 700; font-size: 15px;
  letter-spacing: 0.02em; color: var(--bone); text-decoration: none;
  border-bottom: 1px solid var(--hairline); padding-bottom: 2px;
}
.page__link:hover { border-bottom-color: var(--ember); }
.page__link:focus-visible { outline: 1.5px solid var(--bone); outline-offset: 3px; }

/* Join form: transparent field, hairline underline (brand input spec) */
.join__form { display: flex; flex-direction: column; gap: 14px; width: 100%; max-width: 380px; margin-top: 6px; }
.join__form input {
  font-family: var(--geita); font-size: 16px; padding: 10px 2px;
  border: none; border-bottom: 1px solid var(--bone-dim);
  background: transparent; color: var(--bone); width: 100%;
  border-radius: 0;
  transition: border-color 160ms var(--ease-out), border-width 160ms var(--ease-out);
}
.join__form input::placeholder { color: rgba(199,187,163,0.55); }
.join__form input:focus-visible { outline: none; border-bottom: 1.5px solid var(--bone); }
.join__form.is-invalid input { border-bottom: 1.5px solid var(--bone); }
.join__error { margin: 0; min-height: 1em; font-family: var(--geita); font-size: 13px; color: var(--bone); }

.btn {
  font-family: var(--geita); font-weight: 700; font-size: 13px;
  letter-spacing: 0.10em; text-transform: uppercase;
  border: 1px solid var(--ember);            /* line tier so the edge reads on dark */
  border-radius: 8px; cursor: pointer; padding: 14px 24px; min-height: 44px;
  background: var(--oxblood); color: var(--bone);
  transition: filter 160ms var(--ease-out), transform 140ms var(--ease-out);
}
.btn:hover { filter: brightness(1.08); }
.btn:active { transform: translateY(1px); filter: brightness(0.96); }
.btn:focus-visible { outline: 1.5px solid var(--bone); outline-offset: 2px; }

/* =========================================================================
   OPEN PAGE geometry (unchanged) + close
   ========================================================================= */
.card.is-open {
  width: min(77vw, 1425px);
  height: 82dvh;
  border-radius: 56px 56px 0 0;
  z-index: 200 !important;
  cursor: default;
  box-shadow: 0 -20px 60px -30px rgba(0,0,0,0.6);
}
.card__close {
  position: absolute; top: 20px; right: 20px; z-index: 5;
  width: 44px; height: 44px; border-radius: 999px;
  border: 1px solid var(--hairline);
  background: var(--surface-2); color: var(--bone); font-size: 14px; cursor: pointer;
  opacity: 0; pointer-events: none;
  transition: opacity 240ms var(--ease-out) 120ms, transform 140ms var(--ease-out), filter 160ms;
}
.card.is-open .card__close { opacity: 1; pointer-events: auto; }
.card__close:hover { filter: brightness(1.15); transform: scale(1.06); }
.card__close:active { transform: scale(0.94); }
.card__close:focus-visible { outline: 1.5px solid var(--bone); outline-offset: 2px; }

/* Decorative layer only. MUST stay pointer-events:none - .stage is a z-10
   context at root, so any interactive overlay above it swallows every click
   and wheel on the open card (this regression has happened twice now). */
.scrim {
  position: fixed; inset: 0; z-index: 150;
  background: transparent;
  pointer-events: none;
  opacity: 0; transition: opacity 360ms var(--ease-out);
}
.scrim.is-on { opacity: 1; }

/* =========================================================================
   RAILS + HINT
   ========================================================================= */
.rail {
  display: flex; align-items: center; gap: 14px; background: none; border: none;
  cursor: pointer; color: var(--bone-dim); padding: 16px 14px;
  transition: color 200ms var(--ease-out), transform 300ms var(--ease-out);
}
.rail[disabled], .deck-open .rail { transition: none; }
.rail--prev { grid-column: 1; justify-self: end; }
.rail--next { grid-column: 3; justify-self: start; }
.rail__arrow { font-size: clamp(26px, 2.6vw, 36px); line-height: 1; transition: transform 300ms var(--ease-out); }
.rail__label {
  position: relative; display: inline-block; padding-bottom: 16px;
  font-family: var(--slack); font-weight: 300;
  font-size: clamp(26px, 3.2vw, 42px); letter-spacing: 0.04em;
}
.rail__label::after {
  content: ""; position: absolute; left: 0; bottom: 4px;
  width: 2.4em; height: 2px; background: currentColor; opacity: 0.4;
}
.rail:hover { color: var(--bone); }
.rail--prev:hover .rail__arrow { transform: translateX(-4px); }
.rail--next:hover .rail__arrow { transform: translateX(4px); }
.rail:focus-visible { outline: 1.5px solid var(--bone); outline-offset: 4px; border-radius: 8px; }
.deck-open .rail { opacity: 0; pointer-events: none; }

.hint {
  position: fixed; left: 0; right: 0; bottom: 30px; z-index: 20; margin: 0; text-align: center;
  font-family: var(--geita); font-size: 12px; letter-spacing: 0.04em; color: var(--bone-dim);
  transition: opacity 400ms var(--ease-out);
}
.deck-open .hint { opacity: 0; }

@keyframes deck-in {
  from { transform: translate(-50%, -50%) translateY(14px); opacity: 0; }
  to   { transform: translate(-50%, -50%); opacity: 1; }
}
.card.is-active.deck-in { animation: deck-in 640ms var(--ease-out); }

/* =========================================================================
   MOBILE (geometry unchanged)
   ========================================================================= */
@media (max-width: 900px) {
  :root { --card-w: min(72vw, 324px); --card-h: min(72dvh, calc(min(72vw, 324px) / 0.594)); }
  .rail { display: none; }
  .stage { grid-template-columns: 1fr; }
  .deck { grid-column: 1; }
  .frame__tag { display: none; }
  .card.is-open { width: 89vw; height: 84dvh; border-radius: 32px 32px 0 0; }
  .hint { bottom: 22px; }
  .page { padding: 26px 22px; padding-top: clamp(32px, 9vh, 72px); }
  .page__title { font-size: clamp(24px, 7vw, 32px); }
  .page__body { font-size: 15px; }
  .card__title { font-size: clamp(20px, 6vw, 26px); }
}

/* =========================================================================
   REDUCED MOTION (unchanged behaviour)
   ========================================================================= */
@media (prefers-reduced-motion: reduce) {
  .card { transition: opacity 220ms ease, width 260ms ease, height 260ms ease; }
  .card.is-open { transform: translate(-50%, calc(-50% + 9dvh)) !important; }
  .card.is-open .card__front { opacity: 0; }
  .card.is-active.deck-in { animation: none; }
}

/* =========================================================================
   DETAIL-PAGE ICON FIELD (reference vibe: reading column left, occult icon
   texture filling the right of the panel). Icons are fill=currentColor; the
   JS injects a scattered <use> field into each card back, behind the text.
   ========================================================================= */
.page__body, .page__whisper, .page__note, .page__caption, .page__lead { max-width: 44ch; }
.page__rule { max-width: 44ch; }
.icon-field {
  position: absolute; inset: 0; z-index: 0; pointer-events: none;
  color: var(--bone-dim); opacity: 0;
  transition: opacity 600ms var(--ease-out) 150ms;
}
.card.is-settled .icon-field { opacity: 0.2; }
@media (max-width: 900px) { .card.is-settled .icon-field { opacity: 0.12; } }
.icon-mark { position: absolute; color: inherit; fill: currentColor; }

/* =========================================================================
   FACE-DOWN CARD BACK: the woodcut "back" of the card - a dense scatter of
   bone marks on the dark stock, the way a tarot deck reads face-down. This
   is what shows when a card flips during the shuffle (net rotation 0, so it
   reads un-mirrored) and for the first beat of opening; it dissolves the
   instant the page settles so the reading surface stays clean. JS injects
   the scattered <use> field.
   ========================================================================= */
.card-back-pattern {
  position: absolute; inset: 0; z-index: 1; border-radius: inherit;
  overflow: hidden; pointer-events: none;
  background: var(--surface); color: var(--bone);
  opacity: 1; transition: opacity 320ms var(--ease-out);
}
.card.is-settled .card-back-pattern { opacity: 0; }
/* "Show me" (open) must NOT show the woodcut back at all - drop it outright
   the moment the card opens, so the flip reveals the clean reading surface. */
.card.is-open .card-back-pattern { display: none; }
