/* ============================================================
   DAWNAVO launch page
   Violet ground, one centred wordmark, light that follows you.
   ============================================================ */

:root {
  --violet: #8838C6;   /* the brand colour, what the light resolves to */
  --dark:   #150724;   /* what the page rests in */
  --paper:  #F7F7F4;

  --ease: cubic-bezier(0.16, 1, 0.3, 1);
}

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

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

body {
  margin: 0;
  min-height: 100svh;
  overflow-x: hidden;
  background: var(--dark);
  color: var(--paper);
  font-family: "Inter", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  text-transform: lowercase;
  -webkit-font-smoothing: antialiased;
}

::selection { background: var(--paper); color: var(--violet); }

.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ---------- light ----------------------------------------- */

/* The page rests in near-black violet. This bloom is the only thing that
   brings it up to the brand colour, and it does so around the wordmark,
   so the centre reads as full violet and the edges fall away into the dark.
   On load it settles from oversized and dim, which lands like a lens
   pulling focus at the same moment the wordmark sharpens out of its blur. */
.bloom {
  position: fixed;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  /* Pulled back from near-opaque now that the photograph sits above it. At
     full strength the bloom simply drowned her: screen blending can only add
     light, and there was no headroom left to add any. */
  background: radial-gradient(58vw 64vh at 50% 44%,
    rgba(136, 56, 198, .55) 0%,
    rgba(136, 56, 198, .28) 38%,
    rgba(136, 56, 198, .10) 63%,
    transparent 79%);
  animation: focus-in 2.8s var(--ease) both;
}

/* The photograph is screened onto the page rather than placed on it. Screen
   blending keeps whichever pixel is lighter, so every black pixel in the file
   disappears completely and only the light that actually fell on her survives.
   The file is prepared for exactly that: flattened to a violet duotone with the
   studio floor masked back into the dark. It is also why a 1800px full-bleed
   background costs 14 KB, since almost the entire image is pure black. */
.hero {
  position: fixed;
  inset: -4%;                 /* slack for the parallax to move into */
  z-index: 2;
  pointer-events: none;
  background: url("/assets/img/hero.webp") no-repeat 50% 40% / cover;
  mix-blend-mode: screen;
  /* Holds the photograph to the upper middle, where the wordmark is. Without
     it her lit shin ran straight across the email field and cost the form its
     contrast, and the studio floor stayed as a pale panel in the corner. */
  -webkit-mask-image: radial-gradient(62% 56% at 50% 34%, #000 26%, transparent 78%);
          mask-image: radial-gradient(62% 56% at 50% 34%, #000 26%, transparent 78%);
  animation: hero-in 3.4s var(--ease) .15s both;
  will-change: transform;
}

@media (max-width: 48rem) {
  .hero { background-image: url("/assets/img/hero-mobile.webp"); }
}

/* Follows the pointer, in the brand colour rather than white: wherever you
   look, the violet resolves. Screen blending means it only ever adds light. */
.glow {
  position: fixed;
  top: 0; left: 0;
  width: 40rem; height: 40rem;
  z-index: 3;
  pointer-events: none;
  opacity: 0;
  transform: translate(-50%, -50%);
  background: radial-gradient(circle,
    rgba(136, 56, 198, .55) 0%,
    rgba(136, 56, 198, .18) 40%,
    transparent 70%);
  mix-blend-mode: screen;
  transition: opacity 700ms ease;
}

.glow.is-on { opacity: 1; }

/* ---------- stage ----------------------------------------- */

.stage {
  position: relative;
  z-index: 4;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 6rem 1.5rem 7rem;
  perspective: 1000px;
}

.tilt {
  display: flex;
  flex-direction: column;
  align-items: center;
  transform-style: preserve-3d;
  transition: transform 120ms ease-out;
}

/* ---------- mark ------------------------------------------ */

.mark {
  display: block;
  width: clamp(3rem, 6.5vw, 4.5rem);
  margin-bottom: clamp(1.25rem, 3vw, 2rem);
  color: var(--paper);
  animation: rise-in 2.2s var(--ease) both;
}

.mark svg { display: block; width: 100%; height: auto; }

/* ---------- wordmark -------------------------------------- */

.wordmark {
  margin: 0;
  display: flex;
  font-size: min(19vw, 12rem);
  font-weight: 800;
  line-height: 1;
  letter-spacing: -.08em;
  user-select: none;
  animation: rise-in 2.2s var(--ease) .1s both;
}

.letter {
  display: inline-block;
  transition: transform 120ms ease-out;
  will-change: transform;
}

/* the tracking pulls the last letter tight against the edge */
.wordmark { padding-right: .08em; }

.soon {
  margin: clamp(1.5rem, 4vw, 2.25rem) 0 0;
  font-size: clamp(.5625rem, 1.2vw, .6875rem);
  font-weight: 200;
  font-style: italic;
  letter-spacing: .6em;
  padding-left: .6em;
  user-select: none;
  animation: rise-in 2.2s var(--ease) .5s both;
}

.soon__text {
  background: linear-gradient(90deg,
    rgba(255, 255, 255, .35) 0%,
    rgba(255, 255, 255, 1) 50%,
    rgba(255, 255, 255, .35) 100%);
  background-size: 200% auto;
  -webkit-background-clip: text;
          background-clip: text;
  -webkit-text-fill-color: transparent;
  animation: sweep 3.4s linear infinite;
}

/* ---------- waitlist -------------------------------------- */

.waitlist {
  margin-top: clamp(2.25rem, 6vw, 3.25rem);
  animation: rise-in 2.2s var(--ease) .8s both;
}

.form { display: flex; align-items: stretch; justify-content: center; }

.form__input {
  width: 15rem;
  max-width: 46vw;
  padding: .75rem 1rem;
  border: 1px solid rgba(255, 255, 255, .28);
  border-right: none;
  background: transparent;
  color: var(--paper);
  font: inherit;
  font-size: .6875rem;
  font-weight: 300;
  letter-spacing: .05em;
  transition: border-color 300ms ease;
  -webkit-appearance: none;
  border-radius: 0;
}

.form__input::placeholder { color: rgba(255, 255, 255, .45); }
.form__input:focus { outline: none; border-color: rgba(255, 255, 255, .75); }

.form__btn {
  flex: 0 0 auto;
  padding: .75rem 1.25rem;
  border: 1px solid var(--paper);
  background: var(--paper);
  color: var(--violet);
  font: inherit;
  font-size: .625rem;
  font-weight: 600;
  letter-spacing: .15em;
  cursor: pointer;
  transition: opacity 300ms ease;
  border-radius: 0;
}

.form__btn:hover { opacity: .82; }
.form__btn[disabled] { opacity: .5; cursor: progress; }

.form__hp { position: absolute; left: -9999px; width: 1px; height: 1px; opacity: 0; }

.form__status {
  margin: 1rem 0 0;
  min-height: 1.1rem;
  text-align: center;
  font-size: .6875rem;
  font-weight: 300;
  letter-spacing: .08em;
  color: rgba(255, 255, 255, .85);
}

.form.is-done { display: none; }

/* ---------- social ---------------------------------------- */

.social {
  display: flex;
  gap: 1.5rem;
  margin-top: clamp(2.25rem, 6vw, 3rem);
  animation: rise-in 2.2s var(--ease) 1s both;
}

.social__link {
  display: block;
  width: 1.125rem;
  color: var(--paper);
  opacity: .38;
  transition: opacity 300ms ease, transform 300ms var(--ease);
}

.social__link svg { display: block; width: 100%; height: auto; }
.social__link:hover { opacity: 1; transform: translateY(-2px); }
.social__link.is-soon { cursor: default; }

/* ---------- foot ------------------------------------------ */

.foot {
  position: fixed;
  bottom: 2.25rem;
  left: 0;
  right: 0;
  z-index: 4;
  text-align: center;
  /* the one line that keeps its capital: it is a notice, not a design element */
  text-transform: none;
  font-size: .625rem;
  font-weight: 300;
  letter-spacing: .3em;
  padding-left: .3em;
  color: rgba(255, 255, 255, .38);
  animation: rise-in 2.2s var(--ease) 1.2s both;
}

/* ---------- focus ----------------------------------------- */

:where(a, button, input):focus-visible {
  outline: 2px solid var(--paper);
  outline-offset: 3px;
}

/* ---------- motion ---------------------------------------- */

@keyframes rise-in {
  from { opacity: 0; filter: blur(18px); transform: translateY(10px); }
  to   { opacity: 1; filter: blur(0);    transform: translateY(0); }
}

@keyframes hero-in {
  from { opacity: 0; }
  to   { opacity: .55; }
}

@keyframes focus-in {
  from { opacity: 0; transform: scale(1.4); }
  to   { opacity: 1; transform: scale(1); }
}

@keyframes sweep {
  0%   { background-position: -200% center; }
  100% { background-position:  200% center; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 1ms !important;
    animation-delay: 0ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 1ms !important;
  }
  .glow { display: none; }
}

/* ---------- small screens --------------------------------- */

@media (max-width: 26rem) {
  .form { flex-direction: column; align-items: stretch; width: min(17rem, 78vw); }
  .form__input { width: 100%; max-width: none; border-right: 1px solid rgba(255, 255, 255, .28); }
  .form__btn { margin-top: .5rem; }
}
