/* ==========================================================================
   FRASER WESTERN — a bit of everything
   Deep charcoal / navy undertones / refined blue light.
   Cabinet Grotesk (display) + Switzer (text), via Fontshare.
   ========================================================================== */

/* ---------- Tokens ---------- */
:root {
  /* surfaces */
  --bg:        #090B10;   /* charcoal with a navy undertone */
  --bg-raise:  #10141D;
  --bg-card:   #11151F;

  /* text */
  --text:      #E9ECF2;
  --text-2:    #98A0B3;
  --text-3:    #7A8296;

  /* light */
  --blue:      #8AB4FF;   /* refined accent */
  --blue-glow: rgba(96, 140, 255, 0.12);
  --hairline:  rgba(233, 236, 242, 0.09);
  --hairline-strong: rgba(233, 236, 242, 0.22);

  /* type */
  --font-display: "Cabinet Grotesk", "Arial Black", sans-serif;
  --font-text: "Switzer", -apple-system, "Segoe UI", sans-serif;

  --text-sm: 0.875rem;
  --text-base: 1rem;
  --text-md: 1.125rem;
  --text-lede: clamp(1.125rem, 1rem + 0.6vw, 1.375rem);
  --text-h2: clamp(2.2rem, 1.6rem + 3vw, 3.75rem);

  /* space — generous, cinematic */
  --space-1: 0.5rem;
  --space-2: 1rem;
  --space-3: 1.75rem;
  --space-4: 3rem;
  --space-5: 5rem;
  --space-6: 8rem;

  --radius: 16px;
  --radius-sm: 10px;

  --z-header: 100;
  --z-grain: 500;
  --z-skip: 1000;
  --z-modal: 2000;

  --ease: cubic-bezier(0.22, 1, 0.36, 1);
  --dur: 260ms;
}

/* ---------- Base ---------- */
*, *::before, *::after { box-sizing: border-box; }

/* The browser's own [hidden] rule and one of our own classes (e.g. .btn's
   display:inline-flex) always have identical specificity — ours loads later
   and wins, so a "hidden" button quietly stays visible. This one line fixes
   it everywhere, permanently, instead of patching each component that hits
   it one at a time. */
[hidden] { display: none !important; }

html {
  scroll-behavior: smooth;
  -webkit-text-size-adjust: 100%;
  overflow-x: clip;
}

body {
  margin: 0;
  font-family: var(--font-text);
  font-size: var(--text-base);
  line-height: 1.65;
  color: var(--text);
  background: var(--bg);
  overflow-x: clip;
}

/* film grain — fixed, subtle, never interactive */
body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: var(--z-grain);
  pointer-events: none;
  opacity: 0.05;
  mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)' opacity='0.55'/%3E%3C/svg%3E");
}

img, svg { display: inline-block; vertical-align: middle; max-width: 100%; }

h1, h2, h3 {
  font-family: var(--font-display);
  font-weight: 700;
  line-height: 1.05;
  margin: 0 0 var(--space-2);
  letter-spacing: -0.015em;
}

p { margin: 0 0 var(--space-2); }
em { font-style: italic; }

a { color: var(--blue); text-underline-offset: 3px; }

::selection { background: rgba(138, 180, 255, 0.28); }

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

.shell {
  width: min(100% - 3rem, 72rem);
  margin-inline: auto;
}

.accent { color: var(--blue); }
.dim { color: var(--text-2); }

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

.skip-link {
  position: fixed;
  top: -100px;
  left: var(--space-2);
  z-index: var(--z-skip);
  padding: 0.75rem 1.25rem;
  background: var(--text);
  color: var(--bg);
  border-radius: var(--radius-sm);
  text-decoration: none;
  font-weight: 600;
  transition: top var(--dur) var(--ease);
}
.skip-link:focus { top: var(--space-2); }

/* ---------- Type utilities ---------- */
.eyebrow {
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--blue);
  margin-bottom: var(--space-2);
}

.title-xl { font-size: var(--text-h2); font-weight: 700; }

.lede {
  font-size: var(--text-lede);
  line-height: 1.6;
  color: var(--text-2);
  max-width: 34rem;
}
.lede-center { margin-inline: auto; }

.footnote { font-size: var(--text-sm); color: var(--text-3); margin-top: var(--space-2); }
.footnote-center { text-align: center; }

/* ---------- Buttons & controls ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  min-height: 48px;
  padding: 0.8rem 2rem;
  border: 0;
  border-radius: 999px;
  font-family: var(--font-text);
  font-size: var(--text-base);
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
  transition: transform var(--dur) var(--ease),
              box-shadow var(--dur) var(--ease),
              background-color var(--dur) var(--ease),
              border-color var(--dur) var(--ease),
              color var(--dur) var(--ease);
}
.btn:hover { transform: translateY(-1px); }
.btn:active { transform: translateY(0) scale(0.98); }

.btn-solid {
  background: var(--text);
  color: var(--bg);
}
.btn-solid:hover {
  background: #FFFFFF;
  box-shadow: 0 8px 40px -8px rgba(138, 180, 255, 0.35);
}

.btn-ghost {
  background: transparent;
  color: var(--text);
  border: 1px solid var(--hairline-strong);
}
.btn-ghost:hover { border-color: var(--blue); color: var(--blue); }

.btn-sm { min-height: 44px; padding: 0.55rem 1.4rem; font-size: var(--text-sm); }

/* Works as an <a> or a <button> — plain buttons carry browser-default white
   backgrounds/borders/fonts that <a> never has, so those are reset explicitly
   here rather than relying on a page-by-page override. */
.quiet-link {
  display: inline-block;
  margin-top: var(--space-3);
  color: var(--text-2);
  font-family: inherit;
  font-size: var(--text-sm);
  text-decoration: none;
  background: none;
  border: 0;
  border-bottom: 1px solid var(--hairline-strong);
  padding: 0.4rem 0.1rem;
  cursor: pointer;
  transition: color var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.quiet-link:hover { color: var(--text); border-color: var(--text); }

/* ---------- Header ---------- */
/* transparent over the hero so nothing blocks the arc; solidifies on scroll */
.site-header {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: var(--z-header);
  background: transparent;
  border-bottom: 1px solid transparent;
  transition: transform 380ms var(--ease),
              background-color var(--dur) var(--ease),
              border-color var(--dur) var(--ease);
}
.site-header.is-scrolled {
  background: rgba(9, 11, 16, 0.62);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-bottom-color: var(--hairline);
}
/* slid up out of the way so nothing overlays the hero arch/figure */
.site-header.is-hidden {
  transform: translateY(-100%);
}

.header-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  width: 100%;                                    /* full width so items reach the corners */
  padding-block: 0.9rem;
  padding-inline: clamp(1.25rem, 3vw, 2.5rem);
}

.wordmark {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: 1.25rem;
  letter-spacing: 0.02em;
  color: var(--text);
  text-decoration: none;
  padding: 0.4rem 0;
}
.wordmark-dot { color: var(--blue); }

.header-actions { display: flex; align-items: center; gap: var(--space-1); }

/* Join button fades while the menu overlay is open */
html.menu-locked .header-actions .btn {
  opacity: 0;
  pointer-events: none;
}

/* ---------- Header avatar (members.html only) ---------- */
.avatar-menu { position: relative; }

.avatar-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  border: 1px solid var(--hairline-strong);
  background: var(--bg-card);
  padding: 0;
  cursor: pointer;
  overflow: hidden;
  flex-shrink: 0;
  transition: border-color var(--dur) var(--ease);
}
.avatar-btn:hover, .avatar-btn:focus-visible { border-color: var(--blue); }

.avatar-img { width: 100%; height: 100%; object-fit: cover; }

.avatar-fallback {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 0.9rem;
  color: var(--blue);
}

.avatar-dropdown {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  min-width: 180px;
  background: var(--bg-card);
  border: 1px solid var(--hairline-strong);
  border-radius: var(--radius-sm);
  box-shadow: 0 20px 50px -18px rgba(0, 0, 0, 0.6);
  padding: var(--space-1);
  z-index: var(--z-header);
  display: flex;
  flex-direction: column;
}

.avatar-dropdown button {
  background: none;
  border: 0;
  text-align: left;
  padding: 0.6rem 0.8rem;
  border-radius: var(--radius-sm);
  color: var(--text-2);
  font-family: var(--font-text);
  font-size: var(--text-sm);
  cursor: pointer;
  transition: background var(--dur) var(--ease), color var(--dur) var(--ease);
}
.avatar-dropdown button:hover { background: var(--bg-raise); color: var(--text); }

/* ---------- Menu toggle (hamburger → X) ---------- */
.menu-toggle {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  width: 44px;
  height: 44px;
  padding: 0;
  background: transparent;
  border: 0;
  cursor: pointer;
}
.menu-line {
  display: block;
  width: 22px;
  height: 1.5px;
  background: var(--text);
  transition: transform var(--dur) var(--ease);
}
.menu-toggle[aria-expanded="true"] .menu-line:first-child {
  transform: translateY(3.75px) rotate(45deg);
}
.menu-toggle[aria-expanded="true"] .menu-line:last-child {
  transform: translateY(-3.75px) rotate(-45deg);
}

/* ---------- Menu overlay ---------- */
html.menu-locked { overflow: hidden; }

.menu-overlay {
  position: fixed;
  inset: 0;
  z-index: 95; /* below the header, so the toggle stays reachable */
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-4);
  background: rgba(9, 11, 16, 0.95);
  backdrop-filter: blur(18px);
  -webkit-backdrop-filter: blur(18px);
  opacity: 0;
  visibility: hidden;
  transition: opacity 320ms var(--ease), visibility 0s linear 320ms;
}
.menu-overlay.is-open {
  opacity: 1;
  visibility: visible;
  transition: opacity 320ms var(--ease);
}

.menu-nav {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
}
.menu-nav a {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(2rem, 6.5vw, 3.25rem);
  letter-spacing: -0.01em;
  line-height: 1.1;
  color: var(--text-2);
  text-decoration: none;
  padding: 0.1em 0.3em;
  opacity: 0;
  translate: 0 16px;
  transition: opacity 420ms var(--ease), translate 420ms var(--ease), color 180ms var(--ease);
}
.menu-overlay.is-open .menu-nav a { opacity: 1; translate: 0 0; }
.menu-overlay.is-open .menu-nav a:nth-child(1) { transition-delay: 60ms, 60ms, 0ms; }
.menu-overlay.is-open .menu-nav a:nth-child(2) { transition-delay: 120ms, 120ms, 0ms; }
.menu-overlay.is-open .menu-nav a:nth-child(3) { transition-delay: 180ms, 180ms, 0ms; }
.menu-overlay.is-open .menu-nav a:nth-child(4) { transition-delay: 240ms, 240ms, 0ms; }
.menu-nav a:hover { color: var(--text); }

.menu-meta { display: flex; gap: var(--space-3); }
.menu-meta a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  color: var(--text-3);
  font-size: var(--text-sm);
  text-decoration: none;
  padding: 0.5rem 0.6rem;
  transition: color var(--dur) var(--ease);
}
.menu-meta a:hover { color: var(--text); }

/* ---------- Welcome modal (one-time, new signups only) ---------- */
html.modal-open { overflow: hidden; }

.welcome-modal {
  position: fixed;
  inset: 0;
  z-index: var(--z-modal);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-3);
}

.welcome-modal-overlay {
  position: absolute;
  inset: 0;
  background: rgba(5, 6, 10, 0.72);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}

.welcome-modal-box {
  position: relative;
  width: min(100%, 30rem);
  background: var(--bg-card);
  border: 1px solid var(--hairline-strong);
  border-radius: var(--radius);
  padding: var(--space-4) var(--space-3) var(--space-3);
  text-align: center;
  box-shadow: 0 40px 100px -24px rgba(0, 0, 0, 0.65);
  animation: welcome-in 420ms var(--ease);
}
@keyframes welcome-in {
  from { opacity: 0; transform: translateY(12px) scale(0.98); }
  to   { opacity: 1; transform: translateY(0) scale(1); }
}

.welcome-modal-box .eyebrow { margin-inline: auto; }
.welcome-modal-box .title-xl { font-size: clamp(1.8rem, 1.4rem + 2vw, 2.5rem); }
.welcome-modal-box .lede { margin: 0 auto var(--space-3); }
.welcome-modal-box .btn { width: 100%; }

.welcome-modal-close {
  position: absolute;
  top: var(--space-2);
  right: var(--space-2);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  border: 1px solid var(--hairline);
  background: transparent;
  color: var(--text-2);
  cursor: pointer;
  transition: color var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.welcome-modal-close:hover {
  color: var(--text);
  border-color: var(--hairline-strong);
}

/* ---------- Hero ---------- */
/* the track supplies a short extra scroll run for the arc's rotation; the
   hero stays sticky for that whole span via plain CSS — no JS needed for
   the pin itself, only the arc's per-frame rotation is JS's job. */
.hero-track {
  position: relative;
  min-height: calc(100vh + 640px);
}
@media (max-width: 640px) {
  .hero-track { min-height: calc(100vh + 440px); }
}
/* reduced-motion users never see the rotation (js/main.js skips it), so
   don't make them scroll through the extra runway for nothing */
@media (prefers-reduced-motion: reduce) {
  .hero-track { min-height: 100dvh; }
}

.hero {
  position: sticky;
  top: 0;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  overflow: clip;
}

.hero-atmosphere {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    radial-gradient(55% 38% at 50% 10%, var(--blue-glow), transparent 65%),
    radial-gradient(42% 34% at 50% 64%, rgba(96, 140, 255, 0.09), transparent 60%),
    radial-gradient(120% 100% at 50% 50%, transparent 55%, rgba(0, 0, 0, 0.55) 100%);
}

/* --- photo arc: the "ocean" wheel (positions set by JS; decorative) ---
   overflow:hidden makes the container's BOTTOM edge the waterline — any card
   (or part of one) below it is clipped away, smoothly and at full colour, as
   the wheel turns. The container reaches from the waterline up past the top
   card (height set by JS via --arc-h). */
.arc {
  position: absolute;
  top: clamp(84px, 11vh, 140px);
  left: 0; right: 0;
  height: var(--arc-h, 300px);
  overflow: hidden;
  pointer-events: none;
  z-index: 1;
}

.arc-card {
  position: absolute;
  left: 50%;
  bottom: 0;                               /* anchored at the waterline */
  width: var(--size, 90px);
  height: var(--size, 90px);
  /* --x / --y (up from the waterline) drive position via transform only, so the
     per-frame scroll rotation stays on the compositor (no layout thrash) */
  transform: translate(-50%, 50%)
             translate(var(--x, 0px), calc(-1 * var(--y, 0px)))
             rotate(var(--rot, 0deg));
  border-radius: 14px;
  border: 1px solid var(--hairline);
  overflow: hidden;                        /* clip zoomed photos to the card */
  box-shadow: 0 20px 50px -18px rgba(0, 0, 0, 0.75);
  will-change: transform;
  opacity: 0;                              /* revealed by JS (entrance) */
  transition: opacity 900ms var(--ease), translate 900ms var(--ease);
  translate: 0 18px;
  transition-delay: calc(var(--i, 0) * 80ms);
}
.arc.is-ready .arc-card { opacity: 1; translate: 0 0; }

.arc-card img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: inherit;
  /* cinematic grade: pulled saturation, lifted contrast, darkened to sit in the scene */
  filter: saturate(0.8) contrast(1.06) brightness(0.8);
}

/* cool tint + shadowing over the photo, below the top-light */
.arc-card::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  border-radius: inherit;
  background: linear-gradient(165deg, rgba(96, 140, 255, 0.10), rgba(9, 11, 16, 0.38));
}

.arc-card::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 2;
  border-radius: inherit;
  background: linear-gradient(155deg, rgba(255, 255, 255, 0.10), transparent 42%);
}

/* graded placeholder art — swap for real photos */
.art-1 { background: linear-gradient(160deg, #1B2333, #0D1119); }
.art-2 { background: linear-gradient(160deg, #14202B, #0A0F15); }
.art-3 { background: linear-gradient(160deg, #202638, #10131D); }
.art-4 { background: linear-gradient(160deg, #182B33, #0B1217); }
.art-5 { background: linear-gradient(160deg, #232B42, #11141F); }
.art-6 { background: linear-gradient(160deg, #182031, #0C0F17); }
.art-7 { background: linear-gradient(160deg, #1D3038, #0D1419); }
.art-8 { background: linear-gradient(160deg, #1A2137, #0E111B); }
.art-9 { background: linear-gradient(160deg, #212942, #101320); }
.art-10 { background: linear-gradient(160deg, #223047, #0F1524); }
.art-11 { background: linear-gradient(160deg, #1C2A2E, #0C1315); }
.art-12 { background: linear-gradient(160deg, #26293D, #12131E); }
.art-13 { background: linear-gradient(160deg, #1E2A3D, #0D131F); }
.art-14 { background: linear-gradient(160deg, #2A2436, #13111C); }

/* --- name + cutout lockup --- */
.hero-stage {
  position: relative;
  z-index: 2;
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
  padding: clamp(120px, 18vh, 200px) 1.5rem clamp(70px, 10vh, 120px);
}

.hero-eyebrow {
  font-size: 0.8rem;
  font-weight: 500;
  letter-spacing: 0.34em;
  text-transform: uppercase;
  color: var(--text-2);
  margin-bottom: var(--space-3);
}

.lockup {
  position: relative;
  font-size: clamp(3rem, 11vw, 10rem);
  display: flex;
  flex-direction: column;
  align-items: center;
  padding-top: 1.1em;               /* headroom for the figure */
  line-height: 0.92;
}

.lockup-line {
  font-family: var(--font-display);
  font-weight: 800;
  letter-spacing: -0.01em;
  white-space: nowrap;
  user-select: none;
}
.lockup-back  { position: relative; z-index: 1; color: #B9C1D2; }
.lockup-front {
  position: relative;
  z-index: 3;
  color: var(--text);
  margin-top: 0.02em;
  text-shadow: 0 30px 80px rgba(0, 0, 0, 0.8);
}

/* tagline — refined subtitle beneath the name */
.hero-tagline {
  position: relative;
  z-index: 4;
  margin: clamp(0.85rem, 2.4vh, 1.6rem) 0 0;
  font-family: var(--font-text);
  font-size: clamp(0.9rem, 0.82rem + 0.4vw, 1.15rem);
  font-weight: 500;
  letter-spacing: 0.015em;
  line-height: 1.45;
  color: var(--text-3);
  text-align: center;
  max-width: 30ch;
  text-wrap: balance;
}
.hero-tagline span { color: var(--text); }

.figure-wrap {
  position: absolute;
  left: 50%;
  bottom: 0.05em;
  transform: translateX(-50%);
  height: 3.05em;
  z-index: 2;
  pointer-events: none;
}

.figure { height: 100%; width: auto; position: relative; z-index: 2; }
.figure-img {
  height: 100%;
  width: auto;
  position: relative;
  z-index: 2;
  object-fit: contain;
  /* grade the daylight shot into the night scene */
  filter: saturate(0.94) contrast(1.04) brightness(0.9)
          drop-shadow(0 24px 44px rgba(0, 0, 0, 0.55));
}

.figure-glow {
  position: absolute;
  left: 50%;
  top: 42%;
  transform: translate(-50%, -50%);
  width: 2.6em;
  height: 2.9em;
  z-index: 1;
  background: radial-gradient(50% 50% at 50% 50%, rgba(96, 140, 255, 0.18), transparent 70%);
}

.figure-shadow {
  position: absolute;
  left: 50%;
  bottom: -0.05em;
  transform: translateX(-50%);
  width: 1.5em;
  height: 0.18em;
  z-index: 0;
  background: radial-gradient(50% 50% at 50% 50%, rgba(0, 0, 0, 0.75), transparent 70%);
  filter: blur(5px);
}

/* On phones the name font is small, so the em-based figure is tiny and leaves
   black space. Decouple the figure height here and scale it up (keeping the
   image's proportions) so the cutout fills the hero from the name up to the arch. */
@media (max-width: 640px) {
  /* JS (fitFigure) sets the real height so the head sits just under the arch;
     this clamp is the no-JS fallback. */
  .figure-wrap { height: clamp(290px, 45dvh, 400px); }
  .figure-glow { width: 56vw; height: 72%; top: 44%; }
  .figure-shadow { width: 42vw; height: 14px; bottom: 0; }
  /* bigger name so it holds its own beneath the enlarged figure (WESTERN still fits) */
  .lockup { font-size: clamp(3.5rem, 18vw, 4.5rem); }
  /* bottom room so the tagline clears the scroll cue */
  .hero-stage { padding-bottom: clamp(96px, 13vh, 124px); }
}

.scroll-cue {
  position: absolute;
  left: 50%;
  bottom: clamp(12px, 2.4vh, 22px);
  transform: translateX(-50%);
  z-index: 3;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  width: 44px;
  height: 40px;
}
.scroll-cue-line {
  display: block;
  width: 1px;
  height: 30px;
  background: linear-gradient(to bottom, var(--text-2), transparent);
  transform-origin: top;
}
@media (prefers-reduced-motion: no-preference) {
  .scroll-cue-line { animation: cue 2.4s var(--ease) infinite; }
}
@keyframes cue {
  0%   { transform: scaleY(0); opacity: 0; }
  35%  { transform: scaleY(1); opacity: 1; }
  100% { transform: scaleY(1) translateY(14px); opacity: 0; }
}

/* ---------- Statement ---------- */
.statement { padding-block: var(--space-6) var(--space-5); }
.statement-line {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(1.5rem, 1.1rem + 2.2vw, 2.5rem);
  line-height: 1.3;
  letter-spacing: -0.01em;
  max-width: 30ch;
  margin: 0 auto;
  text-align: center;
}

/* ---------- Sections ---------- */
.section { padding-block: var(--space-6); }

/* ---------- Book ---------- */
.book { border-top: 1px solid var(--hairline); }

.book-grid {
  display: grid;
  gap: var(--space-5);
  align-items: center;
}
@media (min-width: 900px) {
  .book-grid { grid-template-columns: 5fr 7fr; }
}

.book-cover-wrap { display: flex; justify-content: center; }

.book-cover {
  position: relative;
  width: min(78vw, 300px);
  aspect-ratio: 3 / 4.3;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding: 2rem 1.75rem;
  background: linear-gradient(165deg, #141926 0%, #0C0F16 70%);
  border: 1px solid var(--hairline);
  border-radius: 6px 14px 14px 6px;
  box-shadow: 0 40px 80px -30px rgba(0, 0, 0, 0.8);
  transition: transform 400ms var(--ease), box-shadow 400ms var(--ease);
}
.book-cover:hover {
  transform: translateY(-6px) rotate(-0.5deg);
  box-shadow: 0 50px 90px -30px rgba(0, 0, 0, 0.85), 0 0 60px -20px rgba(96, 140, 255, 0.25);
}
/* spine light */
.book-cover::before {
  content: "";
  position: absolute;
  top: 0; bottom: 0; left: 10px;
  width: 1px;
  background: linear-gradient(to bottom, rgba(138, 180, 255, 0.4), transparent 80%);
}

.book-cover-status {
  align-self: flex-start;
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--blue);
  border: 1px solid rgba(138, 180, 255, 0.3);
  border-radius: 999px;
  padding: 0.35rem 0.8rem;
}

.book-cover-title {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: clamp(2.2rem, 8vw, 3rem);
  line-height: 1;
  letter-spacing: -0.01em;
  color: var(--text);
}

.book-cover-author {
  font-size: 0.75rem;
  font-weight: 500;
  letter-spacing: 0.26em;
  text-transform: uppercase;
  color: var(--text-2);
}

/* ---------- Checkpoint ---------- */
.checkpoint { border-top: 1px solid var(--hairline); }

.cp-grid {
  display: grid;
  gap: var(--space-5);
  align-items: center;
}
@media (min-width: 900px) {
  /* mirrored against the book section so the page alternates */
  .cp-grid { grid-template-columns: 7fr 5fr; }
}

.cp-visual { display: flex; justify-content: center; }

.cp-screen {
  width: min(78vw, 300px);
  padding: 1.25rem 1.1rem 1.4rem;
  background: linear-gradient(165deg, #141926 0%, #0C0F16 70%);
  border: 1px solid var(--hairline);
  border-radius: 26px;
  box-shadow: 0 40px 80px -30px rgba(0, 0, 0, 0.8);
  transition: transform 400ms var(--ease), box-shadow 400ms var(--ease);
}
.cp-screen:hover {
  transform: translateY(-6px);
  box-shadow: 0 50px 90px -30px rgba(0, 0, 0, 0.85), 0 0 60px -20px rgba(96, 140, 255, 0.25);
}

.cp-screen-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 0.7rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-3);
}
.cp-live { display: inline-flex; align-items: center; gap: 0.4rem; color: var(--blue); }
.cp-dot {
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--blue);
  box-shadow: 0 0 8px var(--blue);
}
@media (prefers-reduced-motion: no-preference) {
  .cp-dot { animation: cp-pulse 2s ease-in-out infinite; }
}
@keyframes cp-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.35; } }

.cp-timer {
  font-variant-numeric: tabular-nums;   /* stops the digits jittering */
  color: var(--text-2);
  letter-spacing: 0.08em;
}

.cp-code {
  margin: var(--space-3) 0;
  padding: 0.9rem 1rem;
  text-align: center;
  border: 1px dashed rgba(138, 180, 255, 0.35);
  border-radius: 14px;
  background: rgba(96, 140, 255, 0.06);
}
.cp-code-label {
  display: block;
  font-size: 0.62rem;
  font-weight: 600;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--text-3);
  margin-bottom: 0.35rem;
}
.cp-code-value {
  display: block;
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.5rem;
  letter-spacing: 0.16em;
  font-variant-numeric: tabular-nums;
  color: var(--text);
}

.cp-tasks { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.5rem; }
.cp-tasks li {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.6rem 0.7rem;
  border-radius: 10px;
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid var(--hairline);
  font-size: 0.78rem;
  color: var(--text-2);
}
.cp-tasks .is-done { color: var(--text-3); text-decoration: line-through; }
.cp-tasks .is-active {
  color: var(--text);
  border-color: rgba(138, 180, 255, 0.4);
  background: rgba(96, 140, 255, 0.08);
}
.cp-tasks .is-locked { opacity: 0.45; }

.cp-tick {
  flex: none;
  width: 14px; height: 14px;
  border-radius: 50%;
  background: var(--teal, #1F6F5C);
  background: rgba(138, 180, 255, 0.9);
  position: relative;
}
.cp-tick::after {
  content: "";
  position: absolute;
  left: 4.5px; top: 2px;
  width: 3px; height: 6px;
  border: solid #0A0D14;
  border-width: 0 1.5px 1.5px 0;
  transform: rotate(45deg);
}
.cp-pip {
  flex: none;
  width: 14px; height: 14px;
  border-radius: 50%;
  border: 1.5px solid var(--hairline-strong);
}
.cp-tasks .is-active .cp-pip { border-color: var(--blue); box-shadow: 0 0 8px rgba(138, 180, 255, 0.5); }

/* ---------- Club (join section, shared) ---------- */
.club { border-top: 1px solid var(--hairline); }

.club-inner {
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
}

/* ---------- Login page ---------- */
.login-section { padding-top: calc(96px + var(--space-5)); min-height: 100dvh; }
.login-shell { display: flex; justify-content: center; }
.login-panel {
  width: min(100%, 26rem);
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
}
.login-panel .title-xl { font-size: clamp(2rem, 1.5rem + 2vw, 2.75rem); }
.login-panel .join-form,
.login-panel .join-sent,
.login-panel .join-member { width: 100%; }

.club-wordmark {
  font-family: var(--font-display);
  font-weight: 800;
  font-size: clamp(2.6rem, 9vw, 6.5rem);
  line-height: 1;
  letter-spacing: 0.02em;
  margin: 0 0 var(--space-3);
  color: transparent;
  -webkit-text-stroke: 2px rgba(233, 236, 242, 0.55);
  user-select: none;
}
@supports not (-webkit-text-stroke: 1px black) {
  .club-wordmark { color: var(--text); }
}

.join-form {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  width: min(100%, 30rem);
  margin-top: var(--space-4);
}
@media (min-width: 560px) {
  .join-form { flex-direction: row; }
  .join-form .btn { flex-shrink: 0; }
  /* signup forms carry a name field too — two text inputs + a button in one
     row reads cramped, so these stay stacked instead */
  .join-form-signup { flex-direction: column; width: min(100%, 26rem); }
  .join-form-signup .btn { width: 100%; }
}

.join-input {
  flex: 1;
  min-height: 48px;
  padding: 0.8rem 1.4rem;
  border-radius: 999px;
  border: 1px solid var(--hairline-strong);
  background: rgba(255, 255, 255, 0.03);
  color: var(--text);
  font-family: var(--font-text);
  font-size: var(--text-base);
  transition: border-color var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.join-input::placeholder { color: var(--text-3); }
.join-input:focus {
  outline: none;
  border-color: var(--blue);
  box-shadow: 0 0 0 4px rgba(138, 180, 255, 0.15);
}
.join-input[aria-invalid="true"] { border-color: #E2542C; }

.form-error {
  color: #F09070;
  font-size: var(--text-sm);
  margin: var(--space-1) 0 0;
}

/* ==========================================================================
   MEMBERS AREA
   ========================================================================== */

/* keep gated content hidden until the session check clears it */
body.is-gated main,
body.is-gated .site-footer { visibility: hidden; }

.member-hero {
  position: relative;
  min-height: 62dvh;
  display: flex;
  align-items: center;
  overflow: clip;
  padding-top: 84px;
}
.member-hero-inner { position: relative; z-index: 2; text-align: center; }
.member-hero .eyebrow { margin-inline: auto; }

/* ---------- Community bubbles (members.html hero) ---------- */
.bubble-field {
  position: absolute;
  inset: 0;
  z-index: 1;
  overflow: hidden;
}

.bubble {
  position: absolute;
  top: 0;
  left: 0;
  border-radius: 50%;
  overflow: hidden;
  background: var(--bg-card);
  border: 1px solid var(--hairline-strong);
  display: flex;
  align-items: center;
  justify-content: center;
  will-change: transform;
  cursor: pointer;
  box-shadow: 0 12px 30px -14px rgba(0, 0, 0, 0.5);
}
.bubble img { width: 100%; height: 100%; object-fit: cover; display: block; }
.bubble-label {
  font-family: var(--font-display);
  font-weight: 700;
  color: var(--blue);
}

/* ---------- The vault ---------- */
.vault { border-top: 1px solid var(--hairline); }

.vault-grid {
  display: grid;
  gap: var(--space-3);
  margin-top: var(--space-4);
}
@media (min-width: 760px)  { .vault-grid { grid-template-columns: repeat(3, 1fr); } }
/* keeps a single card (currently just Checkpoint) from stretching full width */
.vault-grid .vault-card { max-width: 26rem; width: 100%; margin-inline: auto; }

.vault-card {
  display: flex;
  flex-direction: column;
  padding: var(--space-3);
  background: linear-gradient(165deg, #141926 0%, #0C0F16 75%);
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
  transition: transform 400ms var(--ease), box-shadow 400ms var(--ease), border-color 400ms var(--ease);
}
.vault-card:hover {
  transform: translateY(-6px);
  border-color: rgba(138, 180, 255, 0.28);
  box-shadow: 0 40px 70px -30px rgba(0, 0, 0, 0.85), 0 0 60px -24px rgba(96, 140, 255, 0.3);
}

/* ---------- Notice board (members.html, read-only) ---------- */
.notice-list { display: grid; gap: var(--space-2); margin-top: var(--space-4); }

.notice-item {
  padding: var(--space-3);
  background: linear-gradient(165deg, #141926 0%, #0C0F16 75%);
  border: 1px solid var(--hairline);
  border-radius: var(--radius);
}
.notice-item-date { font-size: var(--text-sm); color: var(--text-3); margin-bottom: var(--space-1); }
.notice-item-body { color: var(--text-2); line-height: 1.6; white-space: pre-wrap; }

.vault-card-top {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  margin-bottom: var(--space-3);
}
.vault-index {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 0.8rem;
  letter-spacing: 0.18em;
  color: var(--blue);
}
.vault-card h3 { font-size: clamp(1.5rem, 1.2rem + 1vw, 1.9rem); margin-bottom: var(--space-1); }
.vault-card p {
  color: var(--text-2);
  font-size: var(--text-sm);
  margin-bottom: var(--space-3);
  flex: 1;
}

.vault-action {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  align-self: flex-start;
  min-height: 44px;
  padding: 0.6rem 1.2rem;
  border-radius: 999px;
  font-size: var(--text-sm);
  font-weight: 600;
  text-decoration: none;
}
/* waiting = not yet available; reads as intentional, not broken */
.vault-action.is-waiting {
  color: var(--text-3);
  border: 1px dashed var(--hairline-strong);
}
.vault-action.is-waiting::before {
  content: "";
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--text-3);
}
/* when a thing goes live, swap the class to .is-live and make it an <a> */
.vault-action.is-live {
  background: var(--text);
  color: var(--bg);
  transition: transform var(--dur) var(--ease), box-shadow var(--dur) var(--ease);
}
.vault-action.is-live:hover {
  transform: translateY(-1px);
  box-shadow: 0 8px 40px -8px rgba(138, 180, 255, 0.35);
}

/* ---------- Join form states ---------- */
.join-sent {
  display: none;
  flex-direction: column;
  align-items: center;
  gap: var(--space-1);
  width: min(100%, 30rem);
  margin-top: var(--space-4);
  padding: var(--space-3);
  border: 1px solid rgba(138, 180, 255, 0.3);
  background: rgba(96, 140, 255, 0.06);
  border-radius: var(--radius);
  text-align: center;
}
.join-sent.is-visible { display: flex; }
.join-sent.is-visible ~ .join-form,
.join-form.is-hidden { display: none; }
.join-sent-title {
  font-family: var(--font-display);
  font-weight: 700;
  font-size: 1.25rem;
  color: var(--text);
  margin: 0;
}
.join-sent p { color: var(--text-2); font-size: var(--text-sm); margin: 0; }
.join-sent-icon { color: var(--blue); margin-bottom: var(--space-1); }

/* ---------- Guest vs member ----------
   js/auth.js puts .is-member / .is-guest on <html>, so a signed-in member sees a
   way into the vault instead of a signup form they don't need. */
.join-member {
  display: none;
  flex-direction: column;
  align-items: center;
  gap: var(--space-1);
  width: min(100%, 30rem);
  margin-top: var(--space-4);
  padding: var(--space-3);
  border: 1px solid rgba(138, 180, 255, 0.3);
  background: rgba(96, 140, 255, 0.06);
  border-radius: var(--radius);
  text-align: center;
}
.join-member p { color: var(--text-2); font-size: var(--text-sm); margin: 0; }
.join-member .btn { margin-top: var(--space-2); }
.join-member .quiet-link { margin-top: var(--space-1); }

/* member-only bits stay hidden until proven otherwise (so guests never see them) */
[data-member-only] { display: none !important; }

html.is-member [data-member-panel] { display: flex; }
html.is-member .btn[data-member-only] { display: inline-flex !important; }
html.is-member .menu-nav [data-member-only] { display: block !important; }

html.is-member .join-form,
html.is-member .join-sent,
html.is-member [data-guest-only] { display: none !important; }

/* The homepage's Club Fray join section is the exception — it should look
   identical whether you're signed in or not, so it doesn't inherit the
   is-member swap above (no "you're already in" panel there). */
html.is-member .join-form-signup { display: flex !important; }

/* ---------- Footer ---------- */
.site-footer {
  border-top: 1px solid var(--hairline);
  padding-block: var(--space-4);
  margin-top: var(--space-6);
}

.footer-inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
  text-align: center;
}
@media (min-width: 768px) {
  .footer-inner { flex-direction: row; justify-content: space-between; }
}

.footer-name { font-family: var(--font-display); font-weight: 700; }

.footer-links { display: flex; gap: var(--space-2); }
.footer-links a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  color: var(--text-2);
  text-decoration: none;
  font-size: var(--text-sm);
  padding: 0.5rem 0.6rem;
  transition: color var(--dur) var(--ease);
}
.footer-links a:hover { color: var(--text); }

.footer-fine { font-size: var(--text-sm); color: var(--text-3); }

/* ==========================================================================
   CLUB PAGE
   ========================================================================== */

.club-hero {
  position: relative;
  min-height: 78dvh;
  display: flex;
  align-items: center;
  overflow: clip;
}

.club-hero-inner {
  position: relative;
  z-index: 2;
  text-align: center;
  padding-top: 80px;
}

.club-title {
  font-size: clamp(4rem, 17vw, 12rem);
  font-weight: 800;
  line-height: 0.9;
  letter-spacing: 0.01em;
  margin-bottom: var(--space-3);
}

/* ---------- Tenets ---------- */
.tenets { border-top: 1px solid var(--hairline); }

.tenet-grid {
  display: grid;
  gap: var(--space-4);
}
@media (min-width: 768px) {
  .tenet-grid { grid-template-columns: repeat(3, 1fr); }
}

.tenet {
  border-top: 1px solid var(--hairline-strong);
  padding-top: var(--space-3);
}
.tenet-number {
  display: block;
  font-size: 0.75rem;
  font-weight: 600;
  letter-spacing: 0.22em;
  color: var(--blue);
  margin-bottom: var(--space-2);
}
.tenet h2 {
  font-size: clamp(1.8rem, 1.4rem + 1.6vw, 2.5rem);
  margin-bottom: var(--space-1);
}
.tenet p { color: var(--text-2); font-size: var(--text-base); margin: 0; }

/* ---------- Events ---------- */
.events { border-top: 1px solid var(--hairline); }
.events-inner { max-width: 38rem; }

/* ---------- Reduced motion ---------- */
@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;
  }
}
