/* ==========================================================================
   Vivana — vivana.app
   Ported from the Claude Design canvas export (Vivana Site / Vivana Pages /
   Vivie). Inline styles from the export are consolidated into tokens here.

   Light-theme token values are darkened from the raw design values where the
   design would not have reached WCAG AA against the page gradient's darkest
   stop (--bg-end). Two accent tokens exist for that reason:
     --accent       surface / fill colour (buttons, dots, rings)
     --accent-text  the same hue, safe as TEXT on the page background
   ========================================================================== */

/* --- 1. Tokens ---------------------------------------------------------- */

:root {
  /* Terra (default) — light */
  --bg-start: #F7EFE7;
  --bg-end: #DECAB0;
  --text: #33241B;
  --text-2: #62544B;
  --accent: #C04F2A;
  --accent-text: #933C20;
  --accent-partner: #E0824F;
  --on-accent: #FFF7F1;
  --card-shadow: rgba(150, 84, 50, .32);
  --blob-a: rgba(190, 118, 80, .26);
  --blob-b: rgba(209, 158, 94, .24);
  --divider: rgba(110, 80, 60, .14);
  --glass: rgba(255, 255, 255, .5);
  --sheen: rgba(255, 255, 255, .85);
  --field: rgba(255, 255, 255, .7);
  --field-border: #7E6957;
  --pill-text: #4A3E35;
  --danger: #A32B22;
  --done: #22833B;
  --on-done: #FFFFFF;

  /* Day parts — shared across palettes, as in the design */
  --morning: #CD6100;
  --midday: #E79F00;
  --evening: #D95000;
  --night: #9665D4;

  --maxw: 1120px;
  --gut: 24px;
  --ease: cubic-bezier(.22, 1, .36, 1);
  --pop: cubic-bezier(.34, 1.3, .64, 1);
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg-start: #1D1512;
    --bg-end: #2E1E14;
    --text: #F6EDE3;
    --text-2: #B7A290;
    --accent: #E07A55;
    --accent-text: #E5865F;
    --accent-partner: #C05F3C;
    --on-accent: #2A130A;
    --card-shadow: rgba(0, 0, 0, .6);
    --blob-a: rgba(224, 122, 85, .24);
    --blob-b: rgba(200, 150, 80, .18);
    --divider: rgba(255, 255, 255, .09);
    --glass: rgba(255, 255, 255, .07);
    --sheen: rgba(255, 255, 255, .14);
    --field: rgba(255, 255, 255, .06);
    --field-border: rgba(255, 255, 255, .46);
    --pill-text: #D8C9BA;
    --danger: #F07A70;
    --done: #30D158;
    --on-done: #08240F;
    --morning: #FC8E20;
    --midday: #FFCA06;
    --evening: #FF8647;
    --night: #B077FF;
  }
}

:root[data-theme="moss"] {
  --bg-start: #EEF0E5;
  --bg-end: #CBD1BC;
  --text: #232A1C;
  --text-2: #535B4C;
  --accent: #637B4C;
  --accent-text: #4C5E3A;
  --accent-partner: #8CA671;
  --on-accent: #F9FBF4;
  --card-shadow: rgba(70, 88, 48, .30);
  --blob-a: rgba(111, 138, 85, .32);
  --blob-b: rgba(176, 158, 108, .24);
  --divider: rgba(35, 42, 28, .14);
  --field-border: #667061;
  --pill-text: #3E453A;
  --danger: #A42C22;
  --done: #23843B;
}

@media (prefers-color-scheme: dark) {
  :root[data-theme="moss"] {
    --bg-start: #151A11;
    --bg-end: #232D1B;
    --text: #EDF1E3;
    --text-2: #A8B298;
    --accent: #A3BC85;
    --accent-text: #A3BC85;
    --accent-partner: #82A063;
    --on-accent: #16200D;
    --card-shadow: rgba(0, 0, 0, .6);
    --blob-a: rgba(150, 180, 120, .22);
    --blob-b: rgba(170, 150, 90, .18);
    --divider: rgba(255, 255, 255, .09);
    --field-border: rgba(255, 255, 255, .46);
    --pill-text: #CFD6C6;
    --danger: #F4877E;
    --done: #30D158;
  }
}

:root[data-theme="lavender"] {
  --bg-start: #EFEDF7;
  --bg-end: #D1CAE0;
  --text: #2A2440;
  --text-2: #5A546D;
  --accent: #796AC0;
  --accent-text: #5948AA;
  --accent-partner: #A99BDF;
  --on-accent: #FFFFFF;
  --card-shadow: rgba(84, 72, 134, .32);
  --blob-a: rgba(139, 126, 200, .36);
  --blob-b: rgba(197, 157, 201, .26);
  --divider: rgba(42, 36, 64, .14);
  --field-border: #6A647D;
  --pill-text: #433D52;
  --danger: #A32C22;
  --done: #22833B;
}

@media (prefers-color-scheme: dark) {
  :root[data-theme="lavender"] {
    --bg-start: #17141F;
    --bg-end: #262040;
    --text: #EFEBF9;
    --text-2: #A59DC2;
    --accent: #A99BE6;
    --accent-text: #A99BE6;
    --accent-partner: #8B7EC8;
    --on-accent: #1A1430;
    --card-shadow: rgba(0, 0, 0, .6);
    --blob-a: rgba(139, 126, 200, .28);
    --blob-b: rgba(96, 74, 150, .32);
    --divider: rgba(255, 255, 255, .09);
    --field-border: rgba(255, 255, 255, .46);
    --pill-text: #CFC9DE;
    --danger: #F2837A;
    --done: #30D158;
  }
}

/* --- 2. Font ------------------------------------------------------------ */

@font-face {
  font-family: "Nunito";
  src: url("/assets/fonts/nunito-var.51741681.woff2") format("woff2") tech(variations),
       url("/assets/fonts/nunito-var.51741681.woff2") format("woff2-variations");
  font-weight: 500 800;
  font-style: normal;
  font-display: swap;
}

/* --- 3. Base ------------------------------------------------------------ */

*, *::before, *::after { box-sizing: border-box; }
[hidden] { display: none !important; }

html {
  /* matches the <meta name="theme-color"> pair — see CHECKLIST §0.6 */
  background-color: var(--bg-start);
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  min-height: 100vh;
  font-family: "Nunito", ui-rounded, "SF Pro Rounded", system-ui, -apple-system, "Segoe UI", sans-serif;
  font-size: 19px;
  line-height: 1.55;
  font-weight: 500;
  color: var(--text);
  background: linear-gradient(180deg, var(--bg-start), var(--bg-end)) no-repeat;
  background-color: var(--bg-start);
  -webkit-font-smoothing: antialiased;
  text-wrap: pretty;
  overflow-x: clip;
  position: relative;
}

h1, h2, h3, h4 { font-weight: 800; letter-spacing: -.015em; line-height: 1.12; text-wrap: balance; }
h1 { letter-spacing: -.02em; }
p { margin: 0 0 1em; }
img, svg { max-width: 100%; }
img { height: auto; }

a { color: var(--accent-text); text-decoration-thickness: .08em; text-underline-offset: .18em; }
/* Trailing "go on" arrow. Drawn, not typed: the subset of Nunito this site
   ships has no U+2192, so a literal arrow would fall back to another face. */
.link-arrow { width: .72em; height: .72em; vertical-align: -.02em; margin-left: .25em; }
a:hover { color: var(--text); }

:focus-visible {
  outline: 3px solid var(--accent-text);
  outline-offset: 3px;
  border-radius: 4px;
}

::selection { background: var(--accent); color: var(--on-accent); }

.visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden; clip-path: inset(50%);
  white-space: nowrap; border: 0;
}

.skip-link {
  position: absolute;
  left: 12px; top: -100px;
  z-index: 100;
  background: var(--accent);
  color: var(--on-accent);
  font-weight: 800;
  padding: 12px 20px;
  border-radius: 0 0 12px 12px;
  text-decoration: none;
  transition: top 180ms var(--ease);
}
.skip-link:focus { top: 0; color: var(--on-accent); }

/* Launch switch: scripts/config.js -> launched stamps data-launched on <html>.
   While Vivana is not on the App Store, .js-launched-only stays hidden. See the
   README, "Flipping the launched switch" — the App Store badge must be added as
   real markup at that point, not shipped hidden here. */
.js-launched-only { display: none; }
html[data-launched="true"] .js-launched-only { display: inline-flex; }
html[data-launched="true"] .js-waitlist-only { display: none; }

/* --- 4. Layout ---------------------------------------------------------- */

.wrap { max-width: var(--maxw); margin: 0 auto; padding-inline: var(--gut); }
.wrap--narrow { max-width: 820px; }

.blobs {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
  z-index: 0;
}
.blob {
  position: absolute;
  border-radius: 50%;
  will-change: transform;
}
.blob--a {
  top: -120px; left: -140px; width: 520px; height: 520px;
  background: radial-gradient(circle, var(--blob-a) 0%, transparent 62%);
}
.blob--b {
  bottom: -160px; right: -160px; width: 560px; height: 560px;
  background: radial-gradient(circle, var(--blob-b) 0%, transparent 62%);
}

.page { position: relative; z-index: 1; }

/* --- 5. Header ---------------------------------------------------------- */

.site-header {
  position: sticky;
  top: 0;
  z-index: 40;
  background: transparent;
  box-shadow: inset 0 -1px 0 transparent;
  transition: background-color 400ms var(--ease), box-shadow 400ms var(--ease);
}
.site-header.is-scrolled {
  background: var(--glass);
  backdrop-filter: blur(24px) saturate(170%);
  -webkit-backdrop-filter: blur(24px) saturate(170%);
  box-shadow: inset 0 -1px 0 var(--divider);
}
.site-header__inner {
  max-width: var(--maxw);
  margin: 0 auto;
  padding: 12px var(--gut);
  display: flex;
  align-items: center;
  gap: 20px;
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  text-decoration: none;
  color: var(--text);
  font-weight: 800;
  font-size: 22px;
}
.brand:hover { color: var(--text); }
.brand__mark { border-radius: 9px; display: block; flex: none; }

.nav {
  display: flex;
  gap: 22px;
  margin-left: auto;
  font-size: 16px;
  font-weight: 700;
}
.nav a { color: var(--text); text-decoration: none; opacity: .8; }
.nav a:hover, .nav a[aria-current="page"] { opacity: 1; text-decoration: underline; }
@media (max-width: 719px) { .nav { display: none; } }

.header-cta { margin-left: auto; }
@media (max-width: 400px) { .header-cta { display: none; } }

/* --- 6. Buttons & pills ------------------------------------------------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 52px;
  padding: 0 22px;
  border: 0;
  border-radius: 999px;
  background: var(--accent);
  color: var(--on-accent);
  font: inherit;
  font-weight: 800;
  font-size: 17px;
  cursor: pointer;
  text-decoration: none;
  white-space: nowrap;
  transition: opacity 200ms var(--ease), transform 200ms var(--ease);
}
.btn:hover { opacity: .88; color: var(--on-accent); }
.btn:active { transform: translateY(1px); }
.btn[disabled] { opacity: .7; cursor: progress; }
.btn--sm { min-height: 40px; padding: 0 16px; font-size: 15px; }
.btn--ghost {
  background: transparent;
  color: var(--accent-text);
  box-shadow: inset 0 0 0 2px var(--divider);
}
.btn--ghost:hover { color: var(--text); opacity: 1; box-shadow: inset 0 0 0 2px var(--accent); }

.eyebrow {
  margin: 0 0 10px;
  font-size: 15px;
  font-weight: 800;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--accent-text);
}

.lede { color: var(--text-2); font-size: clamp(18px, 1.6vw, 22px); font-weight: 500; }
.muted { color: var(--text-2); }

.card {
  background: var(--glass);
  backdrop-filter: blur(24px) saturate(170%);
  -webkit-backdrop-filter: blur(24px) saturate(170%);
  border-radius: 18px;
  padding: 26px;
  box-shadow: 0 18px 36px var(--card-shadow), inset 0 1px 0 var(--sheen);
}

.phone {
  width: min(270px, 80%);
  background: #141414;
  border-radius: 44px;
  padding: 9px;
  box-shadow: 0 30px 60px var(--card-shadow);
  flex: none;
}
.phone img { display: block; width: 100%; border-radius: 36px; }
.media { display: flex; justify-content: center; }

/* --- 7. Hero ------------------------------------------------------------ */

.hero {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 40px;
  align-items: center;
  padding: 56px 0 72px;
}
.hero__copy { max-width: 560px; }
.hero h1 { margin: 0 0 20px; font-size: clamp(40px, 6vw, 72px); line-height: 1.04; }
.hero__lede { margin: 0 0 30px; max-width: 34ch; }
.hero__art {
  display: flex;
  align-items: flex-end;
  justify-content: center;
  min-height: 420px;
}
.hero__vivie {
  width: clamp(150px, 34%, 200px);
  flex: none;
  margin-right: -24px;
  margin-bottom: 24px;
  position: relative;
  z-index: 2;
}
.hero .phone { width: min(270px, 62%); }

/* --- 8. Promise cards --------------------------------------------------- */

.promises {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 20px;
  padding: 0 0 88px;
}
.promises h3 { margin: 14px 0 6px; font-size: 22px; }
.promises p { margin: 0; color: var(--text-2); font-size: 17px; }

/* --- 9. Feature rows ---------------------------------------------------- */

.features { display: flex; flex-direction: column; gap: 96px; padding-bottom: 96px; }
.feature {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 40px;
  align-items: center;
}
.feature h2 { margin: 0 0 14px; font-size: clamp(30px, 3.4vw, 40px); }
.feature p { color: var(--text-2); max-width: 46ch; }
@media (min-width: 880px) {
  .feature--flip .media { order: -1; }
}

.dayparts { display: flex; flex-wrap: wrap; gap: 10px; margin: 0; padding: 0; list-style: none; }
.daypart {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 15px;
  font-weight: 700;
  padding: 6px 12px;
  border-radius: 999px;
  background: var(--glass);
  box-shadow: inset 0 1px 0 var(--sheen);
}
.dot { width: 10px; height: 10px; border-radius: 50%; flex: none; }
.dot--morning { background: var(--morning); }
.dot--midday { background: var(--midday); }
.dot--evening { background: var(--evening); }
.dot--night { background: var(--night); }

/* --- 10. Demos (CSS only; end state is the default) --------------------- */

.demo { padding: 18px; max-width: 400px; border-radius: 18px; }
.demo__line {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 16px;
  font-weight: 600;
  min-height: 28px;
}
.demo__spark {
  width: 26px; height: 26px;
  border-radius: 50%;
  background: var(--accent);
  flex: none;
  display: grid;
  place-items: center;
}
.demo__typed {
  display: inline-block;
  max-width: 100%;
  overflow: hidden;
  white-space: nowrap;
  vertical-align: bottom;
}
.demo__caret {
  display: inline-block;
  width: 2px; height: 18px;
  background: var(--accent);
  vertical-align: -3px;
  margin-left: 2px;
  opacity: 0;
}
.demo__pills { margin-top: 14px; display: flex; gap: 6px; }
.pill {
  font-size: 13px;
  font-weight: 800;
  padding: 4px 10px;
  border-radius: 999px;
  background: var(--divider);
  color: var(--pill-text);
}
.pill--on { background: var(--accent); color: var(--on-accent); }
.demo__part {
  margin-top: 10px;
  font-size: 13px;
  font-weight: 800;
  color: var(--text-2);
  display: flex;
  align-items: center;
  gap: 6px;
}
.demo__part .dot { width: 8px; height: 8px; }
.demo__blocks { margin-top: 8px; display: flex; flex-direction: column; gap: 8px; }
.block-card {
  display: flex;
  align-items: center;
  gap: 10px;
  background: var(--glass);
  border-radius: 14px;
  padding: 10px 12px;
  box-shadow: 0 8px 20px var(--card-shadow), inset 0 1px 0 var(--sheen);
}
.block-card--done { border-left: 3px solid var(--done); }
.block-card__name { font-size: 16px; font-weight: 700; flex: 1; }
.block-card__meta { font-size: 13px; color: var(--text-2); font-weight: 700; }
.demo__replay {
  margin-top: 10px;
  border: 0;
  background: transparent;
  color: var(--accent-text);
  font: inherit;
  font-weight: 800;
  font-size: 14px;
  cursor: pointer;
  padding: 4px 0;
}

.ring-demo { display: flex; align-items: center; gap: 22px; flex-wrap: wrap; }
.ring { transform: rotate(-90deg); flex: none; }
.ring__track { stroke: var(--divider); }
.ring__arc { stroke: var(--accent); }
.ring-demo__pct { margin: 0; font-size: 36px; font-weight: 800; line-height: 1; }
.ring-demo__pct span { font-size: 20px; }
.ring-demo__note { margin: 4px 0 0; font-size: 15px; color: var(--text-2); font-weight: 700; }

/* rollover demo — CSS-only "tap to tick" via a hidden checkbox */
.tick-toggle { position: absolute; opacity: 0; width: 0; height: 0; }
.tick-label {
  display: flex;
  align-items: center;
  gap: 10px;
  background: var(--glass);
  border-radius: 14px;
  padding: 10px 12px;
  box-shadow: 0 8px 20px var(--card-shadow), inset 0 1px 0 var(--sheen), 0 0 0 1.5px transparent;
  cursor: pointer;
  transition: box-shadow 2200ms var(--ease);
}
.tick-toggle:focus-visible + .tick-label { outline: 3px solid var(--accent-text); outline-offset: 3px; }
.tick-toggle:checked + .tick-label { box-shadow: 0 8px 20px var(--card-shadow), inset 0 1px 0 var(--sheen), 0 0 0 1.5px var(--done); }
.tick {
  width: 22px; height: 22px;
  border-radius: 50%;
  border: 2px solid var(--divider);
  background: transparent;
  display: grid;
  place-items: center;
  flex: none;
  transition: background-color 300ms var(--ease), border-color 300ms var(--ease);
}
.tick svg { opacity: 0; transition: opacity 300ms var(--ease); }
.tick-toggle:checked + .tick-label .tick { background: var(--done); border-color: var(--done); }
.tick-toggle:checked + .tick-label .tick svg { opacity: 1; }
.tick path { stroke: var(--on-done); }

.roll-card { transition: opacity 400ms var(--ease), transform 400ms var(--ease); }

.wrap-stat { display: flex; gap: 20px; align-items: baseline; flex-wrap: wrap; }
.wrap-stat__n { font-size: 34px; font-weight: 800; line-height: 1; }
.wrap-stat__sub { font-size: 18px; color: var(--text-2); }
.wrap-stat__l { font-size: 15px; color: var(--text-2); font-weight: 700; }

.calm { position: relative; }
.calm__aura {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  pointer-events: none;
}
.calm__breathe {
  width: min(340px, 100%);
  aspect-ratio: 1;
  border-radius: 50%;
  background: radial-gradient(circle, var(--blob-a) 0%, transparent 65%);
  opacity: .65;
}
.calm__ripple {
  position: absolute;
  width: 220px; height: 220px;
  border-radius: 50%;
  border: 1.5px solid var(--accent);
  opacity: 0;
}
.calm .phone { position: relative; }

/* --- 11. Private / centred section -------------------------------------- */

.centred { text-align: center; }
.centred h2 { margin: 0 auto 12px; font-size: clamp(28px, 3.2vw, 36px); max-width: 24ch; }
.centred p { margin: 0 auto; color: var(--text-2); max-width: 48ch; }

/* --- 12. Pricing -------------------------------------------------------- */

.plans {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 20px;
  align-items: stretch;
}
.plan { position: relative; display: flex; flex-direction: column; }
.plan h3 { margin: 0; font-size: 24px; }
.plan__tagline { margin: 6px 0 16px; font-size: 17px; color: var(--text-2); font-weight: 600; }
.plan__price {
  margin: 0;
  font-size: 34px;
  font-weight: 800;
  line-height: 1;
  letter-spacing: -.01em;
}
.plan__price span { font-size: 16px; color: var(--text-2); font-weight: 700; letter-spacing: 0; }
.plan__note { margin: 8px 0 18px; font-size: 15px; color: var(--text-2); font-weight: 600; min-height: 23px; }
.plan ul { margin: 0; padding: 0; list-style: none; display: flex; flex-direction: column; gap: 8px; font-size: 16px; font-weight: 600; flex: 1; }
.plan li { display: flex; gap: 10px; align-items: flex-start; }
.plan li svg { flex: none; margin-top: 5px; }
.plan__badge {
  position: absolute;
  top: -14px; right: 20px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: var(--accent);
  color: var(--on-accent);
  font-size: 13px;
  font-weight: 800;
  padding: 5px 11px;
  border-radius: 999px;
}

.table-scroll { overflow-x: auto; margin: 0 0 24px; }
table.compare {
  width: 100%;
  min-width: 560px;
  border-collapse: collapse;
  font-size: 16px;
  background: var(--glass);
  border-radius: 18px;
  overflow: hidden;
  box-shadow: 0 18px 36px var(--card-shadow), inset 0 1px 0 var(--sheen);
}
table.compare caption { caption-side: top; text-align: left; padding: 0 0 12px; color: var(--text-2); font-size: 16px; font-weight: 600; }
table.compare th, table.compare td { padding: 12px 16px; text-align: left; border-bottom: 1px solid var(--divider); }
table.compare thead th { font-weight: 800; font-size: 16px; }
table.compare tbody th { font-weight: 600; }
table.compare tbody tr:last-child th, table.compare tbody tr:last-child td { border-bottom: 0; }
table.compare td { color: var(--text-2); font-weight: 600; }

/* --- 13. FAQ ------------------------------------------------------------ */

.faq-list { display: flex; flex-direction: column; gap: 10px; }
.faq-item {
  background: var(--glass);
  backdrop-filter: blur(24px) saturate(170%);
  -webkit-backdrop-filter: blur(24px) saturate(170%);
  border-radius: 18px;
  box-shadow: 0 18px 36px var(--card-shadow), inset 0 1px 0 var(--sheen);
}
.faq-item > summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 18px 22px;
  font-size: 19px;
  font-weight: 800;
  cursor: pointer;
  border-radius: 18px;
  list-style: none;
}
.faq-item > summary::-webkit-details-marker { display: none; }
.faq-item > summary::marker { content: ""; }
.faq-item > summary svg { flex: none; transition: transform 350ms var(--ease); }
.faq-item[open] > summary svg { transform: rotate(180deg); }
.faq-item p { margin: 0; padding: 0 22px 20px; color: var(--text-2); font-size: 17px; }

.qa { max-width: 68ch; }
.qa h2 { margin: 36px 0 8px; font-size: 24px; }
.qa h2:first-of-type { margin-top: 0; }
.qa p { color: var(--text-2); }

/* --- 14. Forms ---------------------------------------------------------- */

.waitlist { display: flex; flex-direction: column; gap: 12px; max-width: 460px; }
.waitlist--inline { max-width: 480px; }
.waitlist__row { display: flex; flex-wrap: wrap; gap: 10px; }
.waitlist__row .field { flex: 1 1 200px; width: auto; }
.field-label { display: flex; flex-direction: column; gap: 6px; font-size: 15px; font-weight: 800; }
.field {
  flex: none;
  min-height: 52px;
  width: 100%;
  padding: 0 18px;
  border-radius: 999px;
  border: 2px solid var(--field-border);
  background: var(--field);
  color: var(--text);
  font: inherit;
  font-size: 17px;
  font-weight: 500;
}
.field::placeholder { color: var(--text-2); opacity: 1; }
.field:focus { border-color: var(--accent); }
.field[aria-invalid="true"] { border-color: var(--danger); }
.form-error {
  margin: 0 0 0 18px;
  font-size: 15px;
  font-weight: 700;
  color: var(--danger);
}
.form-hint { margin: 4px 0 0 18px; font-size: 15px; color: var(--text-2); font-weight: 600; }
.check {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 16px;
  font-weight: 600;
  cursor: pointer;
}
.check input { width: 20px; height: 20px; accent-color: var(--accent); margin: 0; flex: none; }
.turnstile { min-height: 65px; }
/* Share links land on /#waitlist, /#android and /#feature-news (see
   _redirects). Each of those ids is the SECTION holding the card, not the form
   inside it, so the card's heading is what lands in view: the sticky header is
   64px tall, and .section has no top padding, so the card starts 20px clear of
   it. scripts/waitlist.js re-scrolls after the scroll reveal has run, because a
   [data-reveal] block is still translated down 16px when the browser makes its
   own fragment jump. */
#waitlist, #android, #feature-news { scroll-margin-top: 84px; }
/* Home-page URLs copied before the features card existed still end in
   #also-features, which is the CHECKBOX inside the Android form — roughly
   230-320px below its card, depending on how the copy wraps. The margin is
   what keeps that card's heading on screen when scripts/waitlist.js is not
   there to correct the scroll. */
#also-features { scroll-margin-top: 400px; }

.success-card {
  display: flex;
  gap: 14px;
  align-items: center;
  padding: 16px 18px;
  border-radius: 14px;
  background: var(--glass);
  box-shadow: inset 0 1px 0 var(--sheen);
}
.success-card svg { flex: none; }
.success-card p { margin: 0; }
.success-card__title { font-weight: 800; }
.success-card__sub { margin: 2px 0 0 !important; font-size: 16px; color: var(--text-2); font-weight: 600; }

.spinner {
  width: 18px; height: 18px;
  border-radius: 50%;
  border: 2.5px solid currentColor;
  border-right-color: transparent;
  display: inline-block;
}

/* --- 15. Confirmed page ------------------------------------------------- */

.confirmed { max-width: 560px; }
.confirmed h1 { margin: 0 0 6px; font-size: clamp(32px, 5vw, 40px); }
.position-label {
  margin: 0;
  font-size: 14px;
  font-weight: 800;
  color: var(--text-2);
  letter-spacing: .06em;
  text-transform: uppercase;
}
.position {
  margin: 2px 0 18px;
  font-size: clamp(48px, 9vw, 64px);
  font-weight: 800;
  line-height: 1;
  letter-spacing: -.02em;
  color: var(--accent-text);
}
.share { display: flex; gap: 8px; }
.share input {
  flex: 1;
  min-width: 0;
  min-height: 48px;
  padding: 0 16px;
  border-radius: 999px;
  border: 2px solid var(--field-border);
  background: var(--field);
  color: var(--text-2);
  font: inherit;
  font-size: 15px;
  font-weight: 600;
  text-overflow: ellipsis;
}
.share .btn { min-height: 48px; padding: 0 20px; font-size: 15px; }

/* --- 16. Article / legal ------------------------------------------------ */

.article { max-width: 68ch; margin: 0 auto; }
.article h1 { margin: 0 0 8px; font-size: clamp(32px, 5vw, 40px); }
.article h2 { margin: 32px 0 8px; font-size: 24px; }
/* deep links (e.g. /faq/#cancel-bloom) must clear the sticky header */
.qa h2[id], .article h2[id] { scroll-margin-top: 84px; }
.article h3 { margin: 24px 0 6px; font-size: 20px; }
.article p, .article li { color: var(--text-2); }
.article ul, .article ol { padding-left: 1.3em; }
.article li { margin-bottom: .4em; }
.article .meta { margin: 0 0 28px; color: var(--text-2); font-size: 16px; font-weight: 600; }
.callout {
  background: var(--glass);
  backdrop-filter: blur(24px) saturate(170%);
  -webkit-backdrop-filter: blur(24px) saturate(170%);
  border-radius: 18px;
  padding: 18px 22px;
  box-shadow: 0 18px 36px var(--card-shadow), inset 0 1px 0 var(--sheen);
  margin: 0 0 24px;
  font-size: 17px;
}
.callout p { color: var(--text); }
.callout p:last-child { margin-bottom: 0; }

/* --- 17. 404 ------------------------------------------------------------ */

.notfound {
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 40px 0 80px;
}
.notfound h1 { margin: 0 0 10px; font-size: clamp(30px, 6vw, 40px); }
.notfound p { color: var(--text-2); max-width: 40ch; }

/* --- 18. Sections & footer ---------------------------------------------- */

.section { padding: 0 0 96px; }
.section--tight { padding-bottom: 64px; }
.section__head { text-align: center; margin-bottom: 36px; }
.section__head h2 { margin: 0 auto 10px; font-size: clamp(30px, 3.4vw, 40px); }
.section__head p { margin: 0 auto; color: var(--text-2); max-width: 44ch; }

.site-footer {
  padding: 32px 0 44px;
  box-shadow: inset 0 1px 0 var(--divider);
  font-size: 15px;
  font-weight: 600;
  color: var(--text-2);
}
.site-footer__links {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 18px;
  justify-content: center;
  align-items: center;
  margin: 0 0 18px;
  padding: 0;
  list-style: none;
}
.site-footer a { color: var(--text-2); text-decoration: none; }
.site-footer a:hover { color: var(--text); text-decoration: underline; }

.theme-picker {
  margin: 0 0 18px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  flex-wrap: wrap;
}
.theme-picker > span { font-size: 14px; font-weight: 700; }
.theme-picker__options {
  display: flex;
  gap: 4px;
  background: var(--glass);
  border-radius: 999px;
  padding: 4px;
  box-shadow: inset 0 1px 0 var(--sheen);
}
.theme-picker label {
  font-size: 14px;
  font-weight: 800;
  padding: 6px 14px;
  border-radius: 999px;
  cursor: pointer;
  color: var(--text-2);
}
.theme-picker input { position: absolute; opacity: 0; width: 0; height: 0; }
.theme-picker input:checked + label { background: var(--accent); color: var(--on-accent); }
.theme-picker input:focus-visible + label { outline: 3px solid var(--accent-text); outline-offset: 2px; }

.site-footer__legal { margin: 0; text-align: center; }

/* --- 19. Motion --------------------------------------------------------- */
/* Everything above renders the FINAL state. The rules below only add motion,
   and only when JS has confirmed the visitor has not asked for reduced motion
   (html[data-motion="full"]). Nothing here is required to read the page. */

@keyframes vv-drift-a { from { transform: translate(0, 0); } to { transform: translate(4%, 3%); } }
@keyframes vv-drift-b { from { transform: translate(0, 0); } to { transform: translate(-3%, -4%); } }
@keyframes vv-float { from { transform: translateY(0); } to { transform: translateY(-10px); } }
@keyframes vv-breathe { 0%, 100% { transform: scale(.92); opacity: .5; } 50% { transform: scale(1.08); opacity: .85; } }
@keyframes vv-ripple { 0% { transform: scale(.6); opacity: .5; } 100% { transform: scale(1.6); opacity: 0; } }
@keyframes vv-spin { to { transform: rotate(360deg); } }
@keyframes vv-logo { from { stroke-dashoffset: 1; } to { stroke-dashoffset: 0; } }
@keyframes vv-echo { from { opacity: 0; } to { opacity: 1; } }
@keyframes vv-type { from { width: 0; } to { width: 100%; } }
@keyframes vv-blinkcaret { 0%, 100% { opacity: 1; } 50% { opacity: 0; } }
@keyframes vv-cardin { from { opacity: 0; transform: scale(.8); } to { opacity: 1; transform: scale(1); } }
@keyframes vv-ring { from { stroke-dashoffset: var(--from); } to { stroke-dashoffset: var(--to); } }
@keyframes vv-rollout { 0%, 20% { opacity: 1; transform: translateY(0); } 25%, 45% { opacity: 0; transform: translateY(6px); } 50%, 100% { opacity: 1; transform: translateY(0); } }

.spinner { animation: vv-spin .8s linear infinite; }

html[data-motion="full"] .blob--a { animation: vv-drift-a 47s ease-in-out infinite alternate; }
html[data-motion="full"] .blob--b { animation: vv-drift-b 61s ease-in-out infinite alternate; }
html[data-motion="full"] .hero .phone { animation: vv-float 5s ease-in-out infinite alternate; }
html[data-motion="full"] .calm__breathe { animation: vv-breathe 12s ease-in-out infinite; }
html[data-motion="full"] .calm__ripple { animation: vv-ripple 12s ease-out infinite; }
html[data-motion="full"] .brand__mark [data-logo="v"] { animation: vv-logo 600ms var(--ease) both; }
html[data-motion="full"] .brand__mark [data-logo="e1"] { animation: vv-echo 300ms ease-out 450ms both; }
html[data-motion="full"] .brand__mark [data-logo="e2"] { animation: vv-echo 300ms ease-out 600ms both; }

/* Reveal-on-scroll. The gate needs BOTH attributes, and scripts/site.js — the
   only thing that can ever add data-in — is also the only thing that sets
   data-reveal-ready, on the line before it starts observing. So if that file
   is blocked, 404s or throws on parse, nothing is hidden in the first place:
   content is never gated behind an animation, and there is no timer to lose.
   (site.js marks whatever is already on screen as data-in in the same task,
   so switching the gate on cannot flash.)
   The demo elements (.demo__typed, .demo__block--*, .ring__arc--*) need no
   equivalent: their base state IS their end state (the ring's dash offsets
   are HTML attributes) and their [data-in] rules only layer motion on top. */
html[data-motion="full"][data-reveal-ready] [data-reveal]:not([data-in]) { opacity: 0; transform: translateY(16px); }
html[data-motion="full"] [data-reveal] {
  transition: opacity 500ms var(--ease), transform 500ms var(--ease);
}
html[data-motion="full"] [data-reveal][data-in] { opacity: 1; transform: none; }

/* typing demo */
html[data-motion="full"] [data-in] .demo__typed { animation: vv-type 1.5s steps(36, end) 300ms both; }
html[data-motion="full"] [data-in] .demo__caret { animation: vv-blinkcaret 900ms step-end 300ms 2, vv-echo 1ms linear 2.1s reverse forwards; opacity: 1; }
html[data-motion="full"] [data-in] .demo__block--1 { animation: vv-cardin 500ms var(--pop) 2.1s both; }
html[data-motion="full"] [data-in] .demo__block--2 { animation: vv-cardin 500ms var(--pop) 3.5s both; }

/* grow ring */
html[data-motion="full"] [data-in] .ring__arc--a { animation: vv-ring 1400ms var(--ease) 200ms both; --from: 38; --to: 0; }
html[data-motion="full"] [data-in] .ring__arc--b { animation: vv-ring 1400ms var(--ease) 1700ms both; --from: -4; --to: -42; }

/* kind-rollover loop */
html[data-motion="full"] .roll-card { animation: vv-rollout 6.8s linear infinite; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
  [data-reveal] { opacity: 1 !important; transform: none !important; }
}

/* --- 20. Vivie (ported from Vivie.dc.html) ------------------------------ */
/* The SVG renders complete with no animation at all; the rules below only add
   the grow / idle motion, and only when data-motion="full". */

.vivie { display: block; overflow: visible; height: auto; width: 100%; }

@keyframes vv-pop { from { transform: scale(.4); opacity: 0; } to { transform: scale(1); opacity: 1; } }
@keyframes vv-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes vv-draw { from { stroke-dashoffset: 1; } to { stroke-dashoffset: 0; } }
@keyframes vv-leaf { from { transform: scale(0); } to { transform: scale(1); } }
@keyframes vv-spark { 0% { transform: scale(0); } 60% { transform: scale(1.25); } 100% { transform: scale(1); } }
@keyframes vv-sway { from { transform: rotate(-2.2deg); } to { transform: rotate(2.2deg); } }
@keyframes vv-blink { 0%, 93% { transform: scaleY(1); } 95.5%, 97% { transform: scaleY(.08); } 100% { transform: scaleY(1); } }
@keyframes vv-glance { 0%, 64% { transform: translate(0, 0); } 67%, 74% { transform: translate(4px, -5px); } 77%, 100% { transform: translate(0, 0); } }
@keyframes vv-twinkle { 0%, 100% { transform: scale(1); opacity: 1; } 50% { transform: scale(1.15); opacity: .85; } }

html[data-motion="full"] .vivie[data-vivie="grow"] [data-v="body"] { animation: vv-pop 500ms var(--pop) both; }
html[data-motion="full"] .vivie[data-vivie="grow"] [data-v="face"] { animation: vv-fade 300ms var(--ease) 400ms both; }
html[data-motion="full"] .vivie[data-vivie="grow"] [data-v="stalk"] { animation: vv-draw 960ms linear 450ms both; }
html[data-motion="full"] .vivie[data-vivie="grow"] [data-v="leaf"] { animation: vv-leaf 300ms var(--pop) both; }
html[data-motion="full"] .vivie[data-vivie="grow"] [data-v="leaf"]:nth-of-type(1) { animation-delay: 700ms; }
html[data-motion="full"] .vivie[data-vivie="grow"] [data-v="leaf"]:nth-of-type(2) { animation-delay: 810ms; }
html[data-motion="full"] .vivie[data-vivie="grow"] [data-v="leaf"]:nth-of-type(3) { animation-delay: 920ms; }
html[data-motion="full"] .vivie[data-vivie="grow"] [data-v="leaf"]:nth-of-type(4) { animation-delay: 1030ms; }
html[data-motion="full"] .vivie[data-vivie="grow"] [data-v="leaf"]:nth-of-type(5) { animation-delay: 1140ms; }
html[data-motion="full"] .vivie[data-vivie="grow"] [data-v="leaf"]:nth-of-type(6) { animation-delay: 1250ms; }
html[data-motion="full"] .vivie[data-vivie="grow"] [data-v="spark"] { animation: vv-spark 500ms var(--pop) 1500ms both; }
html[data-motion="full"] .vivie[data-vivie="grow"] [data-v="sway"] { animation: vv-sway 2.8s ease-in-out 1.7s infinite alternate; }
html[data-motion="full"] .vivie[data-vivie="grow"] [data-v="lids"] { animation: vv-blink 3s linear 2s infinite; }
html[data-motion="full"] .vivie[data-vivie="grow"] [data-v="pupils"] { animation: vv-glance 9s ease-in-out 2s infinite; }

html[data-motion="full"] .vivie[data-vivie="idle"] [data-v="sway"] { animation: vv-sway 2.8s ease-in-out infinite alternate; }
html[data-motion="full"] .vivie[data-vivie="idle"] [data-v="lids"] { animation: vv-blink 3s linear infinite; }
html[data-motion="full"] .vivie[data-vivie="idle"] [data-v="pupils"] { animation: vv-glance 9s ease-in-out infinite; }
html[data-motion="full"] .vivie[data-vivie="idle"] [data-v="spark"] { animation: vv-twinkle 2.4s ease-in-out infinite; }

.vivie[data-vivie="static"] [data-v="pupils"] { transform: translate(-5px, -4px); }
