/* swapbook.online — landing v2 "night ledger", animated and interactive (owner 2026-11-06).
   Palette sampled from the owner's logo (2026-11-06): navy ground, cyan → violet → magenta.
   Cyan = our side of a swap, magenta = their side, the two together = a deal that closed.
   No third-party requests; the page reads complete without JavaScript and with reduced motion:
   html.js = JavaScript runs (widgets appear) · html.anim = motion is allowed (hidden start states live ONLY under .anim). */

@font-face{font-family:"Besley";src:url(fonts/besley-display.woff2) format("woff2");font-weight:700 800;font-style:normal;font-display:swap}
@font-face{font-family:"Besley";src:url(fonts/besley-italic.woff2) format("woff2");font-weight:500;font-style:italic;font-display:swap}
@font-face{font-family:"Libre Franklin";src:url(fonts/franklin-text.woff2) format("woff2");font-weight:400 800;font-style:normal;font-display:swap}
@font-face{font-family:"IBM Plex Mono";src:url(fonts/plexmono-400.woff2) format("woff2");font-weight:400;font-style:normal;font-display:swap}
@font-face{font-family:"IBM Plex Mono";src:url(fonts/plexmono-500.woff2) format("woff2");font-weight:500;font-style:normal;font-display:swap}
@font-face{font-family:"Montserrat";src:url(fonts/montserrat-wordmark.woff2) format("woff2");font-weight:800;font-style:normal;font-display:swap}

:root{
  --ground:#050b17;
  --panel:#0a1226;
  --bubble-in:#131c36;
  --bubble-out:#1a2550;
  --page-we:#0d1a3a;
  --page-they:#190f3a;
  --ink:#f3f5fb;
  --ink-2:#bdc6e0;
  --ink-3:#8590b4;
  --rule:rgba(189,198,224,.15);
  --rule-2:rgba(189,198,224,.28);
  --we:#45e6fa;
  --mid:#8f8bff;
  --they:#f266fb;
  --grad:linear-gradient(90deg,#45e6fa 0%,#7f9bff 42%,#b06cff 70%,#f266fb 100%);
  --m:56px;      /* the ledger margin column */
  --pad:16px;
  --edge:12px;   /* how close a pasted-in element comes to the screen edge */
  --display:"Besley",Georgia,"Times New Roman",serif;
  --text:"Libre Franklin",system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;
  --mono:"IBM Plex Mono",ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
}

*,*::before,*::after{box-sizing:border-box}
html{background:var(--ground);-webkit-text-size-adjust:100%;text-size-adjust:100%;scroll-behavior:smooth}
body{
  margin:0;color:var(--ink);font:400 17px/1.55 var(--text);
  background:
    radial-gradient(120% 100% at 0% 0%,rgba(13,56,97,.50),rgba(13,56,97,0) 62%),
    radial-gradient(110% 90% at 100% 0%,rgba(58,20,92,.46),rgba(58,20,92,0) 64%);
  background-repeat:no-repeat;background-size:100% 760px;
  -webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;
}
h1,h2,h3,p,ol,ul,dl,dd,dt,figure{margin:0;padding:0}
ol,ul{list-style:none}
img,svg{display:block}
b{font-weight:600}
[hidden]{display:none !important}
.sprite{position:absolute}
.s-we{stroke:var(--we)}.s-they{stroke:var(--they)}
.f-we{fill:var(--we)}.f-they{fill:var(--they)}
.ico{display:inline-block;vertical-align:baseline;flex:none}
.ico--swap{vertical-align:-2px;margin:0 3px}
.we{color:var(--we)}
.they{color:var(--they)}

.sheet{position:relative;max-width:720px;margin:0 auto;overflow-x:clip}

/* ---- top bar ---- */
.bar{
  position:sticky;top:0;z-index:30;display:flex;align-items:center;justify-content:space-between;gap:10px;min-height:64px;
  padding:max(8px,env(safe-area-inset-top)) var(--pad) 6px 12px;background:rgba(5,11,23,0);
  transition:background-color .25s ease,box-shadow .25s ease;
}
.bar.is-stuck{background:var(--ground);box-shadow:0 1px 0 var(--rule-2)}
.brand{display:inline-flex;align-items:center;gap:8px;color:var(--ink);text-decoration:none;-webkit-tap-highlight-color:transparent}
.brand__mark{display:block;width:58px}
.brand__mark .lg{width:100%}
.bar__cta{display:none}
.js .bar__cta{
  position:absolute;right:var(--pad);bottom:9px;  /* out of the flow: hidden, it must not push the bar wider than the screen */
  display:inline-flex;align-items:center;min-height:44px;padding:0 14px;border-radius:7px;background:var(--grad);color:#050b17;
  font:800 13.5px/1 var(--text);text-decoration:none;white-space:nowrap;
  opacity:0;transform:translateY(-8px);pointer-events:none;transition:opacity .25s ease,transform .25s ease;
}
.js .bar.show-cta .bar__cta{opacity:1;transform:none;pointer-events:auto}
.brand__name{font:800 21px/1 "Montserrat",var(--text);letter-spacing:-.01em}
.brand__name b{font-weight:800;background:var(--grad);-webkit-background-clip:text;background-clip:text;color:transparent}

/* ---- the page: everything sits right of the margin rule ---- */
main{position:relative;padding:0 var(--pad) 0 var(--m)}
main::before{
  content:"";position:absolute;top:0;bottom:0;left:calc(var(--m) - 10px);width:4px;
  border-left:1px solid rgba(69,230,250,.55);border-right:1px solid rgba(242,102,251,.55);
}
.bleed{margin-left:calc(var(--edge) - var(--m));margin-right:calc(var(--edge) - var(--pad))}
.mg{
  position:absolute;left:calc(-1 * var(--m));top:.2em;width:calc(var(--m) - 17px);
  text-align:right;font:500 10px/1.45 var(--mono);letter-spacing:0;color:var(--ink-3);white-space:nowrap;
}
.rows .mg{top:17px}  /* sits on the first line of its row */
.mg.we{color:var(--we)}
.mg.they{color:var(--they)}

/* ---- 1 · opening ---- */
.hero{padding:26px 0 0}
h1{font:800 clamp(30px,9.3vw,58px)/1.05 var(--display);letter-spacing:-.012em;text-wrap:balance}
.lead{margin-top:20px;font-size:18px;line-height:1.5;color:var(--ink-2);max-width:31em}
.act{margin-top:26px}
.cta{
  position:relative;overflow:hidden;display:inline-flex;align-items:center;gap:12px;min-height:56px;padding:0 22px;border-radius:8px;
  background:var(--grad);color:#050b17;font:800 17px/1.1 var(--text);text-decoration:none;
  box-shadow:0 10px 34px -12px rgba(143,139,255,.7);
  -webkit-tap-highlight-color:transparent;
}
.cta:active{transform:translateY(1px)}
.cta:focus-visible,.brand:focus-visible,.bar__cta:focus-visible,.kb button:focus-visible,.day button:focus-visible,.access__mark:focus-visible,.verdicts > div:focus-visible{outline:2px solid var(--ink);outline-offset:3px}
.note{margin-top:14px;font:400 12.5px/1.5 var(--mono);color:var(--ink-3)}

.tally{margin-top:38px;padding:0 0 22px}
.tally svg{width:100%;height:auto}
.tally__wide{display:none}
.tally path{fill:none;stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round}
.tally figcaption{margin:12px 0 0 calc(var(--m) - var(--edge));font:400 12.5px/1.4 var(--mono);color:var(--ink-3)}

/* ---- blocks ---- */
.blk{position:relative;padding:48px 0 4px}
.blk::before{  /* a ruled line across the whole sheet opens every block */
  content:"";position:absolute;top:0;left:calc(-1 * var(--m));right:calc(-1 * var(--pad));
  border-top:1px solid var(--rule-2);
}
h2{font:700 clamp(27px,7.7vw,42px)/1.1 var(--display);letter-spacing:-.008em;margin-bottom:20px;text-wrap:balance}
.blk > p{color:var(--ink-2);max-width:33em}
.blk > p.big{margin-top:22px;color:var(--ink);font-size:18px;line-height:1.45}
.blk > p.say{margin-top:26px;color:var(--ink);font:italic 500 21px/1.35 var(--display);max-width:22em}

.rows > li,.rows > div{position:relative;padding:11px 0 12px;border-top:1px solid var(--rule)}
.rows > li:last-child,.rows > div:last-child{border-bottom:1px solid var(--rule)}

/* 2 · five places */
.places li{display:grid;grid-template-columns:7.6em 1fr;column-gap:8px;align-items:baseline}
.places li > span:last-child{color:var(--ink-2)}
.chain{margin-top:22px;font:400 12.5px/1.4 var(--mono);color:var(--ink-2)}
.chain li{position:relative;padding:3px 0 3px 22px;white-space:nowrap}
.chain li::before{
  content:"";position:absolute;left:0;top:.72em;width:15px;height:8px;
  border-top:1.6px solid currentColor;
}
.chain li::after{
  content:"";position:absolute;left:9px;top:calc(.72em - 3.2px);width:7px;height:7px;
  border-top:1.6px solid currentColor;border-right:1.6px solid currentColor;transform:rotate(45deg);
}
.chain li:first-child{padding-left:0;color:var(--ink)}
.chain li:first-child::before,.chain li:first-child::after{content:none}
.chain li:nth-child(2)::before,.chain li:nth-child(2)::after{color:#45e6fa}
.chain li:nth-child(3)::before,.chain li:nth-child(3)::after{color:#6fb0ff}
.chain li:nth-child(4)::before,.chain li:nth-child(4)::after{color:#8f8bff}
.chain li:nth-child(5)::before,.chain li:nth-child(5)::after{color:#c06cfd}
.chain li:nth-child(6)::before,.chain li:nth-child(6)::after{color:#f266fb}

/* 3 · the chat, pasted into the book */
.chat{
  position:relative;z-index:1;background:var(--panel);border:1px solid var(--rule-2);border-radius:18px;
  padding:12px 12px 16px;
}
.who{font:400 11px/1 var(--mono);color:var(--ink-3);margin:8px 6px 6px}
.who--out{text-align:right}
.msg{position:relative;border-radius:16px}
.msg--out{width:fit-content;max-width:88%;margin-left:auto;background:var(--bubble-out);border-bottom-right-radius:5px;padding:9px 13px 10px}
.cmd{font:500 14.5px/1.7 var(--mono);color:var(--ink);overflow-wrap:break-word}
.js .cmd [data-k]{cursor:pointer;border-radius:5px;padding:5px 3px;margin:-5px -3px;transition:background-color .2s ease,opacity .2s ease;-webkit-tap-highlight-color:transparent}
.js .cmd.has-hl [data-k]{opacity:.42}
.js .cmd.has-hl [data-k].is-hl{opacity:1;background:rgba(189,198,224,.16)}
.says{margin:7px 6px 0;text-align:right;min-height:1.4em;font:400 12px/1.4 var(--mono);color:var(--ink-3)}
.says b{font-weight:500;color:var(--ink)}
.js .gloss > div{cursor:pointer;transition:background-color .2s ease}
.gloss > div.is-hl{background:linear-gradient(90deg,rgba(143,139,255,.16),rgba(143,139,255,0))}
.gloss > div.is-hl dd{color:var(--ink)}
.card{max-width:340px}
.msg--in{background:var(--bubble-in);border-bottom-left-radius:5px;padding:11px 13px 12px;font-size:15px;line-height:1.45;color:var(--ink)}
.card__head b{font-weight:700}
.card__pages{margin-bottom:.9em}
.card__ob .ico{margin-right:2px}
.card__ob + .card__ob{margin-top:2px}
.st{color:var(--ink-2)}
.st.is-done{color:var(--we)}
.st.is-no-show{color:var(--they)}
.kb{display:grid;gap:5px;margin-top:5px}
.kb__row{display:grid;grid-template-columns:1fr 1fr;gap:5px}
.kb__row.is-one{grid-template-columns:1fr}
.kb button{
  min-height:44px;padding:4px 8px;border:0;border-radius:9px;background:rgba(189,198,224,.13);color:var(--ink);
  font:500 14.5px/1.15 var(--text);cursor:pointer;-webkit-tap-highlight-color:transparent;touch-action:manipulation;
}
.kb button:active{background:rgba(189,198,224,.24)}
.hint{margin:12px 6px 0;font:400 12px/1.4 var(--mono);color:var(--ink-3)}

.gloss{margin-top:24px}
.gloss > div{display:grid;grid-template-columns:7.4em 1fr;column-gap:10px;align-items:baseline;padding:7px 0 8px}
.gloss dt{font:500 14px/1.5 var(--mono);color:var(--ink)}
.gloss dd{color:var(--ink-2);font-size:16px}
.gloss .mg{top:10px}

/* 4 · the reminders, timed down the margin */
.times li::before,.stages li::before{
  content:"";position:absolute;left:-12px;top:20px;width:8px;height:8px;border-radius:50%;
  background:var(--ground);border:1.6px solid var(--we);
}
.times li.minor p{color:var(--ink-2);font-size:16px}
.times li.minor::before{border-color:var(--ink-3)}

/* 5 · the spread: one deal, two entries */
.spread{
  position:relative;z-index:1;display:grid;grid-template-columns:1fr 1fr;margin-top:26px;
  background:var(--ground);border-radius:14px;
}
.spread__head{
  grid-column:1/-1;padding:0 4px 10px;text-align:center;font:500 14px/1.4 var(--mono);color:var(--ink);
  background:linear-gradient(var(--ground),var(--ground));
}
.pg{position:relative;padding:14px 12px 30px 14px}
.pg--we{background:var(--page-we);border-radius:12px 0 0 12px;border-top:2px solid var(--we);box-shadow:inset -14px 0 16px -14px rgba(0,0,0,.75)}
.pg--they{background:var(--page-they);border-radius:0 12px 12px 0;border-top:2px solid var(--they);box-shadow:inset 14px 0 16px -14px rgba(0,0,0,.75)}
.pg h3{font:600 13px/1.2 var(--text);letter-spacing:.02em;margin-bottom:12px}
.pg--we h3{color:var(--we)}
.pg--they h3{color:var(--they)}
.pg__what{font:700 20px/1.15 var(--display)}
.pg__when{margin-top:4px;font-size:14.5px;color:var(--ink)}
.pg__proof{margin-top:8px;padding-top:8px;border-top:1px dashed var(--rule-2);font:400 12px/1.4 var(--mono);color:var(--ink-2)}
/* a side is "done"; "delivered" is the deal's word, so one stamp sits across the gutter */
.pg__st{margin-top:10px;font:500 13px/1.3 var(--mono)}
.pg--we .pg__st{color:var(--we)}
.pg--they .pg__st{color:var(--they)}
.spread__stamp{grid-column:1/-1;justify-self:center;position:relative;z-index:1;margin-top:-18px}
.spread__foot{
  grid-column:1/-1;margin-top:10px;padding-top:9px;text-align:center;font:400 12.5px/1.4 var(--mono);color:var(--ink-2);
  border-top:3px double var(--rule-2);
}

/* the verdicts are stamps */
.stamp{
  --under:var(--ground);
  display:inline-block;padding:7px 10px 6px;border:2px solid currentColor;border-radius:5px;
  font:800 12.5px/1 var(--text);letter-spacing:.15em;text-transform:uppercase;white-space:nowrap;
  transform:rotate(-4deg);transform-origin:50% 50%;
}
.stamp > span{display:block;margin-right:-.15em}
.stamp--ok{
  border-color:transparent;
  background:linear-gradient(var(--under),var(--under)) padding-box,var(--grad) border-box;
  filter:drop-shadow(0 0 9px rgba(143,139,255,.38));
}
.stamp--ok > span{background:var(--grad);-webkit-background-clip:text;background-clip:text;color:transparent}
.stamp--short{
  color:var(--mid);transform:rotate(2.5deg);
  /* the ink runs short on the right */
  -webkit-mask-image:linear-gradient(90deg,#000 0,#000 58%,rgba(0,0,0,.3) 92%);
  mask-image:linear-gradient(90deg,#000 0,#000 58%,rgba(0,0,0,.3) 92%);
}
.stamp--no{color:var(--they);border-style:dashed;transform:rotate(-2deg);filter:drop-shadow(0 0 9px rgba(242,102,251,.3))}

.verdicts{margin-top:30px}
.verdicts > div{display:grid;grid-template-columns:132px 1fr;column-gap:8px;align-items:center;padding:14px 0;border-top:1px solid var(--rule)}
.verdicts > div:last-child{border-bottom:1px solid var(--rule)}
.verdicts dd{color:var(--ink-2);font-size:16px;line-height:1.45}

/* stamp landing on the demo card */
.stamp--land{--under:var(--bubble-in);position:absolute;right:-4px;top:-17px;z-index:2}

/* 6 · the refusals */
.nots p{color:var(--ink-2)}
.nots b{color:var(--ink);font-weight:600}
.nots .mg{top:16px;font-size:11px;color:var(--ink);letter-spacing:.08em;text-transform:uppercase}

/* 7 · now · next · later */
.stages .mg{font-size:10.5px}
.stages .is-now .mg{color:var(--ink)}
.stages .is-now::before{background:var(--we);box-shadow:0 0 10px rgba(69,230,250,.7)}
.stages .is-next p,.stages .is-later p{color:var(--ink-3)}
.stages .is-next::before{border-color:var(--ink-3)}
.stages .is-later::before{border-color:var(--ink-3);border-style:dotted}
.stages .is-next,.stages .is-later{border-top-style:dashed}
.stages li:last-child{border-bottom-style:dashed}

.access{padding:34px 0 10px}
.access__mark{display:block;width:min(250px,72%);margin:0 0 22px -6px;padding:0;border:0;background:none;cursor:pointer;-webkit-tap-highlight-color:transparent}
.access__mark .lg{width:100%}
.access .act{margin-top:2px}

.foot{padding:34px var(--pad) max(40px,env(safe-area-inset-bottom)) var(--m);font:400 11.5px/1.6 var(--mono);color:var(--ink-3);border-top:1px solid var(--rule-2);margin-top:26px}
.foot p{max-width:44em}

/* ---- wider phones ---- */
@media (min-width:380px){
  .chain{font-size:13.5px}
}
@media (min-width:400px){
  :root{--m:60px;--pad:20px}
}

/* ---- the wide version of the same page ---- */
@media (min-width:720px){
  :root{--m:112px;--pad:56px;--edge:40px}
  body{font-size:18px;background-size:100% 900px}
  .sheet{border-left:1px solid var(--rule);border-right:1px solid var(--rule)}
  .bar{padding:14px var(--pad) 8px 34px}
  .brand__mark{width:70px}
  .brand__name{font-size:25px}
  .hero{padding-top:44px}
  .lead{font-size:20px}
  .tally__narrow{display:none}
  .tally__wide{display:block}
  .tally{margin-top:54px}
  .blk{padding-top:76px}
  .mg{font-size:11.5px;width:calc(var(--m) - 24px)}
  .times li::before,.stages li::before{left:-12px}
  .chat{padding:18px 22px 22px}
  .chain{font-size:14.5px}
  .cmd{font-size:16px}
  .msg--in{font-size:16px}
  .card{max-width:400px}
  .pg{padding:20px 22px 34px 24px}
  .pg__what{font-size:24px}
  .stamp{font-size:13.5px}
  .verdicts > div{grid-template-columns:170px 1fr}
  .blk > p.say{font-size:24px}
  .access__mark{width:290px}
}

/* ---- narrow phones: when the compact action shows, the wordmark makes room ---- */
@media (max-width:429px){
  .js .bar.show-cta .brand__name{display:none}
}

/* ---- 4 · the day of one swap: six reminders, in the bot's words ---- */
.day{display:none}
.js .day{display:block;margin:0 0 20px}
.day__chips{position:relative;display:grid;grid-template-columns:repeat(6,1fr);border-bottom:1px solid var(--rule-2)}
.day__chips button{
  position:relative;min-height:46px;padding:0 0 8px;border:0;background:none;color:var(--ink-3);
  font:500 10.5px/1 var(--mono);cursor:pointer;-webkit-tap-highlight-color:transparent;touch-action:manipulation;
  transition:color .2s ease;
}
.day__chips button::after{
  content:"";position:absolute;left:50%;bottom:-5px;width:8px;height:8px;margin-left:-4px;border-radius:50%;
  background:var(--ground);border:1.6px solid var(--ink-3);transition:background-color .2s ease,border-color .2s ease,box-shadow .2s ease;z-index:1;
}
.day__chips button.is-past{color:var(--ink-2)}
.day__chips button.is-past::after{border-color:var(--we);background:var(--we)}
.day__chips button[aria-selected="true"]{color:var(--ink)}
.day__chips button[aria-selected="true"]::after{border-color:#fff;background:#fff;box-shadow:0 0 0 4px rgba(143,139,255,.35),0 0 14px rgba(143,139,255,.9)}
.day__line{position:absolute;left:0;right:0;bottom:-1.5px;height:2px;background:var(--grad);transform-origin:0 50%;transform:scaleX(.0833);transition:transform .45s cubic-bezier(.3,.7,.2,1)}
.day__note{margin-top:16px;background:var(--bubble-in);border-radius:16px 16px 16px 5px;padding:9px 13px 12px}
.day__note .who{margin:0 0 5px}
.day__msgs{display:grid}
.day__msg{grid-area:1/1;font-size:15px;line-height:1.45;color:var(--ink);opacity:0;visibility:hidden;transform:translateY(6px);transition:opacity .3s ease,transform .3s ease,visibility 0s linear .3s}
.day__msg.is-on{opacity:1;visibility:visible;transform:none;transition:opacity .3s ease .08s,transform .3s ease .08s,visibility 0s}
.day__msg b{font-weight:700}
.times li{transition:background-color .3s ease}
.times li.is-live{background:linear-gradient(90deg,rgba(69,230,250,.12),rgba(69,230,250,0))}
.times li.is-live p{color:var(--ink)}
.times li.is-live .mg{color:var(--ink)}

/* ---- 5 · the verdicts restamp the spread ---- */
.js .verdicts > div{cursor:pointer;-webkit-tap-highlight-color:transparent;transition:background-color .25s ease}
.verdicts > div[aria-pressed="true"]{background:linear-gradient(90deg,rgba(143,139,255,.15),rgba(143,139,255,0))}
.verdicts > div[aria-pressed="true"] dd{color:var(--ink)}
.spread[data-v="short"] [data-they-st],.spread[data-v="no-show"] [data-they-st]{color:var(--ink)}
.spread[data-v="no-show"] [data-they-proof]{visibility:hidden}
.spread__stamp.stamp--short{--under:var(--ground);background:var(--ground)}
.spread__stamp.stamp--no{background:var(--ground)}
.blk > p.hint{margin:12px 0 0;font:400 12px/1.4 var(--mono);color:var(--ink-3)}

/* ==== motion ====  everything below needs html.anim, except the widgets' own state changes above */

/* the timeline: the double rule fills as the page is read, the marker is "now" */
.rail{display:none;position:absolute;top:0;bottom:0;left:calc(var(--m) - 10px);width:4px;pointer-events:none}
.anim .rail{display:block}
.rail__fill{position:absolute;inset:0;border-left:1px solid var(--we);border-right:1px solid var(--they);transform-origin:50% 0;transform:scaleY(0);will-change:transform}
.rail__now{
  position:absolute;left:50%;top:0;width:11px;height:11px;margin:-5.5px 0 0 -5.5px;border-radius:50%;
  background:linear-gradient(90deg,var(--we),var(--they));box-shadow:0 0 0 3px rgba(5,11,23,.9),0 0 14px 3px rgba(143,139,255,.85);will-change:transform;
}
.anim main::before{opacity:.45}
.anim .rows > * > .mg,.anim .rows > * > dt > .mg{transition:opacity .3s ease,color .3s ease}
.anim .rows:not(.stages) > :not(.t-past) > .mg,.anim .rows > :not(.t-past) > dt > .mg{opacity:.5}
.anim .rows > .t-now > .mg,.anim .rows > .t-now > dt > .mg{color:#fff}
.anim .times li::before,.anim .stages li::before{transition:background-color .3s ease,box-shadow .3s ease,border-color .3s ease}
.anim .times li.t-past::before{background:var(--we)}
.anim .times li.t-now::before{background:#fff;border-color:#fff;box-shadow:0 0 12px 2px rgba(143,139,255,.9)}

/* reveal: rows are written as the reader reaches them */
.anim .rv{opacity:0;transform:translateY(14px)}
.anim .rv.is-in{opacity:1;transform:none;transition:opacity .55s cubic-bezier(.2,.7,.2,1) var(--d,0ms),transform .65s cubic-bezier(.2,.7,.2,1) var(--d,0ms)}
.anim .w{display:inline-block;opacity:0;transform:translateY(.42em)}
.anim .is-in > .w{opacity:1;transform:none;transition:opacity .5s ease-out calc(var(--i) * 55ms),transform .6s cubic-bezier(.2,.7,.2,1) calc(var(--i) * 55ms)}

/* the tally is ruled by hand, gate after gate */
.anim .tally path{stroke-dasharray:1;stroke-dashoffset:1}
.anim .tally.is-in path{stroke-dashoffset:0;transition:stroke-dashoffset .5s ease-out var(--d,0ms)}

/* the main button: a glint and a nudge */
.anim .cta::before{
  content:"";position:absolute;top:0;bottom:0;left:0;width:46%;
  background:linear-gradient(100deg,rgba(255,255,255,0),rgba(255,255,255,.55),rgba(255,255,255,0));
  transform:translateX(-130%) skewX(-12deg);animation:glint 6.5s ease-in-out 1.6s infinite;
}
@keyframes glint{0%{transform:translateX(-130%) skewX(-12deg)}16%,100%{transform:translateX(330%) skewX(-12deg)}}
.anim .cta .ico{animation:nudge 1.9s ease-in-out infinite}
@keyframes nudge{0%,100%{transform:none}50%{transform:translateX(5px)}}

/* the chain never ends: the steps light up in turn */
.anim .chain.is-live li{animation:step 5.4s linear infinite}
.anim .chain.is-live li:nth-child(2){animation-delay:.9s}
.anim .chain.is-live li:nth-child(3){animation-delay:1.8s}
.anim .chain.is-live li:nth-child(4){animation-delay:2.7s}
.anim .chain.is-live li:nth-child(5){animation-delay:3.6s}
.anim .chain.is-live li:nth-child(6){animation-delay:4.5s}
@keyframes step{0%,15%{color:#fff}17%,100%{color:var(--ink-2)}}
.anim .chain li:first-child{color:var(--ink-2)}

/* the line types itself, the card arrives */
.js .cmd .ch{opacity:0}
.js .cmd .ch.on{opacity:1}
.js .card.is-waiting{opacity:0;transform:translateY(8px)}
.js .card{transition:opacity .28s ease-out,transform .28s ease-out}
.js .card.is-hit{animation:hit .32s ease-out}
@keyframes hit{30%{transform:translate(-2px,1px)}60%{transform:translate(2px,0)}}

/* stamps land */
.anim [data-thump].is-waiting{opacity:0}
.anim [data-thump].is-in,.js .stamp.is-in{animation:thump .24s cubic-bezier(.2,.9,.3,1.25) both}
@keyframes thump{from{opacity:0;scale:1.8}to{opacity:1;scale:1}}

/* the book opens */
.anim .spread{perspective:1100px}
.anim .spread .pg{transition:transform .9s cubic-bezier(.2,.75,.2,1),opacity .5s ease-out;backface-visibility:hidden}
.anim .spread .pg--we{transform-origin:100% 50%}
.anim .spread .pg--they{transform-origin:0 50%}
.anim .spread:not(.is-open) .pg--we{transform:rotateY(82deg);opacity:0}
.anim .spread:not(.is-open) .pg--they{transform:rotateY(-82deg);opacity:0}
.anim .spread .spread__head,.anim .spread .spread__foot,.anim .spread .pg > *{transition:opacity .5s ease-out .55s}
.anim .spread:not(.is-open) .spread__head,.anim .spread:not(.is-open) .spread__foot,.anim .spread:not(.is-open) .pg > *{opacity:0}
.anim .spread:not(.is-stamped) .spread__stamp{opacity:0}

/* "now" is live */
.anim .stages .is-now::after{
  content:"";position:absolute;left:-12px;top:20px;width:8px;height:8px;border-radius:50%;border:1.5px solid var(--we);
  animation:ping 2.6s ease-out infinite;
}
@keyframes ping{0%{transform:scale(1);opacity:.9}70%,100%{transform:scale(3.4);opacity:0}}

@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *,*::before,*::after{animation:none !important;transition:none !important}
}

/* The SwapBook emblem (v2/logo.py). Lengths inside the SVG are in its own user units (viewBox 1090x880).
   Static by default; motion only under html.anim (JavaScript on, no reduced motion):
   .is-drawn  the strokes draw on once            .is-ready (set after the draw) + .is-live (on screen):
              the light runs B -> S and the arrows trade the brand colours
   .is-swap   a short burst on tap */

.lg{display:block;height:auto;overflow:visible}
.lg__book{fill:none;stroke-linejoin:round;stroke-linecap:round}
.lg__cover{stroke-width:16}
.lg__stack{stroke-width:7;opacity:.65}
.lg__page{stroke-width:10}
.lg__page--l{fill:#0d1a3a}
.lg__page--r{fill:#190f3a}
.lg__o{fill:none;stroke:#060b1a;stroke-width:100;stroke-linejoin:round}
.lg__c{fill:none;stroke-width:66;stroke-linejoin:round}
.lg__f{fill:none;stroke:#fff;stroke-width:20;stroke-linecap:round;stroke-dasharray:.13 1;stroke-dashoffset:.14;opacity:0}
.lg__h{stroke:#060b1a;stroke-width:16;stroke-linejoin:round;paint-order:stroke}
.lg__h--1{transform-origin:452px 210px}
.lg__h--2{transform-origin:290px 505px}

/* small sizes: fewer, heavier lines */
.lg--s .lg__stack{display:none}
.lg--s .lg__cover{stroke-width:30}
.lg--s .lg__page{stroke-width:20}
.lg--s .lg__o{stroke-width:104}
.lg--s .lg__c{stroke-width:70}
.lg--l{filter:drop-shadow(0 0 16px rgba(143,123,255,.45))}

/* ---- draw-on, once ---- */
.anim .lg .lg__c,.anim .lg .lg__o{stroke-dasharray:1;stroke-dashoffset:1}
.anim .lg .lg__h{transform:scale(0)}
.anim .lg .lg__book{opacity:0}
.anim .lg.is-drawn .lg__book{opacity:1;transition:opacity .5s ease-out}
.anim .lg.is-drawn .lg__c,.anim .lg.is-drawn .lg__o{stroke-dashoffset:0;transition:stroke-dashoffset .7s cubic-bezier(.5,0,.2,1)}
.anim .lg.is-drawn .lg__c--b,.anim .lg.is-drawn .lg__o--b{transition-delay:.25s}
.anim .lg.is-drawn .lg__c--a2,.anim .lg.is-drawn .lg__o--a2{transition-delay:.6s;transition-duration:.9s}
.anim .lg.is-drawn .lg__c--a1,.anim .lg.is-drawn .lg__o--a1{transition-delay:1.05s}
.anim .lg.is-drawn .lg__h{transform:scale(1);transition:transform .32s cubic-bezier(.2,.9,.3,1.4)}
.anim .lg.is-drawn .lg__h--2{transition-delay:1.42s}
.anim .lg.is-drawn .lg__h--1{transition-delay:1.68s}

/* ---- alive: the light runs from the B into the S; the two arrows trade the brand colours ---- */
.anim .lg.is-ready.is-live .lg__f--b{animation:lg-run-b 5.2s linear infinite}
.anim .lg.is-ready.is-live .lg__f--a2{animation:lg-run-a2 5.2s linear infinite}
.anim .lg.is-ready.is-live .lg__f--a1{animation:lg-run-a1 5.2s linear infinite}
@keyframes lg-run-b{0%{stroke-dashoffset:.14;opacity:.75}26%{stroke-dashoffset:-1;opacity:.75}26.1%,100%{stroke-dashoffset:-1;opacity:0}}
@keyframes lg-run-a2{0%,17.9%{stroke-dashoffset:.14;opacity:0}18%{stroke-dashoffset:.14;opacity:.8}60%{stroke-dashoffset:-1;opacity:.8}60.1%,100%{stroke-dashoffset:-1;opacity:0}}
@keyframes lg-run-a1{0%,45.9%{stroke-dashoffset:.14;opacity:0}46%{stroke-dashoffset:.14;opacity:.8}72%{stroke-dashoffset:-1;opacity:.8}72.1%,100%{stroke-dashoffset:-1;opacity:0}}
/* one cycle cyan -> violet -> magenta and back (9 s there and back); the four stops ride it a quarter apart:
   head of the S-arrow, its tail, head of the B-arrow, its tail. When the heads meet in violet the tails are at
   cyan and magenta, so the emblem is never one flat colour. */
.anim .lg.is-ready.is-live .lg-a,.anim .lg.is-ready.is-live .lg-at,.anim .lg.is-ready.is-live .lg-b,.anim .lg.is-ready.is-live .lg-bt{animation:lg-cycle 4.5s ease-in-out infinite alternate}
.anim .lg.is-ready.is-live .lg-at{animation-delay:-2.25s}
.anim .lg.is-ready.is-live .lg-b{animation-delay:-4.5s}
.anim .lg.is-ready.is-live .lg-bt{animation-delay:-6.75s}
@keyframes lg-cycle{0%{stop-color:#45e6fa}50%{stop-color:#8f7bff}100%{stop-color:#f266fb}}

/* ---- a tap: both arrows fire at once ---- */
.anim .lg.is-swap .lg__f--b,.anim .lg.is-swap .lg__f--a2,.anim .lg.is-swap .lg__f--a1{animation:lg-burst .9s linear both}
@keyframes lg-burst{0%{stroke-dashoffset:.14;opacity:.9}99%{stroke-dashoffset:-1;opacity:.9}100%{stroke-dashoffset:-1;opacity:0}}
.anim .lg.is-swap .lg__h--1{animation:lg-nudge-1 .6s cubic-bezier(.3,0,.2,1) .25s}
.anim .lg.is-swap .lg__h--2{animation:lg-nudge-2 .6s cubic-bezier(.3,0,.2,1) .25s}
@keyframes lg-nudge-1{50%{transform:translate(16px,22px) scale(1.08)}}
@keyframes lg-nudge-2{50%{transform:translate(-19px,-19px) scale(1.08)}}
