/* ============================================================
   Poof — landing v4 (2026 brand)
   Ink base · plum surfaces · Electric→Royal accent · aurora depth
   Type: Plus Jakarta Sans, single-family system —
         headings 700/800 (tight -0.02em), body 400/500. No mono.
   v4: locked section order (hero → poof → quick add → planner
       → make it yours → privacy → FAQ → CTA), fixed-height animated
       containers so nothing reflows the page. All motion respects
       prefers-reduced-motion.
   ============================================================ */

:root {
  --lavender: #C29AFF;
  --electric: #9B5CFF;
  --iris: #7B5CFF;
  --royal: #6B28D6;
  --plum: #1A1040;
  --ink: #0B0712;

  --periwinkle: #7C8CFF;
  --amber: #FFB454;
  --jade: #4FD6A8;
  --bloom: #FF8AD8;

  --bg: var(--ink);
  --surface: #140C24;
  --card: #1A1040;
  --card-2: #211449;
  --line: rgba(194, 154, 255, 0.14);
  --text: #F5F1FF;
  --text-2: rgba(245, 241, 255, 0.72);
  --text-3: rgba(245, 241, 255, 0.5);
  --grad: linear-gradient(135deg, var(--electric), var(--royal));
  --grad-bright: linear-gradient(135deg, var(--lavender), var(--electric));

  --font-display: "Plus Jakarta Sans", system-ui, -apple-system, sans-serif;
  --font-body: "Plus Jakarta Sans", system-ui, -apple-system, sans-serif;

  --r-lg: 28px;
  --r-md: 18px;
  --r-sm: 12px;
  --wrap: 1140px;
  --ease: cubic-bezier(0.22, 1, 0.36, 1);
}

* { margin: 0; padding: 0; box-sizing: border-box; }
html { scroll-behavior: smooth; }

body {
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  font-size: 17px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

/* HORIZONTAL OVERFLOW GUARD — read this before changing it.
   The decorative .hero-glow / .sparkle-field intentionally bleed past the
   viewport (see the note by the responsive grid below), so the document is
   ~10-55px wider than the window. We need that clipped on <html>, not only on
   <body>, or a real (trusted) click's native focus-scroll-into-view can shift
   the whole page sideways at the mobile-nav breakpoint.

   It MUST be `clip`, never `hidden`. `overflow-x: hidden` on <html> makes the
   viewport a scroll container and stops <body>'s own overflow from propagating
   to it — <body> then becomes the scrollport for .nav, whose `position: sticky`
   silently stops working (the nav scrolls away with the page). `clip` creates
   no scroll container at all, so .nav keeps sticking to the viewport.

   Wrapped in @supports so a browser without `overflow: clip` falls back to the
   old body-only clipping (correct sticky nav, just the minor focus-scroll nit)
   rather than to no clipping at all. */
@supports (overflow: clip) {
  html { overflow-x: clip; }
  /* Once <html> is clipped it no longer propagates <body>'s overflow, so
     <body> must be `clip` too — leaving it `hidden` would make IT the scroll
     container and break the sticky nav in exactly the same way. */
  body { overflow-x: clip; }
}

.wrap { max-width: var(--wrap); margin: 0 auto; padding: 0 28px; }
.wrap.narrow { max-width: 760px; }

/* ---------- background aurora ---------- */
.bg-fx {
  position: fixed; inset: 0; z-index: -1; pointer-events: none;
  background:
    radial-gradient(52rem 36rem at 12% -6%, rgba(155, 92, 255, 0.16), transparent 60%),
    radial-gradient(40rem 30rem at 96% 12%, rgba(255, 138, 216, 0.07), transparent 55%),
    radial-gradient(46rem 40rem at 50% 118%, rgba(107, 40, 214, 0.14), transparent 60%),
    var(--bg);
}

/* ---------- type ---------- */
h1, h2, h3 { font-family: var(--font-display); font-weight: 700; letter-spacing: -0.01em; }
h1 { font-size: clamp(2.6rem, 6vw, 4.4rem); line-height: 1.04; font-weight: 800; letter-spacing: -0.02em; }
h2 { font-size: clamp(1.9rem, 3.6vw, 2.7rem); line-height: 1.12; font-weight: 800; letter-spacing: -0.02em; }
h3 { font-size: 1.22rem; line-height: 1.3; }
p { color: var(--text-2); }

.grad-text {
  background: var(--grad-bright);
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent; color: transparent;
}
.line2 { color: var(--text); }

.eyebrow {
  display: inline-flex; align-items: center; gap: 8px;
  font-size: 0.82rem; font-weight: 600; letter-spacing: 0.16em;
  text-transform: uppercase; color: var(--lavender);
}
.eyebrow .spark { color: var(--bloom); letter-spacing: 0; }

.section-head { text-align: center; max-width: 640px; margin: 0 auto 56px; }
.section-head p { margin-top: 14px; font-size: 1.06rem; }
.section-head .eyebrow { margin-bottom: 14px; }

/* ---------- nav ---------- */
.nav {
  position: sticky; top: 0; z-index: 50;
  backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
  background: rgba(11, 7, 18, 0.72);
  border-bottom: 1px solid transparent;
  transition: border-color 0.3s var(--ease);
}
.nav.scrolled { border-bottom-color: var(--line); }
.nav-inner { display: flex; align-items: center; justify-content: space-between; height: 74px; }
.brand { display: flex; align-items: center; }
.nav .wordmark { height: 34px; width: auto; }
.nav-links { display: flex; gap: 30px; }
.nav-links a {
  color: var(--text-2); text-decoration: none; font-size: 0.95rem; font-weight: 500;
  transition: color 0.2s;
}
.nav-links a:hover { color: var(--text); }

/* ---------- buttons ---------- */
.btn {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 12px 22px; border-radius: 999px;
  font-weight: 600; font-size: 0.98rem; text-decoration: none;
  transition: transform 0.25s var(--ease), box-shadow 0.25s var(--ease), background 0.25s;
}
.btn-primary {
  background: var(--grad); color: #fff;
  box-shadow: 0 6px 24px rgba(155, 92, 255, 0.35);
}
.btn-primary:hover { transform: translateY(-2px); box-shadow: 0 10px 32px rgba(155, 92, 255, 0.5); }
.btn-ghost {
  color: var(--text); border: 1px solid var(--line); background: rgba(26, 16, 64, 0.4);
}
.btn-ghost:hover { transform: translateY(-2px); border-color: rgba(194, 154, 255, 0.35); }

/* "Get Poof" nav CTA — one step smaller than the default button. */
.nav-cta { display: flex; align-items: center; gap: 10px; }
.nav-cta .btn-primary { padding: 10px 18px; font-size: 0.92rem; }

/* Hamburger — hidden on desktop, shown < 960px (see the media query). */
.nav-toggle {
  display: none; flex-direction: column; justify-content: center; gap: 5px;
  width: 44px; height: 44px; padding: 11px; margin: -4px;
  background: none; border: 0; cursor: pointer;
}
.nav-toggle span {
  display: block; height: 2px; width: 100%; border-radius: 2px;
  background: var(--text); transition: transform .25s var(--ease), opacity .2s var(--ease);
}
.nav.open .nav-toggle span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.nav.open .nav-toggle span:nth-child(2) { opacity: 0; }
.nav.open .nav-toggle span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

/* "Notify me at launch" line under the App Store CTA. */
.notify-line { margin-top: 18px; font-size: 0.9rem; color: var(--text-3); }
.notify-line a { color: var(--lavender); font-weight: 600; text-decoration: none; border-bottom: 1px solid rgba(155, 92, 255, 0.4); }
.notify-line a:hover { color: var(--text); }

.appstore {
  display: inline-flex; align-items: center; gap: 12px;
  background: #fff; color: #0B0712; text-decoration: none;
  border-radius: 16px; padding: 12px 20px;
  font-weight: 600; line-height: 1.15;
  transition: transform 0.25s var(--ease), box-shadow 0.25s var(--ease);
  box-shadow: 0 8px 28px rgba(245, 241, 255, 0.12);
}
.appstore:hover { transform: translateY(-2px); box-shadow: 0 12px 36px rgba(245, 241, 255, 0.2); }
.appstore svg { width: 26px; height: 26px; }
.appstore .as-top { display: block; font-size: 0.68rem; font-weight: 500; opacity: 0.65; }
.appstore .as-main { display: block; font-family: var(--font-display); font-size: 1.15rem; font-weight: 700; }
.appstore .soon {
  margin-left: 6px; font-size: 0.62rem; font-weight: 700; letter-spacing: 0.1em;
  background: var(--grad); color: #fff; padding: 4px 8px; border-radius: 999px;
}
.appstore.big { padding: 15px 26px; }

/* ---------- hero ---------- */
.hero { padding: 84px 0 56px; }
.hero-grid {
  display: grid; grid-template-columns: 1.05fr 0.95fr;
  gap: 48px; align-items: center;
}
.hero-copy .eyebrow { margin-bottom: 18px; }
.lede { margin: 22px 0 32px; font-size: 1.14rem; max-width: 34rem; }
.hero-cta { display: flex; gap: 14px; flex-wrap: wrap; align-items: center; }
.trust {
  display: flex; gap: 12px; align-items: center; flex-wrap: wrap;
  margin-top: 26px; font-size: 0.85rem; color: var(--text-3);
}
.trust b { font-weight: 600; color: var(--text-2); }
.trust .dot { width: 4px; height: 4px; border-radius: 50%; background: var(--iris); }

.hero-visual { position: relative; display: flex; justify-content: center; }
.hero-glow {
  position: absolute; inset: -6% -12%;
  background: radial-gradient(closest-side, rgba(155, 92, 255, 0.32), transparent 72%);
  z-index: 0;
}

/* Subtle drifting sparkles (populated by script.js) — the tasteful ambient motion. */
.sparkle-field { position: absolute; inset: -10%; z-index: 1; pointer-events: none; }
.sparkle-field .spk {
  position: absolute; color: var(--lavender);
  opacity: 0; animation: twinkle 5s ease-in-out infinite;
}
.sparkle-field .spk svg { display: block; width: 100%; height: 100%; }
@keyframes twinkle {
  0%, 100% { opacity: 0; transform: translateY(6px) scale(0.6) rotate(0deg); }
  50% { opacity: var(--peak, 0.7); transform: translateY(-6px) scale(1) rotate(35deg); }
}

.phone {
  position: relative; z-index: 2;
  width: min(320px, 78vw);
  border-radius: 46px; overflow: hidden;
  border: 1px solid rgba(194, 154, 255, 0.22);
  box-shadow: 0 30px 80px rgba(0, 0, 0, 0.55), 0 8px 30px rgba(107, 40, 214, 0.35);
  background: var(--plum);
}
.phone img { display: block; width: 100%; height: auto; }
.phone.small { width: min(270px, 70vw); border-radius: 40px; }
.phone.tilt { transform: rotate(2.2deg); }

/* Featured app icon — a deliberate badge overlapping the phone (replaces the
   old random floating chips). */
.icon-badge {
  position: absolute; z-index: 3;
  top: 8%; left: -6%;
  width: 108px; height: 108px;
  border-radius: 25%;
  overflow: hidden;
  box-shadow: 0 18px 46px rgba(107, 40, 214, 0.5), 0 0 0 1px rgba(255,255,255,0.08) inset;
}
.icon-badge img { display: block; width: 100%; height: 100%; }

/* Gentle floats — the ambient life of the page. */
.float-y { animation: floatY 6.5s ease-in-out infinite; }
.float-y-slow { animation: floatY 8.5s ease-in-out 0.6s infinite; }
@keyframes floatY { 0%, 100% { transform: translateY(0) rotate(var(--rot, 0deg)); } 50% { transform: translateY(-12px) rotate(var(--rot, 0deg)); } }
.phone.tilt.float-y { --rot: 2.2deg; }

/* ---------- cards ---------- */
.feature-grid { display: grid; gap: 18px; grid-template-columns: repeat(3, 1fr); }

.card {
  background: linear-gradient(180deg, var(--card-2), var(--card));
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: 30px 26px;
  transition: transform 0.35s var(--ease), border-color 0.35s, box-shadow 0.35s;
}
.card:hover {
  transform: translateY(-4px);
  border-color: rgba(194, 154, 255, 0.3);
  box-shadow: 0 18px 44px rgba(107, 40, 214, 0.25);
}
.card h3 { margin: 16px 0 8px; }
.card p { font-size: 0.98rem; }

.f-icon {
  width: 46px; height: 46px; border-radius: 14px;
  display: grid; place-items: center; font-size: 1.3rem;
  background: color-mix(in srgb, var(--tint) 16%, transparent);
  border: 1px solid color-mix(in srgb, var(--tint) 30%, transparent);
}

/* ---------- splits ---------- */
.split { padding: 100px 0; }
.split-grid {
  display: grid; grid-template-columns: 1.05fr 0.95fr;
  gap: 60px; align-items: center;
}
.split-copy h2 { margin: 14px 0 16px; }
.split-copy p { font-size: 1.05rem; }
.split-copy i { color: var(--lavender); font-style: italic; }
.split-visual { display: flex; justify-content: center; position: relative; }
.dissolve-art { width: min(420px, 88vw); }

.mini-list { list-style: none; margin-top: 26px; display: grid; gap: 14px; }
.mini-list li { display: flex; gap: 12px; align-items: flex-start; font-size: 0.98rem; color: var(--text-2); }
.mini-list b { color: var(--text); font-weight: 600; }
.tick {
  flex: none; width: 22px; height: 22px; border-radius: 50%;
  display: grid; place-items: center; margin-top: 2px;
  background: rgba(79, 214, 168, 0.16); border: 1px solid rgba(79, 214, 168, 0.35);
}
.tick svg { width: 11px; height: 11px; stroke: var(--jade); }

/* One line on desktop (the five finishers used to wrap at 16:9); wrap is only
   allowed back in on small phones below, where the column gets narrow. */
.effect-chips { display: flex; gap: 7px; flex-wrap: nowrap; margin-top: 20px; }
.effect-chip {
  font-size: 0.82rem; font-weight: 600; color: var(--text); white-space: nowrap;
  background: rgba(155, 92, 255, 0.12);
  border: 1px solid rgba(155, 92, 255, 0.28);
  padding: 7px 12px; border-radius: 999px;
  transition: transform 0.2s var(--ease), background 0.2s;
}
.effect-chip:hover { transform: translateY(-2px); background: rgba(155, 92, 255, 0.2); }

/* ---------- quick add ---------- */
.quickadd { padding: 100px 0; }
.type-demo {
  max-width: 720px; margin: 0 auto;
  background: linear-gradient(180deg, var(--card-2), var(--card));
  border: 1px solid var(--line); border-radius: var(--r-lg);
  padding: 28px 30px;
  box-shadow: 0 24px 60px rgba(0, 0, 0, 0.4);
}
/* LAYOUT-JUMP FIX: the typing demo re-renders its text and chips every few
   seconds. Both live inside fixed-height boxes sized for their tallest state,
   so the cycle can never change the height of .type-demo (and never reflows
   the page below it). */
.type-field { display: flex; align-items: center; gap: 12px; min-height: 44px; }
.type-wand { color: var(--lavender); flex: none; }
.type-wand svg { width: 24px; height: 24px; }
.type-line {
  font-family: var(--font-display); font-size: clamp(1.15rem, 2.6vw, 1.5rem); font-weight: 600;
  display: inline-flex; align-items: center;
}
.caret { width: 2px; height: 1.25em; margin-left: 3px; background: var(--lavender); animation: blink 1.05s steps(1) infinite; }
@keyframes blink { 50% { opacity: 0; } }

/* Fixed height (not min-height): one chip row on wide screens, two/three
   rows reserved at narrower widths below. Chips appearing or vanishing can
   never grow or shrink this box. */
.parsed-chips {
  display: flex; gap: 8px; flex-wrap: wrap; align-content: flex-start;
  margin-top: 20px; height: 40px; overflow: hidden;
}
.pchip {
  font-size: 0.85rem; font-weight: 600; line-height: 1.4; color: var(--lavender);
  background: rgba(155, 92, 255, 0.13);
  border: 1px solid rgba(155, 92, 255, 0.26);
  padding: 7px 13px; border-radius: 999px;
  opacity: 0; transform: translateY(6px);
  animation: chipIn 0.4s var(--ease) forwards;
}
.pchip.apply { background: var(--grad); color: #fff; border-color: transparent; }
@keyframes chipIn { to { opacity: 1; transform: none; } }

/* ---------- magic planner ---------- */
.planner { padding: 100px 0; background: linear-gradient(180deg, transparent, rgba(26, 16, 64, 0.35) 16%, rgba(26, 16, 64, 0.35) 84%, transparent); }
.planner .split-visual { align-items: center; }

/* The Magic Planner screen, recreated: summary card + timed rows + breaks, with
   the wand-weave beat played over the rows (see .plan-weave and script.js). */
.plan-screen {
  position: relative;
  width: min(410px, 100%);
  background: linear-gradient(180deg, rgba(33,20,73,0.97), rgba(20,12,42,0.98));
  border: 1px solid var(--line); border-radius: 26px;
  padding: 16px 16px 18px;
  box-shadow: 0 34px 80px rgba(0,0,0,0.55), inset 0 1px 0 rgba(255,255,255,0.05);
}
.plan-topbar { display: flex; align-items: center; gap: 8px; padding: 2px 6px 12px; }
.plan-wand-tile { width: 20px; height: 20px; color: var(--lavender); display: inline-flex; }
.plan-wand-tile svg { width: 100%; height: 100%; }
.plan-screen-title { font-family: var(--font-display); font-weight: 700; font-size: 1.02rem; color: var(--text); }
.plan-done { margin-left: auto; font-weight: 600; font-size: 0.9rem; color: var(--lavender); }

.plan-summary {
  display: flex; align-items: center; gap: 12px;
  background: rgba(155,92,255,0.09); border: 1px solid rgba(155,92,255,0.18);
  border-radius: 16px; padding: 12px 14px; margin-bottom: 16px;
}
.plan-summary-icon {
  width: 42px; height: 42px; border-radius: 12px; flex: none;
  display: grid; place-items: center; color: #fff;
  background: var(--grad); box-shadow: 0 8px 20px rgba(155,92,255,0.4);
}
.plan-summary-icon svg { width: 22px; height: 22px; }
.plan-summary-title { font-family: var(--font-display); font-weight: 700; font-size: 1.02rem; color: var(--text); }
.plan-summary-sub { font-size: 0.8rem; color: var(--text-3); margin-top: 1px; }

.plan-label {
  font-size: 0.68rem; font-weight: 700; letter-spacing: 0.09em; text-transform: uppercase;
  color: var(--text-3); padding: 0 4px 10px;
}

/* The stage holds the rows and the weave overlay stacked; a min-height keeps
   the panel from resizing when the plan swaps or the wand plays (no reflow). */
.plan-stage { position: relative; min-height: 268px; }
.plan-rows { display: flex; flex-direction: column; gap: 8px; }
.plan-row {
  display: flex; gap: 11px; align-items: center;
  background: rgba(255,255,255,0.035); border: 1px solid var(--line);
  border-radius: 15px; padding: 10px 12px;
  animation: planRowIn 0.5s var(--ease) both; animation-delay: calc(var(--i) * 0.08s);
}
.plan-break {
  display: flex; justify-content: center;
  animation: planRowIn 0.5s var(--ease) both; animation-delay: calc(var(--i) * 0.08s);
}
.plan-break span {
  font-size: 0.72rem; font-weight: 600; color: var(--text-3);
  background: rgba(255,255,255,0.04); border: 1px solid var(--line);
  border-radius: 999px; padding: 4px 13px;
}
@keyframes planRowIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
.plan-time {
  display: flex; flex-direction: column; width: 48px; flex: none; line-height: 1.15;
}
.plan-time b { font-family: var(--font-display); font-weight: 700; font-size: 0.9rem; color: var(--lavender); }
.plan-time span { font-size: 0.68rem; color: var(--text-3); }
.plan-body { display: flex; flex-direction: column; gap: 5px; min-width: 0; flex: 1; }
.plan-name { font-size: 0.92rem; font-weight: 600; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.plan-tags { display: flex; gap: 5px; flex-wrap: wrap; }
.pt { font-size: 0.66rem; font-weight: 700; font-style: normal; padding: 3px 8px; border-radius: 999px; white-space: nowrap; }
.pt.over { color: #FF7D97; background: rgba(255,92,122,0.16); }
.pt.hi { color: #FF7D97; background: rgba(255,92,122,0.16); }
.pt.med { color: var(--amber); background: rgba(255,180,84,0.16); }
.pt.today { color: var(--lavender); background: rgba(155,92,255,0.18); }
.pt.win { color: var(--jade); background: rgba(79,214,168,0.16); }
.pt.list { color: var(--text-2); background: rgba(255,255,255,0.06); }

/* The wand-weave beat: the app's own PlanWeave, drawn closed-form on a canvas.
   Sits over the rows; fades in while re-planning, fades out onto the new plan. */
.plan-weave {
  position: absolute; inset: -4px; z-index: 3;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 12px;
  border-radius: 18px;
  background: radial-gradient(60% 60% at 50% 42%, rgba(33,20,73,0.86), rgba(20,12,42,0.94));
  opacity: 0; visibility: hidden;
  transition: opacity 0.4s var(--ease), visibility 0.4s;
}
.plan-weave.show { opacity: 1; visibility: visible; }
.plan-weave-canvas { width: 116px; height: 116px; }
.plan-weave-text { font-size: 0.9rem; font-weight: 600; color: var(--text-2); }
/* Rows sit calm under the scrim while the wand does the work. */
.plan-stage.weaving .plan-rows { opacity: 0.5; }
.plan-rows { transition: opacity 0.4s var(--ease); }

/* ---------- make it yours (themes + personalization) ---------- */
.themes { padding: 90px 0 110px; background: linear-gradient(180deg, transparent, rgba(26, 16, 64, 0.35) 20%, rgba(26, 16, 64, 0.35) 80%, transparent); }
.themes .feature-grid { margin-top: 48px; }
.theme-strip { display: flex; justify-content: center; align-items: center; }
.theme-strip .phone { margin: 0 -26px; }
.theme-strip .tilt-l { transform: rotate(-5deg) translateY(16px); z-index: 1; }
.theme-strip .tilt-r { transform: rotate(5deg) translateY(16px); z-index: 1; }
.theme-strip .center { z-index: 2; box-shadow: 0 34px 90px rgba(0, 0, 0, 0.65), 0 10px 34px rgba(107, 40, 214, 0.4); }
.swatch-row { display: flex; justify-content: center; gap: 14px; margin-top: 44px; }
.swatch {
  width: 26px; height: 26px; border-radius: 50%; background: var(--c);
  border: 2px solid rgba(245, 241, 255, 0.25);
  box-shadow: 0 4px 16px color-mix(in srgb, var(--c) 55%, transparent);
  transition: transform 0.25s var(--ease);
}
.swatch:hover { transform: scale(1.25); }

/* ---------- privacy ---------- */
.privacy { padding: 40px 0 100px; }
.privacy-band {
  display: grid; grid-template-columns: auto 1fr auto; gap: 34px; align-items: center;
  background: linear-gradient(135deg, rgba(79, 214, 168, 0.1), rgba(26, 16, 64, 0.65));
  border: 1px solid rgba(79, 214, 168, 0.25);
  border-radius: var(--r-lg); padding: 40px 44px;
}
.privacy-badge {
  width: 74px; height: 74px; border-radius: 22px;
  display: grid; place-items: center;
  background: rgba(79, 214, 168, 0.14); border: 1px solid rgba(79, 214, 168, 0.35);
}
.privacy-badge svg { width: 38px; height: 38px; stroke: var(--jade); }
.privacy-copy h2 { font-size: clamp(1.5rem, 2.6vw, 2rem); margin-bottom: 10px; }
.privacy-facts { display: flex; gap: 26px; }
.privacy-facts div { text-align: center; }
.privacy-facts b { font-family: var(--font-display); font-size: 2rem; font-weight: 800; color: var(--jade); display: block; }
.privacy-facts span { font-size: 0.8rem; color: var(--text-3); letter-spacing: 0.08em; text-transform: uppercase; }

/* ---------- faq ---------- */
.faq { padding: 60px 0 110px; }
.faq details {
  border: 1px solid var(--line); border-radius: var(--r-md);
  background: rgba(26, 16, 64, 0.4);
  padding: 20px 24px; margin-bottom: 12px;
  transition: border-color 0.25s;
}
.faq details[open] { border-color: rgba(194, 154, 255, 0.35); }
.faq summary {
  cursor: pointer; font-weight: 600; font-size: 1.02rem; color: var(--text);
  list-style: none; position: relative; padding: 13px 32px 13px 0;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: "+"; position: absolute; right: 2px; top: 50%; transform: translateY(-50%);
  font-family: var(--font-display); font-size: 1.3rem; color: var(--lavender);
  transition: transform 0.25s var(--ease);
}
.faq details[open] summary::after { transform: translateY(-50%) rotate(45deg); }
.faq details p { margin-top: 12px; font-size: 0.98rem; }

/* ---------- cta ---------- */
.cta { padding: 20px 0 120px; }
.cta-band {
  position: relative; text-align: center; overflow: hidden;
  background:
    radial-gradient(42rem 26rem at 50% -30%, rgba(155, 92, 255, 0.3), transparent 65%),
    linear-gradient(180deg, var(--card-2), var(--plum));
  border: 1px solid rgba(194, 154, 255, 0.22);
  border-radius: 36px; padding: 68px 30px 76px;
}
.cta-burst {
  position: absolute; top: -40px; right: 6%; width: 130px; opacity: 0.8;
  animation: floatY 8s ease-in-out infinite;
}
.cta-icon {
  width: 96px; height: 96px; margin: 0 auto 24px; border-radius: 24%;
  overflow: hidden; position: relative; z-index: 1;
  box-shadow: 0 18px 46px rgba(107, 40, 214, 0.55);
}
.cta-icon img { display: block; width: 100%; height: 100%; }
.cta-band h2 { font-size: clamp(2rem, 4.4vw, 3rem); position: relative; z-index: 1; }
.cta-band p { margin: 14px 0 32px; font-size: 1.08rem; position: relative; z-index: 1; }
.cta-band .appstore { position: relative; z-index: 1; }

/* ---------- footer ---------- */
.footer { border-top: 1px solid var(--line); padding: 54px 0 60px; }
.footer-inner { display: grid; place-items: center; gap: 14px; text-align: center; }
.footer .wordmark { height: 42px; width: auto; }
.foot-line { color: var(--text-3); font-size: 0.92rem; }
.foot-line a {
  color: var(--text-2); text-decoration: none; font-weight: 500;
  border-bottom: 1px solid rgba(194, 154, 255, 0.35);
  transition: color 0.2s, border-color 0.2s;
}
.foot-line a:hover { color: var(--text); border-bottom-color: var(--lavender); }
.foot-links { display: flex; gap: 26px; }
.foot-links a { color: var(--text-2); font-size: 0.92rem; text-decoration: none; }
.foot-links a:hover { color: var(--text); }
.copyright { color: var(--text-3); font-size: 0.8rem; }

/* ---------- reveal ---------- */
.reveal { opacity: 0; transform: translateY(20px); transition: opacity 0.65s var(--ease), transform 0.65s var(--ease); }
.reveal.in { opacity: 1; transform: none; }

/* ---------- responsive ---------- */
@media (max-width: 960px) {
  /* minmax(0, 1fr) (not plain 1fr = minmax(auto,1fr)) so a wide child — e.g. the
     Magic Planner panel's rows — can't stretch the single column past the padded
     wrap and cause horizontal overflow. */
  .hero-grid, .split-grid { grid-template-columns: minmax(0, 1fr); gap: 44px; }
  .split-grid.flip .split-visual { order: 2; }
  .hero { padding-top: 56px; }
  .hero-copy { text-align: center; }
  .lede { margin-inline: auto; }
  .hero-cta, .trust { justify-content: center; }
  .feature-grid { grid-template-columns: 1fr 1fr; }
  .privacy-band { grid-template-columns: 1fr; text-align: center; justify-items: center; }
  .nav-inner { position: relative; }
  .nav-toggle { display: flex; }
  .nav-links {
    position: absolute; top: 100%; left: 0; right: 0;
    flex-direction: column; gap: 0;
    padding: 6px 24px 18px;
    background: rgba(11, 7, 18, 0.97);
    backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
    border-bottom: 1px solid var(--line);
    max-height: 0; opacity: 0; visibility: hidden; overflow: hidden;
    transition: max-height 0.3s var(--ease), opacity 0.25s var(--ease), visibility 0.3s;
  }
  .nav.open .nav-links { max-height: 72vh; opacity: 1; visibility: visible; }
  .nav-links a { padding: 14px 2px; border-bottom: 1px solid rgba(255, 255, 255, 0.06); font-size: 1.05rem; }
  .icon-badge { left: 2%; width: 86px; height: 86px; }
}
/* Reserved heights for the typing demo track its wrap points, not the shared
   breakpoints: chips wrap to two rows below ~768px and three below ~430px;
   the typed line itself can wrap to two lines below ~520px. */
@media (max-width: 768px) {
  .parsed-chips { height: 84px; }
}
@media (max-width: 620px) {
  .feature-grid { grid-template-columns: 1fr; }
  .theme-strip .tilt-l, .theme-strip .tilt-r { display: none; }
  .privacy-facts { gap: 18px; }
}
@media (max-width: 520px) {
  .type-field { min-height: 72px; }
  /* The narrow single-column copy can't hold five finishers on one line; let
     them wrap here (the 16:9 desktop case they were fixed for stays one line). */
  .effect-chips { flex-wrap: wrap; gap: 8px; }
  .effect-chip { font-size: 0.85rem; padding: 8px 14px; }
}
@media (max-width: 430px) {
  .parsed-chips { height: 128px; }
}
@media (max-width: 349px) {
  .parsed-chips { height: 172px; }
}

/* ---------- legal pages (privacy / terms) ---------- */
.legal-hero { padding: 64px 0 20px; text-align: center; }
.legal-hero .eyebrow { justify-content: center; margin-bottom: 16px; }
.legal-hero h1 { font-size: clamp(2.1rem, 5vw, 3rem); }
.legal-updated { margin-top: 12px; color: var(--text-3); font-size: 0.92rem; }
.legal-content { padding: 40px 0 90px; }
.legal-content h2 {
  font-size: 1.3rem; margin-top: 44px; margin-bottom: 14px; color: var(--text);
}
.legal-content h2:first-child { margin-top: 0; }
.legal-content p { margin-bottom: 16px; }
.legal-content p:last-child { margin-bottom: 0; }
.legal-content ul { margin: 0 0 16px 20px; color: var(--text-2); }
.legal-content li { margin-bottom: 8px; }
.legal-content a { color: var(--lavender); }
.legal-content a:hover { color: var(--text); }
.legal-content strong { color: var(--text); }
.legal-section + .legal-section { border-top: 1px solid var(--line); padding-top: 32px; margin-top: 32px; }
.legal-back {
  display: inline-flex; align-items: center; gap: 6px;
  color: var(--text-2); text-decoration: none; font-size: 0.92rem; font-weight: 500;
  margin-bottom: 28px; transition: color 0.2s;
}
.legal-back:hover { color: var(--text); }

/* ---------- reduced motion: still, calm, no ambient movement ---------- */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation: none !important; transition: none !important; }
  .reveal { opacity: 1; transform: none; }
  .plan-row { opacity: 1; transform: none; }
  .pchip { opacity: 1; transform: none; }
  .caret { opacity: 1; }
}

/* ============ 2026-07 refresh: nav icon, wand mark, live poof demo ============ */

/* The app icon in the nav: the first touchpoint, static and always present. */
.brand { gap: 10px; }
.brand-icon {
  width: 34px; height: 34px; border-radius: 8.5px;
  border: 1px solid rgba(255, 255, 255, 0.14);
  box-shadow: 0 2px 12px rgba(107, 40, 214, 0.45);
}

/* The wand, inline (matches the in-app WandMark: diagonal shaft + tip sparkle). */
.wand-mark { display: inline-flex; width: 16px; height: 16px; color: var(--electric, #9B5CFF); }
.wand-mark svg { width: 100%; height: 100%; }

/* ---- Live poof demo (a short list mirroring TaskCardView + the blip) ----
   The container is a FIXED height sized for three rows plus the undo pill, so a
   row poofing out or a new one sliding in never changes the page height. */
.poof-demo {
  position: relative;
  width: min(400px, 100%);
  height: 236px;
  margin: 0 auto;
}
.poof-list { list-style: none; margin: 0; padding: 0; }
.poof-row {
  position: relative; overflow: hidden;
  display: flex; align-items: center; gap: 12px;
  padding: 13px 16px; margin-bottom: 10px;
  background: rgba(38, 28, 66, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.07);
  border-radius: 16px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);
  max-height: 80px;
  transition: max-height 0.42s var(--ease), padding 0.42s var(--ease),
              margin 0.42s var(--ease), opacity 0.3s ease, transform 0.3s ease,
              border-color 0.3s ease;
}
.poof-row:last-child { margin-bottom: 0; }
.demo-emoji { font-size: 20px; flex: none; }
.demo-title {
  flex: 1;
  font-weight: 600; font-size: 16.5px; color: #fff;
  position: relative; white-space: nowrap; overflow: hidden;
}
/* The strike draws across the glyphs, like the app's swipe-complete. */
.demo-title::after {
  content: ""; position: absolute; left: 0; top: 54%;
  height: 2px; width: 100%; background: rgba(255, 255, 255, 0.75);
  transform: scaleX(0); transform-origin: left center;
  transition: transform 0.18s ease-out;
}
.poof-row.marked .demo-title::after { transform: scaleX(1); }
.demo-check {
  width: 30px; height: 30px; border-radius: 50%; flex: none;
  display: grid; place-items: center;
  border: 2px solid rgba(155, 92, 255, 0.65); color: transparent;
  transition: background 0.18s ease-out, color 0.18s ease-out, transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.demo-check svg { width: 15px; height: 15px; }
.poof-row.marked .demo-check {
  background: linear-gradient(135deg, #C29AFF, #6B28D6);
  border-color: transparent; color: #fff; transform: scale(1.1);
}
/* The vanish: a small pop as the dust takes over (mirrors CompletionEffect.poof). */
.poof-row.poofing { opacity: 0; transform: scale(1.06); }
/* The list closing up behind the poof, and a new row sliding in at the bottom. */
.poof-row.collapsing {
  max-height: 0; padding-top: 0; padding-bottom: 0; margin-bottom: 0;
  opacity: 0; border-color: transparent; transform: scale(1);
}
.poof-row.entering {
  max-height: 0; padding-top: 0; padding-bottom: 0;
  opacity: 0; transform: translateY(6px);
}

.demo-burst { position: absolute; left: 0; right: 0; top: 0; height: 50px; pointer-events: none; }
.demo-burst i {
  position: absolute; left: 50%; top: 50%;
  width: var(--s); height: var(--s); border-radius: 50%;
  background: var(--c);
  opacity: 0;
}
.demo-burst i.spark {
  border-radius: 0;
  background: transparent;
  color: var(--c);
  width: auto; height: auto; font-size: var(--s); line-height: 1;
}
.demo-burst.go i {
  animation: demoDust 0.5s ease-out forwards;
  animation-delay: var(--d);
}
@keyframes demoDust {
  0%   { opacity: 0; transform: translate(-50%, -50%) scale(0.6); }
  18%  { opacity: 0.95; }
  100% { opacity: 0; transform: translate(calc(-50% + var(--x)), calc(-50% + var(--y))) scale(1); }
}

.demo-undo {
  position: absolute; left: 50%; bottom: 0; transform: translateX(-50%) translateY(8px);
  display: flex; align-items: center; gap: 8px;
  white-space: nowrap;
  padding: 10px 12px 10px 16px;
  font-size: 13.5px; color: rgba(255, 255, 255, 0.85);
  background: rgba(38, 28, 66, 0.95);
  border: 1px solid rgba(255, 255, 255, 0.07);
  border-radius: 999px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);
  opacity: 0; transition: opacity 0.3s ease, transform 0.3s ease;
}
.demo-undo b { color: #fff; font-weight: 600; }
.demo-spark { color: #C29AFF; }
.demo-undo-btn {
  padding: 5px 14px; border-radius: 999px; font-weight: 700; color: #fff;
  background: linear-gradient(135deg, #C29AFF, #6B28D6);
}
.poof-demo.done .demo-undo { opacity: 1; transform: translateX(-50%) translateY(0); }

@media (prefers-reduced-motion: reduce) {
  .poof-row, .poof-row.poofing { transition: opacity 0.3s ease; transform: none; }
  .demo-burst.go i { animation: none; }
}

/* ============================================================
   LAUNCH COUNTDOWN (2026-08) — the big one in the bottom CTA
   band, the compact pill in the nav, and the "follow for launch"
   CTA that replaces the old go-nowhere "Get Poof" buttons.

   Built out of the page's existing vocabulary: plum card gradient,
   lavender hairline borders, the aurora --grad-bright for numerals,
   the same uppercase micro-label as .plan-label / .privacy-facts.
   The only new motion is a slow aurora sheen across the tiles and a
   one-frame lift on the seconds — both killed by the global
   prefers-reduced-motion rule above, and the JS skips the seconds
   lift entirely when reduced motion is on.

   NO-LAYOUT-SHIFT CONTRACT: the markup ships with "––" placeholders
   and every tile/segment is min-width'd for its widest real value
   with tabular figures, so the box is final-size before script.js
   runs and never resizes as the digits roll.
   ============================================================ */

/* ---------- big countdown (bottom CTA) ---------- */
.countdown { position: relative; z-index: 1; margin: 30px 0 30px; }
.countdown .eyebrow { margin-bottom: 18px; }

.cd-grid {
  display: flex; justify-content: center; align-items: stretch;
  gap: 14px;
}

.cd-unit {
  position: relative; overflow: hidden;
  flex: 0 0 auto; min-width: 122px;
  padding: 20px 12px 15px;
  background: linear-gradient(180deg, rgba(33, 20, 73, 0.94), rgba(20, 12, 42, 0.9));
  border: 1px solid rgba(194, 154, 255, 0.22);
  border-radius: 24px;
  box-shadow: 0 18px 44px rgba(0, 0, 0, 0.42), inset 0 1px 0 rgba(255, 255, 255, 0.06);
}
/* Aurora hairline along the top edge — the same trick the app uses to make a
   dark card look lit rather than flat. */
.cd-unit::before {
  content: ""; position: absolute; inset: 0 0 auto; height: 1px;
  background: linear-gradient(90deg, transparent, var(--lavender), transparent);
  opacity: 0.55;
}
/* Slow aurora sheen sweeping tile to tile — staggered by --i. */
.cd-unit::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(100deg, transparent 38%, rgba(194, 154, 255, 0.16) 50%, transparent 62%);
  transform: translateX(-120%);
  animation: cdSheen 7s var(--ease) infinite;
  animation-delay: calc(var(--i, 0) * 0.35s);
}
@keyframes cdSheen {
  0%, 62% { transform: translateX(-120%); }
  88%, 100% { transform: translateX(120%); }
}

.cd-num {
  display: block;
  font-family: var(--font-display);
  font-size: clamp(2.5rem, 6.4vw, 3.5rem); line-height: 1;
  font-weight: 800; letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums; font-feature-settings: "tnum" 1;
  background: var(--grad-bright);
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent; color: transparent;
}
.cd-label {
  display: block; margin-top: 10px;
  font-size: 0.66rem; font-weight: 700; letter-spacing: 0.17em;
  text-transform: uppercase; color: var(--text-3);
}

/* The seconds tile is the alive one: a breathing glow, plus a one-frame lift
   each time the number rolls (script.js re-triggers .roll). */
.cd-unit.cd-seconds { border-color: rgba(194, 154, 255, 0.34); }
/* Breathe the hairline, not the numeral — the numeral's animation slot is
   reserved for .roll below, and two animations on one element would fight. */
.cd-unit.cd-seconds::before { animation: cdBreathe 2.6s ease-in-out infinite; }
@keyframes cdBreathe { 0%, 100% { opacity: 0.45; } 50% { opacity: 1; } }
.cd-num.roll { animation: cdRoll 0.42s var(--ease); }
@keyframes cdRoll {
  0% { transform: translateY(-7px); opacity: 0.45; }
  100% { transform: none; opacity: 1; }
}

/* The date line under the tiles: this is the accessible, never-stale statement
   of the launch date (the ticking tiles themselves are aria-hidden so screen
   readers aren't spammed once a second). */
/* Scoped with .countdown so these win over the broader `.cta-band p` rule. */
.countdown .cd-date {
  margin: 20px auto 0; max-width: 34rem;
  font-size: 0.95rem; color: var(--text-3); letter-spacing: 0.01em;
}
.countdown .cd-date b { color: var(--text-2); font-weight: 600; }

/* Post-launch state — swapped in by script.js the moment the target passes, so
   the page never shows negative numbers. */
.cd-live { display: none; }
.countdown.is-launched .cd-pre { display: none; }
.countdown.is-launched .cd-live { display: block; }
.cd-live-mark {
  display: inline-flex; align-items: center; gap: 10px;
  font-family: var(--font-display); font-weight: 800;
  font-size: clamp(2rem, 5.2vw, 3rem); letter-spacing: -0.02em;
  background: var(--grad-bright);
  -webkit-background-clip: text; background-clip: text;
  -webkit-text-fill-color: transparent; color: transparent;
}
.countdown .cd-live-sub { margin: 12px auto 0; max-width: 34rem; font-size: 1.02rem; color: var(--text-2); }

/* ---------- compact countdown (nav) ---------- */
.cd-mini {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 7px 13px; border-radius: 999px;
  text-decoration: none; white-space: nowrap;
  background: rgba(155, 92, 255, 0.12);
  border: 1px solid rgba(155, 92, 255, 0.3);
  color: var(--text); font-size: 0.82rem; font-weight: 700; line-height: 1;
  font-variant-numeric: tabular-nums; font-feature-settings: "tnum" 1;
  transition: border-color 0.25s var(--ease), background 0.25s;
}
.cd-mini:hover { background: rgba(155, 92, 255, 0.2); border-color: rgba(194, 154, 255, 0.5); }
.cd-mini .cdm-spark { color: var(--lavender); font-weight: 400; }
.cd-mini .cdm-time { display: inline-flex; align-items: baseline; gap: 6px; }
/* 2ch each so 9 -> 10 -> 11 can't nudge the pill's width. */
.cd-mini .cdm-seg > b { display: inline-block; min-width: 2ch; text-align: right; font-weight: 700; }
.cd-mini .cdm-seg > i { font-style: normal; font-weight: 600; color: var(--text-3); }
.cd-mini .cdm-live { display: none; letter-spacing: 0.06em; text-transform: uppercase; font-size: 0.74rem; }
.cd-mini.is-launched .cdm-time { display: none; }
.cd-mini.is-launched .cdm-live { display: inline; }

/* ---------- follow-for-launch CTA ---------- */
.btn-lg { padding: 15px 28px; font-size: 1.04rem; }
.btn .btn-ico { width: 18px; height: 18px; flex: none; }
.cta-actions {
  display: flex; justify-content: center; align-items: center;
  gap: 14px; flex-wrap: wrap;
  position: relative; z-index: 1;
}
/* Pre-launch the App Store badge is a statement, not a link — there is nothing
   to link to yet, so it renders as a static badge instead of a dead anchor. */
.appstore.is-static { cursor: default; }
.appstore.is-static:hover { transform: none; box-shadow: 0 8px 28px rgba(245, 241, 255, 0.12); }
/* Mobile-drawer-only follow link (the nav button is hidden on small screens). */
.nav-follow { display: none; }
.nav-links a.nav-follow { color: var(--lavender); font-weight: 700; }

/* ---------- countdown responsive ---------- */
@media (max-width: 960px) {
  /* In the drawer the follow CTA reappears as a link so it's never lost. */
  .nav-links a.nav-follow { display: block; }
}
@media (max-width: 700px) {
  /* Nav gets tight: the pill is the priority, the button moves into the drawer. */
  .nav-cta .btn-primary { display: none; }
}
@media (max-width: 620px) {
  .cd-grid { flex-wrap: wrap; gap: 10px; }
  .cd-unit { flex: 0 0 calc(50% - 5px); min-width: 0; padding: 16px 10px 12px; }
  .cd-num { font-size: clamp(2.2rem, 11vw, 2.9rem); }
}
@media (max-width: 420px) {
  /* Drop the seconds from the nav pill before it can crowd the hamburger. */
  .cd-mini { padding: 7px 11px; gap: 6px; font-size: 0.78rem; }
  .cd-mini .cdm-sec { display: none; }
}

/* ============================================================
   MOBILE PASS (2026-08-02)
   A light correctness pass ahead of the LinkedIn post, which
   lands most of this week's traffic on a phone. Only two kinds
   of rule live here, so the desktop layout is untouched:

     1) touch-target expansions that cost ZERO layout pixels —
        vertical padding on inline links (an inline box's padding
        is hit-testable but does not grow the line box), or a
        transparent ::after "hit plate" where a border-bottom
        rules padding out;
     2) small-screen spacing, inside max-width queries.

   Nothing here restructures, restyles, or re-types the page, and
   nothing touches the countdown's target or the CTA destinations.
   ============================================================ */

/* ---- Anchor targets clear the sticky nav ----------------------------
   .nav is sticky and 74px tall, and nothing set a scroll-margin, so every
   drawer link (#magic, #quickadd, …) parked its section's eyebrow and
   heading underneath the bar. 88px = the nav plus a little air. */
section[id], header[id], body[id] { scroll-margin-top: 88px; }

/* ---- Touch targets: 44x44 minimum -----------------------------------
   Measured at 375x812 before this pass: brand 34px tall, nav countdown
   pill 28.5px, "Email me at launch" 23px, footer "Zachary Carter" 20px,
   the footer link row broken onto three lines, and the inline links on
   privacy.html / terms.html 21.5px. */

/* The brand lockup was only as tall as its 34px icon. .nav-inner is a
   fixed 74px with centred items, so a 44px floor moves nothing. */
.brand { min-height: 44px; }

/* The countdown pill keeps its 28px look — a 44px lozenge would out-weigh
   the 34px app icon beside it — so the hit area is grown with a transparent
   plate instead. `inset` resolves against the PADDING box (26.5px tall here,
   i.e. the 28.5px pill minus its 1px borders), so -9px is what actually
   buys 44.5px. -4px horizontally leaves 3px of clearance to the hamburger,
   which sits 6px away and is itself fully tappable (verified). */
.cd-mini { position: relative; }
.cd-mini::after {
  content: ""; position: absolute; inset: -9px -4px;
  border-radius: inherit;
}

/* Inline links with no underline of their own: vertical padding grows the
   hit box without touching the line box, so the text never moves and the
   link can still wrap mid-sentence. 12px each side => 45.5px. */
.legal-content p a, .legal-content li a { padding: 12px 0; }

/* These two carry a border-bottom, so padding would drop the underline
   away from the text. They get the same transparent plate instead.
   `nowrap` is load-bearing here, not cosmetic: a plate is one box, so if
   the link fragmented across two lines the plate would cover the gap
   between the fragments instead of the link. Neither string is long
   enough to need to break. */
.notify-line a, .foot-line a { position: relative; white-space: nowrap; }
.notify-line a::after, .foot-line a::after {
  content: ""; position: absolute; left: 0; right: 0;
  top: 50%; height: 44px; transform: translateY(-50%);
}

/* ---- The mobile drawer has to be reachable in landscape ---------------
   .nav-links is capped at 72vh with `overflow: hidden`. Portrait that is
   ~585px against 421px of links, so it never bites. Rotate the phone
   (measured at 844x390: cap 281px, content 421px) and the last three
   items — Privacy, FAQ, and the "Follow for launch day" CTA — are clipped
   with no way to reach them. Let the drawer scroll when it has to; on a
   tall screen the content still fits and nothing scrolls. Scoped to the
   breakpoint that actually turns .nav-links into a drawer. */
@media (max-width: 960px) {
  .nav-links { overflow-x: hidden; overflow-y: auto; -webkit-overflow-scrolling: touch; }
}

/* The footer link row: at 375px the three links were squeezed into ~50px
   columns and each broke onto two or three lines ("Terms / of / Service").
   Let the row wrap as a row instead, and pad each link to a 44px target.
   The negative block margin cancels that padding optically, so the
   footer's vertical rhythm is unchanged at every width. */
.foot-links {
  flex-wrap: wrap; justify-content: center;
  column-gap: 24px; row-gap: 0; margin-block: -11px;
}
.foot-links a { display: inline-block; padding: 11px 0; white-space: nowrap; }

/* ---- Small-screen spacing ------------------------------------------- */
@media (max-width: 620px) {
  /* .privacy-band and .cta-band ARE the .wrap element, so their own padding
     shorthand overrode .wrap's 28px gutter: both cards sat flush against
     both screen edges with their borders and rounded corners clipped by the
     viewport. Put the gutter on the section and pull the card's inner
     padding in to match. */
  .privacy { padding: 24px 20px 72px; }
  .privacy-band { padding: 34px 24px; }
  .cta { padding: 12px 20px 72px; }
  .cta-band { padding: 52px 20px 56px; }
  /* `.cta-band p` sets margin-bottom: 32px, which on the last line stacked
     with the band's own bottom padding into ~110px of dead space. */
  .cta-band .notify-line { margin-bottom: 0; }

  /* 100px of section padding reads right at 1440px and bloated at 375px —
     it put 200px of empty page between every pair of sections. */
  .split, .quickadd, .planner { padding: 72px 0; }
  .themes { padding: 66px 0 80px; }
  .faq { padding: 44px 0 76px; }
  .hero { padding: 44px 0; }
  .section-head { margin-bottom: 40px; }

  /* .eyebrow is an inline-FLEX row, so when its text wraps (only the hero's
     "The To-Do App With a Little Magic" does, and only under ~400px) the ✦
     stays pinned to the far left of the box while the text centres itself
     line by line — the spark reads as detached from the words. inline-block
     lets the mark flow with the text and wrap alongside it. margin-bottom
     still applies (it would not on plain `inline`), and the `gap` the flex
     row was using is replaced by a margin on the mark. */
  .eyebrow { display: inline-block; }
  .eyebrow > .spark, .eyebrow > .wand-mark { margin-right: 7px; }
  .eyebrow > .wand-mark { vertical-align: -2px; }

  /* Legal pages: same story, one long column of text. */
  .legal-hero { padding: 44px 0 12px; }
  .legal-content { padding: 30px 0 68px; }
}

/* ==========================================================================
   HERO COUNTDOWN + NAV PILL VISIBILITY (2026-08-02)
   The hero countdown is the SAME component as the one in the CTA band, one
   size down — same tiles, sheen, seconds-breathe and roll, so there's one
   countdown design on the site rather than two that merely resemble each
   other. Only scale, spacing and alignment change here.
   ========================================================================== */

.countdown.cd-hero {
  margin: 26px 0 30px;
  text-align: left;
}
.countdown.cd-hero .eyebrow { margin-bottom: 12px; }
.countdown.cd-hero .cd-grid { justify-content: flex-start; gap: 10px; }

/* ~72% of the CTA-band tile. Big enough to be the thing your eye lands on
   after the headline, small enough that it doesn't outrank it. */
.countdown.cd-hero .cd-unit {
  min-width: 88px;
  padding: 14px 10px 11px;
  border-radius: 18px;
  box-shadow: 0 12px 30px rgba(0, 0, 0, 0.38), inset 0 1px 0 rgba(255, 255, 255, 0.06);
}
.countdown.cd-hero .cd-num { font-size: clamp(1.75rem, 4.2vw, 2.4rem); }
.countdown.cd-hero .cd-label { margin-top: 7px; font-size: 0.58rem; letter-spacing: 0.15em; }
.countdown.cd-hero .cd-live { text-align: left; }

/* Centre with the rest of the copy on the stacked layout. */
@media (max-width: 960px) {
  .countdown.cd-hero { text-align: center; }
  .countdown.cd-hero .cd-grid { justify-content: center; }
  .countdown.cd-hero .cd-live { text-align: center; }
}

/* Four tiles no longer fit one row much below 420px; 2x2 keeps them legible
   instead of shrinking the numerals into the noise. */
@media (max-width: 420px) {
  .countdown.cd-hero .cd-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 8px;
  }
  .countdown.cd-hero .cd-unit { min-width: 0; }
}

/* The nav pill yields whenever a bigger countdown is on screen. Visibility +
   width, not display:none — the nav's flex layout stays put, so nothing else
   in the bar shifts as it comes and goes. */
.cd-mini {
  transition: opacity 0.28s var(--ease), transform 0.28s var(--ease);
}
.cd-mini.is-hidden {
  opacity: 0;
  transform: translateY(-6px);
  pointer-events: none;
}
@media (prefers-reduced-motion: reduce) {
  .cd-mini { transition: none; }
}


/* ==========================================================================
   LANDING POLISH (2026-08-02, evening)
   ========================================================================== */

/* 1 · Nav app icon stays completely static — no drift, no settle on load.
   Nothing was animating it, but this pins it so nothing can. */
.brand-icon { animation: none !important; transform: none !important; transition: none !important; }

/* 2 · Hero countdown centres its tiles and its label, on every width.
   (It previously left-aligned with the copy column on desktop.) */
/* Centre each tile's number over its own label. The block itself stays left,
   flush with the headline and lede — centring the group as well left it
   visibly inset from the copy above it. */
.countdown.cd-hero .cd-unit { text-align: center; }
.countdown.cd-hero .cd-num,
.countdown.cd-hero .cd-label { text-align: center; }

/* 3 · The App Store button takes the same pill as the follow CTA, so the two
   read as a matched pair wherever they sit together — hero and CTA band. */
.appstore { border-radius: 999px; padding: 12px 24px; }

/* 4 · A touch more air between the countdown pill and the follow button. */
.nav-cta { gap: 18px; }

/* 5 · CTA band: the floating burst is gone (see index.html); the panel now
   carries a softer directional gradient of its own plus a quiet stardust
   field, so the corner reads as depth rather than a pasted-on ornament. */
.cta-band {
  background:
    radial-gradient(38rem 22rem at 78% -18%, rgba(194, 154, 255, 0.20), transparent 62%),
    radial-gradient(42rem 26rem at 22% 118%, rgba(107, 40, 214, 0.28), transparent 66%),
    linear-gradient(158deg, #241546 0%, #1B1038 46%, var(--plum) 100%);
}
.cta-dust { position: absolute; inset: 0; pointer-events: none; z-index: 0; }
.cta-dust i {
  position: absolute; border-radius: 50%;
  background: var(--lavender);
  box-shadow: 0 0 6px rgba(194, 154, 255, 0.6);
}


/* ==========================================================================
   HEADLINE PERIOD FIX (2026-08-02)
   Plus Jakarta Sans gives its period unusually wide sidebearings. On headlines
   it reads as a gap — and this site's headlines are full of them ("Do. Done.
   Gone.", "Get It Done. Watch It Vanish."). This face carries ONE glyph, the
   period, subset from Inter and inlined as base64 (1.2 KB, no extra request).
   Listed first in the stack, the browser takes U+002E from here and every
   other character from Plus Jakarta Sans.
   Display type only — body copy at normal size doesn't show the problem.
   ========================================================================== */
@font-face {
  font-family: PeriodFix;
  src: url(data:font/woff2;base64,d09GMgABAAAAAASwABEAAAAAClAAAARHAAQAQgAAAAAAAAAAAAAAAAAAAAAAAAAAP0hWQVKBBz9NVkFSgSgGYD9TVEFUgiInNAA0L4EkEQgKLEswgV4BNgIkAwgLBgAEIAWHNAcgG0MJKB6FTdlXOM4wbJ50lY+8uM6rVjw8b8fbuW/efE5ET1LBC7ukomrhal3JqEL61H7tIeY7pBMxRCSdf/M9zDIhM0QSIRM1MfD0dXtLh+eQQOM18SeMQglh7eNe4zf5L2W8gWyKdZEg1YoNM54OVBpgLCSZYCn1SgM6Pb/xEz0Qi21LXWx+G3Ec4kOqRwh9PwE6g2sABNqrx0pwhHoltRwA4HWvA6CWA7Wc6+VfBgFCUiIJhXzwMu8/b3kGSRKgSWnyRU0NEECWYbr8gqoGKJz0T3vVWRwFEKgEli7qz8alY8XXexMO/gQ8fJxJz1+MfXixxrJfrFZSTsqf4G7QSZ+4PT3wCJUFkowAgEOOrQN8GMuzXj/QEZp+SesRkE8o/9BfpxCaFOisD4xWf+FF1lVdDK48eVpXJ86+rCTX5dQbyCNh2b480Zknd7rbY571pk/96F+BFDN0IyBm6iWYpQ8wWz9gjkHAXKNgOM8kCIFxqoDxPrl1QowGhZCkWE16GSGISbFNMDkdBY1Tgpha9IfCacX1KPIM5wOCQkiKKlmkkV1QfdJ6Q4+7u7UMPWP2rkmTxj9aywGJ06YaBKga9UeZIj229XX2F7eQn3TWpqoijW6Ggv5A1LIGqhCrKa6HiBgXdLqp8UDofWGCLEbzRFrNk2ibMFmWjuIp9LIwVVb052n/5PUIcfCgHpBARqBCRwAZENXJt34b13zXets3rv56aDV9+XZsmA1AIIGecAxwypRGI6MGur54ncFgWUPfUfvIzkH14qtvd9WrLz73TO/n1KXXtO7bt2PLxv/FcOOWHfuuK3MUa+X29e+9P0deXbcY/5qbItJrmKe1bz/tygW89L/Se9P2nkfd3p6Ob0eb3ds3qGr77v25135brmmNaKradxP99lVTXNfm+28/Vn37/Q9/x3/wTCSrublL957D9A16du/SfB2BbMH37dBXT9yp7a1FE/jzuWk1rHvfnm775cHHmn5BIYHgdmNd7ibbybfS3iaVdaymba8CyfUqF2kRAEAn9c4RGkRuxmoIQovVSNq6G4XjvCHrmYzS1PT1N7jCYSVB91ygCFXciHFaYy3GG8zdmKA9nsJE3e7GJJ3xPCbrzduYojW+xlT9+RnTtMcGTDeaXZihNbWnmdydZnF/ms3DaQ6Pp7k8neZxjVpnWvhI5mtPh1mg0V0yCTg8igjw8YsgDvEYxBoVxTARu0waEaOCIubUUDyNyULY8ChKZ0nw8uIIKF5NmUeFRuFlsigsXsKMRvu8zfcxODWyElOIh4+PXzI15Rb5DUOiKnzKP03ad2DLgWRek9vKUW/cGhI89rrBItCoyC6Vzr9lh44SVJTICIvgCuMEU4Lj8LoC1ZKLjKlkM+DFm2xhVAlqFAcYCsE8jawK3pwo37lN+wrJ+CDlF3pswBGOimLyAB+HRLHCNVSJnBvcr/nXSlQNwIFH3a4DAAAA) format('woff2');
  font-weight: 100 900;
  font-display: swap;
  unicode-range: U+002E;
}
h1, h2, h3,
.lede,
.type-line,
.cta-band h2,
.appstore .as-main { font-family: PeriodFix, var(--font-display); }

/* ==========================================================================
   PILL PARITY + HERO LIFT (2026-08-02)
   ========================================================================== */

/* The App Store button is a two-line lockup ("Coming to the" / "App Store");
   its neighbours are single-line. Left alone they never match. Give each pair
   a shared min-height and centre both vertically so the pills are the same
   size regardless of how many lines their labels run to. */
.hero-cta { align-items: stretch; }
.hero-cta .appstore,
.hero-cta .btn-ghost {
  min-height: 58px;
  padding-top: 0; padding-bottom: 0;
  display: inline-flex; align-items: center;
}

.cta-actions, .cta-band .cta-actions { align-items: stretch; }
.cta-band .appstore,
.cta-band a[data-follow] {
  min-height: 68px;
  padding-top: 0; padding-bottom: 0;
  display: inline-flex; align-items: center;
}

/* Hero starts higher — there was a lot of dead room above the eyebrow. */
.hero { padding-top: 14px; }
@media (max-width: 960px) { .hero { padding-top: 10px; } }

/* ==========================================================================
   SEVEN THEMES — full fan + swatch emphasis (2026-08-02)
   All seven captured from the real app (simctl, --theme 0-6), Aurora centred
   with the rest in the palette's own order around it. Hovering, focusing or
   tapping a swatch brings its phone forward and names it.
   ========================================================================== */
.theme-strip {
  display: flex; justify-content: center; align-items: center;
  padding: 26px 0 10px;
}
.tphone {
  position: relative;
  width: min(190px, 26vw);
  margin: 0 -20px;
  border-radius: 26px; overflow: hidden;
  border: 1px solid rgba(194, 154, 255, 0.22);
  background: var(--plum);
  box-shadow: 0 22px 54px rgba(0, 0, 0, 0.55), 0 6px 20px rgba(107, 40, 214, 0.3);
  /* fan: --i runs -3..3, so rotation and lift are symmetric about Aurora */
  transform: rotate(calc(var(--i) * 3.4deg)) translateY(calc(abs(var(--i)) * 9px));
  z-index: calc(4 - abs(var(--i)));
  transition: transform 0.4s var(--ease), opacity 0.35s var(--ease),
              box-shadow 0.35s var(--ease), filter 0.35s var(--ease);
}
.tphone img { display: block; width: 100%; height: auto; }
.tphone.is-center {
  z-index: 5;
  box-shadow: 0 34px 84px rgba(0, 0, 0, 0.65), 0 10px 34px rgba(107, 40, 214, 0.45);
}

/* When any swatch is engaged the strip dims and the matching phone lifts. */
.theme-strip.has-active .tphone { opacity: 0.42; filter: saturate(0.65); }
.theme-strip.has-active .tphone.is-active {
  opacity: 1; filter: none; z-index: 6;
  transform: rotate(0deg) translateY(-14px) scale(1.14);
  box-shadow: 0 40px 92px rgba(0, 0, 0, 0.7), 0 12px 40px rgba(107, 40, 214, 0.55);
}

.swatch-row { display: flex; justify-content: center; gap: 14px; margin-top: 34px; }
.swatch {
  width: 26px; height: 26px; padding: 0; border-radius: 50%;
  background: var(--c); cursor: pointer;
  border: 2px solid rgba(245, 241, 255, 0.25);
  box-shadow: 0 4px 16px color-mix(in srgb, var(--c) 55%, transparent);
  transition: transform 0.25s var(--ease), border-color 0.25s var(--ease);
}
.swatch:hover, .swatch:focus-visible, .swatch.is-active {
  transform: scale(1.32); border-color: rgba(245, 241, 255, 0.85); outline: none;
}

.theme-name {
  text-align: center; margin: 16px 0 0; min-height: 1.6em;
  font-size: 0.98rem; color: var(--text-3);
  transition: opacity 0.2s var(--ease);
}
.theme-name b { color: var(--text); font-weight: 700; margin-right: 8px; }

@media (max-width: 760px) {
  /* Seven phones don't fit; show the middle three and let the swatches carry
     the rest — the strip is illustrative, the swatch row is the real control. */
  .tphone { width: min(150px, 30vw); margin: 0 -14px; }
  .tphone[style*="--i:-3"], .tphone[style*="--i:3"],
  .tphone[style*="--i:-2"], .tphone[style*="--i:2"] { display: none; }
  .swatch-row { gap: 12px; flex-wrap: wrap; }
}

/* The swatches are 26px by design — the dot IS the control. Give each an
   invisible 44x44 hit area so they still meet the touch-target floor without
   changing how they look. */
.swatch { position: relative; }
.swatch::after {
  content: ""; position: absolute; left: 50%; top: 50%;
  width: 44px; height: 44px; transform: translate(-50%, -50%);
  border-radius: 50%;
}

/* ==========================================================================
   HERO PHONE + THEME NAME (2026-08-02, late)
   ========================================================================== */

/* The float animation lifts the phone 12px at its peak, which pushed the top
   of the device up behind the sticky nav. Drop the whole visual so even the
   top of the arc clears the bar — the copy column is untouched. */
.hero-visual { padding-top: 34px; }
@media (max-width: 960px) { .hero-visual { padding-top: 18px; } }

/* Theme label is the name alone now — sized up a little since it's carrying
   the line by itself. */
.theme-name {
  font-family: var(--font-display);
  font-size: 1.12rem; font-weight: 700; color: var(--text);
}


/* ==========================================================================
   MOBILE HERO RE-SEQUENCE + THEME STRIP AS A REAL CONTROL (2026-08-03)
   ========================================================================== */

/* --- 1 · Three lines that must never wrap on the stacked layout -----------
   The headline, the trust line and the countdown each read as one statement;
   broken across two rows they read as two. Each is sized off vw so it holds
   one line all the way down to 320px rather than relying on a breakpoint. */

@media (max-width: 960px) {
  /* "Do. Done. Gone." — the <br> is the desktop line break; on the stacked
     layout the whole tagline sits on one line. The ::before restores the word
     space the removed <br> was providing. */
  .hero h1 {
    white-space: nowrap;
    /* The vw term is what actually holds the line together at 320px, where the
       clamp's own 2.6rem floor is still ~26px too wide. */
    font-size: min(clamp(2.6rem, 6vw, 4.4rem), 10.3vw);
  }
  .hero h1 br { display: none; }
  /* Restores the word space the removed <br> was carrying. NBSP rather than a
     plain space so it can never be collapsed or trimmed. */
  .hero h1 .grad-text::before { content: "\00a0"; }

  /* Free · No account, ever · Your tasks stay on your phone — the gaps give up
     width before the type does, so the line stays as legible as it can. */
  .trust {
    flex-wrap: nowrap; white-space: nowrap;
    gap: min(12px, 1.7vw);
    font-size: min(0.85rem, 2.8vw);
  }
  .trust .dot { flex: 0 0 auto; }
}

/* Four countdown tiles stay on one row — hero and CTA band both. This
   replaces the 2x2 wrap at 620 and the 2-col grid the hero took at 420. */
@media (max-width: 620px) {
  .cd-grid { flex-wrap: nowrap; gap: min(10px, 2vw); }
  .cd-unit { flex: 1 1 0; min-width: 0; padding: 14px 4px 11px; }
  .cd-num { font-size: min(2.9rem, 8.4vw); }
  .cd-label { margin-top: 7px; font-size: min(0.66rem, 2.2vw); letter-spacing: 0.08em; }
}
@media (max-width: 420px) {
  .countdown.cd-hero .cd-grid {
    display: flex; grid-template-columns: none; gap: min(10px, 2vw);
  }
  .countdown.cd-hero .cd-unit { min-width: 0; }
}

/* --- 2 · Hero re-sequence on the stacked layout ---------------------------
   Order becomes: eyebrow → headline → lede → CTAs → trust line → the phone →
   the countdown. The phone has to land between two children of .hero-copy, so
   .hero-copy goes display:contents and its children share one ordering
   context with .hero-visual. Inherited properties (text-align) still pass
   through a contents box, so the centring above is unaffected; the grid gap
   is dropped and the vertical rhythm carried by explicit margins instead. */
@media (max-width: 960px) {
  .hero-copy { display: contents; }
  .hero-grid { gap: 0; }

  .hero-copy > .eyebrow { order: 1; }
  .hero-copy > h1       { order: 2; }
  .hero-copy > .lede    { order: 3; }
  /* .lede already carries 32px below it, so the trust line only tops up. */
  .hero-copy > .trust   { order: 4; margin-top: 4px; }
  .hero-copy > .countdown.cd-hero { order: 5; margin: 34px 0 0; }
  /* The CTAs sit directly under the countdown they answer... */
  .hero-copy > .hero-cta { order: 6; margin-top: 30px; }
  /* ...and the phone closes the hero, below the See the Magic pill. */
  .hero-visual          { order: 7; margin-top: 32px; }
}

/* --- 3 · The theme strip re-centres on the selected theme -----------------
   Seven phones never fit on a phone screen. Instead of showing a fixed middle
   three, the visible window is the selected theme plus its two neighbours in
   the palette's own order, wrapping at the ends — so every swatch brings its
   own phone to the centre. script.js writes data-rel (-3..3, signed distance
   from the selection) and flags the strip [data-ready] once it has. */
@media (max-width: 760px) {
  /* Pre-JS fallback: the static middle three, exactly as before. */
  .theme-strip:not([data-ready]) .tphone[style*="--i:-3"],
  .theme-strip:not([data-ready]) .tphone[style*="--i:3"],
  .theme-strip:not([data-ready]) .tphone[style*="--i:-2"],
  .theme-strip:not([data-ready]) .tphone[style*="--i:2"] { display: none; }

  .theme-strip[data-ready] .tphone { display: none; }
  .theme-strip[data-ready] .tphone[data-rel="-1"],
  .theme-strip[data-ready] .tphone[data-rel="0"],
  .theme-strip[data-ready] .tphone[data-rel="1"] { display: block; }

  /* Re-fan the window off data-rel, not the fixed --i. `order` matters as much
     as the transform: the window wraps, so when Moonlight is selected its
     left-hand neighbour is Graphite — which sits *after* it in the DOM and
     would otherwise flex to the right of it while tilted like a left edge. */
  .theme-strip[data-ready] .tphone[data-rel="-1"] { order: 1; transform: rotate(-3.4deg) translateY(9px); z-index: 3; }
  .theme-strip[data-ready] .tphone[data-rel="0"]  { order: 2; transform: none; z-index: 5; }
  .theme-strip[data-ready] .tphone[data-rel="1"]  { order: 3; transform: rotate(3.4deg) translateY(9px); z-index: 3; }
  /* The centre phone is the selection, so it lifts rather than scaling into
     its neighbours the way the desktop treatment can afford to. */
  .theme-strip[data-ready].has-active .tphone[data-rel="0"] {
    transform: translateY(-8px) scale(1.05);
  }
}

/* --- 4 · Say that the swatches are a control -----------------------------
   Two phrasings, one per input model — the desktop line has to explain that
   hover previews and click holds, which means nothing on a touch screen. */
.theme-hint {
  text-align: center; margin: 8px 0 0;
  font-size: 0.85rem; color: var(--text-3);
}
.theme-hint .on-touch { display: none; }
@media (hover: none) {
  .theme-hint .on-hover { display: none; }
  .theme-hint .on-touch { display: inline; }
}
