/* SealNest website — the landing page (index.html). Builder A. Loads after tokens.css.
   Every class here starts with lp-. Colours, type, radii, shadows and easings come from
   tokens.css. The drawn passport and payment card carry fallback colours in index.html as SVG
   attributes; the rules under "the drawings" below repaint them from tokens.css, so they follow
   the palette (a booklet in the accent, a stone card, oat details).

   THE ONE MOTION RULE (SPEC.md 2.2): every animated thing's default style is its
   FINISHED state. A "before" state exists only under html.motion and only until
   is-played / is-in arrives. Transitions are declared on the PLAYED state only, so a
   picture that is played again (SealNestSite.replay) snaps to the start and then plays,
   instead of reversing nothing. Each picture plays once; there is no "Play again" button.

   Contents
     1. Hero            4. Read plate        5. Moments           8. Close
     2. Shared pieces   5. Sell plate        6. Price             9. Small screens
     3. Bring it in                          7. Where it works
*/

/* ================================ 1. HERO ================================ */
/* Under 900 px the hero is one column: headline, one line, the phone, then the App Store line.
   The words' box is taken out of the layout (display:contents) so its three children can be
   placed one by one, and the App Store line can sit UNDER the phone while it is only a line of
   text. That keeps the phone's Unlock button on the first screen of an iPhone. Once there is a
   real App Store address (html.store-live) the button goes back above the phone. */
.lp-hero{--lp-ctl:254px;padding:22px 0 56px}       /* --lp-ctl: the height of the demo's controls under its phone (demo/demo.css) */
.lp-hero-grid{display:grid;grid-template-columns:minmax(0,1fr);justify-items:center;text-align:center}
.lp-hero-words{display:contents}
.lp-h1{order:1;min-width:0;max-width:100%}
.lp-hero-words .lead{order:2;margin-left:auto;margin-right:auto;text-wrap:balance}
@media (max-width:640px){ .lp-hero-words .lead{margin-top:16px;font-size:17px;line-height:1.42} }   /* three lines on a phone: kept compact so the Unlock button stays on the first screen */
.lp-hero-demo{order:3;width:100%;min-width:0;margin-top:20px}
.lp-hero-words:only-child{display:block;grid-column:1 / -1;text-align:center;padding-bottom:0}   /* demo.show off: no phone, the words alone, centred */
.lp-hero-words:only-child .lead{margin-left:auto;margin-right:auto}
.lp-hero-store{order:4;margin-top:6px}
html.store-live .lp-hero-store{order:2;margin-top:24px}
.lp-not{display:inline-block;color:var(--accent-ink)}
/* a short phone window (a small iPhone with Safari's bars showing): less air above the phone,
   so its Unlock button is still on the first screen */
@media (max-width:899.98px) and (max-height:660px){
  .lp-hero{padding-top:18px}
  .lp-hero-words .lead{margin-top:16px}
  .lp-hero-demo{margin-top:18px}
}

@media (min-width:900px){
  .lp-hero{padding:48px 0 72px}
  .lp-hero-grid{grid-template-columns:minmax(0,1fr) minmax(320px,380px);column-gap:56px;
    align-items:center;justify-items:stretch;text-align:left}
  /* the words are centred on the PHONE, not on the phone plus the controls under it */
  .lp-hero-words{display:block;min-width:0;padding-bottom:var(--lp-ctl)}
  .lp-h1{font-size:min(var(--fs-h1),5.1vw)}          /* two lines beside the phone, at every width */
  .lp-hero-words .lead{margin-left:0;margin-right:0}
  .lp-hero-demo{margin-top:0}
  .lp-hero-store,html.store-live .lp-hero-store{margin-top:22px}
}

/* The line always says "Your life should not be a product." — "not" is there from the first frame,
   tilted and a little large, and at 0.7 s it is stamped down into place in the accent while the line
   turns to ink. It must never read "should be a product", not even for a frame: a screenshot or a
   link preview can catch any frame. After that the hero is still. */
@keyframes lp-rise{from{opacity:0;transform:translateY(14px)}}
@keyframes lp-rise-demo{from{opacity:0;transform:translateY(24px)}}
@keyframes lp-ink{from{color:var(--them-ink)}}
@keyframes lp-stamp{from{transform:scale(1.35) rotate(-4deg)}}
html.motion .lp-h1{animation:lp-rise 400ms var(--ease) backwards,lp-ink 400ms var(--ease) 700ms backwards}
html.motion .lp-not{animation:lp-stamp 240ms var(--ease-spring) 700ms backwards}
html.motion .lp-hero-words .lead{animation:lp-rise 400ms var(--ease) 250ms backwards}
html.motion .lp-hero-store{animation:lp-rise 400ms var(--ease) 350ms backwards}
html.motion .lp-hero-demo{animation:lp-rise-demo 500ms var(--ease) 150ms backwards}

/* ============================ 2. SHARED PIECES ============================ */

/* ---- the grey line and the giant line (exact, SPEC 5.0) ---- */
.lp-they{margin:0;font:600 clamp(20px,3.2vw,30px)/1.2 var(--font-sans);letter-spacing:-.01em;color:var(--them-ink)}
/* The giant line. At launch it is a whole sentence ("We can't read it."): one line from about
   700 px wide, two lines on a phone. With claims.themLines on it is two words under the grey line
   and takes the larger size. */
.lp-we{margin-top:0;font-size:clamp(54px,8.6vw,124px);line-height:.98;letter-spacing:-.04em}
.lp-they + .lp-we{margin-top:6px;font-size:clamp(56px,13vw,160px);line-height:.95}
.lp-we b{font-weight:400;color:var(--accent-ink)}

.lp-plate--sell .lp-we{font-size:clamp(46px,8.6vw,124px);max-width:8em;margin-left:auto;margin-right:auto}
.lp-plate--read{--lp-we-at:900ms}
.lp-plate--sell{--lp-we-at:1200ms}
/* Before its picture plays, the sentence is already there, in grey (the band is never blank).
   It turns to ink, and its key word to green, at the moment the picture has made its point:
   the same move as the headline at the top of the page. */
html.motion [data-play-scope]:not(.is-played) .lp-we,
html.motion [data-play-scope]:not(.is-played) .lp-we b{color:var(--them-ink)}
html.motion [data-play-scope].is-played .lp-we,
html.motion [data-play-scope].is-played .lp-we b{transition:color 320ms var(--ease) var(--lp-we-at)}
/* with the grey line above it (claims.themLines) the giant line arrives instead */
html.motion [data-play-scope]:not(.is-played) .lp-they + .lp-we{opacity:0;transform:translateY(16px) scale(1.04)}
html.motion [data-play-scope].is-played .lp-they + .lp-we{
  transition:opacity 280ms var(--ease) var(--lp-we-at),transform 280ms var(--ease) var(--lp-we-at)}
/* the line under it never arrives before it */
html.motion .lp-plate[data-play-scope]:not(.is-played) .say{opacity:0}
html.motion .lp-plate[data-play-scope].is-played .say{transition:opacity 280ms var(--ease) calc(var(--lp-we-at) + 120ms)}

/* ---- a picture ---- */
.lp-pic{position:relative;display:flow-root;margin:40px auto 0}   /* flow-root: the lift below must not collapse away */

/* ---- when a picture starts ----
   js/site.js plays a picture when most of it is on screen (70% of the picture, or 60% of the window
   for a picture taller than that) and it has stayed there a moment. Nothing here depends on the
   window's height, so it is the same on a page of its own, in a frame that scrolls inside itself,
   and in a frame a host has made as tall as the page. */

/* ---- the green outline that draws itself closed ----
   index.html ships one rounded <rect> (the finished outline, for scripts off).
   js/landing.js swaps it for a <path> of the same shape that starts and ends at bottom
   centre, with pathLength="1", so one dash can draw it closed at any size. */
.lp-outline{position:absolute;inset:0;width:100%;height:100%;overflow:visible;pointer-events:none}
.lp-outline-line{fill:none;stroke:var(--accent);stroke-width:2}
.lp-outline path{stroke-dasharray:1 2;stroke-linecap:square}   /* square ends overlap where the line starts and stops: no hairline gap */
html.motion [data-play]:not(.is-played) .lp-outline{opacity:0}
html.motion [data-play]:not(.is-played) .lp-outline path{stroke-dashoffset:1.02}
html.motion [data-play].is-played .lp-outline{transition:opacity 1ms linear var(--lp-outline-at)}
html.motion [data-play].is-played .lp-outline path{transition:stroke-dashoffset var(--lp-outline-ms,600ms) var(--lp-outline-ease,var(--ease)) var(--lp-outline-at)}

/* ---- the wax seal (SPEC 5.2.1): used in "Bring it in" and at the close ---- */
.lp-seal{position:absolute;z-index:2;left:50%;bottom:30px;width:132px;height:132px;margin-left:-66px}
.lp-seal::after{content:"";position:absolute;z-index:-1;left:4%;right:4%;bottom:-8%;height:32%;
  background:radial-gradient(closest-side,var(--seal-shade),transparent)}
.lp-seal-wax{position:relative;display:block;width:100%;height:100%;overflow:visible}
.lp-seal-skirt{fill:var(--seal-deep);transform-origin:66px 66px}
.lp-seal-body{fill:var(--seal)}
.lp-seal-stop-hi{stop-color:var(--seal-light)}
.lp-seal-stop-lo{stop-color:var(--seal-deep)}
.lp-seal-groove-dark{fill:none;stroke:var(--seal-shade);stroke-width:1.5}
.lp-seal-groove-light{fill:none;stroke:var(--seal-light);stroke-width:1}
.lp-seal-shine{fill:var(--seal-light);opacity:0}
/* the logo pressed into the wax: assets/mark.svg#press is the bare shape in see-through dark and
   light, so it takes the wax's own colour. (A logo file without that view shows its whole icon here.) */
.lp-seal-mark{position:absolute;left:50%;top:50%;width:58px;height:58px;margin:-29px 0 0 -29px}
.lp-seal-ring{position:absolute;inset:10.6%;border:2px solid var(--seal);border-radius:50%;opacity:0;pointer-events:none}

/* The logo. It is what the green line starts from and returns to: it pops onto the tray's bottom
   edge just before the line leaves it, and the wax comes down on top of it when the line has come
   all the way round and met it again. By default (and with motion off) it is not there: it is
   under the seal. */
.lp-logo{position:absolute;z-index:1;left:50%;bottom:73px;width:46px;height:46px;margin-left:-23px;border-radius:12px;opacity:0;pointer-events:none;
  box-shadow:0 0 0 3px var(--surface),0 6px 16px -6px var(--seal-shade)}
.lp-logo img{display:block;width:100%;height:100%;border-radius:12px}
@keyframes lp-logo{0%{opacity:0;transform:scale(.45);animation-timing-function:var(--ease-spring)}20%{opacity:1;transform:scale(1)}
  99%{opacity:1;transform:scale(1)}100%{opacity:0;transform:scale(1)}}
html.motion [data-play].is-played .lp-logo{animation:lp-logo calc(var(--lp-seal-at) + 170ms - var(--lp-logo-at)) linear var(--lp-logo-at) both}

@keyframes lp-seal-drop{from{opacity:0;transform:scale(1.7)}to{opacity:1;transform:scale(.94)}}
@keyframes lp-seal-squash{0%{transform:scale(.94)}45%{transform:scale(1.04)}100%{transform:scale(1)}}
@keyframes lp-seal-skirt{from{transform:scale(.9)}}
@keyframes lp-seal-ring{from{opacity:.35;transform:scale(1)}to{opacity:0;transform:scale(2.4)}}
@keyframes lp-seal-shine{0%{opacity:0;transform:translateX(0)}25%{opacity:.55}75%{opacity:.55}100%{opacity:0;transform:translateX(200px)}}

html.motion [data-play]:not(.is-played) .lp-seal,
html.motion .lp-seal[data-play]:not(.is-played){opacity:0}
html.motion [data-play].is-played .lp-seal,
html.motion .lp-seal[data-play].is-played{
  animation:lp-seal-drop 170ms var(--ease-in) var(--lp-seal-at) both,
            lp-seal-squash 380ms var(--ease) calc(var(--lp-seal-at) + 170ms) forwards}
html.motion [data-play].is-played .lp-seal-skirt{animation:lp-seal-skirt 380ms var(--ease-spring) calc(var(--lp-seal-at) + 170ms) backwards}
html.motion [data-play].is-played .lp-seal-ring{animation:lp-seal-ring 700ms var(--ease) calc(var(--lp-seal-at) + 170ms)}
html.motion [data-play].is-played .lp-seal-shine{animation:lp-seal-shine 500ms var(--ease) calc(var(--lp-seal-at) + 550ms)}

/* ============================ 3. BRING IT IN ============================ */
.lp-gather{--lp-card:var(--card);--lp-soft:var(--card-soft);overflow:hidden;overflow:clip;padding-bottom:calc(var(--band-pad) - 34px)}
.lp-gather-h{margin-top:6px}
html.motion [data-play-scope]:not(.is-played) .lp-gather-h{opacity:0;transform:translateY(14px)}
html.motion [data-play-scope].is-played .lp-gather-h{transition:opacity 300ms var(--ease) 600ms,transform 300ms var(--ease) 600ms}

/* the stage: 72 px clear above the tray, 96 px below */
.lp-stage{--lp-outline-at:2000ms;--lp-outline-ms:1100ms;--lp-outline-ease:cubic-bezier(.62,.05,.36,1);--lp-seal-at:3100ms;--lp-logo-at:1700ms;
  position:relative;width:min(100%,868px);margin:0 auto;padding:72px 0 96px}

/* the tray. Its paper (ground + shadow) is ::after so it can fade in by opacity alone;
   ::before is the dashed grey "not yet" outline. Extra room at the bottom keeps the seal
   off the labels. */
.lp-nest{position:relative;z-index:0;border-radius:var(--radius-lg);padding:22px 22px 76px}
.lp-nest::after{content:"";position:absolute;z-index:-1;inset:0;border-radius:inherit;background:var(--surface);box-shadow:var(--shadow)}
.lp-nest::before{content:"";position:absolute;inset:0;border-radius:inherit;border:1.5px dashed var(--them);opacity:0;pointer-events:none}

.lp-things{list-style:none;margin:0;padding:0;display:flex;justify-content:center;gap:16px}
.lp-thing{position:relative;flex:0 1 104px;min-width:0;display:flex;flex-direction:column;align-items:center;gap:8px}
.lp-art{position:relative;display:block;width:100%;aspect-ratio:3/2;border-radius:10px;box-shadow:var(--shadow)}
.lp-face{position:absolute;inset:0;width:100%;height:100%}
.lp-face--grey{opacity:0}
.lp-label{font-size:14px;line-height:1.3;color:var(--ink-2);white-space:nowrap}
.lp-label--two{white-space:normal;text-align:center;text-wrap:balance}      /* "Secure documents" may take two lines */
/* one line of examples under the tray */
.lp-docs{margin:0 auto;max-width:30em;font-size:16.5px;line-height:1.5;color:var(--ink-2);text-wrap:balance}
.lp-docs b{font-weight:600;color:var(--ink)}
html.motion [data-play-scope]:not(.is-played) .lp-docs{opacity:0}
html.motion [data-play-scope].is-played .lp-docs{transition:opacity 400ms var(--ease) 3500ms}

/* the drawings: colour face */
.lp-c-card{fill:var(--lp-card);stroke:var(--line-2);stroke-width:1}
.lp-c-ink{fill:var(--ink)}
.lp-c-ink-s{fill:none;stroke:var(--ink);stroke-width:2.6;stroke-linecap:round;stroke-linejoin:round}
.lp-c-thick{stroke-width:4.6}
.lp-c-moss{fill:var(--accent)}
.lp-c-moss-s{fill:none;stroke:var(--accent);stroke-width:3;stroke-linecap:round;stroke-linejoin:round}
.lp-c-track-s{fill:none;stroke:var(--line-2);stroke-width:3}
.lp-c-soft{fill:var(--lp-soft)}
.lp-c-fold{fill:var(--surface-3);stroke:var(--line-2);stroke-width:1;stroke-linejoin:round}
.lp-c-digits{font:700 18px/1 var(--font-mono)}
.lp-c-pan{font:600 13px/1 var(--font-mono)}
.lp-c-dim{opacity:.6}
/* the passport booklet, its page and portrait, and the stone payment card: colours from tokens.css */
.lp-c-book1{stop-color:var(--book-1)}
.lp-c-book2{stop-color:var(--book-2)}
.lp-c-stone1{stop-color:var(--stone-1)}
.lp-c-stone2{stop-color:var(--stone-2)}
.lp-c-fixp,.lp-c-fixd{fill:var(--oat)}
.lp-c-fixq{fill:var(--book-2)}
.lp-c-pan{fill:var(--oat-light)}
/* the same drawings: grey face ("not yours yet") */
.lp-face--grey .lp-c-fixp{fill:var(--them)}
.lp-face--grey .lp-c-fixq{fill:var(--them-fill)}
.lp-face--grey .lp-c-card,.lp-face--grey .lp-c-fix,.lp-face--grey .lp-c-fold{fill:var(--them-fill);stroke:var(--them);stroke-width:1;stroke-opacity:.55}
.lp-face--grey .lp-c-ink,.lp-face--grey .lp-c-moss,.lp-face--grey .lp-c-soft,.lp-face--grey .lp-c-fixd{fill:var(--them)}
.lp-face--grey .lp-c-ink-s,.lp-face--grey .lp-c-moss-s,.lp-face--grey .lp-c-track-s,.lp-face--grey .lp-c-fixd-s{stroke:var(--them)}

/* each thing's place in the timeline, and which neighbours its thread passes under */
.lp-thing:nth-child(1){--i:0}.lp-thing:nth-child(2){--i:1}.lp-thing:nth-child(3){--i:2}.lp-thing:nth-child(4){--i:3}
.lp-thing:nth-child(5){--i:4}.lp-thing:nth-child(6){--i:5}.lp-thing:nth-child(7){--i:6}

/* the scatter (under 900 px; the wide values are in the media query below) */
.lp-thing:nth-child(1){--sx:-18px;--sy:-40px;--sr:-7deg;z-index:4}
.lp-thing:nth-child(2){--sx:14px;--sy:-64px;--sr:5deg;z-index:3}
.lp-thing:nth-child(3){--sx:-10px;--sy:-30px;--sr:6deg;z-index:3}
.lp-thing:nth-child(4){--sx:22px;--sy:-52px;--sr:-8deg;z-index:4}
.lp-thing:nth-child(5){--sx:-26px;--sy:48px;--sr:7deg;z-index:4}
.lp-thing:nth-child(6){--sx:8px;--sy:66px;--sr:-5deg;z-index:3}
.lp-thing:nth-child(7){--sx:30px;--sy:40px;--sr:9deg;z-index:4}
/* threads that run to the RIGHT side of the screen (the rest run left) */
.lp-thing:nth-child(3),.lp-thing:nth-child(4),.lp-thing:nth-child(7){--t-left:50%;--t-right:auto;--t-origin:0%;--t-dir:1}

@media (min-width:900px){
  .lp-thing:nth-child(1){--sx:-210px;--sy:-46px;--sr:-8deg;z-index:4}
  .lp-thing:nth-child(2){--sx:-120px;--sy:84px;--sr:6deg;z-index:3}
  .lp-thing:nth-child(3){--sx:-40px;--sy:-92px;--sr:5deg;z-index:2;--t-left:auto;--t-right:50%;--t-origin:100%;--t-dir:-1}
  .lp-thing:nth-child(4){--sx:0px;--sy:110px;--sr:-6deg;z-index:1}
  .lp-thing:nth-child(5){--sx:60px;--sy:-84px;--sr:7deg;z-index:2}
  .lp-thing:nth-child(6){--sx:150px;--sy:90px;--sr:-9deg;z-index:3}
  .lp-thing:nth-child(7){--sx:220px;--sy:-40px;--sr:4deg;z-index:4}
  .lp-thing:nth-child(5),.lp-thing:nth-child(6){--t-left:50%;--t-right:auto;--t-origin:0%;--t-dir:1}
}

/* the thread (::before) and the one dot leaving along it (::after). Nothing is drawn where
   a thread ends: it simply runs off the side of the screen. */
.lp-thing::before{content:"";position:absolute;z-index:-1;top:34%;left:var(--t-left,auto);right:var(--t-right,50%);
  width:100vw;height:1px;background:var(--them);transform:scaleX(0);transform-origin:var(--t-origin,100%) 50%;pointer-events:none}
.lp-thing::after{content:"";position:absolute;z-index:-1;top:calc(34% - 2px);left:calc(50% - 2.5px);
  width:5px;height:5px;border-radius:50%;background:var(--them);opacity:0;pointer-events:none}
@keyframes lp-leak{from{transform:translateX(0) scale(1)}to{transform:translateX(calc(var(--t-dir,-1) * min(36vw,320px))) scale(.2)}}

/* before */
html.motion [data-play]:not(.is-played) .lp-thing{transform:translate(var(--sx),var(--sy)) rotate(var(--sr))}
html.motion [data-play]:not(.is-played) .lp-face--grey{opacity:1}
html.motion [data-play]:not(.is-played) .lp-face:not(.lp-face--grey){opacity:0}
html.motion [data-play]:not(.is-played) .lp-thing::before{transform:scaleX(1)}
html.motion [data-play]:not(.is-played) .lp-thing::after{opacity:1}
html.motion [data-play]:not(.is-played) .lp-nest::before{opacity:1}
html.motion [data-play]:not(.is-played) .lp-nest::after{opacity:0}
html.motion [data-play]:not(.is-played) .lp-label{opacity:0}       /* names arrive once the things are home: no label is ever half hidden */
/* the dots only travel while the stage is on screen and the mess is still a mess, and only
   twice (under five seconds): nothing on the page moves for long without being asked to */
html.motion .lp-thing::after{animation:lp-leak 2.4s linear calc(var(--i) * -.3s) 2 paused}
html.motion .lp-stage.is-visible:not(.is-played) .lp-thing::after{animation-play-state:running}

/* the timeline, from the moment is-played arrives */
@keyframes lp-dip{35%{transform:translateY(6px)}}
html.motion [data-play].is-played .lp-thing::before{transition:transform 400ms var(--ease-in) 500ms}
html.motion [data-play].is-played .lp-thing::after{transition:opacity 160ms linear 500ms}
html.motion [data-play].is-played .lp-thing{transition:transform 760ms cubic-bezier(.2,.9,.28,1.14) calc(700ms + var(--i) * 70ms)}
html.motion [data-play].is-played .lp-face--grey{transition:opacity 300ms linear calc(1100ms + var(--i) * 70ms)}
html.motion [data-play].is-played .lp-face:not(.lp-face--grey){transition:opacity 1ms linear calc(1100ms + var(--i) * 70ms)}
html.motion [data-play].is-played .lp-label{transition:opacity 300ms var(--ease) calc(1300ms + var(--i) * 70ms)}
html.motion [data-play].is-played .lp-nest::after{transition:opacity 700ms var(--ease) 900ms}
html.motion [data-play].is-played .lp-nest::before{transition:opacity 300ms linear 1900ms}
html.motion [data-play].is-played .lp-nest{animation:lp-dip 260ms var(--ease) calc(var(--lp-seal-at) + 170ms)}

/* ============================== 4. READ PLATE ============================== */
.lp-pic--read{--lp-outline-at:2400ms;width:min(100%,380px);margin-top:40px}
.lp-pic--read .seg{margin-top:20px}

/* the card looks like the app, not the website */
.lp-vcard{position:relative;text-align:left;background:var(--app-surface);border:1px solid var(--app-line);
  border-radius:18px;box-shadow:var(--shadow);padding:18px 20px;color:var(--app-ink)}
.lp-vcard .lp-outline{inset:-1px;width:calc(100% + 2px);height:calc(100% + 2px)}
.lp-vcard-title{position:relative;display:flex;align-items:center;gap:12px;margin:0;
  font-size:20px;font-weight:800;line-height:1.2;letter-spacing:-.03em;color:var(--app-ink)}
.lp-vcard-title::before{content:"";flex:0 0 36px;height:36px;border-radius:10px;background:var(--app-tile);border:1px solid var(--app-tile-line)}
.lp-vcard-title [data-secret]{min-width:0}
.lp-vcard-rows{margin:14px 0 0}
.lp-vcard-rows > div{position:relative;padding:9px 0 10px;border-top:1px solid var(--app-line)}
.lp-vcard-rows > div:last-child{padding-bottom:2px}
.lp-vcard dt{font-size:12.5px;line-height:1.3;color:var(--app-ink-2)}
.lp-vcard dd{margin:2px 0 0;min-width:0;overflow:hidden;font-size:16px;line-height:1.4;color:var(--app-ink)}
.lp-vcard .is-noise{color:var(--app-ink-2)}
/* "What we see": the field names step back (still readable, about 3:1) and the noise makes the point */
.lp-vcard.is-we dt{opacity:.6}
html.motion .lp-vcard dt{transition:opacity var(--dur-2) var(--ease)}

/* the grey reader: a 2 px line with a soft glow above it, moving inside a window the size
   of the card. Resting place (and finished state): just below the window, out of sight. */
.lp-reader{position:absolute;inset:0;overflow:hidden;border-radius:17px;pointer-events:none}
.lp-reader::before,.lp-reader::after{content:"";position:absolute;left:0;right:0;top:0;height:100%;transform:translateY(34px)}
.lp-reader::before{background:linear-gradient(to top,var(--them),transparent) bottom/100% 28px no-repeat;opacity:.32}
.lp-reader::after{border-bottom:2px solid var(--them)}
@keyframes lp-sweep{from{transform:translateY(-100%)}to{transform:translateY(34px)}}
html.motion [data-play].is-played .lp-reader::before,
html.motion [data-play].is-played .lp-reader::after{animation:lp-sweep 900ms linear backwards,lp-sweep 900ms linear 1500ms}

/* each row is washed grey as the reader crosses it — the first time only */
.lp-vcard-title::after,.lp-vcard-rows > div::after{content:"";position:absolute;inset:-4px -10px;border-radius:9px;
  background:var(--them);opacity:0;pointer-events:none}
.lp-vcard-rows > div::after{inset:2px -10px 1px}
@keyframes lp-wash{50%{opacity:.5}}
html.motion [data-play].is-played .lp-vcard-title::after{animation:lp-wash 260ms linear 40ms}
html.motion [data-play].is-played .lp-vcard-rows > div:nth-child(1)::after{animation:lp-wash 260ms linear 190ms}
html.motion [data-play].is-played .lp-vcard-rows > div:nth-child(2)::after{animation:lp-wash 260ms linear 340ms}
html.motion [data-play].is-played .lp-vcard-rows > div:nth-child(3)::after{animation:lp-wash 260ms linear 490ms}
html.motion [data-play].is-played .lp-vcard-rows > div:nth-child(4)::after{animation:lp-wash 260ms linear 640ms}

/* ---- the key: who holds it ---- */
.lp-key{margin:38px auto 0;max-width:34em}
.lp-key-i{display:block;box-sizing:content-box;width:26px;height:26px;margin:0 auto 14px;padding:13px;border:1px solid var(--line-2);border-radius:50%;background:var(--surface);
  fill:none;stroke:var(--accent-ink);stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round}
.lp-key-h{font-size:clamp(25px,3.4vw,36px);line-height:1.12;letter-spacing:-.022em;font-weight:400;color:var(--ink)}
.lp-key .say{margin-top:10px;text-wrap:balance}
html.motion [data-play-scope]:not(.is-played) .lp-key{opacity:0;transform:translateY(14px)}
html.motion [data-play-scope].is-played .lp-key{transition:opacity 400ms var(--ease) 3100ms,transform 400ms var(--ease) 3100ms}

/* ============================== 5. SELL PLATE ============================== */
.lp-pic--sell{width:min(100%,420px);margin-top:16px}
@media (min-width:900px){ .lp-pic--sell{width:min(100%,600px,78vh)} }      /* a laptop gets a picture that matches its headline */
.lp-sell{display:block;width:100%;height:auto;overflow:visible}

/* finished state: one card with a green outline, and six rings left with nothing, each one
   crossed out. No lines, no filled dots. The crossed rings say "nobody gets it" even to
   someone who never saw it move. */
.lp-sell-line{fill:none;stroke:var(--them);stroke-width:1.5;stroke-dasharray:1 2;stroke-dashoffset:1.02}
.lp-sell-ghost{fill:var(--them-fill);stroke:var(--them);stroke-width:1;opacity:0}
.lp-sell-node{opacity:.55;transform-origin:var(--ox) var(--oy)}    /* its own dot's centre, in drawing units */
.lp-sell-ring{fill:var(--ground);stroke:var(--them);stroke-width:1.5}
.lp-sell-fill{fill:var(--them);opacity:0}
.lp-sell-no{fill:none;stroke:var(--them);stroke-width:1.5;stroke-linecap:round}
.lp-sell-card{fill:var(--surface);stroke:var(--line-2);stroke-width:1.5}
.lp-sell-photo{fill:var(--them-fill)}
.lp-sell-person,.lp-sell-bar{fill:var(--them)}
.lp-sell-bar--2{opacity:.5}
.lp-sell-outline{fill:none;stroke:var(--accent);stroke-width:2;stroke-dasharray:1 2;stroke-linecap:square}

/* per dot: its turn (clockwise from the top left), its centre, and how far its ghost copy
   travels (dot centre minus the point where its line leaves the card) */
.lp-sell-leak--a{--k:0;--ox:60px;--oy:40px;--dx:-78px;--dy:-62px}
.lp-sell-leak--b{--k:1;--ox:300px;--oy:40px;--dx:78px;--dy:-62px}
.lp-sell-leak--d{--k:2;--ox:314px;--oy:134px;--dx:84px;--dy:0px}
.lp-sell-leak--f{--k:3;--ox:284px;--oy:240px;--dx:64px;--dy:74px}
.lp-sell-leak--e{--k:4;--ox:76px;--oy:240px;--dx:-64px;--dy:74px}
.lp-sell-leak--c{--k:5;--ox:50px;--oy:134px;--dx:-80px;--dy:0px}

/* who each dot is: a kind of buyer, never a company. Finished: grey and struck through. Before:
   in plain ink, so the picture says who is being sent your things while the lines draw to them. */
.lp-sell-who{font:600 13.5px/1 var(--font-sans);fill:var(--muted)}
.lp-sell-strike{fill:none;stroke:var(--muted);stroke-width:1.6;stroke-linecap:round;stroke-dasharray:1 2;stroke-dashoffset:0}

/* before: the card alone, with six hollow grey rings waiting */
html.motion [data-play]:not(.is-played) .lp-sell-node{opacity:1}
html.motion [data-play]:not(.is-played) .lp-sell-outline{stroke-dashoffset:1.02}
html.motion [data-play]:not(.is-played) .lp-sell-no{opacity:0}
html.motion [data-play]:not(.is-played) .lp-sell-who{fill:var(--ink-2)}
html.motion [data-play]:not(.is-played) .lp-sell-strike{stroke-dashoffset:1.02}

/* 0–1100 ms: six copies of you, taken. 1400–2200 ms: every line pulls back, last one first. */
@keyframes lp-line-out{to{stroke-dashoffset:0}}
@keyframes lp-line-back{from{stroke-dashoffset:0}to{stroke-dashoffset:1.02}}
@keyframes lp-ghost{0%{opacity:0;transform:translate(0,0)}20%{opacity:1}75%{opacity:1}
  100%{opacity:0;transform:translate(var(--dx),var(--dy))}}
@keyframes lp-node-pulse{0%{opacity:1;transform:scale(1)}50%{opacity:1;transform:scale(1.25)}100%{opacity:1;transform:scale(1)}}
@keyframes lp-node-dim{from{opacity:1}to{opacity:.55}}
@keyframes lp-fill-on{from{opacity:0}to{opacity:1}}
@keyframes lp-fill-off{from{opacity:1}to{opacity:0}}
html.motion [data-play].is-played .lp-sell-line{
  animation:lp-line-out 300ms var(--ease) calc(var(--k) * 150ms) forwards,
            lp-line-back 250ms var(--ease-in) calc(1400ms + (5 - var(--k)) * 100ms) forwards}
html.motion [data-play].is-played .lp-sell-ghost{animation:lp-ghost 300ms var(--ease) calc(var(--k) * 150ms)}
html.motion [data-play].is-played .lp-sell-node{
  animation:lp-node-pulse 200ms var(--ease) calc(var(--k) * 150ms + 250ms) both,
            lp-node-dim 400ms var(--ease) calc(1400ms + (5 - var(--k)) * 100ms + 250ms) forwards}
html.motion [data-play].is-played .lp-sell-fill{
  animation:lp-fill-on 120ms linear calc(var(--k) * 150ms + 230ms) forwards,
            lp-fill-off 250ms var(--ease-in) calc(1400ms + (5 - var(--k)) * 100ms) forwards}
/* each name is struck through as its line lets go */
html.motion [data-play].is-played .lp-sell-who{transition:fill 240ms linear calc(1400ms + (5 - var(--k)) * 100ms + 250ms)}
html.motion [data-play].is-played .lp-sell-strike{transition:stroke-dashoffset 260ms var(--ease) calc(1400ms + (5 - var(--k)) * 100ms + 250ms)}
/* each ring is crossed out as its line lets go */
html.motion [data-play].is-played .lp-sell-no{transition:opacity 200ms var(--ease) calc(1400ms + (5 - var(--k)) * 100ms + 250ms)}
/* 2200–2800 ms: the green outline draws closed around the one card that remains */
html.motion [data-play].is-played .lp-sell-outline{transition:stroke-dashoffset 600ms var(--ease) 2200ms}

/* the two stamps */
.lp-stamps{list-style:none;margin:12px 0 0;padding:0;display:flex;flex-wrap:wrap;justify-content:center;gap:14px}
.lp-stamp{font:700 20px/1 var(--font-sans);color:var(--accent-ink);border:2px solid var(--accent-ink);border-radius:8px;
  padding:10px 16px;transform:rotate(-2deg)}
.lp-stamp:nth-child(2){transform:rotate(1.5deg)}
html.motion [data-play-scope]:not(.is-played) .lp-stamp{opacity:0;transform:scale(1.3)}
html.motion [data-play-scope].is-played .lp-stamp{transition:opacity 220ms var(--ease-spring) 2800ms,transform 220ms var(--ease-spring) 2800ms}
html.motion [data-play-scope].is-played .lp-stamp:nth-child(2){transition-delay:2920ms}

/* ============================== 5. MOMENTS ============================== */
/* Four moments people know, each a small grey question and a big answer. Each is a feature of the free app. */
.lp-moments{padding:calc(var(--band-pad) + 10px) 0}
.lp-moments .eyebrow{margin-bottom:0}
.lp-moment-list{list-style:none;margin:34px auto 0;padding:0;max-width:760px;display:grid;gap:clamp(36px,5.4vw,58px)}
.lp-moment .lp-they{font-size:clamp(19px,2.6vw,26px)}
.lp-moment-a{margin:8px auto 0;max-width:15em;font-size:clamp(31px,5.8vw,56px);line-height:1.06;letter-spacing:-.03em;color:var(--ink);text-wrap:balance}
.lp-moment-a b{font-weight:400;color:var(--accent-ink)}
.lp-keep{white-space:nowrap}
.lp-moments .say{margin-top:clamp(36px,5.4vw,54px)}
.lp-moments .say b{font-weight:700;color:var(--ink)}
html.motion .lp-moment.reveal:nth-child(2){transition-delay:90ms}
html.motion .lp-moment.reveal:nth-child(3){transition-delay:180ms}
html.motion .lp-moment.reveal:nth-child(4){transition-delay:270ms}

/* ================================ 6. PRICE ================================ */
/* The free app: one card listing what is in it. With the plans on sale: Free, Personal and Family side by
   side from 980 px (one above the other below that). Personal wears the green outline, the same line that
   closes around "yours" higher up. */
.lp-plans{display:grid;grid-template-columns:minmax(0,1fr);gap:16px;max-width:720px;margin:36px auto 0;text-align:left}
.lp-plan{display:flex;flex-direction:column;background:var(--card);border:1px solid var(--card-line);   /* a card must be lighter than the band it sits on */
 
  border-radius:var(--radius-lg);box-shadow:var(--shadow);padding:24px 24px 26px}
.lp-plan--plus{border-color:var(--accent);box-shadow:0 0 0 1px var(--accent),var(--shadow)}
.lp-plan-name{display:flex;align-items:center;justify-content:space-between;gap:10px;min-height:28px;
  font-size:17px;line-height:1.2;font-weight:700;letter-spacing:-.01em;color:var(--ink)}
.lp-plan-tag{flex:0 0 auto;font-size:12.5px;font-weight:600;letter-spacing:0;line-height:1.2;white-space:nowrap;
  padding:5px 10px;border-radius:var(--radius-pill);background:var(--accent-soft);color:var(--accent-ink)}
.lp-plan-price{display:flex;flex-wrap:wrap;align-items:baseline;gap:0 9px;margin:14px 0 0;font-size:17px;line-height:1.3;color:var(--ink-2)}
.lp-plan-price b{font-weight:400;font-size:46px;line-height:1;letter-spacing:-.03em;color:var(--ink)}
.lp-plan-alt{flex:0 0 100%;margin-top:6px;font-size:15.5px;color:var(--ink-2)}
.lp-plan-list{margin:18px 0 0;padding-top:18px;border-top:1px solid var(--line);gap:9px}
.lp-plan-lead{margin:18px 0 0;padding-top:18px;border-top:1px solid var(--line);font-size:15.5px;font-weight:600;color:var(--ink)}
.lp-plan-lead + .lp-plan-list{margin-top:10px;padding-top:0;border-top:0}
.lp-plan-list--bare{margin-top:0;padding-top:0;border-top:0}
.lp-plans--one{max-width:520px}
.lp-plan-list li{font-size:16px;line-height:1.4;color:var(--ink)}
.lp-ticks{margin-top:28px}
.lp-ticks li{text-wrap:balance}
.lp-member{max-width:520px;margin-left:auto;margin-right:auto;margin-top:24px}
.lp-member p{text-wrap:balance}
@media (min-width:700px){
  .lp-plan{padding:28px 28px 30px}
}
@media (min-width:980px){
  .lp-plans--three{grid-template-columns:repeat(3,minmax(0,1fr));gap:20px;max-width:1080px}
}
html.motion .lp-plan--plus.reveal{transition-delay:80ms}
html.motion .lp-plans--three .lp-plan.reveal:nth-child(3){transition-delay:160ms}
html.motion .lp-ticks li.reveal{transition-delay:160ms}
html.motion .lp-member.reveal{transition-delay:240ms}
/* the tick pops 200 ms after its line arrives */
html.motion .lp-ticks li.reveal::before{transition:transform 240ms var(--ease-spring) 360ms}
html.motion .lp-ticks li.reveal:not(.is-in)::before{transform:rotate(-45deg) scale(0)}

/* ============================= 7. WHERE IT WORKS ============================= */
/* Only the platforms SealNest is on sale for. Still: nothing here moves. */
.lp-where{padding:56px 0}
.lp-where .eyebrow{margin-bottom:0}
.lp-where .chips{margin-top:18px}
.lp-where .fine{margin-top:18px}

/* ================================= 8. CLOSE ================================= */
.lp-seal--close{--lp-seal-at:0ms;position:relative;left:auto;bottom:auto;margin:0 auto 30px}
html.motion .lp-close .store-row.reveal{transition-delay:80ms}

/* ============================ 9. SMALL SCREENS ============================ */
/* under 900 px the seven things wrap: four, then three */
@media (max-width:899.98px){
  .lp-stage{width:min(100%,444px)}
  .lp-things{flex-wrap:wrap;row-gap:14px}
  .lp-thing{flex:0 0 calc((100% - 48px) / 4)}
}
@media (max-width:640px){
  .lp-stage{width:min(100%,428px)}
  .lp-nest{padding:14px 14px 62px}
  .lp-thing{gap:6px}
  .lp-label{font-size:12px}
  .lp-seal{bottom:48px;width:96px;height:96px;margin-left:-48px}
  .lp-logo{width:40px;height:40px;margin-left:-20px;bottom:76px;border-radius:10px}
  .lp-logo img{border-radius:10px}
  .lp-seal--close{bottom:auto;margin:0 auto 26px}
  .lp-seal-mark{width:42px;height:42px;margin:-21px 0 0 -21px}
}
@media (max-width:399.98px){
  .lp-things{gap:10px;row-gap:12px}
  .lp-thing{flex-basis:calc((100% - 30px) / 4)}
}
