/* Landing page, candidate 01 (radar). The page's own look: the store slides'
   night and paper grounds (design/marketing/store/slides.css) with the radar,
   and the phones' app parts from the design kit. The kit lacks three app parts
   the steps show; they are at the end, built from the kit's tokens and the
   values the app's widgets use. */

:root {
  --w-coral: #ff385c;
  --w-coral-deep: #e11d48;
  --w-ink: #1a1d2e;
  --w-muted: #6e7787;
  --w-body: #4a5060;
  --w-paper-top: #fcf7f9;
  --w-paper-bot: #f5edf2;
  --w-night-0: #0f1120;
  --w-night-1: #1b1f3e;
  --w-night-2: #2a2450;
  --w-font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  /* the header's height: the hero starts under it, and a link to a section
     stops short of it */
  --head: 64px;
}

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; }
html { scroll-padding-top: calc(var(--head) + 16px); scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}
/* Every text comes in both languages; the page shows one. The language links
   carry en-GB and de-DE, and the kit's nav bar takes lang itself, so they show. */
html[lang="de"] [lang="en"]:not(k-nav-bar), html[lang="en"] [lang="de"]:not(k-nav-bar) { display: none !important; }
/* Which stores have the app: both, one while the other's listing isn't out
   yet, or none before the app is out, when the page takes addresses for the
   waitlist instead (?live= on this page; build_site.py's LIVE for the site,
   which leaves the other states' elements out altogether). An element marked
   data-live shows only in the states it names. */
html[data-live="both"] [data-live]:not([data-live~="both"]),
html[data-live="app-store"] [data-live]:not([data-live~="app-store"]),
html[data-live="google-play"] [data-live]:not([data-live~="google-play"]),
html[data-live="none"] [data-live]:not([data-live~="none"]) { display: none !important; }
body { background: var(--w-paper-top); color: var(--w-ink); font-family: var(--w-font); line-height: 1.55; -webkit-font-smoothing: antialiased; }
a { color: inherit; }
.wrap { max-width: 1180px; margin: 0 auto; padding: 0 28px; }
.wrap.narrow { max-width: 780px; }
/* One left edge for the headings. "You stay in control" and "Questions" used
   to sit in the narrow column, 200 px further in than the other headings;
   now each takes the page's width, its heading on the left and its lines on
   the right, in the hero's columns, so they start where the phones do. In
   one column the heading stands over its lines. */
.wrap.split { display: grid; grid-template-columns: minmax(0, .9fr) minmax(0, 1.1fr); align-items: start; gap: 24px; }
.wrap.split > h2 { grid-column: 1; margin: 0; }
.wrap.split > :not(h2) { grid-column: 2; }
section > .wrap > h2 { margin: 0 0 44px; font-size: clamp(30px, 3.6vw, 44px); font-weight: 800; line-height: 1.08; letter-spacing: -.028em; }
.paper { background: linear-gradient(180deg, var(--w-paper-top) 0%, var(--w-paper-bot) 100%); }

/* ---------- hero ---------- */
/* The app's welcome sky (welcome_paint.dart's kWelcomePeachSky): the radar's
   own ground in the app, whose night is Autopilot's. Chosen over the night
   ground on 2026-10-01. --page is the page's width: the window's, or .wrap's
   1180 px. */
.hero { --sky: linear-gradient(165deg, #FFF3EA 0%, #FFE4DC 55%, #FFD6CE 100%); --page: min(100vw, 1180px); position: relative; overflow: hidden; padding-top: var(--head); color: var(--w-ink); background: var(--sky); }
/* The header stays at the top of the window, as kansel.app's does: the brand,
   the page's sections in the middle, then the language and the way to the
   app. Frosted, so it reads over every ground, the night bands too; clear
   while the page is at its top (landing.js sets .at-top), so the hero's sky
   runs up to the window's edge as it did. Without the script it is frosted
   throughout. */
.site-head { position: fixed; top: 0; left: 0; right: 0; z-index: 60; background: rgba(255, 252, 250, .88); -webkit-backdrop-filter: saturate(1.6) blur(16px); backdrop-filter: saturate(1.6) blur(16px); box-shadow: 0 1px 0 rgba(26, 29, 46, .08); transition: background-color .2s, box-shadow .2s; }
.site-head.at-top { background: rgba(255, 252, 250, 0); -webkit-backdrop-filter: none; backdrop-filter: none; box-shadow: none; }
.head-row { display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 20px; height: var(--head); }
.brand { justify-self: start; display: inline-flex; align-items: center; gap: 9px; font-size: 18px; font-weight: 800; letter-spacing: -.01em; color: var(--w-ink); text-decoration: none; }
.brand img { display: block; }
.sections { display: flex; gap: 30px; font-size: 14.5px; font-weight: 600; white-space: nowrap; }
.sections a { color: rgba(26, 29, 46, .76); text-decoration: none; }
.sections a:hover { color: var(--w-ink); }
.head-end { justify-self: end; display: flex; align-items: center; gap: 18px; }
/* The way to the app, the header's one coloured thing: the deeper coral, on
   which white reads (4.7:1). */
.get-app { display: inline-flex; align-items: center; height: 38px; padding: 0 17px; border-radius: 999px; background: var(--w-coral-deep); font-size: 14px; font-weight: 700; color: #fff; text-decoration: none; white-space: nowrap; }
.get-app:hover { background: #c8173f; }
/* "Join the waitlist" is longer than "Get the app": the narrowest phones get
   the one word (below, "narrower screens") */
.get-app .short { display: none; }
.site-head a:focus-visible { outline: 3px solid rgba(255, 56, 92, .6); outline-offset: 3px; border-radius: 6px; }
.site-head .get-app:focus-visible { border-radius: 999px; }
.languages { font-size: 13px; color: rgba(26, 29, 46, .4); white-space: nowrap; }
.languages a { color: rgba(26, 29, 46, .7); text-decoration: none; }
.languages a:hover { color: var(--w-ink); text-decoration: underline; }
html[lang="en"] .languages a[hreflang="en"], html[lang="de"] .languages a[hreflang="de"] { color: var(--w-ink); font-weight: 700; }
/* --foot is the room under the grid. The grid is as tall as the window
   leaves it, up to 720 px, so the hero ends at the window's foot in a low
   window instead of under it (below, "the hero in a low window"). */
.hero-grid { --foot: 40px; position: relative; z-index: 2; display: grid; grid-template-columns: minmax(0, .9fr) minmax(0, 1.1fr); align-items: center; gap: 24px; min-height: min(720px, calc(100vh - var(--head) - var(--foot))); min-height: min(720px, calc(100svh - var(--head) - var(--foot))); padding-bottom: var(--foot); }
/* The words sit on the sky at its lightest and the radar on peach: two layers
   over the words' side, above the radar and under the phone, the listings and
   the words. Each is the hero's own box: the header's height above the grid,
   the window's width.
   - ::before paints the sky again, solid to 44 % of the page's width, where
     the words' column ends, and gone by 52 %, short of the phone. The rings
     and the sweep fade into the sky before the words instead of crossing
     them, and since it is the sky itself, its own edge can't be seen.
   - ::after is a wash of near-white: full behind the words' left half, gone
     where their column ends, and gone at the hero's foot, so the hero still
     ends on peach from edge to edge. */
.hero-grid::before,
.hero-grid::after { content: ""; position: absolute; z-index: 1; top: calc(var(--head) * -1); bottom: 0; left: calc((100% - 100vw) / 2); right: calc((100% - 100vw) / 2); pointer-events: none; }
.hero-grid::before { background: var(--sky); -webkit-mask-image: linear-gradient(90deg, #000 calc(50% - var(--page) * .06), transparent calc(50% + var(--page) * .02)); mask-image: linear-gradient(90deg, #000 calc(50% - var(--page) * .06), transparent calc(50% + var(--page) * .02)); }
.hero-grid::after { background: linear-gradient(90deg, rgba(255, 253, 251, .96) calc(50% - var(--page) * .24), rgba(255, 253, 251, 0) calc(50% - var(--page) * .045)); -webkit-mask-image: linear-gradient(180deg, #000 80%, transparent 100%); mask-image: linear-gradient(180deg, #000 80%, transparent 100%); }
.hero-copy { position: relative; z-index: 4; max-width: 540px; padding: 24px 0 48px; }
.eyebrow { display: inline-block; padding: 6px 14px; border-radius: 999px; background: rgba(255, 255, 255, .62); box-shadow: inset 0 0 0 1px rgba(26, 29, 46, .08); font-size: 12px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--w-coral-deep); }
/* The headline on three lines, each a phrase and the last the coloured word:
   "Find your / next home / faster." As large as the words' column allows, less
   in a low window so the badges stay in view. Beside the phone a line never
   wraps again, and its longest line sets the width of the words under it. */
h1 { margin: 24px 0 26px; font-size: clamp(56px, min(8.4vw - 8px, 12.4vh), 88px); font-weight: 800; line-height: 1; letter-spacing: -.022em; white-space: nowrap; }
/* German runs longer: "nächstes Zuhause" has to fit the words' column */
html[lang="de"] h1 { font-size: clamp(40px, 5.2vw - 4px, 58px); line-height: 1.04; }
/* welcome slide 3's headline gradient, kBrandPink to #F07060 */
.hl { background: linear-gradient(90deg, #FF385C, #F07060); -webkit-background-clip: text; background-clip: text; color: transparent; }
.lede { max-width: 500px; margin: 0 0 32px; font-size: 18.5px; line-height: 1.55; color: var(--w-body); }
/* The official store badges, unmodified and sized as #903 sizes them: every
   badge --badge-h tall. Google's files carry transparent padding on a
   646 x 250 canvas (English 41 px all round, German 29 px above and below),
   which the negative margins take back, so each link is exactly its visible
   badge. */
.stores { --badge-h: 52px; display: flex; flex-wrap: wrap; gap: 12px 14px; }
.stores-row { display: flex; flex-wrap: wrap; gap: 12px 14px; }
.badge { display: inline-flex; flex: none; border-radius: 9px; }
.badge:focus-visible { outline: 3px solid rgba(255, 56, 92, .6); outline-offset: 2px; }
.badge > img { display: block; width: auto; }
.app-store > img { height: var(--badge-h); }
.google-play > img[lang="en"] { height: calc(var(--badge-h) * 250 / 168); margin: calc(var(--badge-h) * -41 / 168); }
.google-play > img[lang="de"] { height: calc(var(--badge-h) * 250 / 192); margin: calc(var(--badge-h) * -29 / 192) 0; }
/* While only one store has the app, a quiet note stands where the other's
   badge would: as tall as the badge beside it, in the page's own type. */
.soon { display: inline-flex; align-items: center; justify-content: center; align-self: stretch; min-height: var(--badge-h); padding: 0 16px; border: 1.5px dashed rgba(26, 29, 46, .3); border-radius: 9px; font-size: 13.5px; font-weight: 650; line-height: 1.25; text-align: center; color: var(--w-body); }
.download .soon { border-color: rgba(255, 255, 255, .36); color: rgba(255, 255, 255, .84); }
/* A visitor at a desk can't install from there: the code opens flatstrike.com
   on their phone. It sits in a white tile with its caption under it, and the
   badges are centred on the tile; the tile's padding is the code's quiet
   zone. Not on touch screens, where the badges are a tap away, and not below
   1100 px, where the words' column is too narrow for the tile and both
   badges in one row. */
.qr { display: none; flex-direction: column; align-items: center; gap: 5px; flex: none; width: 84px; padding: 8px 8px 7px; border-radius: 16px; background: #fff; box-shadow: 0 0 0 1px rgba(26, 29, 46, .06), 0 10px 24px -8px rgba(120, 40, 60, .22); }
.qr > img { display: block; width: 68px; height: 68px; }
.qr-cap { max-width: 68px; font-size: 9.5px; font-weight: 700; line-height: 11px; letter-spacing: .01em; text-align: center; color: var(--w-body); }
/* The download band has it too, where the header's button leads at a desk.
   It is centred and has the room, so it shows from 700 px. */
@media (min-width: 700px) and (hover: hover) and (pointer: fine) {
  .download .qr { display: flex; }
  .download .stores { align-items: center; gap: 14px 18px; }
}
@media (min-width: 1100px) and (hover: hover) and (pointer: fine) {
  /* the tile is taller than the badges: a little less headline in a low
     window (11.5vh for 12.4), so the row stays in view. The German headline
     is smaller already and keeps its own size. */
  h1 { font-size: clamp(56px, min(8.4vw - 8px, 11.5vh), 88px); }
  .hero .stores { flex-wrap: nowrap; align-items: center; gap: 0 18px; }
  .hero .qr { display: flex; }
  /* a short headline (a low window) would squeeze the badges under the
     stores' 40 px minimum: the words' block is at least as wide as the tile
     and two 44 px badges */
  .hero-copy { min-width: 392px; }
}
/* One right edge. Beside the phone the words' block is as wide as the
   headline's longest line, and the sentence, the download row and the
   promises end where it ends. The badges share the row's width in the ratio
   of their shapes, so they stay equally tall: --r is each badge's width over
   its height. Google's image is placed over its link, larger than it by the
   file's transparent padding. */
@media (min-width: 901px) {
  .hero-copy { width: fit-content; }
  .hero-copy > .lede,
  .hero-copy > .stores,
  .hero-copy > .promises { width: 0; min-width: 100%; max-width: none; }
  /* the waitlist's row ends there too, and asks for 340 px itself: a short
     headline (a low window) would leave its field no room beside its button */
  .hero-copy > .waitlist { width: 340px; min-width: 100%; max-width: none; }
  .hero .stores-main { flex: 1; min-width: 0; }
  .hero .stores-row { flex-wrap: nowrap; gap: 13px; }
  .hero .badge { position: relative; flex: var(--r) 1 0; min-width: 0; aspect-ratio: var(--r); }
  /* the note takes the missing badge's share of the row, so the badge that
     is there keeps the size it has beside the other */
  .hero .soon { flex: 3.2 1 0; min-width: 0; min-height: 0; padding: 0 8px; }
  .hero .app-store { --r: 2.9916; }
  .hero .google-play { --r: 3.3571; }
  html[lang="de"] .hero .google-play { --r: 3.3646; }
  .hero .badge > img { position: absolute; left: 0; top: 0; width: 100%; height: 100%; margin: 0; }
  .hero .google-play > img[lang="en"] { left: calc(-41 / 564 * 100%); top: calc(-41 / 168 * 100%); width: calc(646 / 564 * 100%); height: calc(250 / 168 * 100%); }
  .hero .google-play > img[lang="de"] { top: calc(-29 / 192 * 100%); height: calc(250 / 192 * 100%); }
}
/* The three promises under the hero's badges, each with a check. The first,
   the one that sets FlatStrike apart, has a row of its own; the checks are
   in ink, so coral is left to the headline's last word. */
.promises { display: flex; flex-wrap: wrap; gap: 8px 22px; margin: 22px 0 0; padding: 0; list-style: none; font-size: 14.5px; font-weight: 600; line-height: 20px; color: var(--w-ink); }
.promises > li { position: relative; padding-left: 22px; }
.promises > li:first-child { flex-basis: 100%; }
.promises > li::after { content: ""; position: absolute; left: 4px; top: 3px; width: 5px; height: 10px; border: solid var(--w-ink); border-width: 0 2px 2px 0; transform: rotate(45deg); }
/* the same three as one line, under the download band's badges, in the
   night's moonlight (slides.css), which reads on it; the muted grey didn't
   (3.3:1) */
.ticks { margin: 20px 0 0; font-size: 14px; color: rgba(201, 205, 242, .8); }

/* ---------- the waitlist, before the app is out ---------- */
/* Where the badges will be, the page takes an address: the field and its
   button in one row, each as tall as a badge, in the header button's shape
   and coral. One line under them says what joining means, or what went
   wrong. Once the address is taken, the answer stands where the row was, as
   tall as the field. The field's type is 16 px: an iPhone zooms into a
   smaller one. */
.sr-only { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }
.waitlist { --field-h: 52px; position: relative; margin: 0; }
.waitlist-row { display: flex; gap: 10px; }
.waitlist-field { flex: 1 1 0; min-width: 0; }
.waitlist input[type="email"] { display: block; width: 100%; height: var(--field-h); margin: 0; padding: 0 20px; border: 0; border-radius: 999px; background: #fff; box-shadow: inset 0 0 0 1.5px rgba(26, 29, 46, .16), 0 10px 24px -14px rgba(120, 40, 60, .3); font: inherit; font-size: 16px; color: var(--w-ink); -webkit-appearance: none; appearance: none; }
.waitlist input[type="email"]::placeholder { color: var(--w-muted); opacity: 1; }
.waitlist input[type="email"]:focus-visible { outline: 3px solid rgba(255, 56, 92, .6); outline-offset: 2px; }
.waitlist button { flex: none; height: var(--field-h); margin: 0; padding: 0 22px; border: 0; border-radius: 999px; background: var(--w-coral-deep); font: inherit; font-size: 15.5px; font-weight: 700; color: #fff; white-space: nowrap; cursor: pointer; }
.waitlist button:hover { background: #c8173f; }
.waitlist button:focus-visible { outline: 3px solid rgba(255, 56, 92, .6); outline-offset: 3px; }
.waitlist button:disabled { opacity: .7; cursor: default; }
/* the API's honeypot: out of sight rather than display: none, which a bot may skip */
.waitlist-pot { position: absolute; left: -9999px; top: 0; width: 1px; height: 1px; opacity: 0; }
.waitlist-note, .waitlist-says { margin: 10px 0 0; font-size: 13px; line-height: 18px; color: var(--w-body); }
.waitlist-note a { color: inherit; text-decoration: underline; text-underline-offset: 2px; white-space: nowrap; }
.waitlist-says:empty { display: none; }
/* what went wrong takes the note's line until the visitor types again */
.waitlist.failed .waitlist-says { font-weight: 650; color: #c8173f; }
.waitlist.failed .waitlist-note { display: none; }
.waitlist.done .waitlist-row { display: none; }
.waitlist.done .waitlist-says { display: flex; align-items: center; min-height: var(--field-h); margin: 0; padding: 8px 22px; border-radius: 999px; background: #fff; box-shadow: inset 0 0 0 1.5px rgba(26, 29, 46, .16), 0 10px 24px -14px rgba(120, 40, 60, .3); font-size: 16px; font-weight: 700; line-height: 20px; color: var(--w-ink); }
.waitlist.done .waitlist-says::before { content: ""; flex: none; width: 7px; height: 13px; margin: -4px 14px 0 4px; border: solid var(--w-coral-deep); border-width: 0 2.5px 2.5px 0; transform: rotate(45deg); }
/* in the night band: centred under its heading, the line in the night's moonlight */
.download .waitlist { max-width: 460px; margin: 0 auto; }
.download .waitlist-note { color: rgba(201, 205, 242, .8); }
.download .waitlist.failed .waitlist-says { color: #ff9db0; }
.download .waitlist.done .waitlist-says { justify-content: center; }
.download .waitlist input[type="email"], .download .waitlist.done .waitlist-says { box-shadow: none; }

/* the radar: rings and sweep centred on the phone, as on store slide 05 */
/* --s-w is the phone's size as the window's width allows it, --s-h as its
   height does (below, "the hero in a low window"); --room is the radar's
   room above and below the phone together; --cap is more room under the
   phone, for the line that tells its story (.hero-story), where the window
   leaves none: the phone and its radar stand that much above the middle. */
.hero-visual { --s-w: .74; --s-h: .74; --s: min(var(--s-w), var(--s-h)); --ph: calc(862px * var(--s)); --room: 80px; --cap: 0px; --mid: calc(50% - var(--cap) / 2); position: relative; align-self: stretch; min-height: calc(var(--ph) + var(--room) + var(--cap)); }
/* a soft coral glow at the radar's centre, under the rings: with the shadow
   below, it stands the phone's white screen off the ground */
.hero-visual::before { content: ""; position: absolute; left: 50%; top: var(--mid); z-index: 0; width: calc(var(--ph) * 1.5); height: calc(var(--ph) * 1.5); border-radius: 50%; background: radial-gradient(closest-side, rgba(255, 86, 92, .34) 0%, rgba(255, 112, 100, .26) 34%, rgba(255, 140, 120, .12) 64%, rgba(255, 160, 140, 0) 100%); transform: translate(-50%, -50%); pointer-events: none; }
.radar { position: absolute; left: 50%; top: var(--mid); width: 0; height: 0; z-index: 0; }
.ring, .sweep { position: absolute; left: 0; top: 0; border-radius: 50%; transform: translate(-50%, -50%); }
/* The app's welcome radar (RadarDial, RadarSweep): rings in kBrandInk at
   14 % outside and 10 % inside, the sweep kBrandPink at 55 % on its edge,
   15 % by 54° and gone by 86°. Small: the outer ring 1.15 phone heights
   across, so the rings frame the phone; the sky painted over the words' side
   (.hero-grid::before) ends the rings and the sweep before the words. */
.ring { border: 2px solid rgba(26, 29, 46, .1); }
.r1 { width: calc(var(--ph) * .57); height: calc(var(--ph) * .57); }
.r2 { width: calc(var(--ph) * .86); height: calc(var(--ph) * .86); }
.r3, .sweep { width: calc(var(--ph) * 1.15); height: calc(var(--ph) * 1.15); }
.r3 { border-color: rgba(26, 29, 46, .14); }
.sweep { background: conic-gradient(from 300deg, rgba(255, 56, 92, .55) 0deg, rgba(255, 56, 92, .15) 54deg, rgba(255, 56, 92, 0) 86deg); }
.blip { position: absolute; left: 0; top: 0; width: 10px; height: 10px; margin: -5px 0 0 -5px; border-radius: 50%; background: #ff5a75; box-shadow: 0 0 16px 3px rgba(255, 56, 92, .75); }
.hero-phone { position: absolute; left: 50%; top: var(--mid); z-index: 2; transform: translate(-50%, -50%); }
/* the phone's shadow on the peach: tight at its edge, then deep and wide */
.hero-phone .k-phone { box-shadow: 0 3px 6px rgba(74, 22, 36, .14), 0 30px 46px -14px rgba(94, 30, 44, .32), 0 80px 120px -30px rgba(150, 48, 62, .4); }
/* the search card answers as a listing lands; so does the phone's frame, for
   a listing that lands while Review Mode covers the card */
#hero-card { outline: 0 solid rgba(255, 56, 92, 0); outline-offset: 2px; }
.hero-phone .k-phone { outline: 0 solid rgba(255, 56, 92, 0); outline-offset: 3px; }
/* a listing the sweep finds: the flat, never its site */
.finds { position: absolute; inset: 0; z-index: 3; pointer-events: none; }
.find { position: absolute; left: 0; top: 0; display: inline-flex; align-items: center; gap: 10px; padding: 9px 16px 10px 12px; border-radius: 16px; background: #fff; box-shadow: 0 10px 26px rgba(26, 29, 46, .16), 0 0 0 1px rgba(26, 29, 46, .05); line-height: 1.25; color: var(--w-ink); white-space: nowrap; opacity: 0; will-change: transform, opacity; }
.find b { display: block; font-size: 14px; font-weight: 700; }
.find small { display: block; font-size: 12.5px; font-weight: 500; color: var(--w-muted); }
.find > i { flex: none; width: 9px; height: 9px; border-radius: 50%; background: var(--w-coral); box-shadow: 0 0 10px 2px rgba(255, 56, 92, .55); }
/* What the phone is doing, a line at a time, under it: each step of the
   story as it plays (owner, 2026-10-02). Every line sits in the one cell, so
   the pill is as wide as the longest line and keeps its size while
   landing.js fades one line out and the next in. Hidden without the script,
   which has the lines. */
.hero-story { position: absolute; left: 50%; top: calc(var(--mid) + var(--ph) / 2 + 12px); z-index: 3; display: grid; width: max-content; max-width: min(100%, 440px); padding: 6px 16px; border-radius: 16px; background: rgba(255, 255, 255, .86); box-shadow: inset 0 0 0 1px rgba(26, 29, 46, .08), 0 8px 20px rgba(94, 30, 44, .12); font-size: 14.5px; font-weight: 600; line-height: 20px; text-align: center; color: var(--w-ink); transform: translateX(-50%); pointer-events: none; }
.hero-story[hidden] { display: none; }
.hero-story > span { grid-area: 1 / 1; opacity: 0; will-change: transform, opacity; }

/* ---------- the hero in a low window ---------- */
/* Beside the phone, the hero fits the window's first screen from 650 px of
   height up, which is about what a 1366 x 768 laptop leaves a page: the
   whole phone, and the words down to the promises. It was 838 px tall at any
   height, so there the promises and the phone's foot were under the fold.
   The phone is as large as the height allows, in steps; the radar's room
   round it and the room under the grid close up; and the words' spacing and
   the English headline give a little. From 830 px up nothing changes.
   Each step's sum: the grid has the window less the header and --foot, and
   the phone with its --room and --cap has to fit in that. The line under the
   phone (.hero-story) is part of the first screen too: down to 790 px it
   fits in the room there is, and below that --cap makes room for it, for
   which the radar's room closes up a little more and the phone is two
   points smaller than the height alone would allow (66 % for 68 %). */
@media (min-width: 901px) and (max-height: 829px) {
  .hero-visual { --room: 48px; }
  .hero-copy { padding: 14px 0 26px; }
}
@media (min-width: 901px) and (max-height: 789px) {
  .hero-grid { --foot: 12px; }
  .hero-visual { --s-h: .66; --room: 32px; --cap: 24px; }
  .hero-copy { padding: 12px 0 24px; }
  h1 { margin: 18px 0 20px; font-size: clamp(56px, min(8.4vw - 8px, 10.4vh), 88px); }
  .lede { margin-bottom: 24px; }
  .promises { margin-top: 18px; }
}
@media (min-width: 901px) and (max-height: 701px) {
  .hero-visual { --s-h: .60; }
  .hero-copy { padding: 8px 0 14px; }
  h1 { margin: 14px 0 16px; font-size: clamp(56px, min(8.4vw - 8px, 9.6vh), 88px); }
  .lede { margin-bottom: 20px; }
  .promises { margin-top: 14px; }
}
@media (min-width: 901px) and (max-height: 649px) {
  .hero-visual { --s-h: .56; }
}
@media (min-width: 901px) and (max-height: 615px) {
  .hero-visual { --s-h: .52; }
}

/* Real listing photos fill the kit's media frames, cropped as the app crops them */
.k-media > img.photo, .k-tracker-media > img.photo { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }

/* the hero phone: Home and the Tracker under one nav bar; Review Mode over
   both once Review now is tapped; "Exit Review Mode?" over that */
.hero-phone .scene.review { z-index: 12; visibility: hidden; opacity: 0; }
.hero-phone .scene.tracker { background: linear-gradient(var(--bg-gradient-top), var(--bg-gradient-bottom)); visibility: hidden; }
.hero-phone .exit-scrim, .hero-phone .exit-dialog { visibility: hidden; opacity: 0; }
.exit-dialog > h3 { margin: 0; }
.exit-rows { margin-top: 16px; }
.exit-rows > div { display: flex; align-items: baseline; padding: 3px 0; font: var(--body-medium) var(--k-font); letter-spacing: var(--body-medium-tracking); color: var(--on-surface); }
.exit-rows > div > span { flex: 1; }
.exit-rows > div > b { font-weight: 800; }
.exit-rows > div > b.applied { color: #4338CA; }  /* _UsageFlashSpec._applyColor */
.exit-rows > div > b.liked { color: #15803D; }    /* _UsageFlashSpec._likeColor */
.k-dialog > p.exit-saved { margin-top: 12px; font: var(--body-small) var(--k-font); letter-spacing: var(--body-small-tracking); color: var(--on-surface-variant); }
.exit-dialog .k-dialog-actions { align-items: center; }
.exit-dialog .k-filled-button { margin: 0; }
.hero-phone .stage { overflow: visible; }
.hero-phone .k-apply-pill { top: 33px; opacity: 0; }  /* the kit's 80 from the screen's top, in a screen below the status bar */
.k-screen > .tap { z-index: 45; }

/* a number that rolls to its next value, as the app's counter does */
.roll { display: inline-grid; overflow: hidden; vertical-align: bottom; }
.roll > b { grid-area: 1 / 1; font: inherit; letter-spacing: inherit; }

/* ---------- phones ---------- */
.phone-box { position: relative; flex: none; width: calc(408px * var(--s)); height: calc(862px * var(--s)); }
.phone-box > .k-phone { transform: scale(var(--s)); transform-origin: 0 0; }
/* the app aligns its own text; nothing from the page around it leaks in */
.phone-box { text-align: left; line-height: normal; }

/* ---------- how it works ---------- */
.how { padding: 104px 0 112px; }
.steps { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 48px 36px; margin: 0; padding: 0; list-style: none; }
/* Each step's number, title and line come before its phone, so a visitor
   reads what the phone is about to show. Side by side the steps are equally
   tall and each phone sits at its step's foot, so the three phones stay level
   under lines of different lengths. */
.step { display: flex; flex-direction: column; align-items: center; text-align: center; }
.step-phone { --s: .62; margin-top: auto; }
.step-text { max-width: 330px; margin-bottom: 30px; }
.step-num { position: relative; display: inline-grid; place-items: center; width: 32px; height: 32px; border-radius: 50%; background: var(--w-ink); font-size: 14px; font-weight: 800; color: #fff; }
/* Side by side, the steps take turns (landing.js): --f lights the playing
   one, from 0 to 1 as it takes the turn, and --p fills the ring round its
   number as it plays. The steps resting dim. */
.steps.in-turn .step-phone { opacity: calc(.55 + .45 * var(--f, 0)); }
.steps.in-turn .step-num { background: color-mix(in srgb, var(--w-coral) calc(var(--f, 0) * 100%), var(--w-ink)); }
.steps.in-turn .step-num::after { content: ""; position: absolute; inset: -6px; border-radius: 50%; background: conic-gradient(var(--w-coral) calc(var(--p, 0) * 1turn), rgba(255, 56, 92, .16) 0); -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 3px), #000 calc(100% - 2.5px)); mask: radial-gradient(farthest-side, transparent calc(100% - 3px), #000 calc(100% - 2.5px)); opacity: var(--f, 0); }
.step h3 { margin: 14px 0 8px; font-size: 22px; line-height: 1.2; letter-spacing: -.015em; }
.step p { margin: 0; font-size: 16px; color: var(--w-body); }

/* ---------- autopilot ---------- */
/* Autopilot as the app's welcome slide and store slide 03 draw it: on night,
   which the app keeps for Autopilot, with the moon over a sleeping skyline
   and a paper plane and its dotted trail for each application on its way
   (design/brand/illustrations). The ground, the moon, the stars and the
   skyline are the store slides' (design/marketing/store/slides.css). Its
   narrower layouts are at the end of this block, not with the page's. */
.autopilot { position: relative; overflow: hidden; padding: 104px 0 112px; color: #fff; background: linear-gradient(180deg, var(--w-night-0) 0%, var(--w-night-1) 58%, var(--w-night-2) 100%); }
.ap-sky { position: absolute; inset: 0; pointer-events: none; }
.ap-star { position: absolute; border-radius: 50%; background: #fff; }
/* two sets of stars, each clear of the words where they sit: beside the phone,
   and above it in one column */
.ap-star.narrow { display: none; }
/* The slides' whole city is 1290 x 560, shown at the band's width from its
   roofs down. The band's foot cuts it 186 units down, between two rows of
   lit windows, so none is cut through; a narrow band shows all of them, 394
   units down. It grows no wider than 1680 px, so in a wider window it can't
   rise behind the words: there it fades out at both ends. */
.ap-skyline { position: absolute; left: 50%; bottom: 0; display: block; width: min(100%, 1680px); height: min(14.4vw, 242px); object-fit: cover; object-position: 50% 0; transform: translateX(-50%); }
@media (min-width: 1681px) {
  .ap-skyline { -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 9%, #000 91%, transparent 100%); mask-image: linear-gradient(90deg, transparent 0, #000 9%, #000 91%, transparent 100%); }
}
/* the hero's columns, so this phone stands under the hero's */
.ap-grid { position: relative; display: grid; grid-template-columns: minmax(0, .9fr) minmax(0, 1.1fr); align-items: center; gap: 24px; }
.ap-copy { position: relative; z-index: 2; max-width: 520px; }
.ap-tag { display: inline-flex; align-items: center; gap: 6px; height: 34px; padding: 0 16px 0 10px; border-radius: 17px; background: rgba(255, 255, 255, .1); box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .16); font-size: 14px; font-weight: 700; line-height: 1; }
.ap-tag > svg { display: block; width: 20px; height: 20px; }
/* it is a link to the plans: a small arrow says so, and it lifts under the pointer */
.ap-tag { color: #fff; text-decoration: none; transition: background-color .15s; }
.ap-tag::after { content: ""; width: 6px; height: 6px; margin-left: 3px; border: solid rgba(255, 255, 255, .7); border-width: 0 2px 2px 0; transform: rotate(-45deg); }
.ap-tag:hover { background: rgba(255, 255, 255, .18); }
.ap-tag:focus-visible { outline: 3px solid rgba(255, 109, 132, .7); outline-offset: 3px; }
.autopilot h2 { margin: 22px 0 18px; font-size: clamp(34px, 4.2vw, 52px); font-weight: 800; line-height: 1.08; letter-spacing: -.028em; }
/* German runs longer: "Autopilot bewirbt sich," has to fit the words' column */
html[lang="de"] .autopilot h2 { font-size: clamp(28px, 3.5vw, 43px); }
/* the slides' night highlight, coral to peach */
.autopilot .hl { background: linear-gradient(90deg, #ff6d84, #f2a08f); -webkit-background-clip: text; background-clip: text; color: transparent; }
/* no word left alone on its last line, where the browser can */
.ap-lede { max-width: 470px; margin: 0; font-size: 18.5px; line-height: 1.55; color: #c9cdf2; text-wrap: pretty; }

/* The scene: the phone left of its column's middle, and the moon in the sky
   that leaves to its right, where the planes fly. --mr is the moon's radius,
   --mx and --my its centre, --px the phone's middle. In a narrow scene the
   phone moves left, as far as the edge, to leave the moon and its z's their
   room; where even that is too little, the moon keeps clear of the phone. */
.ap-visual { --s: .62; --ph: calc(862px * var(--s)); --pw: calc(408px * var(--s)); --mr: calc(var(--ph) * .095); --px: clamp(var(--pw) / 2, 42%, 100% - var(--pw) / 2 - var(--mr) * 3.6); --mx: max(100% - var(--mr) * 2.1, var(--px) + var(--pw) / 2 + var(--mr) * 1.4); --my: calc(var(--mr) * 1.8); position: relative; height: var(--ph); }
.ap-phone { position: absolute; left: var(--px); top: 0; z-index: 2; margin-left: calc(var(--pw) / -2); }
/* on night the dark frame needs an edge: a faint ring, then a deep shadow */
.ap-phone .k-phone { box-shadow: 0 0 0 1.5px rgba(255, 255, 255, .16), 0 0 0 9px rgba(255, 255, 255, .05), 0 50px 90px rgba(0, 0, 0, .55); }
.ap-moon, .ap-moon-glow { position: absolute; left: var(--mx); top: var(--my); border-radius: 50%; transform: translate(-50%, -50%); }
.ap-moon { width: calc(var(--mr) * 2); height: calc(var(--mr) * 2); background: radial-gradient(circle at 38% 38%, #fff6dc, #ffe9a8); -webkit-mask: radial-gradient(circle at 84% 18%, transparent 0 44%, #000 45%); mask: radial-gradient(circle at 84% 18%, transparent 0 44%, #000 45%); }
.ap-moon-glow { width: calc(var(--mr) * 4); height: calc(var(--mr) * 4); background: radial-gradient(closest-side, rgba(255, 236, 168, .28), transparent 72%); }
/* the sleeper's z's, placed and sized by the moon as on slide 03 */
.ap-zzz { position: absolute; font-weight: 800; line-height: 1; color: #8e93c4; }
.ap-zzz.z1 { left: calc(var(--mx) + var(--mr) * 1.16); top: calc(var(--my) - var(--mr) * 1.42); font-size: calc(var(--mr) * .49); }
.ap-zzz.z2 { left: calc(var(--mx) + var(--mr) * 1.57); top: calc(var(--my) - var(--mr) * 1.84); font-size: calc(var(--mr) * .37); opacity: .8; }
.ap-zzz.z3 { left: calc(var(--mx) + var(--mr) * 1.88); top: calc(var(--my) - var(--mr) * 2.14); font-size: calc(var(--mr) * .27); opacity: .6; }
/* an application on its way: the slides' plane and its trail. Under the
   phone, so each plane comes out from behind it, and over the moon. */
.ap-flights { position: absolute; inset: 0; z-index: 1; pointer-events: none; }
.ap-plane { position: absolute; left: 0; top: 0; width: calc(var(--ph) * .084); height: calc(var(--ph) * .084); margin: calc(var(--ph) * -.042) 0 0 calc(var(--ph) * -.042); opacity: 0; filter: drop-shadow(0 6px 10px rgba(0, 0, 0, .35)); will-change: transform, opacity; }
.ap-dot { position: absolute; left: 0; top: 0; width: 4px; height: 4px; margin: -2px 0 0 -2px; border-radius: 50%; background: #ff6d84; opacity: 0; }

@media (max-width: 1080px) {
  .ap-visual { --s: .56; }
}
@media (max-width: 900px) {
  /* one column: the words, then the same scene */
  .ap-grid { grid-template-columns: minmax(0, 1fr); gap: 44px; }
  .ap-skyline { height: 30.6vw; }
  .ap-star.wide { display: none; }
  .ap-star.narrow { display: block; }
  .ap-copy { max-width: 600px; }
  .ap-visual { --s: .64; }
}
@media (max-width: 520px) {
  .autopilot { padding: 72px 0 84px; }
  .ap-lede { font-size: 17px; }
  /* a phone's width: a smaller phone and moon, so the sky beside the phone
     still holds the moon and a plane's way */
  .ap-visual { --s: .56; --mr: calc(var(--ph) * .075); }
  .ap-dot { width: 3px; height: 3px; margin: -1.5px 0 0 -1.5px; }
}
@media (max-width: 380px) {
  /* the narrowest phones: smaller again, or the last z would leave the band */
  .ap-visual { --s: .52; }
}

/* ---------- you stay in control ---------- */
.control { padding: 96px 0; background: #fff; }
.checks { display: grid; gap: 18px; margin: 0; padding: 0; list-style: none; }
.checks li { position: relative; padding-left: 44px; font-size: 18px; line-height: 1.5; }
.checks li::before { content: ""; position: absolute; left: 0; top: 1px; width: 28px; height: 28px; border-radius: 50%; background: #E2F4E7; }
.checks li::after { content: ""; position: absolute; left: 10px; top: 7px; width: 6px; height: 12px; border: solid #247C3D; border-width: 0 2.5px 2.5px 0; transform: rotate(45deg); }

/* ---------- plans ---------- */
.plans { padding: 104px 0; }
/* Side by side the three cards share their rows (subgrid): name, price, list.
   The lists start level under price blocks of different heights, "Free" and
   the paid plans' three lines, at any width; stacked, each card is its own. */
.plan-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 22px; }
.plan { padding: 30px 28px 26px; border: 1px solid #efe4ea; border-radius: 22px; background: #fff; box-shadow: 0 14px 34px -18px rgba(40, 20, 40, .22); }
.plan-grid > .plan { display: grid; grid-template-rows: subgrid; grid-row: span 3; row-gap: 0; }
.plan h3 { margin: 0; font-size: 22px; letter-spacing: -.01em; }
/* The paid plans lead with the three-month price as the app's plan screen
   words it: what a month comes to, with the saving; then what is charged and
   when, in ink; then the monthly price. */
.price { margin: 10px 0 18px; }
.price b { display: block; font-size: 26px; font-weight: 800; letter-spacing: -.02em; color: var(--w-coral-deep); }
.price span { display: block; margin-top: 2px; font-size: 14px; color: var(--w-muted); }
.price span.billed { font-weight: 600; color: var(--w-ink); }
/* "Save 50%", in the green of the control list's checks */
.save { display: inline-block; margin-left: 4px; padding: 3px 9px; border-radius: 999px; background: #E2F4E7; font-size: 12px; font-style: normal; font-weight: 700; line-height: 16px; letter-spacing: 0; color: #1D6B34; vertical-align: 5px; white-space: nowrap; }
.plan ul { display: grid; align-content: start; gap: 10px; margin: 0; padding: 0; list-style: none; }
.plan li { position: relative; padding-left: 26px; font-size: 15.5px; line-height: 1.45; color: var(--w-body); }
.plan li::before { content: ""; position: absolute; left: 4px; top: 4px; width: 5px; height: 10px; border: solid var(--w-coral); border-width: 0 2.2px 2.2px 0; transform: rotate(45deg); }
/* each card's first line, the speed, in both languages: the list holds the
   English line and then the German one, so the first two */
.plan li:nth-child(-n+2) { font-weight: 650; color: var(--w-ink); }
/* in the body's grey: the muted one is too faint on the paper (4.0:1) */
.note { margin: 26px 0 0; font-size: 14px; color: var(--w-body); }

/* ---------- questions ---------- */
.faq { padding: 96px 0; background: #fff; }
details { border-bottom: 1px solid #ece4e8; }
details:first-of-type { border-top: 1px solid #ece4e8; }
summary { position: relative; padding: 20px 44px 20px 0; font-size: 18px; font-weight: 700; list-style: none; cursor: pointer; }
summary::-webkit-details-marker { display: none; }
summary::after { content: "+"; position: absolute; right: 6px; top: 50%; font-size: 26px; font-weight: 400; line-height: 1; color: var(--w-coral); transform: translateY(-50%); }
details[open] summary::after { content: "−"; }
details p { margin: 0 0 22px; font-size: 16.5px; color: var(--w-body); }

/* ---------- download ---------- */
.download { padding: 96px 0; text-align: center; color: #fff; background: linear-gradient(180deg, var(--w-night-1) 0%, var(--w-night-2) 100%); }
.download h2 { margin-bottom: 30px !important; }
.download .stores { justify-content: center; }

/* ---------- the page for an address that isn't one (not-found.html) ---------- */
/* The hero's sky under the header without its sections, and three things on
   it: what happened, why, and the way back. As tall as the window, so the
   footer starts at its foot. */
.head-row.two { grid-template-columns: auto 1fr; }
.lost { display: grid; align-items: center; min-height: 100vh; min-height: 100svh; padding-bottom: 64px; }
.lost > .wrap { width: 100%; }
.lost h1 { margin: 22px 0 24px; }
.lost .get-app { height: 46px; padding: 0 24px; font-size: 15.5px; }
.lost .get-app:focus-visible { outline: 3px solid rgba(255, 56, 92, .6); outline-offset: 3px; }

/* ---------- footer ---------- */
.foot { padding: 34px 0 40px; background: var(--w-night-0); font-size: 13px; color: rgba(201, 205, 242, .7); }
.foot-row { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 14px 24px; }
.foot a { color: rgba(255, 255, 255, .85); text-decoration: none; }
.foot a:hover { text-decoration: underline; }
/* quiet, but readable: at .45 the trademark lines were 3.3:1 */
.credits { flex-basis: 100%; margin: 6px 0 0; font-size: 11px; line-height: 1.5; color: rgba(201, 205, 242, .62); }

/* ---------- stopping the motion ---------- */
/* Motion that starts on its own and runs on can be stopped (WCAG 2.2.2): a
   small switch in the radar's corner and one beside "How it works", each for
   every animation on the page (landing.js). Stopped, the page is as visitors
   who turn off animations see it. Hidden from them, in the review shots and
   without the script, where nothing moves. */
.motion { position: absolute; z-index: 5; display: grid; place-items: center; width: 40px; height: 40px; padding: 0; border: 0; border-radius: 50%; background: rgba(255, 255, 255, .72); box-shadow: inset 0 0 0 1px rgba(26, 29, 46, .1); color: var(--w-ink); cursor: pointer; }
.motion[hidden] { display: none; }
.motion:hover { background: #fff; }
.motion:focus-visible { outline: 3px solid rgba(255, 56, 92, .6); outline-offset: 2px; }
/* two bars while the page moves, a triangle once it is stopped */
.motion::before { content: ""; width: 4px; height: 13px; border: solid currentColor; border-width: 0 4px; opacity: .72; }
.motion[aria-pressed="true"]::before { width: 0; height: 0; margin-left: 3px; border-width: 7px 0 7px 12px; border-color: transparent transparent transparent currentColor; }
/* its name is for screen readers; the page's language rule hides the other one */
.motion > span { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
/* The hero's sits in the top right corner of the radar's cell of the grid
   (the cell is its containing block): beside the phone, and in view with it
   at any window height, where the hero's foot can be below the fold. */
.hero-grid > .motion { grid-area: 1 / 2 / 2 / 3; top: 4px; right: 0; }
/* level with the heading's line, whatever its size */
.how > .wrap { position: relative; }
.how .motion { right: 28px; top: calc(clamp(30px, 3.6vw, 44px) * .54 - 20px); }

/* ---------- narrower screens ---------- */
@media (max-width: 1080px) {
  .hero-visual { --s-w: .66; }
  .sections { gap: 22px; }
  .steps { gap: 48px 20px; }
  .step-phone { --s: .56; }
}
@media (max-width: 900px) {
  /* no room for the sections in the header: the brand, the language, the app */
  .head-row { grid-template-columns: auto 1fr; }
  .sections { display: none; }
  .wrap.split { display: block; }
  .wrap.split > h2 { margin-bottom: 36px; }
  .hero-grid { grid-template-columns: minmax(0, 1fr); gap: 0; min-height: 0; }
  /* one column: the words above, the radar below them, and no ring near the
     words. The wash runs down from the top instead, and a headline's line
     that doesn't fit may wrap. */
  .hero-grid::before { display: none; }
  .hero-grid::after { background: linear-gradient(180deg, rgba(255, 253, 251, .96) 0%, rgba(255, 253, 251, 0) 44%); -webkit-mask-image: none; mask-image: none; }
  h1 { font-size: clamp(46px, 11vw + 4px, 72px); white-space: normal; }
  html[lang="de"] h1 { font-size: clamp(34px, 10.4vw, 60px); }
  .hero-copy { max-width: 600px; padding-bottom: 24px; }
  .hero-visual { --s: .62; min-height: calc(var(--ph) + 150px); }
  /* the radar's cell is the second row now */
  .hero-grid > .motion { grid-area: 2 / 1 / 3 / 2; }
  .steps { grid-template-columns: minmax(0, 1fr); gap: 64px; }
  .step-phone { --s: .64; }
  .plan-grid { grid-template-columns: minmax(0, 1fr); max-width: 520px; }
}
@media (max-width: 520px) {
  :root { --head: 56px; }
  .wrap { padding: 0 16px; }
  /* only the other language, as a link to it */
  html[lang="en"] .languages a[hreflang="en"], html[lang="de"] .languages a[hreflang="de"], .languages > span { display: none; }
  .head-end { gap: 14px; }
  .get-app { height: 36px; padding: 0 15px; }
  .lede { font-size: 17px; }
  .stores { --badge-h: 46px; gap: 10px; }
  .stores-row { gap: 10px; }
  /* a phone's width: the field over its button, each the screen's width, so
     an address has the whole line */
  .waitlist { --field-h: 50px; }
  .waitlist-row { flex-direction: column; }
  .waitlist-field { flex: none; }
  .hero-visual { --s: .56; min-height: calc(var(--ph) + 150px); }
  .find { gap: 8px; padding: 7px 12px 8px 10px; border-radius: 14px; }
  .find b { font-size: 13px; }
  .find small { font-size: 11.5px; }
  .find > i { width: 7px; height: 7px; }
  .hero-story { padding: 5px 14px; font-size: 13.5px; }
  .how, .plans, .control, .faq, .download { padding: 72px 0; }
  .how .motion { right: 16px; }
  .step-phone { --s: .6; }
  .checks li, summary { font-size: 17px; }
}
@media (max-width: 380px) {
  /* the narrowest phones: the header has no room for "Join the waitlist"
     beside the brand and the other language */
  .get-app .long { display: none; }
  .get-app .short { display: inline; }
}

/* ======================================================================
   App parts the design kit lacks
   ====================================================================== */

/* A phone's screens, one over another, each drawn whole; and the finger that
   taps them */
.scenes { position: relative; flex: 1; min-height: 0; }
.scene { position: absolute; inset: 0; display: flex; flex-direction: column; background: var(--bg-gradient-top); will-change: transform, opacity; }
.tap { position: absolute; left: 0; top: 0; z-index: 3; width: 46px; height: 46px; margin: -23px 0 0 -23px; border-radius: 50%; background: rgba(26, 29, 46, .2); opacity: 0; }
/* Edit Search Profile: the rooms chips as the app's, a check on the one picked */
.scene.form .k-form { padding-top: 8px; }
.rooms { margin-top: 6px; }
.rooms > .k-chip { margin: 0; }
.rooms > .k-chip:not(.on) > k-icon { display: none; }

/* Review: the card stage. Two listing cards stacked on the card frame's
   ground; the decision moves them (strike_decision_animations.dart). */
.stage > .card { position: absolute; inset: 0; background: #F4F7F2; will-change: transform, opacity; }
.stage .k-media > div[class^="tab-"] { position: absolute; inset: 0; }
/* a listing's photos side by side; a swipe slides the strip one photo along */
.stage .tab-photos { overflow: hidden; }
.stage .strip { display: flex; width: 100%; height: 100%; will-change: transform; }
.stage .strip > img.photo { display: block; flex: none; width: 100%; height: 100%; object-fit: cover; }
.stage .tab-floor { background: #F8F6F1; }
/* the map as the recording showed it: the whole 390 × 275 media frame, so its
   address chip and locate button sit where the kit's would */
.stage .tab-map > img.map { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
/* the floor plan, letterboxed below the tab bar as the app shows it */
.stage .tab-floor > img.plan { position: absolute; inset: 0; width: 100%; height: 100%; padding: 46px 12px 24px; object-fit: contain; }
.stage .k-stamp { opacity: 0; }

/* The outgoing application (_LetterCard): 326 wide on a 390 phone, padding
   24/24/28, radius 16; the letter fades out over its last 22 %; the rubber
   stamp (_SentRubberStamp) in #10B981, tilted -0.18 rad. */
.letter { position: absolute; left: 50%; top: 50%; z-index: 7; width: 326px; padding: 24px 24px 28px; border-radius: 16px; background: #FFFFFF; box-shadow: 0 16px 32px rgba(0, 0, 0, .18); opacity: 0; transform: translate(-50%, -50%); will-change: transform, opacity; }
.letter-title { display: flex; align-items: center; gap: 6px; font-size: 11px; font-weight: 800; letter-spacing: .6px; line-height: 1; color: #94A3B8; }
.letter-title > k-icon { color: #10B981; }
.letter-from { display: flex; align-items: center; gap: 10px; margin-top: 12px; padding: 10px 12px; border: 1px solid #E2E8F0; border-radius: 12px; background: #F8FAFC; }
.letter-avatar { flex: none; display: grid; place-items: center; width: 30px; height: 30px; border-radius: 50%; background: rgba(16, 185, 129, .1); color: #10B981; }
.letter-from small { display: block; font-size: 10px; font-weight: 800; letter-spacing: .4px; color: #94A3B8; }
.letter-from b { display: block; font-size: 13px; font-weight: 800; color: #0F172A; }
.letter-from div > span { display: block; font-size: 12px; color: #64748B; }
.letter-text { max-height: 168px; margin: 14px 0 0; overflow: hidden; font-size: 14px; line-height: 1.5; color: #334155; white-space: pre-line; -webkit-mask-image: linear-gradient(180deg, #000 78%, transparent); mask-image: linear-gradient(180deg, #000 78%, transparent); }
.letter-stamp { position: absolute; right: -10px; bottom: -12px; display: inline-flex; align-items: center; gap: 8px; padding: 8px 14px; border: 3px solid #10B981; border-radius: 10px; background: rgba(16, 185, 129, .1); font-size: 15px; font-weight: 900; letter-spacing: .5px; color: #10B981; opacity: 0; white-space: nowrap; }
#phone-apply .stage { overflow: visible; }
#phone-apply .k-apply-pill { opacity: 0; }

/* The lock screen (step 2): the phone's own clock on a night wallpaper with
   the welcome sky's sunrise rising into it, and a new listing's push as the
   system shows one with an image, the app's icon on the left and the photo
   on the right. The big clock stands in for the status bar's time. Over the
   app's status bar (40), under the finger (45) and the home indicator (50). */
.lock { position: absolute; inset: 0; z-index: 42; display: flex; flex-direction: column; background: radial-gradient(130% 55% at 50% 112%, rgba(255, 140, 120, .6), transparent 64%), linear-gradient(172deg, #2a2450 0%, #1b1f3e 46%, #0f1120 100%); color: #fff; will-change: transform, opacity; }
.lock k-status-bar .k-status-time { visibility: hidden; }
.lock-clock { margin-top: 30px; text-align: center; }
.lock-clock > span { display: block; font-size: 20px; font-weight: 600; opacity: .92; }
.lock-clock > b { display: block; font-size: 92px; font-weight: 700; line-height: 1.02; letter-spacing: -2.5px; }
.push { display: flex; align-items: center; gap: 11px; margin: 34px 12px 0; padding: 13px 13px 13px 14px; border-radius: 24px; background: rgba(246, 246, 248, .82); -webkit-backdrop-filter: blur(22px) saturate(1.6); backdrop-filter: blur(22px) saturate(1.6); box-shadow: 0 12px 30px rgba(0, 0, 0, .28); font-size: 14.5px; line-height: 1.28; color: #111; will-change: transform, opacity; }
.push-icon { flex: none; width: 38px; height: 38px; border-radius: 9px; }
.push-text { flex: 1; min-width: 0; }
.push-top { display: flex; align-items: baseline; gap: 8px; }
.push-top > b { flex: 1; min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; font-weight: 700; }
.push-top > small { flex: none; font-size: 12.5px; color: rgba(17, 17, 17, .5); }
.push-sub { display: block; font-weight: 600; }
.push-line { display: -webkit-box; overflow: hidden; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
.push-photo { flex: none; align-self: flex-end; width: 44px; height: 44px; border-radius: 9px; object-fit: cover; }
