/* StreetKit homepage. Same palette as the app (src/theme.ts) and the guest web (server/cloud/web/app.css).
   Contrast: --dim and --faint both clear WCAG AA (4.5:1) for small text on --bg, --surface and --raised; --edge is the
   outline of anything interactive (3:1); --border and --border-strong are decorative only. */
@font-face { font-family: "Instrument Sans"; font-style: normal; font-weight: 400 700; font-display: swap; src: url(/fonts/instrument-sans-latin.woff2) format("woff2"); unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }
@font-face { font-family: "Instrument Sans"; font-style: italic; font-weight: 400 700; font-display: swap; src: url(/fonts/instrument-sans-italic-latin.woff2) format("woff2"); unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; }

:root {
  --bg: #0B0B0C; --surface: #141416; --raised: #1C1C1F; --border: #26262A; --border-strong: #3A3A41; --edge: #6A6A72;
  --text: #F2F2F2; --dim: #8A8A90; --faint: #80808A; --green: #34D399; --amber: #F5C451; --red: #F06A6A;
  --radius: 10px; --radius-sm: 7px;
  --measure: 34rem; --gutter: 20px;
  --font: "Instrument Sans", -apple-system, BlinkMacSystemFont, "SF Pro Text", system-ui, sans-serif;
}
@media (min-width: 720px) { :root { --gutter: 32px; } }

* { box-sizing: border-box; }
html { background: var(--bg); color: var(--text); font: 17px/1.5 var(--font); -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }
body { margin: 0; min-height: 100vh; display: flex; flex-direction: column; }
img, svg { display: block; max-width: 100%; }
a { color: inherit; }
button, input { font: inherit; color: inherit; }
:focus-visible { outline: 2px solid var(--green); outline-offset: 2px; }
.sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.skip { position: absolute; left: var(--gutter); top: 0; transform: translateY(-120%); background: var(--text); color: var(--bg); padding: 8px 12px; border-radius: var(--radius-sm); z-index: 10; }
.skip:focus { transform: translateY(12px); }

.wrap { width: 100%; max-width: 1040px; margin: 0 auto; padding: 0 var(--gutter); }

/* header */
.top { position: sticky; top: 0; z-index: 5; background: rgba(11, 11, 12, 0.86); -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px); border-bottom: 1px solid transparent; }
.top.scrolled { border-bottom-color: var(--border); }
.top .wrap { display: flex; align-items: center; justify-content: space-between; height: 60px; gap: 16px; }
.brand { display: inline-flex; align-items: center; gap: 10px; text-decoration: none; }
.brand .mark { width: 28px; height: 28px; }
.brand .word { height: 17px; width: auto; }
.nav { display: flex; align-items: center; gap: 4px; }
.nav a { font-size: 14px; color: var(--dim); text-decoration: none; padding: 8px 10px; border-radius: var(--radius-sm); white-space: nowrap; }
.nav a:hover { color: var(--text); background: var(--surface); }
.nav a.cta { color: var(--text); border: 1px solid var(--edge); margin-left: 6px; }
@media (max-width: 599px) { .nav a:not(.cta) { display: none; } }

/* hero */
.hero { padding: 48px 0 0; }
@media (min-width: 880px) { .hero { padding-top: 72px; } }
.hero .wrap { display: grid; gap: 40px; }
@media (min-width: 880px) { .hero .wrap { grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); align-items: end; gap: 48px; } }
.eyebrow { font-size: 12px; font-weight: 600; letter-spacing: 0.14em; text-transform: uppercase; color: var(--dim); margin: 0 0 18px; display: flex; align-items: center; gap: 10px; white-space: nowrap; }
.eyebrow .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--green); box-shadow: 0 0 0 4px rgba(52, 211, 153, 0.14); }
h1 { font-size: clamp(34px, 6.4vw, 56px); line-height: 1.04; letter-spacing: -0.025em; font-weight: 600; margin: 0 0 20px; max-width: 14ch; text-wrap: balance; }
.lede { font-size: clamp(17px, 2.1vw, 20px); line-height: 1.5; color: var(--dim); margin: 0 0 28px; max-width: var(--measure); text-wrap: pretty; }
.lede strong { color: var(--text); font-weight: 500; }
@media (min-width: 880px) { .hero .wrap > div:first-child { padding-bottom: 48px; } }

/* coming soon */
.pill { white-space: nowrap; font-size: 11px; font-weight: 600; letter-spacing: 0.1em; text-transform: uppercase; color: var(--bg); background: var(--amber); padding: 3px 7px; border-radius: 4px; }
.nav .pill { align-self: center; margin-left: 6px; }

/* the waitlist form, in the hero and in the closing section */
.join { max-width: 460px; }
.join .soon { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 10px; font-size: 14px; color: var(--text); font-weight: 500; margin: 0 0 12px; }
.join form { display: flex; gap: 8px; }
.join input[type="email"] { flex: 1; min-width: 0; height: 48px; padding: 0 14px; background: #FFFFFF; color: #111; border: 1px solid #FFFFFF; border-radius: var(--radius-sm); }
.join input[type="email"]::placeholder { color: #6B6B72; }
.join input[type="email"]:focus { outline: 2px solid var(--green); outline-offset: 1px; }
.join button { height: 48px; padding: 0 18px; border-radius: var(--radius-sm); border: 1px solid var(--green); background: var(--green); color: var(--bg); font-weight: 600; cursor: pointer; white-space: nowrap; }
.join button:hover { filter: brightness(1.05); }
.join button:active { filter: brightness(0.92); }
.join button[disabled] { opacity: 0.6; cursor: default; }
.join .hp { position: absolute; left: -9999px; width: 1px; height: 1px; opacity: 0; }
.join .note { font-size: 13px; color: var(--faint); margin: 12px 0 0; line-height: 1.45; }
.join .note a { color: var(--dim); text-decoration: underline; text-decoration-color: var(--faint); text-underline-offset: 2px; }
.join .msg { font-size: 14px; margin: 10px 0 0; min-height: 1.4em; color: var(--green); }
.join .msg:empty { display: none; }
.join .msg.err { color: var(--red); }
.join .done { display: flex; align-items: flex-start; gap: 10px; padding: 14px 16px; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); }
.join .done .tick { display: inline-grid; place-items: center; width: 22px; height: 22px; border-radius: 50%; background: var(--green); color: var(--bg); flex: none; margin-top: 1px; }
.join .done p { margin: 0; font-size: 15px; line-height: 1.45; }
.join .done p span { color: var(--dim); display: block; font-size: 13px; margin-top: 2px; }
@media (max-width: 420px) { .join form { flex-direction: column; } .join input[type="email"] { flex: none; } }
.notify { background: var(--surface); }
.notify .join.wide { max-width: 560px; }
.notify .kicker { margin-bottom: 18px; }
.notify h2 { margin-bottom: 22px; }
.notify input[type="email"] { border-color: var(--border); }

/* phones */
.phone { position: relative; width: 100%; max-width: 300px; margin: 0 auto; aspect-ratio: 1206 / 2622; background: #000; border-radius: 44px; border: 1px solid var(--border-strong); box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.6), 0 30px 60px -20px rgba(0, 0, 0, 0.7); padding: 10px; }
.phone::before { content: ""; position: absolute; inset: 0; border-radius: inherit; box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.05); pointer-events: none; }
.phone img { width: 100%; height: 100%; object-fit: cover; object-position: top; border-radius: 34px; background: var(--bg); }
.phone.cut { aspect-ratio: 1206 / 1900; border-bottom: 0; border-radius: 44px 44px 0 0; padding-bottom: 0; }
.phone.cut img { border-radius: 34px 34px 0 0; }
.phone.cut::before { border-radius: 44px 44px 0 0; }

/* hero demo: the back of a Canon alone, a USB-C cable from its side port running out of the picture; your iPhone comes
   in on the other end, the camera fires (its rear screen shows the shot), a pulse runs the cable and the shot flies into
   the top left of the grid while the older shots move along; the camera stays where it is with the shot on its rear
   screen, the code comes up, and Tom's phone comes up in front of both the camera and your iPhone (the rear screen goes
   dark), scans the code and opens the photos. Stages come from site.js (cam, plug, snap, grid, tap, qr, scan, open);
   "still" is the no-JS and reduced-motion frame (the camera, the code, Tom's phone in front with the guest page).
   Positions are pixels per breakpoint; the flying shot starts over the camera's screen, --dx/--dy from the tile it
   lands in. The whole figure is self contained: /?demo shows it alone (html.demo-only) and window.StreetKitDemo drives
   it, for the App Store rendering later. */
.demo { margin: 0; }
.demo .scene { position: relative; height: 460px; max-width: 400px; margin: 0 auto; overflow: hidden; --dx: 253px; --dy: -100px; --ds: 1.27; }
.demo .scene::after { content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 1px; background: var(--border); }
.demo .canon { position: absolute; left: 0; top: 120px; width: 360px; aspect-ratio: 1024 / 560; z-index: 1; transform: translate(124px, -60px); transition: transform 0.7s cubic-bezier(0.2, 0.7, 0.2, 1); }
.demo .canon > img { width: 100%; height: 100%; -webkit-mask-image: linear-gradient(to bottom, transparent, #000 8%, #000 86%, transparent), linear-gradient(to right, transparent, #000 9%, #000 80%, transparent); -webkit-mask-composite: source-in; mask-image: linear-gradient(to bottom, transparent, #000 8%, #000 86%, transparent), linear-gradient(to right, transparent, #000 9%, #000 80%, transparent); mask-composite: intersect; }
.demo .lcd { position: absolute; left: 31.05%; top: 41.43%; width: 35.35%; height: 46.07%; border-radius: 3px; overflow: hidden; background: #000; }
.demo .lcd img { width: 100%; height: 100%; object-fit: cover; opacity: 0; transition: opacity 0.5s ease; }
/* the rear screen keeps the shot up until Tom's phone comes in front, then goes dark like a review screen timing out */
.demo[data-stage="grid"] .lcd img, .demo[data-stage="tap"] .lcd img, .demo[data-stage="qr"] .lcd img { opacity: 1; }
.demo .lcd .flash { position: absolute; inset: 0; background: #fff; opacity: 0; }
.demo .cable { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.demo .pulse { stroke-dasharray: 14 100; stroke-dashoffset: 14; opacity: 0; filter: drop-shadow(0 0 4px rgba(52, 211, 153, 0.8)); }
.demo .shot { position: absolute; left: 10px; top: 251.3px; width: 71.33px; height: 71.33px; z-index: 3; opacity: 0; object-fit: cover; box-shadow: 0 10px 24px rgba(0, 0, 0, 0.6); }
.demo .phone { position: absolute; bottom: -1px; margin: 0; max-width: none; aspect-ratio: auto; border-bottom: 0; border-radius: 44px 44px 0 0; padding-bottom: 0; transition: opacity 0.5s ease, transform 0.7s cubic-bezier(0.2, 0.7, 0.2, 1); }
.demo .phone::before { border-radius: 44px 44px 0 0; }
.demo .phone.a { left: 0; width: 236px; height: 300px; z-index: 2; }
.demo .phone.b { left: 204px; width: 168px; height: 292px; z-index: 4; border-radius: 30px 30px 0 0; padding: 7px 7px 0; box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.7), -18px 0 40px -6px rgba(0, 0, 0, 0.75), 0 -10px 50px -8px rgba(0, 0, 0, 0.8), 0 30px 60px -20px rgba(0, 0, 0, 0.7); transform-origin: 50% 100%; }
.demo .phone.b::before { border-radius: 30px 30px 0 0; }
.demo .who { position: absolute; left: 70px; top: -26px; font-size: 11px; font-weight: 600; letter-spacing: 0.1em; text-transform: uppercase; color: var(--faint); white-space: nowrap; text-shadow: 0 1px 2px rgba(0, 0, 0, 0.8), 0 0 12px rgba(0, 0, 0, 0.9); }
.demo .screen { position: relative; width: 100%; height: 100%; overflow: hidden; border-radius: 34px 34px 0 0; background: var(--bg); container-type: inline-size; }
.demo .phone.b .screen { border-radius: 23px 23px 0 0; }
.demo .phone.b .who { left: 14px; }
.demo .screen > img.code, .demo .screen > img.guest { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: top; border-radius: 0; transition: opacity 0.5s ease; }
.demo .code, .demo .guest, .demo .tap, .demo .line, .demo .chip { opacity: 0; }
/* the tap ring sits on the centre of the QR button in the group row (687.5, 230.5 of the 736 px capture) */
.demo .tap { position: absolute; left: 93.41cqw; top: 31.32cqw; width: 34px; height: 34px; margin: -17px 0 0 -17px; border-radius: 50%; border: 2px solid var(--green); box-shadow: 0 0 0 6px rgba(52, 211, 153, 0.25); }
.demo .cam { position: absolute; inset: 0; background: #0E0E10; display: grid; place-items: center; }
.demo .cam::after { content: ""; position: absolute; left: 50%; bottom: 16px; width: 30px; height: 30px; margin-left: -15px; border-radius: 50%; border: 2px solid #F2F2F2; box-shadow: inset 0 0 0 3px #0E0E10, inset 0 0 0 30px #F2F2F2; }
.demo .cam .qr { width: 66%; margin-top: -34px; border-radius: 6px; }
.demo .cam .frame { position: absolute; left: 50%; top: 50%; width: 82%; aspect-ratio: 1; transform: translate(-50%, -50%); margin-top: -17px; }
.demo .cam .line { position: absolute; left: 13%; right: 13%; top: 24%; height: 2px; background: var(--green); box-shadow: 0 0 10px var(--green); }
.demo .cam .chip { position: absolute; left: 50%; bottom: 64px; transform: translateX(-50%); display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; font-size: 10px; font-weight: 600; letter-spacing: 0.02em; color: var(--text); background: rgba(28, 28, 31, 0.96); border: 1px solid var(--border-strong); border-radius: 999px; padding: 6px 10px; box-shadow: 0 8px 20px rgba(0, 0, 0, 0.5); }
.demo .cam .chip .dot { width: 6px; height: 6px; border-radius: 50%; background: var(--green); }
.demo .phone.b { opacity: 0; transform: translateY(36px) scale(0.92); }
/* cam: the camera alone at the left, the phone waits off the left edge; from plug on the camera sits up and over to
   the right and stays there for the rest of the loop, its hump and viewfinder clear of the two phones, Tom's phone
   coming up in front of it */
.demo[data-stage="cam"] .phone.a { transform: translateX(-270px); opacity: 0; }
.demo[data-stage="cam"] .canon { transform: none; }
/* snap: the rear screen flashes and shows the shot, the pulse runs the cable, the shot flies into the first tile */
.demo[data-stage="snap"] .lcd .flash { animation: flash 0.5s ease-out both; }
.demo[data-stage="snap"] .lcd img { animation: show 0.3s ease-out 0.15s both; }
.demo[data-stage="snap"] .pulse { animation: pulse 0.5s linear 0.35s both; }
.demo[data-stage="snap"] .shot { animation: fly 0.8s cubic-bezier(0.2, 0.7, 0.2, 1) 0.75s both; }
.demo[data-stage="snap"] .tile.new { opacity: 0; }
.demo[data-stage="qr"] .code, .demo[data-stage="scan"] .code, .demo[data-stage="open"] .code, .demo[data-stage="still"] .code { opacity: 1; }
.demo[data-stage="scan"] .phone.b, .demo[data-stage="open"] .phone.b, .demo[data-stage="still"] .phone.b { opacity: 1; transform: none; }
.demo[data-stage="open"] .guest, .demo[data-stage="still"] .guest { opacity: 1; }
.demo[data-stage="tap"] .tap { animation: tap 0.9s ease-out both; }
.demo[data-stage="scan"] .line { animation: scan 1s ease-in-out 0.3s 2 alternate both; }
.demo[data-stage="scan"] .chip { animation: chip 0.35s ease-out 2.1s both; }
@keyframes flash { 0% { opacity: 0; } 15% { opacity: 1; } 100% { opacity: 0; } }
@keyframes show { to { opacity: 1; } }
@keyframes pulse { 0% { opacity: 1; stroke-dashoffset: 14; } 100% { opacity: 1; stroke-dashoffset: -100; } }
@keyframes fly { 0% { opacity: 0; transform: translate(var(--dx), var(--dy)) scale(var(--ds)); } 12% { opacity: 1; } 100% { opacity: 1; transform: none; } }
@keyframes tap { 0% { opacity: 0; transform: scale(0.4); } 35% { opacity: 1; transform: scale(1); } 100% { opacity: 0; transform: scale(1.7); } }
@keyframes scan { 0% { opacity: 1; top: 24%; } 100% { opacity: 1; top: 64%; } }
@keyframes chip { 0% { opacity: 0; transform: translate(-50%, 8px); } 100% { opacity: 1; transform: translate(-50%, 0); } }
.demo figcaption { font-size: 13px; color: var(--faint); text-align: center; margin: 14px auto 0; max-width: 400px; text-wrap: pretty; }
@media (prefers-reduced-motion: reduce) { .demo .phone, .demo .canon, .demo .screen img, .demo .tap, .demo .line, .demo .chip, .demo .flash, .demo .pulse, .demo .lcd img, .demo .shot { transition: none; animation: none; } }
@media (max-width: 879px) {
  .demo .scene { height: 420px; --dx: 244px; --dy: -110px; --ds: 1.26; }
  .demo .canon { width: 330px; top: 110px; transform: translate(126px, -60px); }
  .demo .shot { left: 10px; top: 243.3px; width: 66px; height: 66px; }
  .demo .phone.a { width: 220px; height: 262px; }
  .demo .phone.b { left: 188px; width: 160px; height: 272px; }
}
/* the figure alone, for capturing the loop standalone (the App Store preview is rendered from the same markup) */
.demo-only body > :not(main), .demo-only main > :not(.hero), .demo-only .hero .wrap > div:first-child, .demo-only .demo figcaption { display: none; }
.demo-only .hero, .demo-only .hero .wrap { padding: 0; display: block; max-width: none; }
.demo-only .demo .scene { margin: 0; }
.demo.cut, .demo.cut * { transition: none !important; }

/* live grids: the app's group screen rebuilt from the real tiles so new shots can arrive. The chrome is the top of the
   capture (status bar, toolbar, the group row), the tiles are the Maya and Tom portraits, newest first. site.js moves
   the last tile to the front and slides the rest along; the new one gets a short green edge. */
.tiles { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1px; background: var(--bg); }
.tiles.mini { grid-template-columns: repeat(5, 1fr); }
.tile { position: relative; display: block; aspect-ratio: 1; overflow: hidden; background: var(--raised); }
.tile img, .phone .tile img { width: 100%; height: 100%; object-fit: cover; object-position: center; border-radius: 0; }
.tile.new::after { content: ""; position: absolute; inset: 0; box-shadow: inset 0 0 0 2px var(--green); opacity: 0; }
.on .tile.new::after { animation: landed 1.6s ease-out both; }
@keyframes landed { 0% { opacity: 0; } 15% { opacity: 1; } 100% { opacity: 0; } }
.phone .screen > img.chrome { width: 100%; height: auto; border-radius: 0; }
.phone.live .screen { position: relative; width: 100%; height: 100%; overflow: hidden; border-radius: 34px 34px 0 0; background: var(--bg); }

/* sections */
section { padding: 72px 0; border-top: 1px solid var(--border); }
@media (min-width: 880px) { section { padding: 96px 0; } }
.hero + section { border-top: 0; }
h2 { font-size: clamp(26px, 4vw, 36px); line-height: 1.1; letter-spacing: -0.02em; font-weight: 600; margin: 0 0 12px; text-wrap: balance; }
.sub { color: var(--dim); font-size: 17px; margin: 0 0 40px; max-width: var(--measure); text-wrap: pretty; }
.kicker { font-size: 12px; font-weight: 600; letter-spacing: 0.14em; text-transform: uppercase; color: var(--faint); margin: 0 0 14px; }
h3 { font-size: 19px; font-weight: 600; letter-spacing: -0.01em; margin: 0 0 6px; }
p { margin: 0 0 12px; }
.body { color: var(--dim); font-size: 16px; line-height: 1.55; text-wrap: pretty; }
.body strong { color: var(--text); font-weight: 500; }
.icon { width: 22px; height: 22px; flex: none; fill: none; stroke: var(--text); stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
.icon.mark { stroke: none; }
h3 .icon, strong .icon { display: inline-block; vertical-align: -5px; margin-right: 10px; }

/* how it works: five cards of one size, the visual in the same slot at the bottom of each */
.steps { display: grid; gap: 16px; counter-reset: step; list-style: none; padding: 0; margin: 0; }
.step { position: relative; display: flex; flex-direction: column; min-height: 100%; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; }
.step .text { padding: 20px 20px 16px 62px; }
.step::before { counter-increment: step; content: counter(step); position: absolute; left: 20px; top: 20px; width: 28px; height: 28px; display: grid; place-items: center; border-radius: var(--radius-sm); border: 1px solid var(--edge); color: var(--text); font-size: 13px; font-weight: 600; font-variant-numeric: tabular-nums; }
.step h3 { margin-top: 2px; }
.step .body { margin: 0; }
.step .vis { position: relative; height: 230px; margin-top: auto; overflow: hidden; background: linear-gradient(to bottom, var(--surface), #0F0F11); border-top: 1px solid var(--border); }
.step .vis .phone { position: absolute; left: 50%; bottom: -1px; transform: translateX(-50%); width: 200px; height: 206px; margin: 0; max-width: none; aspect-ratio: auto; }
.step .vis .phone.mid { top: 0; bottom: 0; height: auto; width: 200px; border-radius: 0; border-top: 0; border-bottom: 0; padding: 0 8px; }
.step .vis .phone.mid::before { border-radius: 0; }
.step .vis .phone.mid img { border-radius: 0; }
/* step 1: the rig photo (the back of the Canon, the iPhone on the hot shoe), a live grid on the mounted phone's screen
   (measured in the 900 by 830 crop: 250,37 to 800,309) and a pulse down the cable every few seconds, timed so the tile
   arrives as the pulse reaches the phone. The grid is advanced from site.js on the same clock. */
.step .vis .rig { position: absolute; left: 50%; top: 50%; width: 216px; aspect-ratio: 900 / 830; transform: translate(-50%, -50%); }
.step .vis .rig > img { width: 100%; height: 100%; -webkit-mask-image: linear-gradient(to bottom, transparent, #000 6%, #000 94%, transparent), linear-gradient(to right, transparent, #000 4%, #000 96%, transparent); -webkit-mask-composite: source-in; mask-image: linear-gradient(to bottom, transparent, #000 6%, #000 94%, transparent), linear-gradient(to right, transparent, #000 4%, #000 96%, transparent); mask-composite: intersect; }
.rig .mscreen { position: absolute; left: 27.78%; top: 4.46%; width: 61.11%; height: 32.77%; border-radius: 4px; overflow: hidden; background: var(--bg); }
.rig .mscreen .tiles { gap: 1px; }
.rig .cable { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.rig .pulse { stroke-dasharray: 10 100; stroke-dashoffset: 10; opacity: 0; filter: drop-shadow(0 0 4px rgba(52, 211, 153, 0.8)); }
.rig.on .pulse { animation: wire 3s linear infinite; }
@keyframes wire { 0% { opacity: 0; stroke-dashoffset: 10; } 3% { opacity: 1; } 30% { opacity: 1; stroke-dashoffset: -100; } 33% { opacity: 0; stroke-dashoffset: -100; } 100% { opacity: 0; stroke-dashoffset: -100; } }
/* step 2: the live grid in a phone, a new shot every few seconds */
.step .vis .phone.live .tiles { grid-template-columns: repeat(3, 1fr); }
/* step 4: a tap lands on the download button, the zip fills, a Saved chip comes up; four second loop */
.phone.dl { container-type: inline-size; }
.phone.dl { --pad: 8px; }
.phone.dl .ring { position: absolute; left: calc(var(--pad) + 87.8cqw); top: 11.9cqw; width: 30px; height: 30px; margin: -15px 0 0 -15px; border-radius: 50%; border: 2px solid var(--green); box-shadow: 0 0 0 6px rgba(52, 211, 153, 0.25); opacity: 0; }
.phone.dl .bar { position: absolute; left: calc(var(--pad) + 5cqw); top: 17.6cqw; width: 90cqw; height: 3px; border-radius: 2px; background: var(--green); box-shadow: 0 0 8px rgba(52, 211, 153, 0.6); transform: scaleX(0); transform-origin: left; opacity: 0; }
.phone.dl .saved { position: absolute; left: 50%; bottom: 18px; transform: translateX(-50%); display: inline-flex; align-items: center; gap: 6px; white-space: nowrap; font-size: 11px; font-weight: 600; color: var(--bg); background: var(--green); border-radius: 999px; padding: 6px 11px; box-shadow: 0 8px 20px rgba(0, 0, 0, 0.5); opacity: 0; }
.phone.dl .saved svg { width: 12px; height: 12px; }
.phone.dl.on .ring { animation: dltap 4s ease-out infinite; }
.phone.dl.on .bar { animation: dlbar 4s linear infinite; }
.phone.dl.on .saved { animation: dlsaved 4s ease-out infinite; }
@keyframes dltap { 0%, 12% { opacity: 0; transform: scale(0.4); } 20% { opacity: 1; transform: scale(1); } 34% { opacity: 0; transform: scale(1.7); } 100% { opacity: 0; transform: scale(1.7); } }
@keyframes dlbar { 0%, 24% { opacity: 0; transform: scaleX(0); } 26% { opacity: 1; transform: scaleX(0); } 58% { opacity: 1; transform: scaleX(1); } 66% { opacity: 0; transform: scaleX(1); } 100% { opacity: 0; transform: scaleX(1); } }
@keyframes dlsaved { 0%, 58% { opacity: 0; transform: translate(-50%, 8px); } 64% { opacity: 1; transform: translate(-50%, 0); } 90% { opacity: 1; transform: translate(-50%, 0); } 97%, 100% { opacity: 0; transform: translate(-50%, 0); } }
@media (prefers-reduced-motion: reduce) { .rig .pulse, .tile.new::after, .phone.dl .ring, .phone.dl .bar, .phone.dl .saved { animation: none !important; } .phone.dl .saved { opacity: 1; } }
@media (min-width: 600px) { .steps { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1000px) {
  .steps { grid-template-columns: repeat(5, 1fr); gap: 12px; }
  .step .text { padding: 56px 16px 16px 16px; }
  .step::before { left: 16px; top: 16px; }
  .step h3 { font-size: 17px; }
  .step .body { font-size: 14px; }
  .step .vis { height: 210px; }
  .step .vis .phone { width: 150px; height: 186px; }
  .step .vis .rig { width: 176px; }
  .step .vis .phone.mid { width: 164px; padding: 0 7px; --pad: 7px; }
}

/* benefits: four cards with an icon each */
.grid4 { display: grid; gap: 12px; }
@media (min-width: 480px) { .grid4 { grid-template-columns: 1fr 1fr; } }
@media (min-width: 880px) { .grid4 { grid-template-columns: repeat(4, 1fr); gap: 16px; } }
.card { padding: 22px 20px; border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); }
.card h3 { margin-top: 0; font-size: 17px; display: flex; align-items: center; gap: 10px; }
.card h3 .icon, .why h3 .icon { margin: 0; vertical-align: baseline; }
.card .body { margin: 0; font-size: 15px; }

/* why: two audiences, each with one of the shots beside it and a note over the shot, the icon beside the heading */
.why { display: grid; gap: 16px; }
@media (min-width: 880px) { .why { grid-template-columns: 1fr 1fr; gap: 16px; } }
.why .col { position: relative; display: grid; grid-template-columns: 150px 1fr; gap: 18px; align-items: center; padding: 16px; background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); }
.why .pic { display: block; width: 100%; aspect-ratio: 1; border-radius: var(--radius-sm); background: var(--raised); overflow: hidden; }
.why .pic img { width: 100%; height: 100%; object-fit: cover; }
.why .tag { position: absolute; left: 24px; bottom: 24px; max-width: 134px; display: inline-flex; align-items: center; gap: 6px; font-size: 10px; font-weight: 600; line-height: 1.25; color: var(--text); background: rgba(20, 20, 22, 0.94); border: 1px solid var(--border-strong); border-radius: 8px; padding: 5px 8px; }
.why .tag .dot { width: 6px; height: 6px; flex: none; border-radius: 50%; background: var(--green); }
.why .col h3 { font-size: 19px; margin-bottom: 8px; display: flex; align-items: center; gap: 10px; }
.why .col .body { font-size: 16px; margin: 0; }
@media (max-width: 479px) { .why .col { grid-template-columns: 1fr; gap: 14px; } .why .pic { aspect-ratio: 3 / 2; } .why .tag { left: 24px; bottom: auto; top: 24px; max-width: none; } }

/* needs */
.needs { display: grid; gap: 12px; padding: 0; margin: 0; list-style: none; }
@media (min-width: 720px) { .needs { grid-template-columns: repeat(3, 1fr); } }
.needs li { padding: 20px; border: 1px solid var(--border); border-radius: var(--radius); background: var(--surface); font-size: 15px; color: var(--dim); line-height: 1.5; }
.needs li { position: relative; }
.needs li strong { color: var(--text); display: flex; align-items: center; gap: 10px; font-weight: 600; margin-bottom: 6px; }
.needs li strong .icon { margin: 0; }
@media (min-width: 720px) { .needs li:first-child::after { content: ""; position: absolute; right: -13px; top: 50%; width: 14px; height: 2px; background: var(--edge); border-radius: 1px; } }

/* footer */
footer { margin-top: auto; border-top: 1px solid var(--border); padding: 28px 0 calc(28px + env(safe-area-inset-bottom)); font-size: 13px; color: var(--faint); }
footer .wrap { display: flex; flex-wrap: wrap; gap: 10px 18px; align-items: center; justify-content: space-between; }
footer nav { display: flex; flex-wrap: wrap; gap: 4px 18px; }
footer a { color: var(--dim); text-decoration: none; }
footer a:hover { color: var(--text); text-decoration: underline; text-underline-offset: 2px; }
footer .made { display: inline-flex; align-items: center; gap: 8px; }
footer .made svg { width: 16px; height: 16px; opacity: 0.7; }
footer .made .heart { font-size: 12px; }

/* legal documents: same look as the guest web's terms and privacy */
.doc { max-width: 680px; padding-top: 32px; padding-bottom: 64px; }
.doc .docnav { margin: 0 0 18px; }
.doc .back { font-size: 13px; color: var(--text); padding: 6px 10px; border: 1px solid var(--edge); border-radius: var(--radius-sm); background: var(--raised); text-decoration: none; }
.doc h1 { font-size: 30px; max-width: none; margin-bottom: 4px; }
.doc .muted { color: var(--dim); font-size: 15px; }
.doc h2 { font-size: 19px; letter-spacing: 0; margin: 30px 0 8px; }
.doc h3 { font-size: 16px; margin: 16px 0 4px; }
.doc p, .doc li { color: var(--dim); font-size: 16px; line-height: 1.55; margin: 0 0 10px; }
.doc ul { padding-left: 20px; margin: 0 0 10px; }
.doc li { margin-bottom: 4px; }
.doc p a, .doc li a { color: var(--text); text-decoration: underline; text-decoration-color: var(--faint); text-underline-offset: 2px; }
.doc .summary { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 14px 16px 8px; margin: 16px 0 8px; }
.doc .summary h2 { margin: 0 0 8px; font-size: 15px; }
.doc .summary li { color: var(--text); font-size: 15px; }
.doc .small { font-size: 13px; }
.doc .faint { color: var(--faint); }
.doc address { font-style: normal; color: var(--dim); font-size: 16px; line-height: 1.55; margin-bottom: 10px; }
.doc .new { border-left: 2px solid var(--green); padding-left: 14px; }

/* 404 */
.oops { padding: 96px 0; text-align: center; }
.oops h1 { max-width: none; margin: 16px auto 8px; }
.oops p { color: var(--dim); }
.oops .mark { width: 56px; height: 56px; margin: 0 auto; }
