/* ============ Rememind landing — design tokens ============ */
/* Values are read off the Figma frame "Concept A — The Utterance"
   (file jr3os9qMBYyuTz6O6gWu8R, node 523:5692). The layout there is a 1440
   canvas with 220px side padding, i.e. a 1000px content column — which is what
   --maxw is. Section rhythm is Figma's `sp` spacer frames turned into margins. */
:root {
  --bg: #020202;
  --bg-elev: #181818;
  --text: #ffffff;
  --muted: #8c8c8c;
  --muted-2: #808080;
  --accent: #a6ff00;
  --border: #3b3b3b;
  --border-soft: #262626;

  /* space colours — dark ink on top, always */
  --card-green: #a8d672;
  --card-cream: #f6ecc9;
  --card-orange: #e97952;
  --card-blue: #73b4fe;
  --card-cyan: #54c2db;
  --card-grey: #eceeee;
  --card-yellow: #ffd272;
  --card-magenta: #c456a1;
  --ink: #020202;

  /* Figma's content column is 1000px and its side padding sits outside it, so
     the wrapper has to be 1000 + two paddings — otherwise every row is 48px
     narrower than drawn and the long ones wrap a line early. */
  --content: 1000px;
  --pad: 24px;
  --maxw: calc(var(--content) + var(--pad) * 2);
}

* { box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  font-weight: 400;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
}

h1, h2, h3 { margin: 0; }
p { margin: 0; }
ul, ol { margin: 0; padding: 0; list-style: none; }
img { display: block; max-width: 100%; }

.container { max-width: var(--maxw); margin: 0 auto; padding: 0 var(--pad); width: 100%; }
.center { text-align: center; }

.section { padding: 130px 0; position: relative; }

.eyebrow {
  font-size: 14px;
  font-weight: 600;
  letter-spacing: 3px;
  text-transform: uppercase;
  color: var(--muted);
  margin: 0;
}
.accent { color: var(--accent); }

.h2 {
  font-size: clamp(38px, 6vw, 64px);
  font-weight: 900;
  letter-spacing: -0.03em;
  line-height: 1.06;
  text-align: center;
  margin-top: 20px;
}
/* A left-aligned section title wraps onto two lines and gets the looser
   leading it has in Figma; the two centred ones are set tight. */
.h2.left { text-align: left; line-height: 1.2; margin-top: 52px; }
/* "One thought. Zero effort." is drawn as two stacked lines, so the box is
   narrowed rather than the break being hard-coded — every language wraps
   somewhere, and a <br> would put it in the wrong place in seven of them. */
.how .h2 { max-width: 480px; margin-left: auto; margin-right: auto; }
/* Same reason, one line down: "Eight languages." and the promise after it are
   drawn as two lines. */
.langs .h2 { max-width: 640px; }

.lead {
  font-size: clamp(17px, 1.9vw, 19px);
  color: var(--muted);
  line-height: 1.5;
  margin-top: 26px;
}
.lead.center { margin: 26px auto 0; text-align: center; max-width: 640px; }

/* ============ Language switch ============ */
.lang-switch { position: fixed; top: 22px; right: 26px; z-index: 50; }
.lang-toggle {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  background: rgba(24,24,24,0.72);
  backdrop-filter: blur(10px);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 8px 14px;
  color: var(--text);
  font: inherit;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.06em;
  cursor: pointer;
}
.lang-toggle:hover { border-color: var(--accent); }
.lang-caret { width: 11px; height: 7px; color: var(--muted); }
.lang-toggle[aria-expanded="true"] .lang-caret { transform: rotate(180deg); }

.lang-menu {
  position: absolute;
  top: calc(100% + 8px);
  right: 0;
  min-width: 172px;
  background: rgba(16,16,16,0.96);
  backdrop-filter: blur(10px);
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 6px;
  box-shadow: 0 18px 40px rgba(0,0,0,0.6);
}
.lang-btn {
  display: block;
  width: 100%;
  text-align: left;
  background: none;
  border: none;
  border-radius: 9px;
  color: var(--muted);
  font: inherit;
  font-size: 14px;
  padding: 8px 12px;
  cursor: pointer;
}
.lang-btn:hover { background: rgba(255,255,255,0.06); color: var(--text); }
.lang-btn[aria-selected="true"] { color: var(--accent); }

/* ============ Logo ============ */
/* The mark is a drawing of the name, re-exported from Figma after the rename
   (574:8792). It is used at three sizes and never re-typed: the hero, the
   download section, and the app icon on the phone mock's home screen. */
.logo { display: inline-flex; text-decoration: none; line-height: 0; }
.logo-mark { width: 69px; height: 69px; }

/* ============ Opening ============
   The page opens on the mark alone, filling the screen, and then puts itself
   away into the corner it lives in — so the first thing a visitor sees is who
   this is, and the second is the page they came for.

   It moves the real logo rather than a copy: the copy would have to be removed
   at exactly the frame the original appears, and the two are never quite in the
   same place. Because the element is transformed and not repositioned, nothing
   here is layout — the resting page is laid out from the first frame, which is
   also why the demo underneath can be measured while this is still running.

   `.intro` is put on <html> by an inline script in the head, so the big state
   is the first thing painted and there is no flash of the small one. No script,
   no class, no hiding: the page is simply itself. The numbers are set by JS
   from the logo's own measured position; the fallbacks here are what the first
   frame uses until it has them, and are close enough not to jump. */
.intro .lang-switch,
.intro .hero > *:not(.logo) { opacity: 0; }
.intro .hero .logo {
  transform: translate(var(--intro-x, 0px), var(--intro-y, 24vh)) scale(var(--intro-k, 3.4));
}
.intro-anim .hero .logo { transition: transform 820ms cubic-bezier(0.2, 0.7, 0.2, 1); }
/* The page arrives while the mark is still travelling, not after it: waiting
   for the end reads as two events where this is one. */
.intro-anim .lang-switch,
.intro-anim .hero > *:not(.logo) { transition: opacity 620ms ease 240ms; }

@media (prefers-reduced-motion: reduce) {
  .intro .lang-switch,
  .intro .hero > *:not(.logo) { opacity: 1; }
  .intro .hero .logo { transform: none; }
}

/* ============ HERO ============ */
.hero {
  position: relative; /* the demo is anchored to the bottom of this box */
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  /* Kept tight at the top on purpose: the headline is the first thing on the
     page and every pixel above it pushes the demonstration towards the fold. */
  padding: 44px 24px 40px;
}
.hero .logo { margin-bottom: 18px; }
.hero .eyebrow { margin-bottom: 28px; }

/* The headline's size lives on the wrapper, not on the <h1>, because the demo
   lifts the whole composition by exactly one headline line (-0.98em, the
   line-height) when the first line leaves — and that only lands right if the
   element being lifted is the one whose font-size the line is measured in. */
.hero-body {
  /* Above the phone, because the microphone travelling into it lives here and
     has to be seen crossing. The lift makes this element a stacking context of
     its own, so its children cannot climb out of it on their own. */
  position: relative;
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  font-size: clamp(56px, 9.2vw, 132px);
  line-height: 0.98;
  /* Exactly the microphone's transition below, and that is the point: the
     button rides this column up as it crosses into the phone, so if the two
     move on different clocks it arrives, stops, and waits — which is what it
     used to do. One curve, one duration, one movement. */
  transition: transform 1.05s cubic-bezier(0.45, 0.05, 0.25, 1);
}
.hero-title {
  font-weight: 900;
  font-size: inherit;
  line-height: inherit;
  letter-spacing: -0.03em;
}
.hero-title .line { display: block; transition: opacity 0.45s ease, transform 0.6s cubic-bezier(0.2, 0.75, 0.2, 1); }

/* The headline is two lines and each one has to stay one line — a break inside
   «Система организует.» turns the promise into three ragged lines. Russian is
   the one language whose second line is long enough to need it, so it gets a
   size derived from its own width (~10.5× the font size) instead of the
   viewport alone. The extra divisor is slack for a desktop scrollbar, which
   100vw counts and the text cannot use. */
html[lang="ru"] .hero-body { font-size: min(132px, 9.2vw, calc((100vw - 48px) / 11.2)); }
html[lang="ru"] .dl-title { font-size: min(64px, 5.6vw, calc((100vw - 48px) / 11.2)); }

.hero-sub {
  margin-top: 38px;
  font-size: clamp(17px, 1.8vw, 24px);
  color: #8f8f8f;
  max-width: 620px;
  line-height: 1.4;
  transition: opacity 0.4s ease, transform 1.05s cubic-bezier(0.45, 0.05, 0.25, 1);
}

/* The stage keeps the microphone where it is and gives back, as padding, the
   height the hint stopped occupying when it became absolute. */
.hero-stage {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  padding-bottom: 56px;
  font-size: 16px;
  line-height: 1.5;
  letter-spacing: normal;
}
.stage-anchor { position: relative; width: 100%; height: 0; }

.mic {
  position: relative;
  margin-top: 54px;
  width: 104px;
  height: 104px;
  border-radius: 50%;
  background: var(--bg);
  border: 3px solid var(--accent);
  display: grid;
  place-items: center;
  cursor: pointer;
  transition: transform 0.2s ease;
}
.mic:hover { transform: scale(1.04); }
.mic:active { transform: scale(0.97); }
.mic-glow {
  position: absolute;
  inset: -16px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(206,255,72,0.5) 0%, rgba(206,255,72,0) 70%);
  animation: pulse 2.4s ease-in-out infinite;
}
@keyframes pulse {
  0%, 100% { opacity: 0.55; transform: scale(1); }
  50% { opacity: 1; transform: scale(1.08); }
}
.mic-icon { width: 44px; height: 44px; position: relative; z-index: 1; }
.mic-hint {
  position: absolute;
  top: 38px;
  left: 50%;
  transform: translateX(-50%);
  white-space: nowrap;
  font-size: 15px;
  letter-spacing: 0.1em;
  color: var(--muted-2);
  transition: opacity 0.4s ease;
}

/* ============ HERO DEMO ============
   One capture, on the phone it actually happens on. Five states live on the
   section as data-demo — idle, listen, think, file, open — and each one is the
   app's own: the dashboard, the microphone lime while it records, the glass
   and pulsing glow the spaces panel goes to while the pipeline runs, the card
   in the space's own colour naming where the note landed, and the note itself
   with its reminder.

   Nothing here is layout. The whole thing is anchored to the bottom of the
   section and every rule is opacity or transform, so the resting screen is
   exactly as tall as it was and going back to idle is the entire reset — the
   phone sinks the way it rose, which is what keeps the loop from reading as a
   restart. */
/* --demo-top and --demo-k are set by main.js: the phone hangs directly under
   the headline and is as big as the room below it allows, and neither is
   something CSS can work out for itself — the headline's height depends on the
   language, the viewport and the lift. Unset, the layer still lands in a sane
   place and the vh-bound font-size below keeps the phone inside the window. */
.demo {
  position: absolute;
  left: 50%;
  top: var(--demo-top, 46%);
  width: min(94vw, 620px);
  transform: translateX(-50%) scale(var(--demo-k, 1));
  transform-origin: top center;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.5s ease;
}
.hero[data-demo="enter"] .demo,
.hero[data-demo="listen"] .demo,
.hero[data-demo="think"] .demo,
.hero[data-demo="file"] .demo,
.hero[data-demo="open"] .demo { opacity: 1; }

/* What the person said — outside the phone, because it is the one thing on
   screen that is not the app. It arrives a word at a time, the way speech
   does, between two short lines of sound: alive while the sentence is being
   spoken, and left behind — fainter and still — once it has been. */
.demo-line {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
}
.demo-eq {
  display: flex;
  align-items: center;
  gap: 3px;
  height: 16px;
  flex-shrink: 0;
  opacity: 0;
  transition: opacity 0.5s ease;
}
.demo-eq span {
  width: 2px;
  height: 100%;
  border-radius: 2px;
  background: var(--accent);
  transform: scaleY(0.3);
  animation: dp-bar 0.8s ease-in-out infinite alternate;
  animation-play-state: paused;
}
.demo-eq span:nth-child(3n + 1) { animation-delay: 0s; animation-duration: 0.74s; }
.demo-eq span:nth-child(3n + 2) { animation-delay: 0.17s; animation-duration: 1.02s; }
.demo-eq span:nth-child(3n) { animation-delay: 0.33s; animation-duration: 0.62s; }
.hero[data-demo="listen"] .demo-eq { opacity: 0.55; }
.hero[data-demo="listen"] .demo-eq span { animation-play-state: running; }
.hero[data-demo="think"] .demo-eq,
.hero[data-demo="file"] .demo-eq,
.hero[data-demo="open"] .demo-eq { opacity: 0.22; }

.demo-said {
  font-size: clamp(16px, 1.8vw, 20px);
  font-weight: 500;
  line-height: 1.4;
  color: var(--text);
  text-align: center;
  transition: color 0.5s ease;
}
.demo-said .w {
  display: inline-block;
  opacity: 0;
  transform: translateY(6px);
  transition: opacity 0.35s ease, transform 0.35s ease;
}
.demo-said .w.in { opacity: 1; transform: none; }
/* Once the phone has it, the sentence steps back: it is what was said, not
   what was made. */
.hero[data-demo="file"] .demo-said,
.hero[data-demo="open"] .demo-said { color: var(--muted-2); }

/* ---- the phone ----
   Sized in em off one font-size, so the whole device scales with the viewport
   height and every proportion inside it stays the app's. One em is about
   16 real phone pixels: a 390pt screen is 24.1em across. */
.demo-phone {
  position: relative;
  font-size: min(11px, 1.1vh);
  width: 26em;
  height: 54em;
  flex-shrink: 0;
  /* A thin bezel on purpose: every millimetre of frame is a millimetre the
     screen does not get, and the screen is the whole point. */
  border-radius: 4.2em;
  background: #0d0d0d;
  border: 0.2em solid #2e2e2e;
  padding: 0.5em;
  filter: drop-shadow(0 2.2em 2.6em rgba(0, 0, 0, 0.65));
  opacity: 0;
  transform: translateY(44px) scale(0.985);
  transition: opacity 0.55s ease, transform 0.9s cubic-bezier(0.45, 0.05, 0.25, 1);
}
/* Measured, not guessed: main.js reads where the phone's own button sits, and
   it can only do that with the phone in its final position.
   `no-anim` is the other half and it is not optional: putting an element into
   its final position starts a transition, and a rect read one line later is
   the position it has *not* moved from yet. Measuring has to happen with the
   transitions switched off, or every number is the old one. */
.hero.measuring .demo-phone,
.hero.measuring .mic { transform: none; }
.hero.no-anim .hero-body,
.hero.no-anim .hero-title,
.hero.no-anim .hero-sub,
.hero.no-anim .demo,
.hero.no-anim .demo-phone,
.hero.no-anim .mic { transition: none; }
.hero[data-demo="enter"] .demo-phone,
.hero[data-demo="listen"] .demo-phone,
.hero[data-demo="think"] .demo-phone,
.hero[data-demo="file"] .demo-phone,
.hero[data-demo="open"] .demo-phone { opacity: 1; transform: none; }

.dp-glow {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 46em;
  height: 46em;
  margin: -23em 0 0 -23em;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(130, 215, 0, 0.3), transparent 64%);
  z-index: -1;
}

.dp-screen {
  position: relative;
  height: 100%;
  background: var(--bg);
  border-radius: 3.8em;
  padding: 1em 0.45em 0.35em;
  display: flex;
  flex-direction: column;
  gap: 0.7em;
  overflow: hidden;
}

.dp-status {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 0.9em;
  font-size: 0.85em;
  font-weight: 600;
  color: var(--text);
}
.dp-notch { width: 7.5em; height: 1.4em; border-radius: 999px; background: #1a1a1a; }

/* The dashboard's spaces panel — and the surface the loader, the result and
   the space screen each take over in turn. */
.dp-panel {
  position: relative;
  flex: 1;
  min-height: 0;
  border: 0.19em solid var(--border);
  border-radius: 2em;
  overflow: hidden;
  background: linear-gradient(152deg, rgba(172,172,172,0.22) 4%, rgba(56,56,56,0.22) 58%, rgba(0,0,0,0.22) 100%);
}

.dp-grid {
  height: 100%;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  grid-auto-rows: 1fr;
  gap: 0.55em;
  padding: 0.4em;
}
.dp-sp {
  border-radius: 1.5em;
  padding: 0.8em 0.9em;
  color: var(--ink);
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  overflow: hidden;
}
.dp-sp b { font-size: 1.45em; font-weight: 500; line-height: 1.12; overflow-wrap: break-word; }
.dp-sp i { font-size: 0.95em; font-style: normal; font-weight: 600; color: rgba(2, 2, 2, 0.3); }

/* Every state after the dashboard covers the panel and nothing else — the
   status bar and the bar with the button stay where they are, because on the
   phone they do. */
.dp-loading,
.dp-result,
.dp-open {
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity 0.4s ease;
}

/* Working: the panel goes to glass with a pulsing green glow behind it. */
.dp-loading {
  background: rgba(10, 10, 10, 0.55);
  display: grid;
  place-items: center;
}
.dp-pulse {
  width: 18em;
  height: 18em;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(166,255,0,0.9), rgba(166,255,0,0.3) 50%, rgba(166,255,0,0) 72%);
  animation: dp-pulse 1.8s ease-in-out infinite;
  animation-play-state: paused;
}
@keyframes dp-pulse {
  0%, 100% { transform: scale(0.8); opacity: 0.55; }
  50% { transform: scale(1.15); opacity: 1; }
}
.hero[data-demo="think"] .dp-loading { opacity: 1; }
.hero[data-demo="think"] .dp-pulse { animation-play-state: running; }

/* Landed: one card in the space's own colour, its name and the note's title —
   which is the app's own answer to "where did that go". */
.dp-result {
  margin: 0.5em;
  inset: 0;
  border-radius: 1.6em;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 1em;
}
.dp-result b,
.dp-result i {
  display: block;
  text-align: center;
  color: var(--ink);
  font-style: normal;
}
.dp-result b { font-size: 2.2em; font-weight: 500; line-height: 1.2; }
.dp-result i { margin-top: 0.6em; font-size: 1.1em; font-weight: 600; line-height: 1.3; }
.hero[data-demo="file"] .dp-result { opacity: 1; }

/* And the note, in the space it was filed into. */
.dp-open {
  background: var(--bg);
  padding: 1.2em 1em;
  display: flex;
  flex-direction: column;
  gap: 0.6em;
  text-align: left;
}
.dp-open-title { font-size: 1.9em; font-weight: 600; line-height: 1.1; color: var(--text); margin-bottom: 0.2em; }
.dp-note {
  background: #020202;
  border: 0.07em solid #484848;
  border-radius: 0.8em;
  padding: 0.7em 0.8em;
}
.dp-new { border-color: var(--accent); }
.dp-note-t { font-size: 1.05em; font-weight: 600; line-height: 1.5; color: #ebebeb; }
.dp-note-r {
  display: flex;
  align-items: center;
  gap: 0.5em;
  margin-top: 0.3em;
  font-size: 0.9em;
  color: #c2c2c2;
}
.dp-cal { display: inline-flex; }
.dp-cal svg { width: 1.3em; height: 1.3em; }
.hero[data-demo="open"] .dp-open { opacity: 1; }

/* The waveform lies across the whole bar, behind the button and faint enough
   to be the room's sound rather than a control — the button stands in it. */
.dp-wave {
  position: absolute;
  /* Clear of the two side icons: behind the button is the point, and a row of
     bars running under a plus sign only makes the plus hard to read. */
  left: 5.4em;
  right: 5.4em;
  top: 50%;
  height: 3.2em;
  margin-top: -1.6em;
  display: flex;
  align-items: center;
  justify-content: space-between;
  opacity: 0;
  transition: opacity 0.35s ease;
}
.dp-wave span {
  width: 0.22em;
  height: 100%;
  border-radius: 0.2em;
  background: var(--accent);
  transform: scaleY(0.22);
  animation: dp-bar 0.85s ease-in-out infinite alternate;
  animation-play-state: paused;
}
/* Four phases against five durations: twenty different bars before the pattern
   comes round again, which is enough that the row does not read as a loop. */
.dp-wave span:nth-child(4n + 1) { animation-delay: 0s; }
.dp-wave span:nth-child(4n + 2) { animation-delay: 0.19s; }
.dp-wave span:nth-child(4n + 3) { animation-delay: 0.38s; }
.dp-wave span:nth-child(4n) { animation-delay: 0.1s; }
.dp-wave span:nth-child(5n + 1) { animation-duration: 0.72s; }
.dp-wave span:nth-child(5n + 2) { animation-duration: 1.04s; }
.dp-wave span:nth-child(5n + 3) { animation-duration: 0.61s; }
.dp-wave span:nth-child(5n + 4) { animation-duration: 0.93s; }
.dp-wave span:nth-child(5n) { animation-duration: 0.82s; }
@keyframes dp-bar {
  from { transform: scaleY(0.18); }
  to { transform: scaleY(1); }
}
.hero[data-demo="listen"] .dp-wave { opacity: 0.4; }
.hero[data-demo="listen"] .dp-wave span { animation-play-state: running; }

/* The bar: three slots, the button in the middle. The side icons are drawn
   rather than typed — a glyph sits on its own baseline and lands wherever the
   font puts it, which is how the two of them ended up at different heights. */
.dp-bar {
  position: relative;
  height: 6.6em;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 2em;
}
.dp-side {
  position: relative;
  z-index: 1;
  width: 2.6em;
  height: 2.6em;
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.32em;
}
.dp-side span { background: #c2c2c2; border-radius: 999px; }
.dp-plus span { position: absolute; }
.dp-plus span:first-child { width: 1.6em; height: 0.17em; }
.dp-plus span:last-child { width: 0.17em; height: 1.6em; }
.dp-menu span { width: 1.6em; height: 0.17em; }
/* The phone's own button only appears once the page's has finished travelling
   into it — until then the slot is empty and the one in flight is the one you
   are watching. */
.dp-mic {
  position: relative;
  z-index: 1;
  width: 5em;
  height: 5em;
  border-radius: 50%;
  background: var(--ink);
  border: 0.13em solid var(--accent);
  display: grid;
  place-items: center;
  box-shadow: 0 0 1.6em rgba(166, 255, 0, 0.45);
  opacity: 0;
  transition: background 0.35s ease, box-shadow 0.35s ease, transform 0.35s ease,
    opacity 0.25s ease;
}
.hero[data-demo="listen"] .dp-mic,
.hero[data-demo="think"] .dp-mic,
.hero[data-demo="file"] .dp-mic,
.hero[data-demo="open"] .dp-mic { opacity: 1; }
.hero.measuring .dp-mic { opacity: 1; }
.dp-mic-ico {
  width: 2.3em;
  height: 2.3em;
  fill: var(--accent);
  stroke: var(--accent);
  transition: fill 0.35s ease, stroke 0.35s ease, opacity 0.25s ease;
}
/* Recording: the button fills with the accent and the icon goes black — the
   app's own inversion, not a colour picked for the page. */
.hero[data-demo="listen"] .dp-mic {
  background: var(--accent);
  box-shadow: 0 0 2.4em rgba(166, 255, 0, 0.8);
  transform: scale(1.04);
}
.hero[data-demo="listen"] .dp-mic-ico { fill: var(--ink); stroke: var(--ink); }

/* Working: the button holds an ellipsis, exactly as it does on the phone. */
.dp-dots {
  position: absolute;
  display: flex;
  gap: 0.42em;
  opacity: 0;
  transition: opacity 0.25s ease;
}
.dp-dots span { width: 0.45em; height: 0.45em; border-radius: 50%; background: var(--accent); }
.hero[data-demo="think"] .dp-dots { opacity: 1; }
.hero[data-demo="think"] .dp-mic-ico { opacity: 0; }

/* ---- what the resting screen does while all this happens ---- */
/* The promise rises to the top of the section and becomes the heading of the
   demonstration — all the way up, because the logo, the eyebrow and the lead
   have stepped aside and everything below is about to be a phone. How far
   that is depends on where the resting screen happened to centre itself, so
   main.js measures it; the 2em fallback is one headline line, which is the
   least it is ever worth moving. */
.hero[data-demo="enter"] .hero-body,
.hero[data-demo="listen"] .hero-body,
.hero[data-demo="think"] .hero-body,
.hero[data-demo="file"] .hero-body,
.hero[data-demo="open"] .hero-body,
.hero.measuring .hero-body { transform: translateY(calc(-1 * var(--lift, 2em))); }

.hero[data-demo="enter"] .line-say,
.hero[data-demo="listen"] .line-say,
.hero[data-demo="think"] .line-say,
.hero[data-demo="file"] .line-say,
.hero[data-demo="open"] .line-say { opacity: 0; transform: translateY(-14px) scale(0.96); }

.hero[data-demo="enter"] .logo,
.hero[data-demo="listen"] .logo,
.hero[data-demo="think"] .logo,
.hero[data-demo="file"] .logo,
.hero[data-demo="open"] .logo,
.hero[data-demo="enter"] .eyebrow,
.hero[data-demo="listen"] .eyebrow,
.hero[data-demo="think"] .eyebrow,
.hero[data-demo="file"] .eyebrow,
.hero[data-demo="open"] .eyebrow,
.hero[data-demo="enter"] .mic-hint,
.hero[data-demo="listen"] .mic-hint,
.hero[data-demo="think"] .mic-hint,
.hero[data-demo="file"] .mic-hint,
.hero[data-demo="open"] .mic-hint { opacity: 0; }

/* The lead sentence is the only thing on the resting screen that stays: it
   moves to the foot of the first screen and sits there through the whole
   capture. How far down that is depends on the rest, so main.js measures it —
   and the phone's room is measured to stop above it. */
.hero[data-demo="enter"] .hero-sub,
.hero[data-demo="listen"] .hero-sub,
.hero[data-demo="think"] .hero-sub,
.hero[data-demo="file"] .hero-sub,
.hero[data-demo="open"] .hero-sub,
.hero.measuring .hero-sub { transform: translateY(var(--sub-shift, 0px)); }

/* ---- the button moves house ----
   The page's microphone does not disappear and get replaced: it travels, over
   more than a second, into the slot the phone keeps for it. main.js measures
   the two positions and hands the difference over as three numbers; the swap
   at the end is a crossfade between two buttons standing in the same place,
   which is why it cannot be seen. */
.mic {
  z-index: 3;
  transition: transform 1.05s cubic-bezier(0.45, 0.05, 0.25, 1), opacity 0.3s ease 0.05s;
}
.hero[data-demo="enter"] .mic,
.hero[data-demo="listen"] .mic,
.hero[data-demo="think"] .mic,
.hero[data-demo="file"] .mic,
.hero[data-demo="open"] .mic {
  transform: translate(var(--mic-dx, 0px), var(--mic-dy, 0px)) scale(var(--mic-k, 1));
}
.hero[data-demo="listen"] .mic,
.hero[data-demo="think"] .mic,
.hero[data-demo="file"] .mic,
.hero[data-demo="open"] .mic { opacity: 0; }

/* ============ MOMENTS ============ */
.moments-list { margin-top: 60px; }
.moments-list li {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  padding: 32px 0;
  border-top: 1px solid var(--border-soft);
  font-size: clamp(24px, 3.1vw, 44px);
  font-weight: 500;
  letter-spacing: -0.02em;
}
.moments-list li:last-child { border-bottom: 1px solid var(--border-soft); }
.moments-list .say {
  display: inline-flex;
  gap: 10px;
  font-size: 20px;
  font-weight: 400;
  color: var(--muted-2);
  letter-spacing: 0;
  white-space: nowrap;
  flex-shrink: 0;
}
.moments-list .say i { font-style: normal; }

.said-cards {
  margin-top: 24px;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 20px;
}
.said-card,
.place-card,
.photo-card {
  border-radius: 26px;
  padding: 26px 26px 24px;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 24px;
  color: var(--ink);
}
.said-card { min-height: 290px; }
.said-green { background: var(--card-green); }
.said-cream { background: var(--card-cream); }
.said-orange { background: var(--card-orange); }
.said-blue { background: var(--card-blue); }
.said-cyan { background: var(--card-cyan); }
.said-grey { background: var(--card-grey); }
.said-yellow { background: var(--card-yellow); }
.said-magenta { background: var(--card-magenta); }

.said-top { display: flex; flex-direction: column; gap: 14px; }
.said-label {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: rgba(2,2,2,0.45);
}
.said-quote {
  font-size: 25px;
  font-weight: 600;
  line-height: 1.22;
}
.chip {
  align-self: flex-start;
  display: inline-flex;
  align-items: center;
  gap: 7px;
  background: rgba(2,2,2,0.12);
  border-radius: 999px;
  padding: 9px 16px 9px 14px;
  font-size: 15px;
  font-weight: 600;
  color: var(--ink);
}
.chip .arr { font-size: 14px; font-weight: 700; }

.under-cards { margin-top: 24px; font-size: 19px; color: var(--muted-2); }

/* ============ HOW IT WORKS ============ */
.cascade {
  margin: 80px auto 0;
  display: flex;
  flex-direction: column;
  align-items: center;
}
.step { display: flex; flex-direction: column; align-items: center; text-align: center; gap: 14px; }
.step-cap { font-size: 15px; font-weight: 500; color: var(--muted); }
.conn { width: 2px; height: 46px; background: rgba(166,255,0,0.5); }

.wave-pill {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  background: var(--bg);
  border: 1.5px solid var(--accent);
  border-radius: 999px;
  padding: 16px 26px 16px 22px;
}
.rec-dot { width: 12px; height: 12px; border-radius: 50%; background: var(--accent); }
.wave { display: inline-flex; align-items: center; gap: 4px; height: 34px; }
.wave span {
  width: 4px;
  border-radius: 2px;
  background: var(--accent);
  animation: wave 1.1s ease-in-out infinite;
}
.wave span:nth-child(1){height:14px;animation-delay:0s}
.wave span:nth-child(2){height:26px;animation-delay:.1s}
.wave span:nth-child(3){height:20px;animation-delay:.2s}
.wave span:nth-child(4){height:34px;animation-delay:.3s}
.wave span:nth-child(5){height:18px;animation-delay:.4s}
.wave span:nth-child(6){height:30px;animation-delay:.5s}
.wave span:nth-child(7){height:12px;animation-delay:.6s}
.wave span:nth-child(8){height:24px;animation-delay:.7s}
.wave span:nth-child(9){height:16px;animation-delay:.8s}
@keyframes wave { 0%,100%{transform:scaleY(0.5)} 50%{transform:scaleY(1)} }

.transcript {
  background: var(--bg-elev);
  border: 1px solid var(--border);
  border-radius: 20px;
  padding: 24px 30px;
  font-size: clamp(18px, 2.2vw, 26px);
  font-weight: 500;
  color: var(--text);
}

/* The two read-outs sit inside one thin outline: they are one answer about one
   sentence, not two chips that happen to be adjacent. */
.intent {
  display: inline-flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px;
  border: 1px solid #6d6d6d;
  border-radius: 16px;
  padding: 4px;
  max-width: 100%;
}
.intent-pill {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  background: var(--bg-elev);
  border: 1.5px solid rgba(166,255,0,0.6);
  border-radius: 14px;
  padding: 14px 20px 14px 18px;
}
.intent-pill .ico { width: 20px; height: 20px; display: inline-flex; }
.intent-pill .ico svg { width: 20px; height: 20px; }
.intent-txt { display: flex; flex-direction: column; gap: 1px; text-align: left; }
.intent-txt b { font-size: 16px; font-weight: 600; white-space: nowrap; }
.intent-txt i { font-size: 12px; font-style: normal; font-weight: 400; color: var(--muted); }

.space-card {
  width: 280px;
  max-width: 100%;
  height: 150px;
  border-radius: 24px;
  padding: 20px 22px;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  text-align: left;
  color: var(--ink);
}
.sc-name { font-size: 24px; font-weight: 500; }
.sc-bottom { display: flex; align-items: center; justify-content: space-between; font-size: 15px; font-weight: 500; color: rgba(2,2,2,0.55); }
.sc-cal { display: inline-flex; align-items: center; gap: 5px; opacity: 0.55; }
.sc-cal svg { width: 15px; height: 15px; }

/* ============ WHY DIFFERENT ============ */
.why-list { margin-top: 64px; border-top: 1px solid var(--border-soft); }
.why-list li {
  display: flex;
  gap: 48px;
  padding: 44px 0;
  border-bottom: 1px solid var(--border-soft);
}
.why-num { font-size: 30px; font-weight: 800; color: var(--accent); flex-shrink: 0; width: 60px; }
.why-list h3 { font-size: clamp(24px, 3vw, 34px); font-weight: 600; letter-spacing: -0.02em; }
.why-list p { margin-top: 12px; color: var(--muted); font-size: 19px; line-height: 1.5; }

/* ============ TIDY ============ */
/* Two cards, one per direction of the same job — a space grown into two
   topics, and two spaces that were always one. Both drawings are built out of
   the app's own space card (name left, count right, dark ink on the space's
   colour), so a reader who installs the app recognizes the shapes. */
.tidy-cards {
  margin-top: 56px;
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 20px;
}
.tidy-card {
  background: var(--bg-elev);
  border: 1px solid var(--border);
  border-radius: 26px;
  padding: 26px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.tidy-label {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--muted);
}
.tidy-h {
  font-size: clamp(20px, 2.4vw, 25px);
  font-weight: 600;
  line-height: 1.22;
  letter-spacing: -0.01em;
}
/* The drawings are different heights — a list of notes against two chips —
   and two cards side by side with one of them top-heavy reads as unfinished.
   The flow takes the leftover room and centres itself in it. */
.tidy-flow {
  margin-top: 14px;
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 14px;
}
.tsp-row { display: flex; flex-wrap: wrap; justify-content: center; gap: 10px; width: 100%; }
.tsp {
  flex: 1 1 140px;
  max-width: 230px;
  display: inline-flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 14px;
  border-radius: 14px;
  color: var(--ink);
}
.tsp b { font-size: 16px; font-weight: 700; letter-spacing: -0.01em; }
.tsp i { font-style: normal; font-size: 14px; font-weight: 600; color: rgba(2,2,2,0.55); }

.tnotes { width: 100%; display: flex; flex-direction: column; gap: 8px; }
/* The left edge carries the colour of the space each note is about to land
   in — that stripe is the whole argument of the card: the split is by
   meaning, and the two meanings were already there. */
.tnotes li {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  border-radius: 10px;
  border-left: 3px solid transparent;
  background: rgba(255,255,255,0.04);
  font-size: 15px;
  font-weight: 500;
  line-height: 1.3;
}
/* Written against `.tnotes li` rather than the class alone: the row rule above
   sets the same two properties at a higher specificity, so `.tn-a` on its own
   loses silently and the stripe simply never appears. */
.tnotes li.tn-a { border-left-color: var(--card-cyan); background: rgba(84,194,219,0.10); }
.tnotes li.tn-b { border-left-color: var(--card-magenta); background: rgba(196,86,161,0.16); }
/* Ticked are the notes the app is proposing to move out — the same thing the
   sheet shows, and the reason the caption can say "untick what you disagree
   with". Ticking all four would say the space is being emptied, which is the
   one thing a split must never do. */
.tick {
  flex-shrink: 0;
  width: 18px;
  height: 18px;
  border-radius: 5px;
  background: var(--accent);
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.tick svg { width: 11px; height: 9px; }
.tick.off { background: transparent; border: 1.5px solid rgba(255,255,255,0.28); }
.tick.off svg { display: none; }

.tidy-arrow { display: flex; flex-direction: column; align-items: center; gap: 3px; color: var(--accent); }
.tidy-arrow .ta-line { width: 2px; height: 14px; background: rgba(166,255,0,0.5); }
.tidy-arrow svg { width: 14px; height: 8px; }

.tidy-reason { font-size: 15px; line-height: 1.4; color: var(--muted); text-align: center; }
.tidy-cap { margin-top: auto; padding-top: 6px; font-size: 15px; line-height: 1.4; color: var(--muted); }

/* ============ PLACES ============ */
.place-cards,
.photo-cards {
  margin-top: 64px;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 20px;
}
.place-card { min-height: 290px; }
.place-said,
.photo-said { font-size: clamp(20px, 2.4vw, 25px); font-weight: 600; line-height: 1.22; }
.place-bottom,
.photo-bottom { display: flex; flex-direction: column; gap: 24px; }
/* The pin sits in its own inset panel, a shade off the card — it is the thing
   the app produced, not something the sentence said. */
.place-row {
  display: flex;
  align-items: center;
  gap: 10px;
  border-radius: 8px;
  padding: 12px 11px;
}
.said-blue .place-row { background: #6caaf2; border: 1px solid #3479c8; }
.said-cream .place-row { background: #efdfb3; border: 1px solid #baad80; }
.pin { width: 22px; height: 26px; flex-shrink: 0; }
.pin svg { width: 22px; height: 26px; }
.place-name { font-size: clamp(18px, 2.2vw, 25px); font-weight: 600; line-height: 1.22; }
.rem-badge { margin-left: auto; width: 36px; height: 36px; flex-shrink: 0; }
.rem-badge svg { width: 100%; height: 100%; }

/* ============ PHOTOS ============ */
.photo-frame { position: relative; border-radius: 14px; overflow: hidden; aspect-ratio: 438 / 190; }
/* The shot is a portrait phone photo laid on its side, exactly as the frame
   places it — so the box is the frame transposed (190×438 in a 438×190 hole)
   and then turned a quarter. The percentages are that transposition: 190/438
   of the width, 438/190 of the height. */
.photo-shot {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 43.379%;
  height: 230.526%;
  object-fit: cover;
  transform: translate(-50%, -50%) rotate(-90deg);
}
.photo-marks { position: absolute; inset: 0; width: 100%; height: 100%; }
.photo-word {
  position: absolute;
  left: 6.4%;
  top: 15.8%;
  font-size: clamp(18px, 2.4vw, 25px);
  font-weight: 600;
  line-height: 1.22;
  color: var(--accent);
}
.photo-bottom { padding-top: 8px; gap: 14px; }

/* ============ WIDGET + WATCH ============ */
.widget { overflow: hidden; }
.widget-glow {
  position: absolute;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(120,200,0,0.22) 0%, rgba(120,200,0,0) 65%);
  pointer-events: none;
}
.widget-glow.one { width: 699px; height: 699px; left: 50%; top: 54px; margin-left: -222px; }
.widget-glow.two { width: 633px; height: 633px; left: 50%; top: 282px; margin-left: 124px; }

.widget-grid {
  position: relative;
  display: grid;
  grid-template-columns: 546px 1fr;
  gap: 90px;
  align-items: center;
}
.widget-text .h2 { margin-top: 46px; }

.devices { position: relative; justify-self: end; }

/* phone mock */
.phone {
  width: 363px;
  max-width: 100%;
  aspect-ratio: 363 / 744;
  border-radius: 46px;
  background: #000;
  border: 10px solid #1a1a1a;
  box-shadow: 0 30px 80px rgba(0,0,0,0.6);
  overflow: hidden;
  position: relative;
}
.phone-screen {
  position: absolute; inset: 0;
  padding: 20px 24px 12px;
  background:
    radial-gradient(120% 55% at 15% 0%, rgba(166,255,0,0.16), transparent 62%),
    radial-gradient(130% 55% at 90% 100%, rgba(107,167,240,0.16), transparent 58%),
    #0a0a0a;
  display: flex; flex-direction: column;
}
.phone-status { display: flex; justify-content: space-between; align-items: center; font-size: 13px; font-weight: 600; padding: 0 6px 14px; }
.phone-status .sig { width: 40px; height: 12px; border-radius: 3px; background: rgba(255,255,255,0.25); }

.real-widget {
  background: rgba(22,22,22,0.88);
  border: 1px solid rgba(255,255,255,0.08);
  border-radius: 22px;
  padding: 16px;
  backdrop-filter: blur(4px);
}
.rw-head { display: flex; align-items: center; gap: 10px; }
.rw-mic { width: 42px; height: 42px; border-radius: 50%; background: #0a0a0a; border: 1.5px solid var(--accent); display: grid; place-items: center; }
.rw-mic svg { width: 20px; height: 20px; }
.rw-record { font-size: 15px; font-weight: 500; }
.rw-count { margin-left: auto; display: inline-flex; align-items: center; gap: 5px; font-size: 14px; color: var(--muted); }
.rw-count svg { width: 14px; height: 14px; }
.rw-divider { height: 1px; background: rgba(255,255,255,0.1); margin: 12px 0; }
.rw-list { display: flex; flex-direction: column; gap: 10px; }
.rw-row { display: flex; align-items: center; gap: 12px; font-size: 14px; }
.rw-time { width: 46px; font-weight: 500; font-size: 13px; }
.rw-time.red { color: #ff6b5e; }
.rw-time.green { color: var(--accent); }

.phone-apps {
  margin-top: 30px;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 20px 12px;
}
.phone-apps .app { display: flex; flex-direction: column; align-items: center; gap: 7px; }
.phone-apps .ic { width: 54px; height: 54px; border-radius: 15px; }
.phone-apps em { font-style: normal; font-size: 10px; color: rgba(255,255,255,0.75); }
.ic-notes { background: #2a2a2e; }
.ic-cal { background: #2b3546; }
.ic-maps { background: #4a2b28; }
.ic-photos { background: #26332c; }
.ic-clock { background: #4a4128; }
.ic-mail { background: #3a2b40; }

.phone-dock {
  margin-top: auto;
  display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 16px;
  background: rgba(255,255,255,0.07); border-radius: 26px; padding: 13px;
}
.phone-dock span { aspect-ratio: 1; border-radius: 14px; background: rgba(255,255,255,0.14); }

/* watch — it overlaps the phone's left edge exactly as in the frame */
.watch { position: absolute; left: -72px; top: 47%; width: 158px; }
.watch .strap { position: absolute; left: 31px; width: 95px; height: 68px; background: #232323; border-radius: 12px; }
.watch .strap.top { top: 0; }
.watch .strap.bottom { bottom: 0; }
.watch .crown { position: absolute; right: -2px; top: 100px; width: 7px; height: 27px; border-radius: 3px; background: #2e2e2e; }
.watch-body {
  position: relative;
  height: 190px;
  margin: 34px 0;
  background: #1b1b1b;
  border-radius: 34px;
  padding: 8px;
  box-shadow: 0 20px 50px rgba(0,0,0,0.55);
}
.watch-screen {
  position: relative;
  height: 100%;
  background: #050505;
  border-radius: 28px;
  overflow: hidden;
}
.watch-glow {
  position: absolute;
  left: -17px; top: -51px;
  width: 127px; height: 127px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(166,255,0,0.32), rgba(166,255,0,0) 68%);
}
.watch-note { position: absolute; left: 13.6px; right: 13.6px; top: 48px; }
.wn-app { display: flex; align-items: center; gap: 5px; font-size: 8px; font-weight: 600; color: rgba(255,255,255,0.75); letter-spacing: 0.04em; }
.wn-app .dot { width: 6px; height: 6px; border-radius: 50%; background: var(--accent); }
.wn-title { margin-top: 7px; font-size: 11px; font-weight: 700; }
.wn-meta { margin-top: 4px; font-size: 8px; color: rgba(255,255,255,0.55); }
.wn-actions { margin-top: 8px; display: flex; gap: 5px; }
/* Two pills on a 115px watch screen: the longest pair (Russian) needs every
   pixel, and a wrapped action label reads as a broken watch, not a long word. */
.wn-btn { background: rgba(255,255,255,0.12); border-radius: 999px; padding: 6px; font-size: 8px; font-weight: 600; white-space: nowrap; }
.wn-btn.primary { background: var(--accent); color: var(--ink); }

/* ============ EVERYDAY ============ */
.pills { margin-top: 56px; display: flex; flex-wrap: wrap; gap: 12px; }
.pill {
  border: 1.5px solid var(--accent);
  border-radius: 999px;
  padding: 13px 22px;
  font-size: 18px;
  font-weight: 600;
  letter-spacing: -0.01em;
}
.rule { margin: 40px 0 32px; border: none; border-top: 1px solid var(--border-soft); }
.fine { color: var(--muted); font-size: clamp(17px, 2vw, 22px); font-weight: 600; line-height: 1.5; }

/* ============ LANGUAGES ============ */
.lang-cards {
  margin-top: 56px;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 16px;
}
.lang-card {
  background: var(--bg-elev);
  border: 1px solid var(--border);
  border-radius: 18px;
  padding: 24px;
  min-height: 150px;
  display: flex;
  flex-direction: column;
  gap: 14px;
}
.lang-name {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 1.5px;
  text-transform: uppercase;
  color: var(--muted);
}
.lang-quote {
  font-size: 17px;
  font-weight: 500;
  line-height: 1.4;
  letter-spacing: -0.01em;
  /* German and Dutch compound a whole phrase into one word
     (boodschappenlijstje), which is wider than a card on a small phone. */
  overflow-wrap: break-word;
}

/* ============ DOWNLOAD ============ */
/* The glow behind the phone is wider than a narrow screen, and a decoration
   must never be the reason a page scrolls sideways. */
.download { padding-bottom: 90px; overflow: hidden; }
.download .logo { margin-bottom: 46px; }
.dl-title {
  font-size: clamp(40px, 5.6vw, 64px);
  font-weight: 900;
  letter-spacing: -0.03em;
  line-height: 1.24;
}
.dl-title span { display: block; }

.dl-wrap {
  margin-top: 56px;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 64px;
  flex-wrap: wrap;
  text-align: left;
}
.dl-phone {
  position: relative;
  width: 348px;
  max-width: 100%;
  height: 712px;
  border-radius: 46px;
  background: #0d0d0d;
  border: 2px solid #2e2e2e;
  padding: 10px;
  filter: drop-shadow(0 30px 35px rgba(0,0,0,0.6));
}
.dl-glow {
  position: absolute;
  left: 50%; top: 50%;
  width: 633px; height: 633px;
  margin: -316px 0 0 -316px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(130,215,0,0.38), transparent 64%);
  pointer-events: none;
  z-index: -1;
}
.dl-screen {
  position: relative;
  height: 100%;
  background: var(--bg);
  border-radius: 36px;
  /* 6px, not 16: the frame's grid ends up 294px wide inside a 348px phone, so
     each space card is ~140 — the width at which "Apartment" is one line. */
  padding: 14px 6px 18px;
  display: flex;
  flex-direction: column;
  gap: 16px;
  overflow: hidden;
}
.dl-status { display: flex; align-items: center; justify-content: space-between; padding: 0 8px; font-size: 13px; font-weight: 500; }
.dl-status span:first-child { font-size: 14px; font-weight: 600; }
.dl-status .notch { width: 90px; height: 16px; border-radius: 999px; background: #1a1a1a; }
/* `minmax(0, 1fr)` rather than `1fr`, here and in every other even grid on the
   page: a bare `1fr` will not shrink a track below its longest unbreakable
   word, so one long name ("Subscriptions", "boodschappenlijstje") widens its
   whole column and the pair stops being a pair. It is invisible in English
   until a card happens to hold a long word, and guaranteed in translation. */
.dl-grid {
  flex: 1;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  grid-auto-rows: 1fr;
  gap: 10px;
  border: 3px solid var(--border);
  border-radius: 24px;
  padding: 8px;
  background: linear-gradient(152deg, rgba(172,172,172,0.3) 4%, rgba(56,56,56,0.3) 58%, rgba(0,0,0,0.3) 100%);
  box-shadow: inset 0 -19px 25px rgba(0,0,0,0.3);
  overflow: hidden;
}
.dl-grid .sp {
  border-radius: 18px;
  padding: 12px 14px;
  color: var(--ink);
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}
/* A space name is one word as often as not, and a card is 132px wide — so it
   breaks mid-word rather than being cut off at the card edge, which is what
   the frame does with "Subscriptions" too. */
.dl-grid .sp b { font-size: 21px; font-weight: 600; line-height: 1.1; overflow-wrap: break-word; }
.dl-grid .sp i { font-size: 13px; font-style: normal; font-weight: 500; color: rgba(2,2,2,0.55); }

.dl-micbar { display: flex; align-items: center; justify-content: center; gap: 10px; }
.dl-mic {
  width: 58px; height: 58px; flex-shrink: 0;
  border-radius: 50%;
  background: var(--bg);
  border: 2.5px solid var(--accent);
  display: grid; place-items: center;
  box-shadow: 0 0 22px rgba(206,255,72,0.7);
}
.dl-mic svg { width: 24px; height: 24px; }
.dl-wave { flex: 1; min-width: 0; height: 26px; opacity: 0.8; }
.dl-wave svg { width: 100%; height: 100%; }

.dl-cta { display: flex; flex-direction: column; align-items: center; }
.dl-get { font-size: 24px; font-weight: 700; letter-spacing: -0.02em; }
.badges { margin-top: 20px; display: flex; flex-direction: column; gap: 40px; }
.badge-col { display: flex; flex-direction: column; align-items: center; gap: 14px; }
.badge {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  background: var(--bg);
  border: 1px solid #595959;
  border-radius: 14px;
  padding: 12px 22px 12px 18px;
  text-decoration: none;
  color: var(--text);
  transition: border-color 0.15s ease, transform 0.15s ease;
}
.badge:hover { border-color: var(--accent); transform: translateY(-2px); }
.badge-ico { width: 24px; height: 24px; flex-shrink: 0; }
.badge-txt { display: flex; flex-direction: column; gap: 1px; line-height: 1.15; }
.badge-txt small { font-size: 11px; color: rgba(255,255,255,0.7); }
.badge-txt b { font-size: 17px; font-weight: 600; }

.qr { width: 140px; height: 140px; border-radius: 16px; background: #fff; padding: 14px; }

/* ============ CONTACT ============ */
/* The Download block above ends the sales pitch, so this one is quieter: no
   glow, no phone, one box and one button. The section keeps the page's top
   padding and gives its bottom back to the footer, which sits right under it. */
.contact { padding-bottom: 100px; }

.contact-form {
  margin: 44px auto 0;
  max-width: 640px;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 16px;
}

.contact-box {
  width: 100%;
  min-height: 168px;
  resize: vertical;
  background: var(--bg-elev);
  border: 1px solid var(--border);
  border-radius: 18px;
  padding: 20px 22px;
  color: var(--text);
  font: inherit;
  font-size: 17px;
  line-height: 1.5;
}
.contact-box::placeholder { color: var(--muted-2); }
.contact-box:focus { outline: none; border-color: var(--accent); }

.contact-send {
  align-self: center;
  background: var(--accent);
  color: var(--ink);
  border: none;
  border-radius: 999px;
  padding: 15px 30px;
  font: inherit;
  font-size: 17px;
  font-weight: 700;
  letter-spacing: -0.01em;
  cursor: pointer;
  transition: transform 0.2s ease;
}
.contact-send:hover { transform: scale(1.03); }
.contact-send:active { transform: scale(0.98); }

/* Empty until the button has been pressed, so it must not reserve a line —
   it says either "write something first" or "your mail app has it now". */
.contact-note { font-size: 15px; line-height: 1.45; color: var(--muted); }
.contact-note.warn { color: var(--accent); }

.contact-direct { margin-top: 28px; font-size: 15px; color: var(--muted-2); }
.contact-direct a { margin-left: 6px; }

/* The label for the box: read aloud by a screen reader, invisible on screen,
   where the placeholder and the title already say what to write. */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* ============ FOOTER ============ */
.footer {
  border-top: 1px solid var(--border-soft);
  padding: 40px var(--pad);
  display: flex;
  justify-content: space-between;
  align-items: center;
  color: var(--muted-2);
  font-size: 14px;
  max-width: var(--maxw);
  margin: 0 auto;
  flex-wrap: wrap;
  gap: 10px;
}

.footer-link {
  color: var(--muted-2);
  text-decoration: none;
  border-bottom: 1px solid var(--border-soft);
}

.footer-link:hover { color: var(--text); border-bottom-color: var(--muted); }

/* ============ Reveal on scroll ============ */
.reveal { opacity: 0; transform: translateY(24px); transition: opacity 0.7s ease, transform 0.7s ease; }
.reveal.in { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  .reveal { opacity: 1; transform: none; transition: none; }
  .mic-glow, .wave span { animation: none; }
  html { scroll-behavior: auto; }
  /* The hero demo is shown as its own result and never plays: main.js puts it
     straight into the finished state — the note in the space it was filed
     into — and runs no loop. */
  .hero-body,
  .hero-title .line,
  .hero-sub,
  .hero-stage,
  .logo,
  .eyebrow,
  .mic-hint,
  .demo,
  .demo-said,
  .demo-said .w,
  .demo-phone,
  .dp-loading,
  .dp-result,
  .dp-open,
  .dp-wave,
  .dp-wave span,
  .dp-pulse,
  .dp-mic,
  .dp-mic-ico,
  .dp-dots { transition: none; animation: none; }
}

/* ============ Responsive ============ */
/* A laptop screen is often shorter than the first screen wants to be, and the
   demo has to finish inside it or it is not a first screen at all. Below this
   height everything at rest tightens — the resting hero already overflowed
   here before the demo existed, it just had nothing to lose by it. */
@media (max-height: 820px) {
  .hero { padding-top: 56px; padding-bottom: 32px; }
  .hero .logo-mark { width: 56px; height: 56px; }
  .hero .logo { margin-bottom: 16px; }
  .hero .eyebrow { margin-bottom: 26px; }
  .hero-sub { margin-top: 26px; }
  .mic { margin-top: 36px; }
  .hero-stage { padding-bottom: 44px; }
}
@media (max-width: 1060px) {
  .widget-grid { grid-template-columns: 1fr; gap: 56px; justify-items: center; }
  .widget-text { max-width: 546px; }
  .devices { justify-self: center; }
  .watch { left: -56px; }
}
@media (max-width: 900px) {
  .section { padding: 90px 0; }
  .said-cards { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .lang-cards { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
  .why-list li { gap: 24px; }
  .dl-wrap { gap: 48px; }
}
@media (max-width: 640px) {
  /* Two drawings side by side stop being readable before the text does — the
     space chips inside them are the narrowest thing on the page. */
  .tidy-cards { grid-template-columns: 1fr; }
  .watch { position: static; width: 158px; margin: 32px auto 0; }
  .watch .strap, .watch .crown { display: none; }
  .watch-body { margin: 0; }
}
@media (max-width: 560px) {
  :root { --pad: 20px; }
  .lang-switch { top: 14px; right: 14px; }
  .said-cards { grid-template-columns: 1fr; }
  .place-cards, .photo-cards { grid-template-columns: 1fr; }
  /* Eight cards in one column is a long scroll, so they stay paired and shed
     their height instead — the quote is two lines at this width. */
  .lang-card { min-height: 0; padding: 18px; }
  .lang-quote { font-size: 15px; }
  .moments-list li { flex-direction: column; align-items: flex-start; gap: 10px; padding: 26px 0; }
  .moments-list .say { font-size: 15px; }
  .why-list li { flex-direction: column; gap: 14px; padding: 32px 0; }
  .why-num { width: auto; }
  .hero { padding-top: 100px; }
  .dl-wrap { flex-direction: column; }
  .dl-phone { height: auto; aspect-ratio: 348 / 712; }
}
/* A paired card is ~150px wide on a small phone, which is narrower than a
   sentence deserves — below this they go one per row. */
@media (max-width: 480px) {
  .lang-cards { grid-template-columns: 1fr; }
}
