/* joinparasocial.com
   Tokens come from the app (pulse-app) and the Figma file. Every text/background pair below
   was chosen to pass WCAG 2.2 AA; re-check contrast before adding a colour. */

@font-face { font-family: "Fraunces"; src: url(/fonts/fraunces-600.woff2) format("woff2"); font-weight: 600; font-style: normal; font-display: swap; }
@font-face { font-family: "Fraunces"; src: url(/fonts/fraunces-600-italic.woff2) format("woff2"); font-weight: 600; font-style: italic; font-display: swap; }
@font-face { font-family: "Plus Jakarta Sans"; src: url(/fonts/jakarta-400.woff2) format("woff2"); font-weight: 400; font-display: swap; }
@font-face { font-family: "Plus Jakarta Sans"; src: url(/fonts/jakarta-600.woff2) format("woff2"); font-weight: 600; font-display: swap; }
@font-face { font-family: "Plus Jakarta Sans"; src: url(/fonts/jakarta-700.woff2) format("woff2"); font-weight: 700; font-display: swap; }
@font-face { font-family: "Space Mono"; src: url(/fonts/spacemono-700.woff2) format("woff2"); font-weight: 700; font-display: swap; }

:root {
  --ink: #16161F;          /* page background (dark) */
  --ink-deep: #111118;     /* footer */
  --ink-phone: #0C0C12;    /* phone bezel */
  --plum: #1E1530;         /* organiser band */
  --paper: #F4EFE6;        /* photobook-paper sections */
  --cream: #F7F3EA;        /* text on dark */
  --muted: #C9C3D9;        /* body on dark  (11.6:1 on ink) */
  --muted-2: #9A94AD;      /* fine print on dark (6.2:1 on ink) */
  --body-on-paper: #4A4658;/* body on paper (8:1) */
  --violet: #9740FE;       /* brand; white text on it is 4.7:1 */
  --violet-soft: #B9A8FF;  /* accent text on dark (8.9:1) */
  --violet-text: #6D28D9;  /* violet text on paper (6.3:1) */
  --lilac: #CFC2FF;
  --field: #23232F;
  --field-line: #3D3A52;
  --orange: #FF7A1A;
  --pink: #F472B6;
  --blue: #278EFF;
  --green: #22C55E;
  --display: "Fraunces", Georgia, serif;
  --text: "Plus Jakarta Sans", system-ui, -apple-system, "Segoe UI", sans-serif;
  --mono: "Space Mono", ui-monospace, monospace;
  --shadow: 0 18px 40px rgba(23, 15, 38, 0.28);
}

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
body { margin: 0; background: var(--ink); color: var(--cream); font-family: var(--text); font-size: 1rem; line-height: 1.55; }
img { display: block; max-width: 100%; }
h1, h2, h3, p { margin: 0; }
a { color: inherit; }
:focus-visible { outline: 3px solid var(--lilac); outline-offset: 3px; border-radius: 6px; }
.paper :focus-visible { outline-color: var(--violet-text); }

.skip { position: absolute; left: 16px; top: -80px; z-index: 50; background: var(--cream); color: var(--ink); padding: 10px 16px; border-radius: 10px; font-weight: 700; text-decoration: none; }
.skip:focus { top: 16px; }
.visually-hidden { position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }

/* ---------- Hero ---------- */
/* overflow: clip, not just hidden: a hidden box is still scrollable by the browser, so jumping to #join
   scrolled the hero's insides (wordmark over the form, photo columns torn). Clip can't be scrolled.
   'hidden' stays first as the fallback for browsers without clip. */
.hero { position: relative; min-height: clamp(860px, 100svh, 1000px); overflow: hidden; overflow: clip; display: grid; place-items: center; isolation: isolate;
  background: radial-gradient(ellipse at 50% 50%, rgba(151, 64, 254, 0.20), rgba(151, 64, 254, 0) 60%), var(--ink); }
.hero::before, .hero::after { content: ""; position: absolute; left: 0; right: 0; height: 190px; z-index: 1; pointer-events: none; }
.hero::before { top: 0; background: linear-gradient(var(--ink), rgba(22, 22, 31, 0)); }
.hero::after { bottom: 0; background: linear-gradient(rgba(22, 22, 31, 0), var(--ink)); }
.wordmark { position: absolute; top: 36px; left: 50%; transform: translateX(-50%); z-index: 3; font-family: var(--display); font-weight: 600; font-size: 1.625rem; color: var(--cream); text-decoration: none; }

/* The photo wall. Decorative: aria-hidden in the markup. */
.photo-wall { position: absolute; inset: 0; pointer-events: none; }
.col { position: absolute; top: 0; display: flex; flex-direction: column; width: max-content; will-change: transform; }
/* Each column holds its photos twice. Moving it exactly half its height lands the second set where the
   first began, so the loop has no seam. Spacing is margin on each card (not flex gap) so that half
   the height is exactly one set. */
.col.up { animation: drift-up var(--dur, 60s) linear infinite; }
.col.down { animation: drift-down var(--dur, 60s) linear infinite; }
@keyframes drift-up { from { transform: translateY(0); } to { transform: translateY(-50%); } }
@keyframes drift-down { from { transform: translateY(-50%); } to { transform: translateY(0); } }
.col-a { left: 30px; --dur: 64s; }
.col-b { left: 190px; --dur: 80s; }
.col-c { right: 190px; --dur: 72s; }
.col-d { right: 24px; --dur: 58s; }

.pol { position: relative; width: var(--w, 170px); margin: 0 0 30px; padding: 9px 9px 30px; background: #F4EFE6; border-radius: 4px; box-shadow: 0 14px 28px rgba(0, 0, 0, 0.45); transform: rotate(var(--r, 0deg)); }
.pol img { width: 100%; aspect-ratio: 4 / 5; object-fit: cover; background: #D9D2C3; }
.pol.wide img { aspect-ratio: 4 / 3; }
.stamp { position: absolute; right: 16px; bottom: 38px; font-family: var(--mono); font-weight: 700; font-size: 10px; letter-spacing: 0.04em; color: var(--orange); text-shadow: 0 0 3px rgba(255, 122, 26, 0.55); }

.hero-content { position: relative; z-index: 2; width: min(680px, 100% - 32px); padding: 130px 0 96px; text-align: center; }
.eyebrow { display: inline-block; margin-bottom: 26px; padding: 7px 16px; border: 1px solid rgba(158, 134, 255, 0.45); border-radius: 999px; background: rgba(151, 64, 254, 0.16); color: var(--lilac); font-size: 0.8125rem; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase; }
h1 { font-family: var(--display); font-weight: 600; font-size: clamp(2.125rem, 1.1rem + 3vw, 3.25rem); line-height: 1.06; letter-spacing: -0.01em; }
h1 em, .accent { font-style: italic; color: var(--violet-soft); }
.lede { margin: 28px auto 0; max-width: 580px; color: var(--muted); font-size: 1.125rem; display: grid; gap: 12px; }
.lede-lead { color: var(--cream); font-weight: 600; }
/* 600, not <strong>'s default 700: the same weight as .lede-lead, so it lifts the phrase without shouting. */
.lede strong, .organisers strong { font-weight: 600; }
.accent { margin-top: 22px; font-family: var(--display); font-weight: 600; font-size: 1.5rem; }

/* ---------- Waitlist form ---------- */
.join { position: relative; max-width: 580px; margin: 30px auto 0; text-align: left; }
/* Jumping to the form leaves the headline's last line and the label in view, not the field jammed at the top. */
#join { scroll-margin-top: 140px; }
.join label[for="email"] { display: block; margin-bottom: 8px; color: var(--muted); font-size: 0.8125rem; font-weight: 600; }
.join .row { display: flex; gap: 12px; }
.join input[type="email"] { flex: 1; min-width: 0; height: 56px; padding: 0 18px; border: 1px solid var(--field-line); border-radius: 14px; background: var(--field); color: var(--cream); font: inherit; font-size: 1rem; }
.join input[type="email"]::placeholder { color: #8D879F; }
.join input[aria-invalid="true"] { border-color: #FF8A8A; }
.btn { display: inline-flex; align-items: center; justify-content: center; min-height: 56px; padding: 0 24px; border: 0; border-radius: 14px; background: var(--violet); color: #FFFFFF; font: inherit; font-weight: 700; font-size: 1rem; text-decoration: none; cursor: pointer; white-space: nowrap; }
.btn:hover { background: #8530E8; }
.btn[disabled] { opacity: 0.7; cursor: progress; }
.btn-outline { background: transparent; border: 1.5px solid var(--violet-soft); color: var(--cream); }
.btn-outline:hover { background: rgba(185, 168, 255, 0.12); }
.checks { display: grid; gap: 10px; margin-top: 14px; }
.check { display: flex; align-items: center; gap: 10px; color: var(--muted); font-size: 0.9375rem; cursor: pointer; }
.check input { width: 20px; height: 20px; margin: 0; accent-color: var(--violet); flex: none; }
.hp { position: absolute; left: -10000px; width: 1px; height: 1px; overflow: hidden; }
.status { min-height: 1.5em; margin-top: 12px; color: var(--lilac); font-size: 0.9375rem; font-weight: 600; }
.status:focus { outline: none; }
.fine { margin-top: 6px; color: var(--muted-2); font-size: 0.8125rem; text-align: center; }
.join.done .row, .join.done .checks, .join.done label[for="email"] { display: none; }
.join.done .status { margin: 0; padding: 18px 20px; border-radius: 14px; background: rgba(151, 64, 254, 0.16); color: var(--cream); text-align: center; }

/* ---------- Paper sections ---------- */
.paper { background: var(--paper); color: var(--ink); }
.section-head { max-width: 1000px; margin: 0 auto; padding: 0 24px; text-align: center; }
.kicker { font-size: 0.875rem; font-weight: 600; letter-spacing: 0.1em; text-transform: uppercase; color: var(--violet-text); }
h2 { margin-top: 12px; font-family: var(--display); font-weight: 600; font-size: clamp(2rem, 1.2rem + 2.4vw, 3.25rem); line-height: 1.08; }
.section-head p { margin-top: 14px; color: var(--body-on-paper); font-size: 1.1875rem; }

.how { padding: 120px 0 40px; }
/* Each stage spans the full width so its texture can; the side padding keeps the content inside 1152px. */
.stage { position: relative; isolation: isolate; padding: 72px max(24px, calc((100% - 1152px) / 2)) 32px; display: grid; grid-template-columns: 1fr 1fr; gap: 64px; align-items: center; }
.stage.flip .stage-text { order: 2; }
/* Per-stage paper texture, tinted with that stage's accent from the app, fading in and out at the edges
   so stages blend through plain paper. Decorative only: drawn by CSS, invisible to screen readers. */
.stage::before { content: ""; position: absolute; inset: 0; z-index: -1; background-repeat: repeat;
  -webkit-mask-image: linear-gradient(transparent, #000 180px, #000 calc(100% - 180px), transparent);
  mask-image: linear-gradient(transparent, #000 180px, #000 calc(100% - 180px), transparent); }
.tex-dots::before { background-image: url(/textures/dots-tint.svg); }
.tex-grid::before { background-image: url(/textures/grid-tint.svg); }
.tex-crosshatch::before { background-image: url(/textures/crosshatch-tint.svg); }
.tex-grain::before { background-image: url(/textures/grain-tint.svg); }
.tex-ruled::before { background-image: url(/textures/ruled-tint.svg); }
.stage.centered { grid-template-columns: 1fr; text-align: center; gap: 48px; }
.stage.centered .stage-text { max-width: 940px; margin: 0 auto; }
.stage.centered p.body { max-width: 700px; margin-left: auto; margin-right: auto; }
.step { font-family: var(--mono); font-weight: 700; font-size: 0.875rem; letter-spacing: 0.08em; color: var(--violet-text); }
.stage h3 { margin-top: 10px; font-family: var(--display); font-weight: 600; font-size: clamp(1.75rem, 1.1rem + 1.6vw, 2.5rem); line-height: 1.1; }
.stage h3 em { font-style: italic; }
.stage p.body { margin-top: 16px; color: var(--body-on-paper); font-size: 1.125rem; }
.stage-arrow { grid-column: 1 / -1; order: 3; display: grid; place-items: center; width: 44px; height: 44px; margin: 24px auto 0; border-radius: 50%; background: var(--ink); color: var(--cream); font-weight: 700; }
.scene { position: relative; margin: 0 auto; }
.stage > * { min-width: 0; }

/* ---------- Phones (decorative illustrations of the app UI) ---------- */
.phone { position: absolute; width: 260px; height: 540px; padding: 10px; border-radius: 40px; background: var(--ink-phone); box-shadow: var(--shadow); }
.screen { position: relative; width: 240px; height: 520px; overflow: hidden; border-radius: 32px; background: var(--ink); color: var(--cream); font-size: 12px; line-height: 1.4; }
.screen .abs { position: absolute; }
.scr-title { position: absolute; left: 18px; top: 20px; font-weight: 700; font-size: 14px; }
.pill { display: inline-block; padding: 4px 10px; border-radius: 999px; font-weight: 700; font-size: 11px; color: #FFFFFF; }
.pill.dating { background: var(--pink); color: #2A0A1A; }
.pill.friends { background: var(--blue); color: #04172E; }
.pill.orange { background: var(--orange); color: #1A0E00; }
.pill.green { background: var(--green); color: #0C2A16; }
.pill.grey { background: #2A2A3A; color: var(--muted); }
.bubble { width: fit-content; max-width: 170px; padding: 8px 11px; border-radius: 14px; background: #2A2A3A; color: #FFFFFF; font-size: 11.5px; line-height: 1.4; }
.bubble.me { background: var(--violet); margin-left: auto; }
.float-card { position: absolute; display: grid; gap: 8px; padding: 14px; border-radius: 20px; background: #1E1E2A; color: var(--cream); box-shadow: var(--shadow); }
.float-card .title { font-family: var(--display); font-weight: 600; font-size: 18px; }
.float-card .small-title { font-weight: 700; font-size: 13px; }
.avatar { width: 28px; height: 28px; border-radius: 50%; object-fit: cover; border: 2px solid var(--ink); }

/* Stage 1: match */
.scene-match { width: 780px; height: 690px; }
.scene-match .col-label { position: absolute; top: 0; width: 260px; text-align: center; font-weight: 700; font-size: 1.25rem; }
.scene-match .phone { top: 46px; }
.scene-match .p-dating, .scene-match .l-dating { left: 0; }
.scene-match .p-friends, .scene-match .l-friends { right: 0; }
.swipe-card { position: absolute; left: 12px; top: 52px; width: 216px; height: 330px; border-radius: 18px; overflow: hidden; }
.swipe-card img { width: 100%; height: 100%; object-fit: cover; }
.swipe-card::after { content: ""; position: absolute; inset: auto 0 0 0; height: 130px; background: linear-gradient(rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.72)); }
.swipe-card .pill { position: absolute; left: 14px; bottom: 58px; z-index: 1; }
.swipe-card .name { position: absolute; left: 14px; bottom: 22px; z-index: 1; font-weight: 700; font-size: 20px; }
.actions { position: absolute; top: 400px; left: 0; right: 0; display: flex; justify-content: center; gap: 14px; }
.actions .pill { padding: 6px 16px; font-size: 13px; }
.match-dating { left: -150px; top: 500px; width: 220px; }
.match-friends { right: -150px; top: 500px; width: 220px; }
/* The matched person's face hangs off the card's outer corner, in the app's ring colours:
   pink for a dating match, blue for friends (stage 2 turns it purple once you've met). */
.match-avatar { position: absolute; top: -18px; width: 44px; height: 44px; border-radius: 50%; object-fit: cover;
  box-shadow: 0 0 0 3px var(--ink), 0 0 0 6px var(--ring, var(--violet)), 0 8px 18px rgba(23, 15, 38, 0.35); }
.match-dating .match-avatar { left: -8px; --ring: var(--pink); }
.match-friends .match-avatar { right: -8px; --ring: var(--blue); }
/* Centred on both cards: it clears the corner avatar on either side and the two cards match. */
.match-card .title { text-align: center; }

/* Stage 2: meet in person */
.scene-meet { width: 568px; height: 600px; }
.scene-meet .phone { left: 0; top: 20px; }
.qr { position: absolute; left: 30px; top: 100px; width: 180px; height: 180px; border-radius: 18px; background: var(--cream); padding: 14px; }
.qr svg { width: 100%; height: 100%; }
.scanline { position: absolute; left: 22px; right: 22px; top: 104px; height: 3px; border-radius: 2px; background: var(--violet-soft); box-shadow: 0 0 12px var(--violet-soft); opacity: 0; }
.met { position: absolute; left: 0; right: 0; top: 330px; display: grid; justify-items: center; gap: 10px; font-weight: 700; font-size: 15px; }
.met img { width: 60px; height: 60px; border-radius: 50%; object-fit: cover; box-shadow: 0 0 0 4px var(--ink), 0 0 0 7px var(--violet); }
.ring-pair { position: absolute; left: 292px; top: 40px; display: flex; align-items: center; gap: 18px; }
.ring-pair figure { margin: 0; display: grid; justify-items: center; gap: 10px; font-size: 0.875rem; font-weight: 600; color: var(--body-on-paper); }
.ring-pair figure:last-child { color: var(--violet-text); }
.ring { width: 96px; height: 96px; border-radius: 50%; object-fit: cover; box-shadow: 0 0 0 5px var(--paper), 0 0 0 9px var(--blue); transition: box-shadow 0.8s ease; }
.ring-pair .arrow { font-weight: 700; font-size: 32px; color: var(--violet-text); }
.stats { position: absolute; left: 292px; top: 240px; display: flex; gap: 26px; padding: 20px 24px; border-radius: 20px; background: var(--ink); color: var(--cream); box-shadow: var(--shadow); }
.stats div { display: grid; }
.stats b { font-family: var(--display); font-weight: 600; font-size: 30px; line-height: 1.1; }
.stats b.hi { color: var(--violet-soft); }
.stats span { font-size: 12px; color: var(--muted-2); }
/* Above the stats card, which comes later in the markup and would otherwise paint over it. */
.plus-one { position: absolute; left: 330px; top: 226px; z-index: 2; }

/* Stage 3: hangouts */
.scene-hang { width: 568px; height: 740px; }
.scene-hang .p-map { left: 0; top: 0; }
.scene-hang .p-hang { left: 300px; top: 52px; }
.map { position: absolute; inset: 0; background: #1A1C27; }
.map .water { position: absolute; left: -90px; top: 320px; width: 300px; height: 300px; border-radius: 50%; background: #17283D; }
.map .park { position: absolute; border-radius: 14px; background: #1E2E25; }
.map .road { position: absolute; background: #2B2E3E; }
.search { position: absolute; left: 12px; top: 14px; width: 216px; height: 40px; border-radius: 14px; background: var(--field); color: var(--muted-2); padding: 10px 14px; font-size: 13px; }
.cluster { position: absolute; display: grid; place-items: center; border-radius: 50%; background: var(--violet); color: #FFFFFF; font-weight: 700; font-size: 15px; box-shadow: 0 0 0 11px rgba(151, 64, 254, 0.22); }
.cluster.hi { outline: 3px solid var(--cream); }
.map .pin { position: absolute; width: 26px; height: 26px; border-radius: 50%; object-fit: cover; border: 2px solid var(--cream); }
.sheet { position: absolute; left: 0; right: 0; bottom: 0; height: 100px; padding: 24px 18px 0; border-radius: 24px 24px 0 0; background: var(--ink); }
.sheet b { display: block; font-size: 14px; }
.sheet span { color: var(--muted-2); }
.hang-img { position: absolute; left: 0; top: 0; width: 240px; height: 190px; object-fit: cover; }
.hang-body { position: absolute; left: 16px; right: 16px; top: 150px; }
.hang-body h4 { margin: 18px 0 4px; font-size: 17px; line-height: 1.3; }
.hang-body .meta { color: var(--muted-2); }
.going { position: relative; display: flex; align-items: center; margin-top: 18px; height: 70px; }
.going .avatars { display: flex; }
.going .avatars img + img { margin-left: -8px; }
.going .more { margin-left: 6px; color: var(--muted-2); font-weight: 700; }
.count { position: absolute; right: 4px; top: 0; text-align: center; }
.count b { display: block; font-family: var(--display); font-weight: 600; font-size: 40px; line-height: 1; }
.count span { font-weight: 600; color: var(--muted); }
.burst { position: absolute; right: -14px; top: -20px; width: 110px; height: 110px; border-radius: 50%; background: radial-gradient(rgba(151, 64, 254, 0.45), rgba(151, 64, 254, 0) 70%); pointer-events: none; }
.burst i { position: absolute; width: 7px; height: 7px; border-radius: 50%; }
.burst i:nth-child(1) { left: 6px; top: 20px; background: var(--orange); }
.burst i:nth-child(2) { right: 4px; top: 30px; background: var(--pink); }
.burst i:nth-child(3) { left: 10px; bottom: 16px; background: var(--green); }
.burst i:nth-child(4) { right: 10px; bottom: 10px; background: #FFD34D; }
.burst i:nth-child(5) { left: 50px; top: 0; background: var(--violet-soft); }
.full { margin-top: 6px; }
.going-btn { position: absolute; left: 16px; right: 16px; bottom: 22px; height: 46px; display: grid; place-items: center; border-radius: 14px; background: var(--violet); color: #FFFFFF; font-weight: 700; font-size: 14px; }
.chat-float { left: 350px; top: 580px; width: 200px; }

/* Stage 4: your own disposable */
.scene-camera { width: 568px; height: 600px; }
.scene-camera .phone { left: 0; top: 20px; }
.viewfinder { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.cam-top { position: absolute; left: 0; right: 0; top: 0; height: 70px; padding: 20px 18px; background: linear-gradient(rgba(0, 0, 0, 0.6), rgba(0, 0, 0, 0)); font-weight: 700; font-size: 14px; }
.cam-bottom { position: absolute; left: 0; right: 0; bottom: 0; height: 140px; background: rgba(12, 12, 18, 0.82); }
.shots { position: absolute; left: 50%; top: 16px; transform: translateX(-50%); white-space: nowrap; }
.shutter { position: absolute; left: 89px; top: 56px; width: 62px; height: 62px; border-radius: 50%; background: var(--cream); box-shadow: 0 0 0 4px #9A94AD; }
.pov { position: absolute; left: 18px; top: 78px; font-weight: 600; font-size: 11px; color: var(--muted); }
.flash { position: absolute; inset: 0; background: #FFFFFF; opacity: 0; pointer-events: none; }
.drop-label { position: absolute; left: 300px; top: 20px; font-family: var(--mono); font-weight: 700; font-size: 0.875rem; letter-spacing: 0.06em; color: var(--violet-text); }
.drop .pol { position: absolute; margin: 0; --w: 150px; }
.drop .pol:nth-child(1) { left: 290px; top: 64px; --r: -8deg; }
.drop .pol:nth-child(2) { left: 400px; top: 96px; --r: 4deg; }
.drop .pol:nth-child(3) { left: 310px; top: 290px; --r: 6deg; }
.drop .pol:nth-child(4) { left: 420px; top: 320px; --r: -5deg; }

/* Stage 5: the profile's photobook grid (the redesigned profile's 3-column contact sheet), then one
   photobook full screen, then comments popping in over it. */
.scene-feed { width: 568px; height: 640px; }
.scene-feed .p-grid { left: 0; top: 0; }
.scene-feed .p-book { left: 300px; top: 56px; }
.pb-head { position: absolute; left: 16px; top: 22px; display: flex; gap: 10px; align-items: center; }
.pb-head img { width: 40px; height: 40px; border-radius: 50%; object-fit: cover; box-shadow: 0 0 0 2px var(--violet); }
.pb-head b { display: block; font-size: 15px; }
.pb-head span { color: var(--muted-2); font-size: 11px; }
/* The redesigned profile's real tabs and bar shape (pulse-app components/profile/ProfileTabs-new.jsx):
   a rounded bar with a white pill behind the active tab. Icons and counts are dropped at this scale. */
.pb-tabs { position: absolute; left: 10px; right: 10px; top: 76px; display: grid; grid-template-columns: repeat(3, 1fr); gap: 4px; padding: 4px; border-radius: 999px; background: rgba(255,255,255,0.08); color: rgba(255,255,255,0.55); font-weight: 600; font-size: 10.5px; }
.pb-tabs span { height: 26px; display: grid; place-items: center; border-radius: 999px; white-space: nowrap; }
.pb-tabs .on { background: #fff; color: #111; font-weight: 700; }
.pb-window { position: absolute; left: 0; right: 0; top: 116px; bottom: 0; overflow: hidden; }
.pb-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 2px; }
.pb-grid img { display: block; width: 100%; aspect-ratio: 1; object-fit: cover; }
.pb-grid .opens { outline: 3px solid var(--cream); outline-offset: -3px; }
.book-img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.book-top { position: absolute; left: 0; right: 0; top: 0; height: 90px; padding: 20px 14px; display: flex; align-items: flex-start; gap: 8px; background: linear-gradient(rgba(0, 0, 0, 0.65), rgba(0, 0, 0, 0)); }
.book-top img { width: 30px; height: 30px; border-radius: 50%; object-fit: cover; box-shadow: 0 0 0 2px var(--violet); }
.book-top b { display: block; font-size: 13px; color: #FFFFFF; }
.book-top span { font-size: 11px; color: #E4DFF0; }
/* Not ".count": that is stage 3's counter, absolutely positioned top-right, and sharing the name
   pinned this pill into the screen's rounded corner where it was clipped. */
.book-top .book-count { flex: none; margin-left: auto; margin-top: 4px; white-space: nowrap; background: rgba(12, 12, 18, 0.85); color: var(--cream); }
.book-top div span { white-space: nowrap; }
.book-bottom { position: absolute; left: 0; right: 0; bottom: 0; height: 140px; padding: 0 14px 18px; display: flex; flex-direction: column; justify-content: flex-end; gap: 12px; background: linear-gradient(rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.75)); }
.book-dots { display: flex; justify-content: center; gap: 4px; }
.book-dots i { width: 6px; height: 6px; border-radius: 50%; background: #7D778F; }
.book-dots i:first-child { background: var(--cream); }
.book-pills { display: flex; gap: 8px; }
.pill.light { background: var(--cream); color: var(--ink); }
/* max-content: a pinned pill near the scene edge would otherwise shrink and let its text spill out. */
.comment { position: absolute; z-index: 2; width: max-content; display: flex; align-items: center; gap: 10px; padding: 10px 16px 10px 10px; border-radius: 999px; background: #FFFFFF; color: var(--ink); box-shadow: var(--shadow); font-size: 0.875rem; white-space: nowrap; }
/* flex: none stops a long comment squashing the avatar into an oval. */
.comment img { flex: none; width: 30px; height: 30px; border-radius: 50%; object-fit: cover; }
/* Over the open photobook, the way comments arrive in the app; inside the scene's 568px so they never reach the text. */
.comments .comment:nth-child(1) { left: 232px; top: 214px; }
.comments .comment:nth-child(2) { left: 252px; top: 296px; }
.comments .comment:nth-child(3) { left: 232px; top: 378px; }

/* ---------- Scene motion ----------
   Hidden "before" states apply only when app.js has set html.anim (JavaScript on, motion allowed).
   Without it every scene shows its finished state, which is also the reduced-motion experience. */
html.anim .stage:not(.in-view) .match-card,
html.anim .stage:not(.in-view) .match-card .bubble,
html.anim .stage:not(.in-view) .met,
html.anim .stage:not(.in-view) .plus-one,
html.anim .stage:not(.in-view) .p-hang,
html.anim .stage:not(.popped) .burst,
html.anim .stage:not(.popped) .full,
html.anim .stage:not(.popped) .chat-float,
html.anim .stage:not(.in-view) .comment { opacity: 0; }

html.anim .stage.in-view .swipe-card { animation: nudge 1.1s 0.3s ease-in-out both; }
html.anim .stage.in-view .actions .pill:last-child { animation: press 0.4s 0.75s ease-out both; }
html.anim .stage.in-view .match-card { animation: rise 0.6s 1.3s ease-out both; }
html.anim .stage.in-view .match-avatar { animation: pop 0.45s 1.6s both; }
html.anim .stage.in-view .match-card .b1 { animation: fade 0.4s 1.9s both; }
html.anim .stage.in-view .match-card .b2 { animation: fade 0.4s 2.6s both; }

html.anim .stage.in-view .scanline { animation: scan 1.1s 0.2s ease-in-out 2 both; }
html.anim .stage.in-view .met { animation: rise 0.5s 2.4s ease-out both; }
html.anim .stage:not(.in-view) .ring.after { box-shadow: 0 0 0 5px var(--paper), 0 0 0 9px var(--blue); }
html.anim .stage.in-view .ring.after { transition-delay: 2.6s; }
html.anim .stage.in-view .plus-one { animation: pop 0.45s 3s both; }
.ring.after { box-shadow: 0 0 0 5px var(--paper), 0 0 0 9px var(--violet); }

html.anim .stage.in-view .cluster { animation: pulse 1.4s ease-in-out 2; }
html.anim .stage.in-view .p-hang { animation: slide-in 0.6s 1.4s ease-out both; }
html.anim .stage.popped .burst { animation: burst 0.7s ease-out both; }
html.anim .stage.popped .count b { animation: pop 0.45s both; }
html.anim .stage.popped .full { animation: pop 0.4s 0.15s both; }
html.anim .stage.popped .chat-float { animation: rise 0.6s 0.6s ease-out both; }

html.anim .stage.in-view .flash { animation: flash 0.5s 0.8s ease-out both; }
html.anim .stage:not(.in-view) .drop .pol { opacity: 0; transform: translate(-60px, 40px) rotate(0deg); filter: blur(8px); }
html.anim .stage.in-view .drop .pol { transition: opacity 0.6s, transform 0.8s cubic-bezier(.2, .8, .2, 1), filter 1.4s; }
html.anim .stage.in-view .drop .pol:nth-child(1) { transition-delay: 1.6s; }
html.anim .stage.in-view .drop .pol:nth-child(2) { transition-delay: 1.8s; }
html.anim .stage.in-view .drop .pol:nth-child(3) { transition-delay: 2.0s; }
html.anim .stage.in-view .drop .pol:nth-child(4) { transition-delay: 2.2s; }

html.anim .stage.in-view .pb-grid { animation: pb-scroll 1.6s 0.3s ease-in-out both; }
html.anim .stage.in-view .pb-grid .opens { animation: tile-pulse 0.45s 1.9s ease-in-out 2; }
/* The open photobook starts as the outlined tile (10th, row 4: still in view after the scroll),
   scaled down over it, and grows to full screen. */
html.anim .stage:not(.in-view) .p-book { opacity: 0; transform: translate(-381px, -38px) scale(0.3); }
html.anim .stage.in-view .p-book { transition: transform 0.7s cubic-bezier(.2, .8, .2, 1) 2.5s, opacity 0.25s 2.5s; }
html.anim .stage.in-view .comments .comment:nth-child(1) { animation: pop 0.45s 3.4s both; }
html.anim .stage.in-view .comments .comment:nth-child(2) { animation: pop 0.45s 4s both; }
html.anim .stage.in-view .comments .comment:nth-child(3) { animation: pop 0.45s 4.6s both; }
@keyframes pb-scroll { from { transform: translateY(0); } to { transform: translateY(-120px); } }
@keyframes tile-pulse { 50% { transform: scale(1.08); } }

@keyframes nudge { 0% { transform: none; } 50% { transform: translateX(26px) rotate(5deg); } 100% { transform: none; } }
@keyframes press { 0% { transform: scale(1); } 50% { transform: scale(1.15); } 100% { transform: scale(1); } }
@keyframes rise { from { opacity: 0; transform: translateY(18px); } to { opacity: 1; transform: none; } }
@keyframes fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes pop { 0% { opacity: 0; transform: scale(0.8); } 70% { opacity: 1; transform: scale(1.06); } 100% { opacity: 1; transform: scale(1); } }
@keyframes scan { 0% { opacity: 1; transform: translateY(0); } 100% { opacity: 1; transform: translateY(172px); } }
@keyframes pulse { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.12); } }
@keyframes slide-in { from { opacity: 0; transform: translateX(40px); } to { opacity: 1; transform: none; } }
@keyframes burst { 0% { opacity: 0; transform: scale(0.3); } 60% { opacity: 1; transform: scale(1.15); } 100% { opacity: 1; transform: scale(1); } }
@keyframes flash { 0% { opacity: 0; } 20% { opacity: 0.85; } 100% { opacity: 0; } }

/* ---------- Organisers, closing, footer ---------- */
.organisers { background: var(--plum); color: var(--cream); }
.organisers .inner { max-width: 1120px; margin: 0 auto; padding: 96px 24px; display: flex; align-items: center; justify-content: space-between; gap: 48px; }
.organisers .kicker { color: var(--lilac); }
.organisers h2 { font-size: clamp(1.875rem, 1.2rem + 1.8vw, 2.75rem); }
.organisers p { margin-top: 14px; max-width: 700px; color: var(--muted); font-size: 1.125rem; }
.closing { padding: 40px 24px 110px; text-align: center; }
.closing h2 { font-size: clamp(1.875rem, 1.2rem + 1.8vw, 2.5rem); margin-bottom: 22px; }
.site-foot { background: var(--ink-deep); color: var(--muted-2); }
.site-foot .inner { max-width: 1120px; margin: 0 auto; padding: 40px 24px; display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 16px 32px; font-size: 0.875rem; }
.site-foot .brand { display: flex; align-items: baseline; gap: 14px; }
.site-foot .brand b { font-family: var(--display); font-weight: 600; font-size: 1.25rem; color: var(--cream); }
.site-foot nav { display: flex; gap: 24px; }

/* Plain pages: privacy, thanks, 404, form errors without JavaScript */
.plain { background: var(--paper); color: var(--ink); }
.plain-main { max-width: 720px; margin: 0 auto; padding: 64px 24px 96px; }
.plain-main h1 { font-size: clamp(2rem, 1.4rem + 2vw, 2.75rem); margin-bottom: 18px; }
.plain-main h2 { font-size: 1.5rem; margin: 36px 0 8px; }
.plain-main p, .plain-main li { color: var(--body-on-paper); font-size: 1.0625rem; }
.plain-main p + p { margin-top: 12px; }
.plain-main a { color: var(--violet-text); }
.plain-top { display: inline-block; margin-bottom: 40px; font-family: var(--display); font-weight: 600; font-size: 1.5rem; color: var(--ink); text-decoration: none; }

/* ---------- Responsive ---------- */
@media (max-width: 1299px) { .col-b, .col-c { display: none; } }
@media (max-width: 1100px) {
  .stage { grid-template-columns: 1fr; gap: 40px; text-align: center; }
  .stage.flip .stage-text { order: 0; }
  .stage-text { max-width: 640px; margin: 0 auto; }
}
@media (max-width: 999px) {
  /* The side columns become two rows across the top, drifting sideways in opposite directions. */
  /* place-items must be reset too: Chrome now applies it to block children, which would shrink the
     photo band (all absolutely positioned children) to zero width. */
  .hero { display: block; min-height: 0; place-items: normal; }
  .hero::before, .hero::after { display: none; }
  .photo-wall { position: relative; width: 100%; height: 222px; margin-top: 70px; overflow: hidden; }
  .photo-wall::after { content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 70px; background: linear-gradient(rgba(22, 22, 31, 0), var(--ink)); }
  .col { flex-direction: row; left: 0; right: auto; top: 0; }
  .col-b, .col-d { display: none; }
  .col-c { display: flex; top: 110px; }
  .col .pol { --w: 82px !important; margin: 0 14px 0 0; padding: 6px 6px 20px; }
  .col .stamp { font-size: 8px; right: 11px; bottom: 26px; }
  .col.up, .col.down { animation-duration: 48s; }
  .col-a { animation-name: drift-right !important; }
  .col-c { animation-name: drift-left !important; }
  .hero-content { margin: 0 auto; padding: 8px 0 72px; }
  .wordmark { top: 22px; font-size: 1.375rem; }
  .organisers .inner { flex-direction: column; align-items: flex-start; }
}
@keyframes drift-left { from { transform: translateX(0); } to { transform: translateX(-50%); } }
@keyframes drift-right { from { transform: translateX(-50%); } to { transform: translateX(0); } }
@media (max-width: 860px) { .scene { zoom: 0.62; } .stage { padding-top: 56px; } }
@media (max-width: 560px) {
  /* Stage 1 is the widest scene: tuck the match cards in under the phones so it fits a phone screen. */
  .scene-match { zoom: 0.42 !important; height: 700px; }
  .match-dating { left: 20px; top: 500px; }
  .match-friends { right: 20px; top: 500px; }
  .join .row { flex-direction: column; }
  .join .btn { width: 100%; }
  .lede { font-size: 1rem; }
  .scene { zoom: 0.5; }
}

/* ---------- Reduced motion: nothing drifts, nothing animates ---------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .col { animation: none !important; }
  *, *::before, *::after { animation-duration: 0.001ms !important; animation-iteration-count: 1 !important; transition-duration: 0.001ms !important; }
}
