/* ==========================================================================
   WishPop — Waitlist hero
   ========================================================================== */

@font-face {
  font-family: 'IBM Plex Sans';
  src: url('../fonts/IBMPlexSans-VariableFont_wdth,wght.ttf') format('truetype-variations');
  font-weight: 100 700;
  font-style: normal;
  font-display: swap;
}

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

html,
body {
  height: 100%;
}

body {
  font-family: 'IBM Plex Sans', -apple-system, "Helvetica Neue", Arial, sans-serif;
  background: #F2F2F2;
  color: #111111;
  -webkit-font-smoothing: antialiased;
  font-synthesis: none;
}

.page {
  position: relative;
  height: 100vh;
  height: 100svh;
  height: 100dvh; /* tracks mobile browser chrome (URL bar) collapsing */
  overflow: hidden;
}

/* --------------------------------------------------------------------------
   1. Navigation
   -------------------------------------------------------------------------- */

.nav {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 40px 56px 0;
  position: relative;
  z-index: 20;
}

.logo {
  font-size: 26px;
  font-weight: 600;
  color: #111111;
  letter-spacing: -0.01em;
}

.btn {
  font-family: inherit;
  background: #111111;
  color: #FFFFFF;
  font-size: 16px;
  font-weight: 500;
  padding: 14px 24px;
  border-radius: 14px;
  border: none;
  cursor: pointer;
  transition: all 150ms ease;
}

.btn:hover {
  background: #000000;
  transform: translateY(-1px);
}

/* --------------------------------------------------------------------------
   2. Headline block
   -------------------------------------------------------------------------- */

.hero {
  max-width: 1000px;
  margin: 140px auto 0;
  text-align: center;
  position: relative;
  z-index: 10;
  padding: 0 24px;
}

h1 {
  font-size: 96px;
  font-weight: 700;
  line-height: 1.05;
  letter-spacing: -0.03em;
  color: #111111;
}

h1 .gray {
  color: #ADADAD;
}

/* typewriter caret — sized in em so it scales with the headline */
.caret {
  display: inline-block;
  width: 0.05em;
  height: 0.78em;
  margin-left: 0.06em;
  background: #ADADAD;
  transform: translateY(0.08em);
  animation: blink 1s steps(2, start) infinite;
}

@keyframes blink {
  50% { opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .caret {
    display: none;
  }
}

.sub {
  margin: 28px auto 0;
  max-width: 620px;
  font-size: 22px;
  font-weight: 400;
  color: #9E9E9E;
  line-height: 1.5;
  text-align: center;
}

/* --------------------------------------------------------------------------
   3. Waitlist form
   -------------------------------------------------------------------------- */

.form {
  margin-top: 40px;
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 16px;
}

.form input {
  font-family: inherit;
  width: 480px;
  height: 60px;
  background: #FFFFFF;
  border: none;
  border-radius: 14px;
  padding: 0 24px;
  font-size: 17px;
  color: #111111;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04);
}

.form input::placeholder {
  color: #B8B8B8;
  font-size: 17px;
}

.form input:focus {
  outline: 2px solid #111111;
  outline-offset: 0;
}

.form .submit {
  font-size: 17px;
  height: 60px;
  padding: 0 32px;
}

.success {
  font-size: 17px;
  font-weight: 500;
  color: #111111;
  text-align: center;
}

/* --- waitlist success modal --- */

.modal {
  position: fixed;
  inset: 0;
  z-index: 50;
  display: flex;
  align-items: center;
  justify-content: center;
}

.modal[hidden] {
  display: none;
}

.modal-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(242, 242, 242, 0.45);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  animation: backdrop-in 220ms ease both;
}

.modal-card {
  position: relative;
  background: #FFFFFF;
  border-radius: 24px;
  padding: 32px;
  width: min(520px, calc(100vw - 48px));
  box-shadow: 0 24px 80px rgba(17, 17, 17, 0.18);
  animation: card-pop 260ms cubic-bezier(0.25, 1, 0.4, 1) both;
}

.modal-icon {
  width: 64px;
  height: auto;
  display: block;
}

.modal-card h2 {
  margin-top: 20px;
  font-size: 26px;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: #111111;
}

.modal-card p {
  margin-top: 10px;
  font-size: 17px;
  line-height: 1.55;
  color: #6B6B6B;
}

.modal-ok {
  width: 100%;
  margin-top: 24px;
  height: 56px;
  font-size: 17px;
}

@keyframes backdrop-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}

@keyframes card-pop {
  from { opacity: 0; transform: scale(0.94) translateY(10px); }
  to   { opacity: 1; transform: none; }
}

@keyframes sheet-up {
  from { opacity: 1; transform: translateY(100%); }
  to   { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  .modal-backdrop,
  .modal-card {
    animation: none;
  }
}

/* confetti canvas rides above everything, purely decorative */
.confetti {
  position: fixed;
  inset: 0;
  z-index: 100;
  pointer-events: none;
  transition: opacity 900ms ease;
}

@keyframes shake {
  10%, 90% { transform: translateX(-2px); }
  20%, 80% { transform: translateX(4px); }
  30%, 70% { transform: translateX(-6px); }
  40%, 60% { transform: translateX(6px); }
  50%      { transform: translateX(-4px); }
}

.shake {
  animation: shake 400ms ease;
}

/* --------------------------------------------------------------------------
   4. Folder stack illustration
   -------------------------------------------------------------------------- */

.stage {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  display: flex;
  justify-content: center;
  align-items: flex-end;
  transform-origin: 50% 100%;
  z-index: 1;
}

.hero-folders {
  display: block;
  width: 1230px;
  height: auto;
  flex: 0 0 auto;
}

/* --- opening animation: deck stacked behind the blue folder fans out ---
   Final state is transform:none — the untouched composition. Custom props
   define where each piece starts (gathered center) and its stagger. */

.fan {
  transform-box: fill-box;
  transform-origin: 50% 60%;
  /* fill-mode backwards (not both): the animation ends at transform:none,
     so nothing changes visually, but transform stays free for :hover. */
  animation: fan-out 950ms cubic-bezier(0.22, 0.85, 0.3, 1) backwards;
  animation-delay: var(--d, 250ms);
  will-change: transform;
}

@keyframes fan-out {
  from {
    transform: translate(var(--sx, 0px), var(--sy, 0px))
               rotate(var(--sr, 0deg))
               scale(0.96);
  }
  to {
    transform: none;
  }
}

.fan-blue    { --sx: 0px;    --sy: 30px;  --sr: 0deg;   --d: 250ms; }
.fan-wedding { --sx: 375px;  --sy: -60px; --sr: 8deg;   --d: 340ms; }
.fan-purple  { --sx: -300px; --sy: 50px;  --sr: -10deg; --d: 370ms; }
.fan-yellow  { --sx: 130px;  --sy: 40px;  --sr: 10deg;  --d: 400ms; }
.fan-red     { --sx: -355px; --sy: -90px; --sr: -14deg; --d: 430ms; }
.fan-green   { --sx: 300px;  --sy: -70px; --sr: 14deg;  --d: 460ms; }

/* --- hover: the card slides up out of its folder pocket --- */

@media (hover: hover) {
  .card-lift {
    transform-box: fill-box;
    transition: transform 260ms cubic-bezier(0.33, 0.8, 0.4, 1);
  }

  .fan:hover .card-lift {
    transform: translateY(-16px);
  }

  .fan-blue:hover .card-lift {
    transform: translateY(-22px);
  }

  /* deeper pocket + partially covered by the wedding card — needs more travel */
  .fan-green:hover .card-lift {
    transform: translateY(-30px);
  }

  /* standalone card — no pocket, the whole card floats up gently */
  .fan-wedding {
    transition: transform 260ms cubic-bezier(0.33, 0.8, 0.4, 1);
  }

  .fan-wedding:hover {
    transform: translateY(-10px);
  }
}

/* applied when the SVG is re-injected after a breakpoint swap */
.hero-folders.no-anim .fan {
  animation: none;
}

@media (prefers-reduced-motion: reduce) {
  .fan {
    animation: none;
  }

  .card-lift,
  .fan-wedding {
    transition: none;
  }
}

/* --------------------------------------------------------------------------
   Responsive
   -------------------------------------------------------------------------- */

@media (min-width: 1280px) and (max-height: 1010px) {
  .stage { transform: scale(0.75); }
}

@media (min-width: 768px) and (max-width: 1279px) {
  h1 { font-size: 64px; }
  .sub { font-size: 19px; max-width: 520px; }
  .form input { width: 360px; }
  .stage { transform: scale(0.75); }
}

@media (max-width: 767px) {
  .nav { padding: 20px 24px; }
  /* sized so "One surprise." / "Zero duplicate gifts." each hold one
     line — a 2-line headline leaves the illustration real room */
  h1 { font-size: clamp(26px, 8vw, 40px); }
  .sub { font-size: 16px; margin-top: 16px; }
  .hero { margin-top: clamp(12px, 4svh, 48px); }
  .form {
    flex-direction: column;
    gap: 10px;
    padding: 0 24px;
    margin-top: 20px;
  }
  .form input { width: 100%; height: 56px; }
  .form .submit { width: 100%; height: 56px; }

  /* modal becomes a bottom sheet on phones */
  .modal { align-items: flex-end; }
  .modal-card {
    width: 100%;
    border-radius: 24px 24px 0 0;
    padding: 28px 24px calc(28px + env(safe-area-inset-bottom));
    animation-name: sheet-up;
  }

  /* content and illustration each own their vertical space: the page
     becomes a flex column and the stage gets only what's left over,
     so the form can never sit on top of the folders on short screens */
  .page {
    display: flex;
    flex-direction: column;
  }
  .stage {
    position: static;
    flex: 1 1 auto;
    min-height: 0;
    margin-top: 12px;
    display: flex;
    align-items: flex-end;
    justify-content: center;
  }
  /* full-bleed width at the artwork's natural ratio; when the leftover
     space is shorter, max-height clamps the box and the layers' slice
     alignment crops the artwork's bottom — folders run off the screen
     edge (the design intent) instead of shrinking */
  .hero-folders {
    position: relative;
    width: 100%;
    height: auto;
    aspect-ratio: 376 / 256;
    max-height: 100%;
  }

  .fan-layer {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    animation: fan-out 950ms cubic-bezier(0.22, 0.85, 0.3, 1) backwards;
    animation-delay: var(--d, 250ms);
    will-change: transform;
  }

  /* layers animate as composited elements; the inner groups stay still */
  .fan {
    animation: none;
    will-change: auto;
  }

  .hero-folders.no-anim .fan-layer {
    animation: none;
  }

  /* dedicated mobile composition rendered at native size — no CSS
     downscaling of the big desktop artwork (that caused the jank) */
  .stage { transform: none; }

  /* fan-out start offsets rescaled to the 376-unit mobile canvas */
  .fan-blue    { --sx: 0px;    --sy: 10px;  }
  .fan-wedding { --sx: 85px;   --sy: -20px; }
  .fan-purple  { --sx: -95px;  --sy: 15px;  }
  .fan-yellow  { --sx: 70px;   --sy: 15px;  }
  .fan-red     { --sx: -100px; --sy: -28px; }
  .fan-green   { --sx: 95px;   --sy: -25px; }

  .fan:hover .card-lift { transform: translateY(-6px); }
  .fan-blue:hover .card-lift { transform: translateY(-8px); }
  .fan-green:hover .card-lift { transform: translateY(-10px); }
  .fan-wedding:hover { transform: translateY(-4px); }
}


/* short phones (SE, minis): tighten the vertical rhythm so the folder
   illustration keeps real presence below the form. Kept last in the
   file so it wins the cascade over the base mobile block above. */
@media (max-width: 767px) and (max-height: 620px) {
  .nav { padding: 14px 24px; }
  .hero { margin-top: 8px; }
  h1 { font-size: clamp(24px, 7.6vw, 34px); }
  .sub { font-size: 15px; margin-top: 12px; }
  .form { margin-top: 16px; }
  .form input,
  .form .submit { height: 50px; }
  .stage { margin-top: 8px; }
}

/* last so it beats the mobile block that assigns the layer animation */
@media (prefers-reduced-motion: reduce) {
  .fan-layer {
    animation: none;
  }
}
