/* ===========================================================================
   RACK — waitlist
   Design tokens are lifted verbatim from the iOS app's Theme.swift so the web
   and the app read as one product: warm cream canvas, bold grotesque display
   type, mono eyebrows, candy-pink hero accent, very round everything.
   Light only. Hero fills the first viewport with the form above the fold;
   below it the page scrolls into the screenshot strip and a last-call CTA.
   ========================================================================= */

/* ── Fonts (the app's bundled families) ─────────────────────────────────── */
@font-face {
  font-family: "Bricolage Grotesque";
  src: url("assets/fonts/BricolageGrotesque-ExtraBold.ttf") format("truetype");
  font-weight: 800; font-display: swap;
}
@font-face {
  font-family: "Bricolage Grotesque";
  src: url("assets/fonts/BricolageGrotesque-Bold.ttf") format("truetype");
  font-weight: 700; font-display: swap;
}
@font-face {
  font-family: "Instrument Sans";
  src: url("assets/fonts/InstrumentSans-Regular.ttf") format("truetype");
  font-weight: 400; font-display: swap;
}
@font-face {
  font-family: "Instrument Sans";
  src: url("assets/fonts/InstrumentSans-Medium.ttf") format("truetype");
  font-weight: 500; font-display: swap;
}
@font-face {
  font-family: "Instrument Sans";
  src: url("assets/fonts/InstrumentSans-SemiBold.ttf") format("truetype");
  font-weight: 600; font-display: swap;
}
@font-face {
  font-family: "IBM Plex Mono";
  src: url("assets/fonts/IBMPlexMono-Medium.ttf") format("truetype");
  font-weight: 500; font-display: swap;
}

/* ── Tokens ─────────────────────────────────────────────────────────────── */
:root {
  /* Palette — Theme.swift */
  --bg:            #F3EEE3;
  --surface:       #ECE7DA;
  --surface-muted: #DFD8C7;
  --ink:           #1A1714;
  --ink-secondary: #8A857B;
  --ink-fixed:     #1A1714;   /* text on candy fills */
  --line:          rgba(26, 23, 20, 0.10);

  /* Candy set */
  --accent:     #E79FC2;   /* the hero pink */
  --lime:       #C6DE6E;
  --butter:     #EBD46A;
  --periwinkle: #AEC1E8;
  --coral:      #E8654E;

  /* Radii */
  --r-l: 26px;
  --r-pill: 999px;

  /* Spacing scale */
  --s-xs: 4px;  --s-s: 8px;   --s-m: 12px;  --s-l: 16px;
  --s-xl: 20px; --s-xxl: 28px; --s-xxxl: 40px;

  --ease-spring: cubic-bezier(0.22, 1, 0.36, 1);

  /* No dark mode — the cream canvas IS the brand, so the page ignores the
     visitor's OS setting. This also stops the UA darkening the email input. */
  color-scheme: light;
}

/* ── Reset / shell ──────────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; }

/* An author `display` rule outranks the UA's `[hidden] { display: none }`, so
   .done/.waitlist would still occupy layout while "hidden". Pin it shut. */
[hidden] { display: none !important; }

html {
  scroll-behavior: smooth;      /* the scroll-cue + bottom CTA jump the page */
}
html, body {
  margin: 0;
  overflow-x: hidden;           /* tilted cards may poke past the edge */
}

body {
  background: var(--bg);
  color: var(--ink);
  font-family: "Instrument Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

/* ── Graph-paper dot grid (the app's splash texture) ────────────────────── */
.dot-grid {
  position: fixed;
  inset: 0;
  background-image: radial-gradient(circle, var(--line) 1.1px, transparent 1.2px);
  background-size: 26px 26px;   /* DotGrid spacing in the app */
  pointer-events: none;
  z-index: 0;
}

/* ── Cutout collage ─────────────────────────────────────────────────────── */
.collage { position: fixed; inset: 0; pointer-events: none; z-index: 1; }

.cutout {
  position: absolute;
  opacity: 0.9;
  filter: drop-shadow(0 14px 22px rgba(26, 23, 20, 0.16));
  animation: sway 6s ease-in-out infinite;
}

/* Pieces bleed off the edges — a closet mid-styling, not a tidy ring. The
   copy now sits dead centre, so everything decorative hugs the margins. */
.c1 { width: 124px; left: -34px;  top: 11%;   transform: rotate(-13deg); animation-delay: 0s;  }
.c2 { width: 78px;  left: 13%;    top: -18px; transform: rotate(-26deg); animation-delay: .5s; }
.c3 { width: 136px; right: -30px; top: 9%;    transform: rotate(11deg);  animation-delay: 1s;  }
.c4 { width: 62px;  left: 3%;     bottom: 6%; transform: rotate(17deg);  animation-delay: 1.5s;}
.c5 { width: 104px; right: 5%;    bottom: -18px; transform: rotate(-8deg); animation-delay: 2s;}
.c6 { width: 68px;  right: 21%;   bottom: -12px; transform: rotate(-32deg); animation-delay: 2.5s;}

@keyframes sway {
  0%, 100% { rotate: -1.6deg; }
  50%      { rotate:  1.6deg; }
}

/* ── Sticker confetti (StarBurst / CrossShape from Components.swift) ────── */
/* Kept to the outer margins — never over running text. */
.stickers { position: fixed; inset: 0; pointer-events: none; z-index: 2; }

.sticker { position: absolute; animation: pulse 3.4s ease-in-out infinite; }
.s1 { width: 24px; fill: var(--accent);     left: 30%;  top: 16%;    animation-delay: 0s;  }
.s2 { width: 32px; fill: var(--butter);     left: 11%;  bottom: 22%; animation-delay: .8s; }
.s3 { width: 20px; fill: var(--periwinkle); right: 7%;  top: 40%;    animation-delay: 1.6s;}
.s4 { width: 22px; fill: var(--lime);       right: 13%; bottom: 26%; animation-delay: 2.4s;}

@keyframes pulse {
  0%, 100% { transform: scale(0.94) rotate(-6deg); opacity: .85; }
  50%      { transform: scale(1.08) rotate(6deg);  opacity: 1;   }
}

/* ── Stage — headline + screenshot strip fill the first viewport ────────── */
.stage {
  position: relative;
  z-index: 3;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: clamp(16px, 4vw, 40px) 0 72px;   /* bottom: room for the scroll cue */
}

.pitch {
  width: min(640px, 100%);      /* wide enough that the h1 breaks only at its <br> */
  padding: 0 var(--s-l);        /* .stage is full-bleed for the strip */
  text-align: center;
}

.wordmark {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  margin-bottom: var(--s-m);
}
.wordmark span {
  font-family: "Bricolage Grotesque", sans-serif;
  font-weight: 800;
  font-size: 20px;
  letter-spacing: -0.9px;       /* the app nests the letters at -5pt */
  color: var(--ink);
}
.wordmark-star { width: 16px; fill: var(--accent); }

.eyebrow {
  margin: 0 0 var(--s-m);
  font-family: "IBM Plex Mono", ui-monospace, monospace;
  font-weight: 500;
  font-size: 9.5px;
  letter-spacing: 1.6px;        /* Theme.eyebrowTracking */
  /* Cased in the markup, NOT via text-transform — uppercasing would turn
     "iOS" into "IOS". */
  color: var(--ink-secondary);
}

.headline {
  margin: 0 0 var(--s-xl);
  font-family: "Bricolage Grotesque", sans-serif;
  font-weight: 800;
  font-size: clamp(26px, 3.2vw, 38px);
  line-height: 1.06;
  letter-spacing: -1.2px;
  color: var(--ink);
}
/* The concrete promise under the headline — Instrument, quiet, two lines max. */
.subhead {
  margin: 0 auto var(--s-xl);
  max-width: 400px;
  font-size: 14.5px;
  line-height: 1.5;
  color: var(--ink-secondary);
}

.headline-alt { position: relative; }
/* A pink marker sweep under the second line — the app's highlight gesture.
   Kept low and thin so it reads as a highlighter, not a strikethrough. */
.headline-alt::after {
  content: "";
  position: absolute;
  left: -2px; right: -2px; bottom: 0.04em;
  height: 0.17em;
  background: var(--accent);
  opacity: 0.5;
  border-radius: var(--r-pill);
  z-index: -1;
}

/* ── Waitlist form ──────────────────────────────────────────────────────── */
.waitlist { max-width: 430px; margin-inline: auto; }

.field {
  display: flex;
  gap: 6px;
  padding: 5px;
  background: var(--surface);
  border: 1.5px solid var(--line);
  border-radius: var(--r-pill);
  transition: border-color .2s ease, box-shadow .2s ease;
}
.field:focus-within {
  border-color: var(--accent);
  box-shadow: 0 0 0 4px rgba(231, 159, 194, 0.22);
}
.field.shake { animation: shake .4s ease; }

@keyframes shake {
  0%, 100% { transform: translateX(0); }
  25%      { transform: translateX(-7px); }
  75%      { transform: translateX(7px); }
}

#email {
  flex: 1;
  min-width: 0;
  border: 0;
  outline: 0;
  background: transparent;
  padding: 0 var(--s-m);
  font-family: inherit;
  font-size: 16px;              /* stays 16px — any smaller and iOS zooms on focus */
  color: var(--ink);
  text-align: left;
}
#email::placeholder { color: var(--ink-secondary); }

/* PrimaryButton: pink capsule, 54px tall, fixed dark text, press-scale. */
.cta {
  flex: none;
  height: 42px;
  padding: 0 var(--s-xl);
  border: 0;
  border-radius: var(--r-pill);
  background: var(--accent);
  color: var(--ink-fixed);
  font-family: inherit;
  font-weight: 600;
  font-size: 14px;
  white-space: nowrap;
  cursor: pointer;
  transition: transform .18s var(--ease-spring), filter .18s ease;
}
.cta:hover  { filter: brightness(1.04); }
.cta:active { transform: scale(0.96); }   /* PressScaleStyle */
.cta:disabled { opacity: .55; cursor: progress; }

.form-note {
  margin: var(--s-m) 0 0;
  font-family: "IBM Plex Mono", ui-monospace, monospace;
  font-size: 9.5px;
  letter-spacing: .3px;
  color: var(--ink-secondary);
}
.form-note.error { color: var(--coral); }

/* ── Scroll cue — pinned to the hero's bottom edge ───────────────────────── */
.scroll-cue {
  position: absolute;
  left: 50%;
  bottom: max(22px, env(safe-area-inset-bottom));
  translate: -50% 0;
  font-family: "IBM Plex Mono", ui-monospace, monospace;
  font-size: 9.5px;
  letter-spacing: 1.6px;
  color: var(--ink-secondary);
  text-decoration: none;
  white-space: nowrap;
  animation: bob 2.6s ease-in-out infinite;
}
.scroll-cue:hover { color: var(--ink); }

@keyframes bob {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(5px); }
}

/* ── Taped-polaroid screenshot strip ────────────────────────────────────── */
/* Phone-first: a snap strip that swipes like a photo roll. The inline padding
   trick centres the row on canvases wide enough to fit all four cards. */
.shots {
  width: 100%;
  display: flex;
  gap: var(--s-xl);
  overflow-x: auto;
  padding: 26px max(20px, calc(50vw - 540px)) 30px;
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}
.shots::-webkit-scrollbar { display: none; }

.shot {
  flex: none;
  width: min(64vw, 240px);
  margin: 0;
  padding: 9px 9px 12px;
  background: var(--surface);
  border: 1.5px solid var(--line);
  border-radius: 20px;
  box-shadow: 0 16px 30px rgba(26, 23, 20, 0.10);
  scroll-snap-align: center;
  position: relative;
  transform: rotate(-1.7deg);
  align-self: flex-start;       /* cards are different heights — hang from the top */
}
.shot:nth-child(even) { transform: rotate(1.5deg); }

/* Washi-tape strip over the top edge, alternating candy colours. */
.shot::before {
  content: "";
  position: absolute;
  top: -11px;
  left: 50%;
  width: 72px;
  height: 22px;
  translate: -50% 0;
  rotate: -4deg;
  border-radius: 3px;
  background: rgba(231, 159, 194, 0.55);   /* accent */
  box-shadow: 0 1px 3px rgba(26, 23, 20, 0.08);
}
.shot:nth-child(2)::before { background: rgba(198, 222, 110, 0.6); rotate: 3deg; }   /* lime */
.shot:nth-child(3)::before { background: rgba(235, 212, 106, 0.6); rotate: -3deg; }  /* butter */
.shot:nth-child(4)::before { background: rgba(174, 193, 232, 0.6); rotate: 4deg; }   /* periwinkle */

.shot img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 13px;
  border: 1px solid var(--line);
}

.shot figcaption {
  margin-top: 10px;
  font-family: "IBM Plex Mono", ui-monospace, monospace;
  font-size: 9.5px;
  letter-spacing: .4px;
  line-height: 1.5;
  color: var(--ink-secondary);
}

/* ── Join — the ask, after the proof ────────────────────────────────────── */
.join {
  position: relative;
  z-index: 3;
  padding: var(--s-xxxl) var(--s-xl) 64px;
  text-align: center;
}
.join-star {
  width: 26px;
  fill: var(--accent);
  animation: pulse 3s ease-in-out infinite;
  margin-bottom: var(--s-s);
}

/* ── Success state ──────────────────────────────────────────────────────── */
.done {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-l);
  flex-wrap: wrap;
  max-width: 540px;
  margin-inline: auto;
  padding: var(--s-xl);
  background: var(--surface);
  border-radius: var(--r-l);
  text-align: left;
}
/* The entrance lives on a class the JS adds AFTER unhiding. Putting it on
   .done itself with `both` fill left the card stuck at opacity 0 — the
   animation can't start while the element is display:none, but the backwards
   fill still applied, so the success state was invisible. */
.done.is-in { animation: rise .45s var(--ease-spring); }

@keyframes rise {
  from { opacity: 0; transform: translateY(14px) scale(.97); }
  to   { opacity: 1; transform: none; }
}

.done-star { width: 40px; flex: none; fill: var(--accent); animation: pulse 3s ease-in-out infinite; }
.done-copy { flex: 1; min-width: 180px; }
.done-title {
  margin: 0 0 2px;
  font-family: "Bricolage Grotesque", sans-serif;
  font-weight: 700;
  font-size: 20px;
  color: var(--ink);
}
/* Emails have no spaces, so a long one would otherwise push the card wider
   than the phone. */
.done-sub {
  margin: 0;
  font-size: 14px;
  color: var(--ink-secondary);
  overflow-wrap: anywhere;
}
.done-reset {
  border: 0;
  background: transparent;
  padding: 0;
  font-family: "IBM Plex Mono", ui-monospace, monospace;
  font-size: 11px;
  letter-spacing: .4px;
  color: var(--ink-secondary);
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
}
.done-reset:hover { color: var(--ink); }

/* ── Footer — in flow now that the page scrolls ─────────────────────────── */
.footer {
  position: relative;
  z-index: 3;
  display: flex;
  justify-content: center;
  gap: var(--s-s);
  padding: var(--s-l) var(--s-xl);
  padding-bottom: max(var(--s-l), env(safe-area-inset-bottom));
  font-family: "IBM Plex Mono", ui-monospace, monospace;
  font-size: 10px;
  letter-spacing: 1px;
  text-transform: uppercase;
  color: var(--ink-secondary);
}
.footer-sep { opacity: .5; }

/* ═══ Responsive ═════════════════════════════════════════════════════════ */

@media (max-width: 1024px) {
  .c1 { width: 104px; }
  .c3 { width: 112px; }
  .c5 { width: 86px; }
  .s1 { left: 22%; }
}

@media (max-width: 760px) {
  /* 6.4vw: "Never stare at a full closet" must clear both hero cutouts. */
  .headline { font-size: clamp(22px, 6.4vw, 30px); letter-spacing: -0.9px; }
  .subhead  { font-size: 13.5px; max-width: 330px; }

  /* Stack the field so the CTA keeps its full width on narrow screens. */
  .field {
    flex-direction: column;
    gap: 6px;
    padding: 8px;
    border-radius: var(--r-l);
  }
  #email { padding: 12px var(--s-l); text-align: center; }
  .cta { width: 100%; }

  /* Success card: a centred vertical stack instead of the desktop row. Wrapped
     onto one line, the star, the copy and the reset link read as a single dense
     block — and the reset link was an 11px underline, well under a thumb. */
  .done {
    flex-direction: column;
    gap: var(--s-m);
    padding: var(--s-xl) var(--s-l);
    text-align: center;
  }
  .done-star { width: 34px; }
  .done-copy { min-width: 0; }

  /* A real pill with a 44px box — the iOS minimum tap target. */
  .done-reset {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 44px;
    padding: 0 var(--s-xl);
    border: 1px solid var(--line);
    border-radius: var(--r-pill);
    text-decoration: none;
  }
  .done-reset:active { transform: scale(0.96); }   /* PressScaleStyle */

  /* Fewer, smaller cutouts so the small canvas stays readable — and none of
     the confetti may land on the headline. */
  .c2, .c4, .c5, .c6 { display: none; }
  .c1 { width: 68px; left: -30px; top: 1%; }
  .c3 { width: 68px; right: -34px; top: 0.5%; }
  .s1, .s3 { display: none; }
  .s2 { left: 6%;  bottom: 16%; }
  .s4 { right: 6%; bottom: 20%; }

  .footer { font-size: 9px; }
}

@media (max-height: 480px) {
  .wordmark { margin-bottom: var(--s-s); }
  .headline { font-size: clamp(26px, 6vw, 38px); margin-bottom: var(--s-l); }
  .eyebrow  { margin-bottom: var(--s-s); }
  .footer   { display: none; }

  /* The stacked card is taller than the form it replaces, and the page never
     scrolls — claw the height back rather than let it clip. */
  .done      { padding: var(--s-l); gap: var(--s-s); }
  .done-star { width: 26px; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation: none !important;
    transition: none !important;
  }
}
