/* ============================================================================
   Saturday Night Revels — landing page.

   SEPARATE FROM styles.css ON PURPOSE. privacy.html and sms-terms.html both
   link styles.css, and those two pages are on file with the carriers (rule 12).
   Restyling a shared stylesheet would change what a reviewer sees on them
   without touching either file. This sheet is loaded by index.html and nothing
   else; styles.css is untouched.

   NO THIRD-PARTY REQUESTS. The only external reference in the whole page is the
   self-hosted woff2 below. No CDN, no Google Fonts, no analytics, no remote
   images — every photograph slot is inline SVG until a real photo exists.
   ========================================================================= */

@font-face {
  font-family: "Anton";
  src: url("/fonts/anton-latin-400.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  /* block, not swap: the headline IS this face, and a swap would let a
     screenshot bot capture the fallback mid-load. */
  font-display: block;
}

:root {
  --ink: #07080B;
  --ink-2: #0C0F16;
  --surface: #11151E;
  --line: #1C2230;

  --blue: #2E8FE0;
  --blue-bright: #5FB8FF;
  --orange: #FF7A1A;

  --paper: #F4F6F9;
  --dim: #9AA6B4;

  --display: "Anton", "Haettenschweiler", "Arial Narrow", "Impact", sans-serif;
  --text: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;

  --gutter: clamp(1.25rem, 5vw, 4rem);
  --measure: 62ch;

  /* The masthead's height is driven entirely by the badge, and the hero has to
     reserve exactly that much. Both read these, so resizing the badge can never
     leave the headline sitting on top of the wordmark again. */
  --badge-size: clamp(104px, 15vw, 208px);
  --mast-pad: clamp(1rem, 2.5vw, 1.75rem);
}

* { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--ink);
  color: var(--paper);
  font-family: var(--text);
  font-size: clamp(1rem, 0.96rem + 0.2vw, 1.125rem);
  line-height: 1.6;
  /* The page is dark end to end; tell the UA so form controls and scrollbars
     follow rather than flashing white. */
  color-scheme: dark;
  overflow-x: hidden;
}

.wrap {
  width: 100%;
  max-width: 78rem;
  margin-inline: auto;
  padding-inline: var(--gutter);
}

/* NO UNDERLINES. See CLAUDE.md, "Links". Weight is what makes a link
   identifiable without relying on colour alone; hover shifts to orange. */
a {
  color: var(--blue-bright);
  text-decoration: none;
  font-weight: 600;
}
a:hover { color: var(--orange); }

/* This page had no focus style at all — links fell back to the UA ring, which
   on a near-black page is close to invisible. */
a:focus-visible {
  outline: 2px solid var(--blue-bright);
  outline-offset: 3px;
  border-radius: 3px;
}

/* Display type, set the way a flyer sets it: heavy, condensed, all caps,
   tracked tight, lines almost touching. */
.display {
  font-family: var(--display);
  text-transform: uppercase;
  font-weight: 400;
  /* Anton's ascent/descent overflow the em box, so anything under ~0.92 makes
     WRAPPED headings collide — a comma on one line lands in the caps of the
     next. The hero opts back into a tighter figure below because its lines are
     explicit blocks that never reflow. */
  line-height: 0.94;
  letter-spacing: 0.005em;
  margin: 0;
}

/* ── image slots ───────────────────────────────────────────────────────────
   Every slot is a fixed-ratio box whose child fills it with object-fit: cover.
   The child is an inline <svg class="slot-media"> today. Dropping in a real
   photograph is <img class="slot-media" src="..." alt="..."> in the same place
   — same box, same ratio, same crop behaviour, no layout change.            */
.slot {
  position: relative;
  overflow: hidden;
  background: var(--ink-2);
}
.slot-media {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* ── masthead ─────────────────────────────────────────────────────────────── */
.mast {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  z-index: 3;
  display: flex;
  align-items: center;
  gap: clamp(0.75rem, 2vw, 1.25rem);
  padding: var(--mast-pad) var(--gutter);
}
.badge {
  display: block;
  /* Logos/README.md: the badge is only used where it renders 200px or larger,
     because the "SATURDAY NIGHT REVELS" ring text is unreadable below that.
     The square includes transparent margin, so the disc itself lands a little
     under the box size. */
  width: var(--badge-size);
  height: auto;
  flex: none;
}
.mast-word {
  font-family: var(--display);
  text-transform: uppercase;
  font-size: clamp(1.05rem, 2.6vw, 1.6rem);
  line-height: 1;
  letter-spacing: 0.06em;
  margin: 0;
}
.mast-city {
  margin: 0.25rem 0 0;
  font-size: 0.7rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--dim);
}

/* ── hero ─────────────────────────────────────────────────────────────────── */
.hero {
  position: relative;
  /* Full-bleed: the artwork is the page's top, not a banner inside it. */
  min-height: min(100svh, 62rem);
  display: grid;
  align-items: end;
  /* Reserves the floating masthead, computed from it rather than guessed.
     The artwork still bleeds to y=0 behind it. */
  padding-top: calc(var(--badge-size) + (var(--mast-pad) * 2) + clamp(1rem, 3vw, 2.5rem));
  padding-bottom: clamp(2.5rem, 7vw, 6rem);
  isolation: isolate;
}
.hero > .slot {
  position: absolute;
  inset: 0;
  z-index: 0;
  background: none;
}
/* Floor the artwork into the page below it so there is no hard seam. */
.hero::after {
  content: "";
  position: absolute;
  inset: auto 0 0 0;
  height: 24%;
  z-index: 1;
  background: linear-gradient(to bottom, transparent, rgba(7, 8, 11, 0.72) 62%, var(--ink));
  pointer-events: none;
}
.hero-copy {
  position: relative;
  z-index: 2;
  width: 100%;
  max-width: 78rem;
  margin-inline: auto;
  padding-inline: var(--gutter);
}
.kicker {
  font-family: var(--display);
  text-transform: uppercase;
  font-size: clamp(0.75rem, 1.6vw, 0.95rem);
  letter-spacing: 0.3em;
  color: var(--blue-bright);
  margin: 0 0 clamp(0.75rem, 2vw, 1.25rem);
}
.kicker .dot { color: var(--orange); }

h1.display {
  font-size: clamp(3rem, 11.8vw, 10rem);
  /* Three hand-set lines, never reflowed — safe to close right up. */
  line-height: 0.84;
  /* Anton's sidebearings leave the caps looking indented against a flush
     column; pull the optical edge back to the grid. */
  margin-left: -0.035em;
}
h1 .l2 { color: var(--blue-bright); }
h1 .l3 { color: var(--orange); }

.hero-lede {
  max-width: 34rem;
  margin: clamp(1.25rem, 3vw, 2rem) 0 0;
  font-size: clamp(1.05rem, 1.6vw, 1.3rem);
  color: var(--paper);
}
.hero-rule {
  width: clamp(4rem, 10vw, 8rem);
  height: 4px;
  margin: clamp(1.25rem, 3vw, 1.75rem) 0 0;
  border: 0;
  background: linear-gradient(90deg, var(--orange), var(--blue));
}

/* ── generic section furniture ────────────────────────────────────────────── */
.band { padding-block: clamp(3.5rem, 9vw, 7rem); }
.band-line { border-top: 1px solid var(--line); }

.eyebrow {
  font-family: var(--display);
  text-transform: uppercase;
  font-size: 0.78rem;
  letter-spacing: 0.28em;
  color: var(--orange);
  margin: 0 0 clamp(0.75rem, 2vw, 1rem);
}
h2.display { font-size: clamp(2rem, 6vw, 4.25rem); }
h3.display { font-size: clamp(1.3rem, 2.6vw, 1.9rem); }

.band p { max-width: var(--measure); }
.dim { color: var(--dim); }

/* ── the room: three swappable slots ──────────────────────────────────────── */
.rooms {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr));
  gap: clamp(0.75rem, 1.6vw, 1.25rem);
  margin-top: clamp(2rem, 5vw, 3rem);
}
.room .slot { aspect-ratio: 4 / 5; border-radius: 2px; }
.room h3 {
  margin: 0.9rem 0 0.25rem;
  font-family: var(--display);
  text-transform: uppercase;
  font-size: 1.05rem;
  letter-spacing: 0.05em;
}
.room p { margin: 0; font-size: 0.95rem; color: var(--dim); }

/* ── how it works ─────────────────────────────────────────────────────────── */
.steps {
  list-style: none;
  counter-reset: step;
  margin: clamp(2rem, 5vw, 3rem) 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 16rem), 1fr));
  gap: clamp(1.5rem, 3vw, 2.5rem);
}
.steps li { counter-increment: step; }
.steps li::before {
  content: counter(step, decimal-leading-zero);
  display: block;
  font-family: var(--display);
  font-size: clamp(2.5rem, 5vw, 3.75rem);
  line-height: 1;
  color: var(--blue);
  margin-bottom: 0.4rem;
}
.steps h3 { margin: 0 0 0.35rem; }
.steps p { margin: 0; color: var(--dim); font-size: 0.98rem; }

/* ── footer ───────────────────────────────────────────────────────────────── */
.foot {
  border-top: 1px solid var(--line);
  padding-block: clamp(2rem, 4vw, 3rem);
  font-size: 0.9rem;
  color: var(--dim);
}
.foot-links {
  display: flex;
  flex-wrap: wrap;
  gap: 1.25rem;
  margin: 0 0 1rem;
  padding: 0;
  list-style: none;
}
.foot p { margin: 0.35rem 0 0; }

/* All three footer links are the same blue. Staff used to sit one step down on
   --blue so it would not compete with the two carrier-filed links; that
   distinction is gone, so there is no .staff rule here. The base `a` and
   `a:hover` rules already supply --blue-bright and --orange, and restating them
   under a class would be dead weight that implies a difference which no longer
   exists. */

/* The whole legal presence: one line, small and dim, deliberately not a
   disclosure block. Kept selectable and with a live mailto so the entity,
   address and email stay reachable rather than decorative. */
.legal {
  font-size: 0.8rem;
  line-height: 1.5;
  color: var(--dim);
  max-width: var(--measure);
}
/* Brighter than the dim line it sits in, and bolder — colour AND weight, so it
   still reads as a link with the underline gone. */
.legal a { color: var(--paper); font-weight: 600; }
.legal a:hover { color: var(--orange); }

/* ── the one motion moment ────────────────────────────────────────────────
   A single orchestrated entrance: the beams come up, then the three headline
   lines, then the rule and the lede. It runs once and settles. Nothing on this
   page loops.

   The resting state IS the finished state — every animated element is fully
   visible with no animation applied. The keyframes only animate INTO that
   state from a transformed start. So a screenshot tool that disables
   animation, or a reader who asked for less motion, gets the final composition
   rather than a blank hero.                                                 */
@media (prefers-reduced-motion: no-preference) {
  /* The whole sequence lands inside ~1s. A screenshot tool that fires on load
     without honouring reduced-motion should not be able to catch this halfway,
     and TCR's reviewer gets the finished composition either way. */
  .rise { animation: rise 620ms cubic-bezier(0.16, 0.84, 0.32, 1) backwards; }
  .kicker.rise { animation-delay: 80ms; }
  h1 .l1 { animation-delay: 150ms; }
  h1 .l2 { animation-delay: 215ms; }
  h1 .l3 { animation-delay: 280ms; }
  .hero-rule.rise { animation-delay: 350ms; }
  .hero-lede.rise { animation-delay: 400ms; }

  .beam-sweep {
    transform-origin: 50% 0%;
    animation: beams 900ms cubic-bezier(0.22, 0.68, 0.28, 1) backwards;
  }
  .haze-in { animation: fade 1000ms ease-out backwards; }
  .crowd-in { animation: crowd 760ms cubic-bezier(0.16, 0.84, 0.32, 1) 80ms backwards; }
}

@keyframes rise {
  from { opacity: 0; transform: translate3d(0, 0.5em, 0); }
}
@keyframes beams {
  from { opacity: 0; transform: scaleY(0.55) scaleX(0.9); }
}
@keyframes fade { from { opacity: 0; } }
@keyframes crowd {
  from { opacity: 0; transform: translate3d(0, 26px, 0); }
}

h1 .l1, h1 .l2, h1 .l3 { display: block; }

/* Print: the compliance content is what matters on paper, not the club. */
@media print {
  body { background: #fff; color: #000; }
  .hero, .rooms, .slot { display: none !important; }
  a { color: #000; }
}
