/* Home sections. Each one has its own light (the screen's glow, the time of day) and its own faint texture.
   Desktop first, then a phone layout per section. */

/* Section textures. The canvas already carries speaker-grille dots, so each section gets a line pattern that suits it
   (no second dot field, which would beat against the first). Default: brushed aluminium, for the notch story. Masked so it fades out. */
.grille { position: absolute; inset: 0; pointer-events: none; z-index: 0;
  background: repeating-linear-gradient(180deg, rgba(255, 255, 255, .035) 0 1px, transparent 1px 4px);
  -webkit-mask-image: var(--grille-mask); mask-image: var(--grille-mask); }

/* Shared header: headline left, its one line on the right, on a shared baseline. */
.split-head { display: grid; grid-template-columns: minmax(0, 1.15fr) minmax(0, .85fr); align-items: end; gap: 24px 64px; margin-bottom: clamp(40px, 5vw, 72px); }
.split-head .lead { margin: 0; padding-bottom: .4em; max-width: 440px; }

/* Hero: the page is the Mac. Full-bleed wallpaper, the nav as its menu bar, the notch fixed at the top of the window. */
/* Not its own stacking layer: a dragged file has to rise above the fixed notch and menu bar */
.hero { position: relative; min-height: max(680px, 100svh); display: grid; align-items: end; padding: 120px 0 clamp(40px, 7vh, 80px); overflow: clip; color: #fff; }
.hero-wall { position: absolute; inset: 0; z-index: 0;
  background: linear-gradient(180deg, rgba(6, 4, 20, .25) 0, rgba(6, 4, 20, 0) 26%, rgba(6, 4, 20, .28) 56%, color-mix(in srgb, var(--canvas) 92%, transparent) 88%, var(--canvas) 100%), url(../img/wall-lg.webp) center 28% / cover;
  animation: wall-in 1800ms var(--ease-expo) both; }
@keyframes wall-in { from { scale: 1.08; filter: brightness(.55) saturate(.8); } }
/* Centred, like the last frame of a product film: the line, one sentence, the action */
.hero-copy { position: relative; z-index: 1; display: flex; flex-direction: column; align-items: center; text-align: center; }
.hero-title { text-align: center; }
.hero-title .hl { display: inline-block; animation: hero-in var(--m-hero) var(--ease) both; animation-delay: calc(300ms + var(--d, 0) * 120ms); }
.hero-side { display: flex; flex-direction: column; align-items: center; margin-top: 22px; animation: hero-in var(--m-hero) 560ms var(--ease) both; }
.hero-lead { max-width: 600px; font-size: clamp(19px, 1.6vw, 22px); line-height: 1.45; color: rgba(255, 255, 255, .82); text-wrap: balance; }
.hero .cta { flex-direction: column; margin-top: 30px; }
.hero .link { color: rgba(255, 255, 255, .82); font-size: 14px; }
.hero .link:hover { color: #fff; }
.hero-meta { display: flex; align-items: center; justify-content: center; flex-wrap: wrap; gap: 4px 18px; margin-top: 22px; }
.hero-meta .fine { color: rgba(255, 255, 255, .62); }
.hero .chip-t { background: none; border: 0; padding: 0 4px; gap: 8px; color: rgba(255, 255, 255, .62); min-height: 40px; font-size: 14px; }
.hero .chip-t:hover { color: #fff; }
.hero .chip-t .sw { transform: scale(.8); }
@keyframes hero-in { from { opacity: 0; transform: translateY(28px); filter: blur(8px); } to { opacity: 1; transform: none; filter: none; } }

/* Files on the desktop, the way Finder shows them: an icon and a label you can read on any wallpaper */
.hero-files { position: absolute; right: clamp(24px, 7vw, 120px); top: 26%; display: grid; gap: 26px; z-index: 2; }
.hero-files:has(.lift) { z-index: 60; } /* above the notch (55) and the menu bar (50) while dragging */
.dfile { display: flex; flex-direction: column; align-items: center; gap: 8px; width: 104px; padding: 10px 6px; border-radius: 12px; color: #fff; cursor: grab; touch-action: none;
  transition: background var(--m-base), opacity 300ms, scale 300ms var(--ease-expo); animation: hero-in 900ms var(--ease) both; animation-delay: 900ms; }
.dfile + .dfile { animation-delay: 1000ms; }
.dfile:hover { background: rgba(255, 255, 255, .12); }
.dfile .thumb { width: 64px; height: 48px; }
.dfile .doc-t { width: 44px; height: 54px; }
.dl { font-size: 12.5px; font-weight: 500; padding: 2px 8px; border-radius: 5px; background: rgba(0, 0, 0, .3); }
.dfile.lift { cursor: grabbing; z-index: 60; scale: 1.06; background: none; will-change: translate; transition: scale 300ms var(--ease-expo); }
.dfile.lift .dl { background: var(--notch-blue); }
/* animation: none, or the entrance animation keeps holding opacity at 1 and the shrunk file stays on the desktop */
.dfile.taken { animation: none; opacity: 0; scale: .4; pointer-events: none; }
.dfile:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }

/* The hero's notch: fixed at the top of the window, real size, above the menu bar */
.hero-notch { position: fixed; left: 0; right: 0; top: 0; height: 0; z-index: 55; --cx: 756; transition: opacity 320ms var(--ease-out), translate 420ms var(--ease-expo); }
.hero-notch.gone { opacity: 0; translate: 0 -48px; }
.hero-notch.gone .isl { pointer-events: none; }
.hero-notch:focus-visible { outline: none; }
.hero-notch:focus-visible .isl { outline: 2px solid var(--focus); outline-offset: 3px; }
.hero-callout { position: fixed; left: 50%; top: 46px; z-index: 55; translate: -50% 0; display: inline-flex; align-items: center; gap: 6px; padding: 7px 14px 7px 10px; border-radius: 999px;
  font: 500 13px/1 var(--mono); color: #fff; background: rgba(0, 0, 0, .5); border: 1px solid rgba(255, 255, 255, .18); backdrop-filter: blur(14px); -webkit-backdrop-filter: blur(14px);
  opacity: 0; pointer-events: none; transition: opacity 400ms var(--ease-out); }
.hero-callout .ic { width: 15px; height: 15px; animation: bob 1.6s var(--ease-inout) infinite; }
.hero-callout.in { opacity: 1; }
.hero-callout.gone, .hero-callout.off, .hero-callout.hush { opacity: 0; }
@keyframes bob { 50% { translate: 0 -3px; } }

/* Try the notch: one small glass card that only says what to do now. A dot per step; it leaves once every step is done. */
.tryit { position: relative; order: 1; justify-self: center; z-index: 2; display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: 10px;
  width: 300px; margin-top: 28px; padding: 14px 12px 12px 16px; border-radius: 20px; color: #fff;
  background: rgba(16, 14, 30, .42); border: 1px solid rgba(255, 255, 255, .16); backdrop-filter: blur(22px) saturate(1.3); -webkit-backdrop-filter: blur(22px) saturate(1.3);
  animation: hero-in 900ms var(--ease) 1100ms both; }
/* minmax(0, 1fr): no single long line may widen the column past the screen.
   align-content: the widget's row, when it has one, packs under the copy instead of splitting the free space. */
.hero { grid-template-columns: minmax(0, 1fr); align-content: end; }
.hero-copy { width: 100%; } /* .wrap's auto margins would otherwise size it to its content */
@media (max-width: 1279.98px) {
  /* The copy keeps the first screen to itself, as it did before the widget, so nothing rises into the desktop files.
     The card follows under it. */
  .hero-copy { min-height: calc(100svh - 120px - clamp(40px, 7vh, 80px)); justify-content: flex-end; }
  .tryit { margin-top: 0; }
}
@media (min-width: 1280px) {
  /* Bottom left, beside the lead: the headline above is too wide to share a row with */
  .tryit { position: absolute; left: clamp(24px, 3vw, 64px); bottom: clamp(40px, 7vh, 80px); margin: 0; }
}
.ti-head { grid-column: 1 / -1; display: flex; justify-content: space-between; align-items: center; padding-right: 4px; }
.ti-head b { font-size: 13px; font-weight: 600; letter-spacing: -.005em; color: rgba(255, 255, 255, .7); }
.ti-dots { display: flex; gap: 6px; }
.ti-dots i { width: 6px; height: 6px; border-radius: 50%; background: rgba(255, 255, 255, .38); transition: background var(--m-slow) var(--ease-out); }
.ti-dots i.on { background: #fff; animation: ti-pop 420ms var(--ease-out); }
@keyframes ti-pop { 40% { scale: 1.6; } }
.ti-steps li { display: none; align-items: center; gap: 10px; min-width: 0; font-size: 15px; font-weight: 600; letter-spacing: -.01em; }
.ti-steps li.next { display: flex; animation: ti-in 420ms var(--ease-expo) both; }
@keyframes ti-in { from { opacity: 0; translate: 0 8px; } }
.ti-t { min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.ti-show { position: relative; flex: none; margin-left: auto; padding: 6px 11px; border-radius: 999px; white-space: nowrap; font-size: 12.5px; font-weight: 500; color: #fff;
  border: 1px solid rgba(255, 255, 255, .3); transition: background var(--m-base), border-color var(--m-base); }
.ti-show::after { content: ""; position: absolute; inset: -9px -4px; } /* a 44px target */
.ti-show:hover { background: rgba(255, 255, 255, .14); border-color: rgba(255, 255, 255, .5); }
/* Play it for me: a round glass button (the white pill stays the page's one filled action) that turns into Stop while it plays */
.ti-play { position: relative; display: grid; place-items: center; width: 40px; height: 40px; border-radius: 50%; color: #fff; background: rgba(255, 255, 255, .14);
  border: 1px solid rgba(255, 255, 255, .18); transition: transform var(--press) var(--spring), background var(--m-base); }
.ti-play::after { content: ""; position: absolute; inset: -3px; border-radius: inherit; } /* 44px target */
.ti-play:hover { background: rgba(255, 255, 255, .22); }
.ti-play:active { transform: scale(.92); }
.ti-play .ic { width: 15px; height: 15px; fill: currentColor; stroke: none; }
.ti-play .go { translate: 1px 0; }
.ti-play .stop, .ti-play.on .go { display: none; }
.ti-play.on .stop { display: block; }
html:not(.js) .tryit { display: none; }

/* Show me: a ring breathes out of what to touch next, the way the beacon does on the idle notch */
/* Targets are already positioned (the files, the notch's round and pill buttons), so the ring needs no position of its own */
.hero-files.nudge::before { inset: -10px; border-radius: 20px; }
.nudge::before { content: ""; position: absolute; inset: -6px; border-radius: inherit; border: 2px solid #fff; pointer-events: none; animation: ring-out 1.3s var(--ease-out) 3 both; }
@keyframes ring-out { from { opacity: .9; scale: .94; } to { opacity: 0; scale: 1.14; } } /* not "nudge": the swipe thumb's keyframes own that name */

/* Promises: a scroll journey in four chapters on the Notch Stage (js/journey.js). The pin holds while the section scrolls;
   each chapter is a few beats and the island moves between them on the app's springs.
   Without JS the stage is hidden and the four lines stack; reduced motion (.still) gets one still frame per chapter. */
.pledge { position: relative; padding: 120px 0; }
.jr-pin { display: grid; justify-items: center; align-content: center; gap: clamp(18px, 3.2vh, 36px); }
.js .pledge:not(.still) { height: 500svh; padding: 0; }
.js .pledge:not(.still) .jr-pin { position: sticky; top: 0; height: 100svh; padding: 64px 0 24px; overflow: hidden; grid-template-rows: auto minmax(0, 1fr) auto; }
.pledge.still .jr-pin { display: none; }
.jr-still { display: grid; gap: 120px; }
.jr-frame { display: grid; justify-items: center; gap: 32px; }

.jr-copy { display: grid; text-align: center; }
.jr-line + .jr-line { margin-top: 32px; }
.jr-h { font-weight: 600; font-size: clamp(28px, 3.4vw, 48px); line-height: 1.08; letter-spacing: -0.035em; text-wrap: balance; max-width: 24ch; margin: 0 auto; color: var(--ink); }
.jr-c { margin-top: 14px; font-size: clamp(17px, 1.4vw, 20px); line-height: 1.4; color: var(--ink-muted); text-wrap: balance; }
.js .pledge:not(.still) .jr-line { grid-area: 1 / 1; margin: 0; opacity: 0; translate: 0 20px; filter: blur(8px);
  transition: opacity 500ms var(--ease-out), translate 700ms var(--ease-expo), filter 500ms var(--ease-out); }
/* The headline comes in word by word, the caption a beat later */
.jr-w { display: inline-block; }
.js .pledge:not(.still) .jr-w { opacity: 0; translate: 0 .5em; filter: blur(10px);
  transition: opacity 500ms var(--ease-out), translate 900ms var(--ease-expo), filter 600ms var(--ease-out); transition-delay: calc(var(--j) * 45ms); }
.js .pledge:not(.still) .jr-c { opacity: 0; transition: opacity 600ms var(--ease-out); }
.js .pledge:not(.still) .jr-line.on, .js .pledge:not(.still) .jr-line.on .jr-w { opacity: 1; translate: none; filter: none; }
.js .pledge:not(.still) .jr-line.on .jr-c { opacity: 1; transition-delay: 320ms; }

/* The stage: the top of the Mac's screen, as large as the pin allows */
/* clip, not hidden: focusing a provider button must not scroll the wider screen inside sideways */
.jy-stage { --cw: 1100; --ch: 640; --cx: 756; align-self: center; width: min(100% - 48px, 1180px, (100svh - 380px) * 1100 / 640); overflow: clip; }
.jr-frame .jy-stage { width: min(100% - 32px, 1000px); }
html:not(.js) .jy-stage, html:not(.js) .jr-rail { display: none; }

/* Scene props, in screen points: the Settings window the key goes into, the field the words go into */
.jy-win { left: 476px; top: 150px; width: 560px; }
.jy-field { left: 496px; top: 300px; width: 520px; }
.jy-win, .jy-field { transition: opacity 400ms var(--ease-out), translate 700ms var(--ease-expo); }
.screen .jy-off { opacity: 0; translate: 0 14px; pointer-events: none; }
.jy-win .bar { position: relative; }
.jy-win .bar b { position: absolute; inset: 0; display: grid; place-items: center; font-size: 13px; font-weight: 600; color: var(--notch-text-2); }
.jy-set { display: grid; gap: 14px; padding: 22px 24px 24px; }
.jy-set .row { gap: 14px; }
.jy-key { flex: 1; display: flex; align-items: center; height: 34px; padding: 0 12px; overflow: hidden; white-space: nowrap; border-radius: 8px;
  background: #141519; border: 1px solid rgba(10, 132, 255, .9); font-size: 14px; letter-spacing: .1em; color: var(--notch-text); transition: border-color 300ms var(--ease-out); }
.jy-win.saved .jy-key { border-color: #2a2b31; }
.jy-win.saved .jy-key .caret, .jy-field:not(.focus) .caret { display: none; }
.jy-ok { gap: 8px; opacity: 0; transition: opacity 300ms var(--ease-out); }
.jy-win.saved .jy-ok { opacity: 1; }
/* The assistant: pick a provider, the reply streams in, the host it went to sits under it */
.jy-ai { display: flex; flex-direction: column; gap: 12px; }
.jy-pp { display: flex; gap: 6px; }
.jy-q { display: flex; gap: 8px; font-size: 13px; }
.jy-ai .ans { margin: 0; }
.jy-ai .ans-p { min-height: 40px; }
.jy-route { margin-top: auto; gap: 8px; }
.jy-route .ic { font-size: 14px; }
.jy-route span:first-of-type { font: 500 12px/1 var(--mono); color: var(--notch-text); }
.jy-tag { margin-left: auto; font-weight: 600; color: var(--notch-green); }
/* The lock in the left wing: the shackle drops shut on the reward spring */
.jy-lock { font-size: 18px; }
.jy-lock rect { fill: currentColor; }
.jy-lock .kh { stroke: #000; stroke-width: 2.2; }
.jy-lock .sh { translate: 0 -3.5px; transition: translate var(--sp-reward-d) var(--sp-reward); }
.jy-lock.shut .sh { translate: none; }
@media (prefers-reduced-motion: reduce) { .jy-lock .sh, .jy-win, .jy-field { transition: none; } }

/* Chapter 4, the seal (js/journey.js). Sizes are in screen points, which the stage draws at about half size, hence the large type. Glass cards for the key, the dictated words and the reply wait on the desktop; scrolling pulls them
   into the notch (journey.js sets each card's translate, scale and opacity). Each .jy-chip is a point; its card centres on it. */
.jy-chips { position: absolute; inset: 0; pointer-events: none; transition: opacity 400ms var(--ease-out), translate 700ms var(--ease-expo); }
.jy-chip { position: absolute; width: 0; height: 0; }
.jy-cc { position: absolute; left: 0; top: 0; translate: -50% -50%; display: flex; align-items: center; gap: 16px; width: max-content; max-width: 430px; padding: 16px 24px 16px 16px;
  border-radius: 22px; color: var(--notch-text); background: rgba(14, 14, 22, .58); border: 1px solid rgba(255, 255, 255, .14);
  backdrop-filter: blur(16px) saturate(1.3); -webkit-backdrop-filter: blur(16px) saturate(1.3); }
.jy-ci { display: grid; place-items: center; flex: none; width: 46px; height: 46px; border-radius: 14px; background: rgba(255, 255, 255, .12); font-size: 23px; }
.jy-ct { min-width: 0; display: grid; gap: 3px; }
.jy-ct b { font-size: 18px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.jy-ct small { font-size: 15px; color: var(--notch-text-2); }
/* The seal itself: a big lock in the peek that turns green as it shuts, then breathes */
.jy-pk { gap: 10px; }
.jy-pk .jy-lock { font-size: 26px; color: var(--notch-text); transition: color 400ms var(--ease-out) 120ms; }
.jy-pk .jy-lock.shut { color: var(--notch-green); }
.jy-sealed .jy-pk .jy-lock.shut { animation: jy-breathe 2.8s var(--ease-inout) 1.4s infinite; }
@keyframes jy-breathe { 50% { filter: drop-shadow(0 0 8px rgba(48, 209, 88, .75)); } }
/* Rings that ripple out from the notch across the whole screen */
.jy-rip { position: absolute; left: 586px; top: -15px; width: 340px; height: 110px; border-radius: 50%; border: 2px solid rgba(255, 255, 255, .6); pointer-events: none;
  animation: jy-rip 1.9s var(--ease-out) 200ms both; }
.jy-rip + .jy-rip { border-color: rgba(48, 209, 88, .7); animation-delay: 520ms; }
@keyframes jy-rip { from { opacity: .9; scale: .5; } to { opacity: 0; scale: 7.5; } }
/* Light runs once around the inside of the screen's edge, then a soft green edge stays: the Mac is sealed */
@property --jy-a { syntax: "<angle>"; inherits: false; initial-value: 0deg; }
.jy-edge, .jy-glow { position: absolute; inset: var(--bz, 10px); z-index: 19; border-radius: calc(var(--r-xl) - var(--bz, 10px)); pointer-events: none; opacity: 0; }
.jy-edge { padding: 2px; background: conic-gradient(from var(--jy-a), transparent 0 68%, rgba(48, 209, 88, .9) 88%, #fff 96%, transparent 100%);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); -webkit-mask-composite: xor; mask-composite: exclude; }
.jy-glow { box-shadow: inset 0 0 0 1.5px rgba(48, 209, 88, .5), inset 0 0 36px rgba(48, 209, 88, .12); transition: opacity 600ms var(--ease-out); }
.jy-sealed .jy-edge { animation: jy-run 1.7s var(--ease-inout) 350ms both; }
.jy-sealed .jy-glow { opacity: 1; transition: opacity 1200ms var(--ease-out) 1.6s; }
@keyframes jy-run { 0% { opacity: 0; --jy-a: 0deg; } 12%, 80% { opacity: 1; } 100% { opacity: 0; --jy-a: 360deg; } }
.jy-stage .wall { transition: filter 1400ms var(--ease-out); }
.jy-stage.jy-sealed .wall { filter: brightness(.7) saturate(1.08); }
/* Reduced motion: the sealed frame, still */
@media (prefers-reduced-motion: reduce) {
  .jy-rip, .jy-edge { display: none; }
  .jy-sealed .jy-pk .jy-lock.shut { animation: none; }
  .jy-glow, .jy-sealed .jy-glow, .jy-stage .wall, .jy-pk .jy-lock, .jy-chips { transition: none; }
}
@media (max-width: 734px) { .jy-cc { max-width: 250px; padding: 12px 16px 12px 12px; } .jy-ci { width: 38px; height: 38px; font-size: 19px; } }

/* Story: one Tuesday in five moments. The pin holds 100svh while the track scrolls past; each moment holds for 110svh. */
.story { position: relative; padding-top: var(--section); background: rgba(10, 10, 14, .55); }
.story-head { position: relative; z-index: 1; }
.story-track { position: relative; height: calc(5 * 110svh + 100svh); }
/* Snap points sit a little inside each moment (never on a boundary), and cancel the page's scroll-padding. */
.snap { position: absolute; left: 0; width: 1px; height: 1px; scroll-snap-align: start; scroll-margin-top: -72px; pointer-events: none; }
.snap:nth-child(1) { top: 16svh; } .snap:nth-child(2) { top: 126svh; } .snap:nth-child(3) { top: 236svh; } .snap:nth-child(4) { top: 346svh; } .snap:nth-child(5) { top: 456svh; }
.story-pin { position: sticky; top: 0; height: 100svh; display: grid; align-items: center; overflow: hidden; }
/* Time of day: the light behind the stage moves from morning blue to evening rose as the day goes on */
.story-light { --h: calc(222 + var(--p, 0) * 108); position: absolute; inset: -10%; pointer-events: none;
  background: radial-gradient(42% 46% at 66% 48%, hsl(var(--h) 84% 62% / .26), transparent 70%),
    radial-gradient(34% 40% at 18% 82%, hsl(calc(var(--h) + 36) 80% 60% / .1), transparent 70%); }
.story-grid { position: relative; display: grid; grid-template-columns: minmax(0, 4fr) minmax(0, 8fr); gap: clamp(32px, 4vw, 64px); align-items: center; width: 100%; }
.story-side { display: flex; flex-direction: column; gap: 28px; }
.story-rail { display: flex; flex-wrap: wrap; gap: 4px; }
.story-rail button { position: relative; min-height: 34px; padding: 0 12px; border-radius: 999px; font-size: 13px; color: var(--ink-muted); transition: color var(--m-base), background var(--m-base); }
.story-rail button::after { content: ""; position: absolute; inset: -5px -1px; }
.story-rail button:hover { color: var(--ink); }
.story-rail button[aria-current="true"] { color: #000; background: var(--ink); }
.story-caps { position: relative; min-height: 380px; }
.cap { position: absolute; left: 0; right: 0; top: 50%; translate: 0 calc(-50% + 28px); display: flex; flex-direction: column; gap: 16px;
  opacity: 0; filter: blur(8px); pointer-events: none;
  transition: opacity 420ms var(--ease-out), translate 900ms var(--ease-expo), filter 420ms var(--ease-out); }
.cap.on { opacity: 1; translate: 0 -50%; filter: none; pointer-events: auto; transition-delay: 120ms; }
.cap.past { translate: 0 calc(-50% - 28px); }
.cap-when { font-size: 15px; color: var(--ink-muted); }
.cap-h { font-weight: 600; font-size: clamp(34px, 3.8vw, 52px); line-height: 1.04; letter-spacing: -0.035em; text-wrap: balance; }
.cap-p { font-size: 18px; line-height: 1.5; color: var(--ink-muted); max-width: 420px; }
.cap .pills { margin-top: 4px; }
.story-stage { --cw: 1240; --ch: 760; --cx: 756; }

/* Explorer */
.ex-sec { position: relative; isolation: isolate; }
/* Features: graph paper, a catalogue laid out in rows */
.ex-sec .grille { --grille-mask: radial-gradient(60% 50% at 50% 55%, #000 10%, transparent 80%);
  background: linear-gradient(90deg, rgba(255, 255, 255, .05) 1px, transparent 1px) 0 0 / 32px 32px, linear-gradient(rgba(255, 255, 255, .05) 1px, transparent 1px) 0 0 / 32px 32px; }
.story-pin .grille { --grille-mask: radial-gradient(50% 60% at 30% 50%, #000, transparent 75%); }
/* Privacy: the hatching inside a security envelope */
.privacy .grille { --grille-mask: linear-gradient(180deg, #000, transparent 60%);
  background: repeating-linear-gradient(45deg, rgba(255, 255, 255, .04) 0 1px, transparent 1px 9px); }
/* Find: search ripples rising from where the field sits */
.find-sec .grille { --grille-mask: radial-gradient(60% 70% at 50% 100%, #000, transparent 75%);
  background: repeating-radial-gradient(circle at 50% 100%, rgba(255, 255, 255, .05) 0 1px, transparent 1px 30px); }
.privacy > .split-head, .privacy > .priv, .find-sec > .wrap { position: relative; z-index: 1; }
.ex { position: relative; z-index: 1; }
.ex-tabs-wrap { position: relative; display: flex; justify-content: flex-start; }
.ex-tabs { display: flex; flex-wrap: wrap; gap: 8px; }
.ex-tab { flex: none; min-height: 40px; padding: 0 18px; border-radius: 999px; font-size: 14px; color: var(--ink-muted); white-space: nowrap; scroll-snap-align: center;
  background: var(--tile-2); border: 1px solid var(--line); transition: color var(--m-base), background var(--m-base), border-color var(--m-base), transform var(--press) var(--ease); }
.ex-tab:hover { color: var(--ink); border-color: var(--line-strong); }
.ex-tab:active { transform: scale(.96); }
.ex-tab[aria-selected="true"] { background: var(--ink); color: #000; border-color: var(--ink); }
.ex-tab:focus-visible { outline-offset: 2px; border-radius: 999px; }
.ex-body { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: 24px; margin-top: 28px; align-items: start; }
.ex-stage-col { position: sticky; top: 88px; }
.ex-stage { --cw: 860; --ch: 640; --cx: 756; }
.ex-head { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; flex-wrap: wrap; margin-bottom: 18px; }
.ex-tag { color: var(--ink-muted); }
.ex-cards { grid-template-columns: 1fr 1fr; }
.ex-all { margin-top: 12px; }
.js .ex-panel { animation: panel-in 300ms var(--ease-quint) both; }
@keyframes panel-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
.js .ex-panel .card { animation: rise 320ms var(--ease-quint) both; }
.js .ex-panel .card:nth-child(2) { animation-delay: 25ms; } .js .ex-panel .card:nth-child(3) { animation-delay: 50ms; }
.js .ex-panel .card:nth-child(4) { animation-delay: 75ms; } .js .ex-panel .card:nth-child(5) { animation-delay: 100ms; } .js .ex-panel .card:nth-child(6) { animation-delay: 125ms; }

/* Privacy: a lamp over the section, the Mac's own Privacy & Security list on the stage */
.privacy { position: relative; background: rgba(10, 10, 14, .55); isolation: isolate; overflow: clip; }
.privacy::before { content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background: radial-gradient(56% 46% at 50% 0, rgba(140, 116, 255, .16), transparent 72%); }
.priv { display: grid; gap: 20px; }
.priv-stage { --cw: 1400; --ch: 640; --cx: 756; }
.priv-picks { display: flex; flex-wrap: wrap; justify-content: center; gap: 10px; }
.pick { display: inline-flex; align-items: center; gap: 10px; min-height: 48px; padding: 0 10px 0 16px; border-radius: 999px; font-size: 15px;
  background: var(--tile-2); border: 1px solid var(--line); transition: border-color var(--m-base), background var(--m-base), transform var(--press) var(--ease); }
.pick:hover { border-color: var(--line-strong); }
.pick:active { transform: scale(.97); }
.pick .ic { width: 18px; height: 18px; color: var(--ink-muted); }
.pick[aria-pressed="true"] { border-color: var(--line-strong); background: var(--tile-3); }
.pick[aria-pressed="true"] .ic { color: var(--ink); }
.pick .sw { transform: scale(.82); }

/* The Privacy & Security window. Sizes are in screen points once it sits on the stage. */
.sys-win { width: 660px; max-width: 100%; margin: 0 auto; border-radius: 14px; overflow: hidden; color: #f5f5f7; font: 400 13px/1.35 -apple-system, BlinkMacSystemFont, system-ui, sans-serif; letter-spacing: 0;
  background: rgba(32, 32, 36, .94); border: 1px solid rgba(255, 255, 255, .1); box-shadow: 0 30px 70px -20px rgba(0, 0, 0, .7); }
.stage .sys-win { position: absolute; left: 50%; top: 120px; translate: -50% 0; max-width: none; }
.sys-bar { position: relative; display: flex; align-items: center; gap: 8px; height: 44px; padding: 0 16px; border-bottom: 1px solid rgba(255, 255, 255, .07); }
.sys-bar i { width: 12px; height: 12px; border-radius: 50%; background: #ff5f57; } .sys-bar i:nth-child(2) { background: #febc2e; } .sys-bar i:nth-child(3) { background: #28c840; }
.sys-bar b { position: absolute; left: 0; right: 0; text-align: center; font-weight: 600; font-size: 13px; pointer-events: none; }
.sys-head { display: flex; justify-content: space-between; padding: 16px 20px 8px; font-weight: 600; font-size: 12px; color: #a1a1a6; }
.perm-list { padding: 0 12px 12px; }
.perm { display: grid; grid-template-columns: 30px 1fr auto; align-items: center; gap: 14px; padding: 10px 8px; border-top: 1px solid rgba(255, 255, 255, .06);
  transition: opacity 300ms var(--ease-out), translate 420ms var(--ease-expo), display 300ms allow-discrete; }
.perm:first-child { border-top: 0; }
.perm[hidden] { display: none !important; }
@starting-style { .perm { opacity: 0; translate: 0 -8px; } }
/* Graphite tiles: the green switch is the row's only colour */
.perm-ic { width: 30px; height: 30px; padding: 6px; border-radius: 8px; color: var(--ink); background: var(--tile-3); box-shadow: inset 0 0 0 1px var(--line-strong); }
.perm-t b { display: block; font-weight: 600; font-size: 13px; }
.perm-t small { display: block; font-size: 12px; color: #a1a1a6; }
.sysw { position: relative; width: 32px; height: 18px; border-radius: 9px; background: rgba(255, 255, 255, .16); animation: sysw-on 420ms 280ms var(--ease-out) forwards; }
.sysw::after { content: ""; position: absolute; left: 2px; top: 2px; width: 14px; height: 14px; border-radius: 50%; background: #fff; box-shadow: 0 1px 2px rgba(0, 0, 0, .3); animation: sysw-knob 420ms 280ms var(--sp-expand) forwards; }
@keyframes sysw-on { to { background: #30d158; } }
@keyframes sysw-knob { to { translate: 14px 0; } }
.perm-none { padding: 20px; text-align: center; font-size: 13px; color: #a1a1a6; }

/* Find a feature */
.find-sec { position: relative; isolation: isolate; overflow: clip; }
.find-sec::before { content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background: radial-gradient(60% 70% at 50% 120%, rgba(124, 92, 255, .2), transparent 70%); }
.find { position: relative; max-width: 640px; margin: 40px auto 0; }
.find-list { max-width: 640px; margin: 12px auto 0; text-align: left; }
.find-list li a { display: flex; align-items: center; gap: 14px; min-height: 60px; padding: 10px 16px; border-radius: 14px; transition: background var(--m-base); animation: rise 300ms var(--ease-quint) both; }
.find-list li:nth-child(2) a { animation-delay: 30ms; } .find-list li:nth-child(3) a { animation-delay: 60ms; } .find-list li:nth-child(4) a { animation-delay: 90ms; } .find-list li:nth-child(5) a { animation-delay: 120ms; }
.find-list li a:hover, .find-list li a:focus-visible { background: var(--tile-2); }
.find-list .ic { width: 22px; height: 22px; color: var(--ink); }
.find-list b { font-weight: 600; display: block; }
.find-list small { display: block; font-size: 14px; color: var(--ink-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.find-list .fl-t { min-width: 0; }
.find-list .empty { padding: 16px; color: var(--ink-muted); text-align: center; }
.find-all { margin-top: 16px; }

/* Get Macadoodle: the lit room. The stage on the left narrates, the card on the right sells. */
.get-sec { position: relative; isolation: isolate; overflow: clip; }
.get-sec::before { content: ""; position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background: radial-gradient(46% 60% at 32% 52%, rgba(150, 110, 255, .22), transparent 72%), radial-gradient(30% 40% at 70% 30%, rgba(255, 150, 190, .14), transparent 70%); }
.get-grid { display: grid; grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); gap: clamp(32px, 5vw, 72px); align-items: center; }
.get-stage { --cw: 1000; --ch: 640; --cx: 756; }
.get-hint { margin-top: 14px; text-align: center; font: 500 13px/1 var(--mono); color: var(--ink-light-muted); transition: opacity 300ms; }
.get-h { font-weight: 600; font-size: clamp(40px, 4.4vw, 60px); line-height: 1.04; letter-spacing: -0.035em; text-wrap: balance; }
.get-price { display: flex; align-items: baseline; gap: 12px; margin-top: 20px; }
.get-price .num { font-weight: 600; font-size: 56px; letter-spacing: -0.03em; line-height: 1; }
.get-once { font-size: 15px; color: var(--ink-light-muted); }
.get-list { margin-top: 24px; }
.get-list li { display: flex; align-items: center; gap: 12px; padding: 12px 0; border-top: 1px solid rgba(0, 0, 0, .08); font-size: 17px; }
.get-list li::before { content: ""; width: 18px; height: 18px; flex: none; border-radius: 50%; background: var(--ink-light);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 1a11 11 0 1 0 0 22 11 11 0 0 0 0-22zm-1.4 15.6L6 12l1.4-1.4 3.2 3.2 6-6L18 9.2z'/%3E%3C/svg%3E") center / contain no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 1a11 11 0 1 0 0 22 11 11 0 0 0 0-22zm-1.4 15.6L6 12l1.4-1.4 3.2 3.2 6-6L18 9.2z'/%3E%3C/svg%3E") center / contain no-repeat; }
.get-fine { margin-top: 16px; text-align: center; font-size: 13px; color: var(--ink-light-muted); }
.get-fine .ul { color: var(--link-light); }

/* Pre-register popup: a dark sheet over the light section, like the directory drawer. No shadow, no gradient. */
.pre { width: min(420px, calc(100% - 32px)); margin: auto; padding: 28px; border: 1px solid var(--line-strong); border-radius: var(--r-lg); color: var(--ink); background: var(--tile-1); }
.pre[open] { animation: pre-in var(--m-medium) var(--ease-out); }
@keyframes pre-in { from { opacity: 0; translate: 0 12px; } }
.pre::backdrop { background: rgba(0, 0, 0, .6); }
.pre-h { font-size: 26px; font-weight: 600; letter-spacing: -.01em; }
.pre-s { margin: 6px 0 20px; color: var(--ink-muted); }
.pre-f { display: block; margin-bottom: 14px; font-size: 13px; color: var(--ink-muted); }
.pre-f small { color: var(--ink-faint); }
.pre-f input { display: block; width: 100%; height: 48px; margin-top: 6px; padding: 0 14px; border-radius: var(--r-md); border: 1px solid var(--line); background: var(--tile-2); color: var(--ink); font: 400 16px/1 var(--sans); }
.pre-f input:focus, .cc-btn:focus-visible { outline: 0; border-color: var(--focus); box-shadow: 0 0 0 4px rgba(0, 113, 227, .3); }
.pre-ph { display: grid; grid-template-columns: 11.5rem 1fr; gap: 8px; }
/* Country picker: a button that opens a searchable panel above it. Slim dark scrollbar, no native white list. */
.cc { position: relative; }
.pre-f input[type="hidden"] { display: none; }
.cc-btn { display: flex; align-items: center; justify-content: space-between; gap: 6px; width: 100%; height: 48px; margin-top: 6px; padding: 0 12px; border-radius: var(--r-md); border: 1px solid var(--line); background: var(--tile-2); color: var(--ink); font: 400 15px/1 var(--sans); text-align: left; }
.cc-btn span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cc-btn svg { flex: none; width: 14px; height: 14px; fill: none; stroke: var(--ink-muted); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; transition: rotate var(--m-base) var(--ease); }
.cc-btn[aria-expanded="true"] svg { rotate: 180deg; }
.cc-panel { position: absolute; left: 0; bottom: calc(100% + 8px); z-index: 5; width: min(320px, calc(100vw - 80px)); padding: 8px; border-radius: 16px; border: 1px solid var(--line-strong); background: #17181b; animation: pre-in var(--m-base) var(--ease-out); }
.cc-panel[hidden] { display: none; }
.pre-f .cc-q { height: 40px; margin: 0 0 6px; padding: 0 12px; border-radius: 10px; background: rgba(255, 255, 255, .05); font-size: 15px; }
.cc-list { max-height: 216px; margin: 0; padding: 0; list-style: none; overflow-y: auto; overscroll-behavior: contain; scrollbar-width: thin; scrollbar-color: rgba(255, 255, 255, .16) transparent; }
.cc-list::-webkit-scrollbar { width: 6px; }
.cc-list::-webkit-scrollbar-track { background: transparent; }
.cc-list::-webkit-scrollbar-thumb { border-radius: 3px; background: rgba(255, 255, 255, .16); }
.cc-list li { display: flex; align-items: baseline; gap: 10px; padding: 10px 12px; border-radius: 10px; font-size: 15px; color: var(--ink); cursor: pointer; }
.cc-list li.on { background: rgba(255, 255, 255, .07); }
.cc-list li[aria-selected="true"] { background: rgba(91, 63, 217, .28); }
.cc-list .cc-d, .cc-btn .cc-d { font: 500 13px/1 var(--mono); color: var(--ink-muted); }
.cc-list .cc-none { color: var(--ink-faint); cursor: default; }
.pre-hp { position: absolute; left: -9999px; width: 1px; height: 1px; opacity: 0; }
.pre-err { margin-bottom: 12px; font-size: 14px; color: #ff6b6b; }
.pre-act { display: flex; flex-direction: column; align-items: stretch; gap: 6px; }
.pre-go { min-height: 50px; border-radius: 999px; background: #5b3fd9; color: #fff; font-size: 17px; font-weight: 600; letter-spacing: -.01em; transition: transform var(--press) var(--ease), background .2s var(--ease), opacity .2s; }
.pre-go:hover { background: #7c5cff; }
.pre-go:active { transform: scale(.98); }
.pre-go:disabled { opacity: .5; pointer-events: none; }
.pre-x { min-height: 44px; font-size: 15px; font-weight: 500; color: #ff6b6b; }
.pre-x:hover { color: #ff8a8a; }
/* FAQ: plain disclosure rows, no cards. */
.faq-list { max-width: 880px; margin-inline: auto; border-top: 1px solid var(--line); }
.faq-i { border-bottom: 1px solid var(--line); }
.faq-i summary { display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 22px 0; font-size: clamp(18px, 2vw, 22px); font-weight: 600; letter-spacing: -.01em; cursor: pointer; list-style: none; }
.faq-i summary::-webkit-details-marker { display: none; }
.faq-i summary::after { content: ""; flex: none; width: 9px; height: 9px; margin-right: 4px; border: solid var(--ink-muted); border-width: 0 2px 2px 0; rotate: 45deg; transition: rotate var(--m-base) var(--ease); }
.faq-i[open] summary::after { rotate: -135deg; }
.faq-i summary:focus-visible { outline: 2px solid var(--focus); outline-offset: 4px; border-radius: 6px; }
.faq-i p { max-width: 680px; padding: 0 0 24px; font-size: 17px; color: var(--ink-muted); }
.pre-fine { margin-top: 16px; font-size: 12px; color: var(--ink-faint); }
/* Success view: a purple disc pops in with two ripples, the check draws, the text rises, confetti covers the screen,
   then the popup closes by itself (4.6s) while the bar runs down. */
.pre-done { padding: 28px 0 4px; text-align: center; cursor: pointer; }
.pre-badge { position: relative; width: 84px; height: 84px; margin: 0 auto 24px; }
.pre-ring { position: absolute; inset: 0; border-radius: 50%; border: 2px solid #7c5cff; opacity: 0; animation: pre-ripple 1.6s var(--ease-out) .25s 2; }
.pre-ring.r2 { animation-delay: .6s; }
@keyframes pre-ripple { from { opacity: .7; scale: 1; } to { opacity: 0; scale: 2.3; } }
.pre-ok { position: relative; display: block; width: 84px; height: 84px; fill: none; stroke: #fff; stroke-width: 3.4; stroke-linecap: round; stroke-linejoin: round; animation: pre-pop .7s var(--spring) both; }
.pre-ok circle { fill: #5b3fd9; stroke: none; }
.pre-ok path { stroke-dasharray: 40; stroke-dashoffset: 40; animation: pre-draw .45s var(--ease-out) .4s forwards; }
@keyframes pre-pop { from { scale: .4; opacity: 0; } }
@keyframes pre-draw { to { stroke-dashoffset: 0; } }
.pre-done .pre-h, .pre-done .pre-s { animation: pre-rise .6s var(--ease-out) .45s both; }
.pre-done .pre-h { font-size: 28px; }
.pre-done .pre-s { margin: 8px 0 0; animation-delay: .6s; overflow-wrap: anywhere; }
@keyframes pre-rise { from { opacity: 0; translate: 0 14px; } }
.pre-bar { display: block; height: 3px; margin-top: 32px; border-radius: 2px; background: #5b3fd9; transform-origin: left; animation: pre-run 4.6s linear forwards; }
@keyframes pre-run { to { transform: scaleX(0); } }
/* Confetti: one canvas for the whole screen, in the top layer so it floats above the popup. */
#confetti { position: fixed; inset: 0; width: 100vw; height: 100vh; margin: 0; padding: 0; border: 0; background: none; overflow: visible; pointer-events: none; }

/* Slide to buy, the Macify slider: a light runs round the rim, the thumb breathes and nudges, the label shines,
   the goal waits at the end. Drag it there, or press Enter. Sparks trail the thumb and burst on success. */
@property --a { syntax: "<angle>"; inherits: false; initial-value: 0deg; }
.get-card { position: relative; }
.sparks { position: absolute; left: -60px; top: -60px; width: calc(100% + 120px); height: calc(100% + 120px); pointer-events: none; z-index: 3; }
.swipe { --x: 0px; --p: 0; --lean: 0px; --thumb: 56px; position: relative; height: 64px; margin-top: 28px; border-radius: 999px; overflow: hidden; isolation: isolate;
  background: radial-gradient(120% 140% at 0% 50%, #2a2a2e, #111113 60%); color: #fff; box-shadow: inset 0 1px 2px rgba(0, 0, 0, .6), 0 14px 30px -16px rgba(0, 0, 0, .6);
  user-select: none; -webkit-user-select: none; touch-action: pan-y; cursor: grab; transition: background .5s var(--ease), box-shadow .5s var(--ease), transform .2s var(--ease); }
.swipe::before { content: ""; position: absolute; inset: 0; border-radius: inherit; padding: 1.5px; z-index: 2; pointer-events: none;
  background: conic-gradient(from var(--a), transparent 0 62%, rgba(255, 255, 255, .85) 75%, transparent 88%);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0); -webkit-mask-composite: xor; mask-composite: exclude; animation: rim 4.5s linear infinite; }
@keyframes rim { to { --a: 360deg; } }
.swipe:hover { transform: translateY(-1px); }
.swipe.dragging { cursor: grabbing; transform: none; }
.swipe.armed { box-shadow: inset 0 1px 2px rgba(0, 0, 0, .6), 0 0 0 4px rgba(0, 102, 204, .18), 0 18px 40px -16px rgba(0, 102, 204, .55); }
.swipe-fill { position: absolute; left: 0; top: 0; bottom: 0; width: calc(var(--x) + var(--thumb) + 8px); border-radius: inherit;
  background: linear-gradient(90deg, rgba(255, 255, 255, .02), rgba(255, 255, 255, calc(.08 + var(--p) * .26))); box-shadow: 14px 0 34px -8px rgba(255, 255, 255, calc(var(--p) * .5)); }
.swipe-label { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; gap: 10px; padding-left: var(--thumb); font-size: 17px; letter-spacing: -0.01em; pointer-events: none;
  opacity: calc(1 - var(--p) * 3); /* gone by a third of the way, so it never overlaps .swipe-mid */
  -webkit-mask-image: linear-gradient(90deg, transparent calc(var(--x) + 70px), #000 calc(var(--x) + 150px)); mask-image: linear-gradient(90deg, transparent calc(var(--x) + 70px), #000 calc(var(--x) + 150px)); }
.shine { background: linear-gradient(90deg, rgba(255, 255, 255, .4) 0%, rgba(255, 255, 255, .4) 38%, #fff 50%, rgba(255, 255, 255, .4) 62%, rgba(255, 255, 255, .4) 100%);
  background-size: 250% 100%; -webkit-background-clip: text; background-clip: text; color: transparent; animation: shine 2.6s linear infinite; }
@keyframes shine { from { background-position: 125% 0; } to { background-position: -125% 0; } }
.chev { display: inline-flex; font: 18px/1 var(--mono); }
.chev i { font-style: normal; opacity: .2; animation: chev 1.6s ease-in-out infinite; }
.chev i:nth-child(2) { animation-delay: .15s; } .chev i:nth-child(3) { animation-delay: .3s; }
@keyframes chev { 30% { opacity: 1; translate: 3px 0; } 60% { opacity: .2; translate: 0 0; } }
/* Centered text that comes up while you slide: keep sliding, then let go. */
.swipe-mid { position: absolute; inset: 0; z-index: 1; display: grid; place-items: center; font-size: 16px; font-weight: 500; letter-spacing: -.01em; color: #fff; pointer-events: none;
  opacity: clamp(0, calc(var(--p) * 3.5 - 1), 1); }
.swipe-mid > * { grid-area: 1 / 1; transition: opacity .2s var(--ease); }
.swipe-mid .m-b, .swipe.armed .swipe-mid .m-a { opacity: 0; }
.swipe.armed .swipe-mid .m-b { opacity: 1; }
.swipe.done .swipe-mid { opacity: 0; }
.swipe-thumb { position: absolute; z-index: 3; left: 4px; top: 4px; width: var(--thumb); height: var(--thumb); border-radius: 999px; overflow: hidden;
  background: linear-gradient(180deg, #fff, #e9e9ee); color: var(--ink-light); display: flex; align-items: center; justify-content: center;
  box-shadow: 0 4px 12px rgba(0, 0, 0, .45), 0 0 calc(var(--p) * 40px) rgba(255, 255, 255, calc(var(--p) * .7)), inset 0 -2px 0 rgba(0, 0, 0, .08);
  transform: translateX(calc(var(--x) + var(--lean))) scale(var(--ts, 1)); }
.swipe:not(.dragging) .swipe-thumb, .swipe:not(.dragging) .swipe-fill { transition: transform .7s var(--spring), width .7s var(--spring), box-shadow .4s var(--ease); }
.swipe.dragging .swipe-thumb { --ts: 1.06; transition: transform .08s linear; }
.swipe-thumb::after { content: ""; position: absolute; inset: 0; border-radius: inherit; box-shadow: 0 0 0 0 rgba(255, 255, 255, .5); animation: halo 2.4s ease-out infinite; pointer-events: none; }
.swipe.dragging .swipe-thumb::after, .swipe.done .swipe-thumb::after { animation: none; }
@keyframes halo { 0% { box-shadow: 0 0 0 0 rgba(255, 255, 255, .45); } 70%, 100% { box-shadow: 0 0 0 14px rgba(255, 255, 255, 0); } }
.swipe-arrow { position: absolute; width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; transform: translateX(calc(var(--p) * 4px)); transition: opacity .3s var(--ease), transform .4s var(--spring); }
.swipe:not(.dragging):not(.done):not(:hover) .swipe-thumb { animation: nudge 3.4s var(--ease) 1.4s infinite; }
@keyframes nudge { 0%, 70%, 100% { translate: 0; } 78% { translate: 12px; } 86% { translate: 0; } 92% { translate: 5px; } }
.swipe-ok { display: flex; align-items: center; gap: 10px; white-space: nowrap; font-size: 16px; font-weight: 500; opacity: 0; transform: scale(.85); transition: opacity .3s var(--ease), transform .5s var(--spring); }
.swipe-check { width: 22px; height: 22px; fill: none; stroke: #fff; stroke-width: 2.6; stroke-linecap: round; stroke-linejoin: round; background: var(--ink-light); border-radius: 50%; padding: 3px; }
.swipe-check path { stroke-dasharray: 24; stroke-dashoffset: 24; transition: stroke-dashoffset .5s var(--ease) .35s; }
.swipe-spin { width: 14px; height: 14px; border: 2px solid rgba(0, 0, 0, .15); border-top-color: var(--ink-light); border-radius: 50%; animation: spin .8s linear infinite; }
@keyframes spin { to { rotate: 360deg; } }
.swipe.done { cursor: default; background: #000; }
.swipe.done .swipe-thumb { width: calc(100% - 8px); transform: translateX(0); transition: width .75s var(--spring), transform .75s var(--spring), box-shadow .5s; box-shadow: 0 0 40px rgba(255, 255, 255, .35); }
.swipe.done .swipe-arrow { opacity: 0; transform: translateX(16px) scale(.5); }
.swipe.done .swipe-ok { opacity: 1; transform: none; transition-delay: .6s; } /* after the thumb has grown, so the text is centered and never clipped */
.swipe.done .swipe-check path { stroke-dashoffset: 0; }
.swipe.done .swipe-label { opacity: 0; }
.swipe:focus-visible { outline: 2px solid var(--link-light); outline-offset: 4px; }
.get-card.celebrate { animation: celebrate 600ms var(--spring); }
@keyframes celebrate { 40% { transform: scale(1.015); } }
.get-card.is-paid .get-list, .get-card.is-paid .swipe, .get-card.is-paid .get-price { display: none; }

.paid { margin-top: 28px; padding: 28px 24px 22px; border-radius: 16px; background: #fff; border: 1px solid rgba(0, 0, 0, .08); animation: paid-in 700ms var(--ease) both; }
@keyframes paid-in { from { opacity: 0; transform: translateY(20px) scale(.98); } to { opacity: 1; transform: none; } }
.paid-k { font-size: 14px; font-weight: 600; color: #248a3d; }
.paid.failed .paid-k { color: #d70015; } .paid.processing .paid-k { color: #b25000; }
.paid-title { margin-top: 8px; font-size: 28px; font-weight: 600; letter-spacing: -0.03em; line-height: 1.1; }
.paid-body { margin-top: 8px; color: var(--ink-light-muted); }
.paid-actions { margin-top: 20px; }
.steps-mini { display: grid; gap: 10px; margin-top: 22px; padding-top: 18px; border-top: 1px solid rgba(0, 0, 0, .08); font-size: 14px; color: var(--ink-light-muted); counter-reset: s; }
.steps-mini li { counter-increment: s; display: flex; align-items: center; gap: 12px; }
.steps-mini li::before { content: counter(s); display: grid; place-items: center; flex: none; width: 24px; height: 24px; border-radius: 50%; font: 500 12px/1 var(--mono); background: var(--parchment); color: var(--ink-light); }
.steps-mini b { color: var(--ink-light); font-weight: 600; }

/* 404: a resting notch with a greeting */
.nf { min-height: 80svh; display: grid; align-items: center; }
.nf-notch { position: absolute; left: 50%; top: 0; translate: -50% 0; height: 32px; width: 190px; border-radius: 0 0 12px 12px; background: #000; color: var(--ink-muted);
  display: grid; place-items: center; font-size: 12px; overflow: hidden; border: 1px solid var(--line); border-top: 0; }
.nf-notch span { opacity: 0; animation: vin 400ms 900ms var(--ease-out) forwards; }

/* Tablet */
@media (max-width: 1068px) {
  .story-grid { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); }
  .story-stage { --cw: 980; --ch: 760; }
  .ex-body { grid-template-columns: minmax(0, 1fr); }
  .ex-stage-col { position: static; }
  .ex-stage { --cw: 1100; --ch: 480; }
  .get-grid { grid-template-columns: minmax(0, 1fr); }
  .get-card { max-width: 560px; }
}

/* Phone: each section gets its own layout */
@media (max-width: 734px) {
  .split-head { grid-template-columns: minmax(0, 1fr); gap: 16px; }
  .split-head .lead { padding: 0; }

  /* The hero is exactly one screen on any phone, files tucked under the notch they are dragged to */
  .hero { min-height: max(560px, 100svh); padding-top: 180px; align-items: end; } /* 180: the headline clears the files (78 to 164) however tall the hero grows */
  .hero .cta { gap: 4px 20px; }
  .hero .chip-t { min-height: 44px; }
  .hero-files { top: 78px; right: max(12px, env(safe-area-inset-right)); gap: 6px; grid-auto-flow: column; }
  .dfile { width: 84px; padding: 6px 4px; }
  .dfile .thumb { width: 52px; height: 40px; } .dfile .doc-t { width: 36px; height: 44px; }
  .hero-callout { top: 34px; }
  /* Phones: the hero is one screen again. The guide docks to the bottom of the screen, in thumb reach, while the hero shows:
     one row of the dots, the step, Show me and play. The hero keeps room for it at the bottom. */
  .hero { padding-bottom: calc(92px + env(safe-area-inset-bottom)); }
  .hero-copy { min-height: 0; }
  .hero-lead { font-size: 17px; max-width: 34ch; }
  .hero-meta { flex-direction: column; gap: 0; }
  .tryit { position: fixed; left: max(12px, env(safe-area-inset-left)); right: max(12px, env(safe-area-inset-right)); bottom: max(12px, env(safe-area-inset-bottom));
    z-index: 54; width: auto; max-width: 480px; margin: 0 auto; justify-self: stretch; /* stretch between the insets; center would shrink it to fit */ grid-template-columns: auto minmax(0, 1fr) auto; gap: 12px; padding: 8px 8px 8px 16px; border-radius: 24px;
    animation-fill-mode: backwards; transition: opacity 300ms var(--ease-out), translate 420ms var(--ease-expo), visibility 0s; }
  /* visibility too: under reduced motion the entrance fill holds opacity at 1 */
  .tryit.away { opacity: 0; translate: 0 24px; visibility: hidden; pointer-events: none; transition: opacity 300ms var(--ease-out), translate 420ms var(--ease-expo), visibility 0s 300ms; }
  .ti-head { grid-column: auto; }
  .ti-head b { display: none; } /* the step says what to do; the card keeps its name for screen readers */
  .ti-dots { gap: 5px; }
  .ti-show { padding: 10px 14px; font-size: 13px; }
  .ti-play { width: 44px; height: 44px; }

  /* Promises: a narrow crop around the notch, still wider than tall so it reads as a Mac screen, the props drawn narrower to fit it */
  .pledge { padding: 96px 0; }
  .js .pledge:not(.still) .jr-pin { padding: 56px 0 16px; }
  .jy-stage { --cw: 520; --ch: 400; width: calc(100% - 32px); }
  .jy-win, .jy-field { left: 536px; width: 440px; }
  .jr-rail { justify-content: center; }

  /* Story: a Mac screen on top, nearly edge to edge, the moment's words filling what is left of the pin.
     The crop is narrow but wider than tall (560 x 490 points: the lowest prop, the Draw trackpad's cue, ends near 472);
     on short phones the screen gets smaller, never the words. */
  .story-track { height: calc(5 * 85svh + 100svh); }
  .snap:nth-child(1) { top: 12svh; } .snap:nth-child(2) { top: 97svh; } .snap:nth-child(3) { top: 182svh; } .snap:nth-child(4) { top: 267svh; } .snap:nth-child(5) { top: 352svh; }
  .story-pin { align-items: stretch; }
  .story-grid { grid-template-columns: minmax(0, 1fr); grid-template-rows: auto minmax(0, 1fr); align-items: stretch; gap: 0; height: 100%; padding: 46px 8px 0; }
  .story-stage-col { order: -1; }
  .story-stage { --cw: 560; --ch: 490; width: min(100%, (100svh - 345px) * 560 / 490); margin-inline: auto; border-radius: 28px; }
  .story-side { gap: 12px; margin: 14px 8px 0; min-height: 0; }
  .story-rail { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; margin: 0 -16px; padding: 0 16px; }
  .story-rail::-webkit-scrollbar { display: none; }
  .story-rail button { flex: none; min-height: 40px; }
  .story-caps { flex: 1; min-height: 0; }
  .cap { top: 4px; translate: 0 20px; gap: 10px; }
  .cap.on { translate: 0 0; } .cap.past { translate: 0 -20px; }
  .cap-when { font-size: 13px; }
  .cap-h { font-size: 28px; }
  .cap-p { font-size: 15px; }
  .cap .pills { display: none; }

  .ex-tabs-wrap { margin: 0 -16px; }
  .ex-tabs { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; scroll-snap-type: x proximity; width: 100%; padding: 2px 16px;
    -webkit-mask-image: linear-gradient(90deg, transparent, #000 16px, #000 calc(100% - 72px), transparent); mask-image: linear-gradient(90deg, transparent, #000 16px, #000 calc(100% - 72px), transparent); }
  .ex-tabs::-webkit-scrollbar { display: none; }
  .ex-tab { min-height: 44px; }
  .ex-body { margin-top: 18px; gap: 18px; }
  .ex-stage { --cw: 500; --ch: 400; border-radius: 28px; }
  .ex-cards { display: flex; overflow-x: auto; scroll-snap-type: x mandatory; gap: 12px; margin: 0 -16px; padding: 0 16px 8px; scrollbar-width: none; scroll-padding: 0 16px; }
  .ex-cards::-webkit-scrollbar { display: none; }
  .ex-cards .card { flex: 0 0 82%; scroll-snap-align: start; }

  /* Privacy: the stage becomes a strip around the notch, which says what each switch asked for;
     the Privacy & Security window sits under the switches at real size (main.js moves it). */
  .priv-stage { --cw: 440; --ch: 170; border-radius: 24px; }
  .priv > .sys-win { width: 100%; font-size: 14px; box-shadow: none; }
  .priv > .sys-win .perm-t b { font-size: 15px; }
  .priv > .sys-win .perm-t small { font-size: 13px; line-height: 1.4; }
  .priv > .sys-win .perm-ic { width: 32px; height: 32px; }
  .priv-picks { justify-content: flex-start; flex-wrap: nowrap; overflow-x: auto; margin: 0 -16px; padding: 2px 16px; scrollbar-width: none;
    -webkit-mask-image: linear-gradient(90deg, #000 calc(100% - 56px), transparent); mask-image: linear-gradient(90deg, #000 calc(100% - 56px), transparent); }
  .priv-picks::-webkit-scrollbar { display: none; }
  .pick { flex: none; }

  /* Sideways rows keep the swipe to themselves: no rubber-banding the page, no back gesture by accident */
  .story-rail, .ex-tabs, .ex-cards, .priv-picks { overscroll-behavior-x: contain; }
  /* Headlines arrive word by word without the blur; a dozen blurred layers per line is the heaviest paint on the page */
  .js .pledge:not(.still) .jr-line, .js .pledge:not(.still) .jr-w, .cap { filter: none; }

  .get-stage { --cw: 540; --ch: 460; border-radius: 28px; }
  .swipe { height: 60px; --thumb: 52px; }
  .swipe-label { font-size: 15px; padding: 0 64px 0 58px; gap: 4px; white-space: nowrap; }
  .get-price .num { font-size: 44px; }
  .get-list li { font-size: 16px; }
  .paid { padding: 24px 18px 18px; }
}
/* Short phones (667 and under): tighter hero type and a lower start, so the copy fits above the docked guide in one screen */
@media (max-width: 734px) and (max-height: 700px) {
  .hero { padding-top: 160px; } /* still clears the desktop files (78 to 165) */
  .hero-side { margin-top: 14px; }
  .hero-title { font-size: 42px; }
  .hero-lead { font-size: 17px; }
  .hero .cta { margin-top: 20px; }
  .hero-meta { margin-top: 10px; }
}
/* Very short phones: the desktop files would land on the headline, so the notch keeps the stage to itself, and the copy can rise (after the 700 rule, which it overrides) */
@media (max-width: 734px) and (max-height: 640px) { .hero-files { display: none; } .hero { padding-top: 96px; } }
/* No hover on touch, so the first file hops toward the notch a few times to say it can be dragged. The first touch retires it. */
@media (hover: none) and (prefers-reduced-motion: no-preference) {
  .hero-files:not(.played) .dfile:first-child { animation: hero-in 900ms var(--ease) 900ms both, hop 1.6s var(--ease-inout) 4.6s 3; }
  @keyframes hop { 0%, 55%, 100% { transform: none; } 22% { transform: translateY(-14px); } 38% { transform: translateY(-3px); } }
}



@media (prefers-reduced-motion: reduce) {
  .hero-title .hl, .hero-side, .hero-wall, .dfile, .paid, .tryit { animation: fade 150ms linear both !important; }
  .hero-callout .ic { animation: none; }
  .ti-dots i.on, .ti-steps li.next { animation: none; }
  .nudge::before { animation: none; opacity: .8; }
  @keyframes fade { from { opacity: 0; } }
  .spin, .shine, .chev i, .swipe::before, .swipe-thumb::after, .swipe-thumb { animation: none !important; }
  .cap, .swipe-thumb { transition: none; }
  .cap, .cap.on, .cap.past { filter: none; }
  .js .ex-panel, .js .ex-panel .card, .find-list li a { animation: none; }
  .sysw, .sysw::after { animation-duration: 1ms; animation-delay: 0ms; }
}
@media (hover: none) { .get-hint { opacity: 0; } }

/* Credits: the open source Macadoodle is built on. Two featured projects, then the rest as rows. */
.credits .split-head { margin-bottom: clamp(32px, 4vw, 56px); }
.cr-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; }
.cr-card { display: flex; flex-direction: column; height: 100%; padding: 28px; border-radius: var(--r-lg); background: var(--tile-1); border: 1px solid var(--line);
  transition: background var(--m-base) var(--ease-out), border-color var(--m-base) var(--ease-out), transform var(--m-medium) var(--ease-quint); }
.cr-card:hover { background: var(--tile-2); border-color: var(--line-strong); }
.cr-card:active, .cr-row:active { transform: scale(.985); }
.cr-card:focus-visible, .cr-row:focus-visible { outline: 2px solid var(--focus); outline-offset: 3px; }
.cr-top { display: flex; align-items: center; gap: 10px; color: var(--ink-muted); }
.cr-top .ic { width: 20px; height: 20px; }
.cr-repo { font: 500 13px/1.2 var(--mono); color: var(--ink-faint); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cr-go { margin-left: auto; color: var(--link); transition: translate var(--m-medium) var(--ease-quint); }
.cr-card:hover .cr-go, .cr-row:hover .cr-go { translate: 2px -2px; }
.cr-k { margin-top: 48px; font: 500 12px/1 var(--mono); letter-spacing: .08em; text-transform: uppercase; color: var(--ink-faint); }
.cr-name { margin-top: 10px; font-weight: 600; font-size: clamp(28px, 3vw, 40px); line-height: 1.1; letter-spacing: -0.03em; }
.cr-p { margin-top: 12px; font-size: 17px; line-height: 1.5; color: var(--ink-muted); text-wrap: pretty; }
.cr-list { margin-top: 16px; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 16px; }
.cr-row { display: flex; align-items: center; gap: 14px; min-height: 72px; padding: 12px 16px; border-radius: 14px; border-top: 1px solid var(--line);
  transition: background var(--m-base) var(--ease-out), transform var(--m-medium) var(--ease-quint); }
.cr-row:hover { background: var(--tile-2); }
.cr-row > .ic:first-child { width: 20px; height: 20px; color: var(--ink-muted); }
.cr-t { flex: 1; min-width: 0; }
.cr-t b { display: block; font-weight: 600; }
.cr-t small { display: block; font-size: 14px; color: var(--ink-muted); }
@media (max-width: 734px) {
  .cr-grid, .cr-list { grid-template-columns: minmax(0, 1fr); }
  .cr-card { padding: 24px; }
  .cr-k { margin-top: 32px; }
  .cr-row .cr-repo { display: none; }
}
@media (prefers-reduced-motion: reduce) { .cr-card, .cr-row, .cr-go { transition: none; } }
