/* ============================================================================
   Maison — site design system
   Ported from the deck system: same palette, same type roles, no gradients.
   ========================================================================= */

:root{
  --ink:#0a0a0f;
  --ink-2:#12121a;
  --paper:#f7f6f2;
  --paper-2:#fffefb;
  --violet:#9b7aff;
  --violet-deep:#6b4fd8;
  --signal:#c9a227;
  --teal:#3f9c94;
  --g1:#4a4a58;
  --g2:#6e6e7d;
  --g3:#9a9aa6;
  --rule:rgba(10,10,15,.14);
  --rule-d:rgba(255,255,255,.16);

  --serif:ui-serif,"New York",Iowan Old Style,Palatino,Georgia,serif;
  --sans:-apple-system,BlinkMacSystemFont,"SF Pro Text","Segoe UI","Helvetica Neue",Helvetica,Arial,sans-serif;
  --mono:ui-monospace,SFMono-Regular,"SF Mono",Menlo,Consolas,monospace;

  --pad:clamp(20px,5vw,78px);
  --maxw:1240px;
}

*{box-sizing:border-box;margin:0;padding:0}
html{scroll-behavior:smooth;-webkit-text-size-adjust:100%}
body{
  background:var(--paper);color:var(--ink);font-family:var(--sans);
  -webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;
  overflow-x:hidden;
}
img,svg,video{display:block;max-width:100%}
a{color:inherit;text-decoration:none}
::selection{background:var(--violet);color:#fff}

/* ---------- layout ---------- */
.wrap{max-width:var(--maxw);margin:0 auto;padding:0 var(--pad)}
section{padding:clamp(52px,9vw,124px) 0}
.dark{background:var(--ink);color:var(--paper)}
.tint{background:#edeae2}

/* ---------- type ---------- */
h1,h2,h3{font-family:var(--serif);font-weight:600;letter-spacing:-.02em;line-height:1.06}
h1{font-size:clamp(37px,8.2vw,104px);letter-spacing:-.032em}
h2{font-size:clamp(27px,4.6vw,58px);line-height:1.1}
h3{font-size:clamp(19px,2.4vw,30px);line-height:1.16;letter-spacing:-.018em}
p{font-size:clamp(15px,1.35vw,20px);line-height:1.55;color:var(--g1)}
.dark p{color:rgba(247,246,242,.74)}
strong{font-weight:650;color:var(--ink)}
.dark strong{color:#fff}

.eyebrow{
  font-family:var(--sans);font-size:clamp(11px,.95vw,12.5px);letter-spacing:.2em;text-transform:uppercase;
  font-weight:700;color:var(--violet-deep);margin-bottom:clamp(14px,1.7vw,22px);display:block;
}
.dark .eyebrow{color:var(--violet)}
.lede{font-size:clamp(16px,1.8vw,25px);line-height:1.45;color:var(--g1);max-width:56ch}
.dark .lede{color:rgba(247,246,242,.8)}
.small{font-size:clamp(13px,1.1vw,15px);line-height:1.5;color:var(--g2)}
.dark .small{color:rgba(247,246,242,.55)}
.rule{height:1px;background:var(--rule);border:0}
.dark .rule{background:var(--rule-d)}

/* the deck's signature emphasis device */
.band{border-left:3px solid var(--violet-deep);padding:8px 0 8px clamp(20px,2.4vw,28px)}
.dark .band{border-left-color:var(--violet)}
.band p{font-size:clamp(17px,2.1vw,27px);line-height:1.34;font-weight:600;color:var(--ink)}
.dark .band p{color:#fff}

/* ---------- buttons ---------- */
.btn{
  display:inline-flex;align-items:center;gap:10px;font-family:var(--sans);
  font-size:clamp(14.5px,1.2vw,16px);font-weight:650;letter-spacing:-.01em;
  padding:clamp(12px,1.15vw,15px) clamp(20px,1.95vw,26px);border-radius:100px;
  border:1px solid transparent;transition:transform .18s ease,background .18s ease,border-color .18s ease;
  cursor:pointer;white-space:nowrap;
}
.btn:hover{transform:translateY(-1px)}
.btn-primary{background:var(--violet-deep);color:#fff}
.btn-primary:hover{background:#5a40c4}
.dark .btn-primary{background:var(--violet);color:#14101f}
.dark .btn-primary:hover{background:#ac90ff}
.btn-ghost{border-color:var(--rule);color:var(--ink)}
.btn-ghost:hover{border-color:var(--ink)}
.dark .btn-ghost{border-color:rgba(255,255,255,.30);color:var(--paper)}
.dark .btn-ghost:hover{border-color:rgba(255,255,255,.5)}
.btns{display:flex;flex-wrap:wrap;gap:13px}

/* ---------- mark ---------- */
.mark path,.mark circle{stroke:currentColor}
.mark .core{fill:var(--violet);stroke:none}

/* ---------- nav ---------- */
.nav{
  position:fixed;top:0;left:0;right:0;z-index:100;
  transition:background .3s ease,border-color .3s ease,backdrop-filter .3s ease;
  border-bottom:1px solid transparent;
}
.nav.solid{background:rgba(10,10,15,.86);backdrop-filter:saturate(180%) blur(18px);border-bottom-color:var(--rule-d)}
.nav__in{max-width:var(--maxw);margin:0 auto;padding:14px var(--pad);display:flex;align-items:center;gap:14px}
.nav__brand{display:flex;align-items:center;gap:11px;color:#fff}
.nav__brand svg{width:31px;height:31px;flex:0 0 auto}
.nav__name{font-weight:650;font-size:clamp(15.5px,1.3vw,17px);letter-spacing:-.015em}
.nav__sp{flex:1}
.nav__links{display:flex;align-items:center;gap:30px}
.nav__links a{font-size:14.5px;font-weight:550;color:rgba(247,246,242,.66);transition:color .18s}
.nav__links a:hover{color:#fff}
.nav .btn{padding:clamp(9px,.9vw,10px) clamp(15px,1.5vw,19px);font-size:clamp(13px,1.15vw,14.5px)}
.nav__links a.on{color:#fff}
/* The access CTA lives outside the links on desktop; inside the panel on mobile. */
.nav__mcta{display:none}
.nav__burger{display:none;width:38px;height:38px;border:0;background:none;cursor:pointer;
  flex-direction:column;justify-content:center;align-items:flex-end;gap:6px;padding:0}
.nav__burger span{display:block;width:22px;height:1.5px;background:rgba(247,246,242,.8);
  transition:transform .25s ease,opacity .2s ease}
.nav.open .nav__burger span:first-child{transform:translateY(3.75px) rotate(45deg)}
.nav.open .nav__burger span:last-child{transform:translateY(-3.75px) rotate(-45deg)}

/* ---------- the living project brief, as shown inside a frame ---------- */
.brief{padding:14px 0;border-bottom:1px solid var(--rule)}
.brief:first-child{padding-top:0}
.brief:last-child{border-bottom:0;padding-bottom:0}
.brief__k{display:block;font-size:10.5px;letter-spacing:.16em;text-transform:uppercase;
  font-weight:800;color:var(--violet-deep);margin-bottom:6px}
.brief p{font-size:clamp(13px,1.2vw,14.5px);line-height:1.5;color:var(--g1)}

/* Five nav items plus the CTA need more room than four did. */
@media(max-width:1040px){
  .nav__burger{display:flex}
  .nav__cta{display:none}
  .nav__links{
    position:fixed;left:0;right:0;top:0;padding:74px var(--pad) 26px;
    background:rgba(10,10,15,.97);backdrop-filter:saturate(180%) blur(18px);
    border-bottom:1px solid var(--rule-d);
    flex-direction:column;align-items:flex-start;gap:0;z-index:-1;
    transform:translateY(-102%);transition:transform .32s cubic-bezier(.22,.61,.36,1);
  }
  .nav.open .nav__links{transform:none}
  .nav__links a{font-size:19px;font-weight:550;width:100%;padding:13px 0;
    border-bottom:1px solid rgba(255,255,255,.08);color:rgba(247,246,242,.82)}
  .nav__links a:last-of-type{border-bottom:0}
  .nav__links a.nav__mcta{display:block;margin-top:20px;text-align:center;border-bottom:0;
    background:var(--violet);color:var(--ink);font-size:16px;font-weight:650;
    border-radius:999px;padding:14px 0}
  .nav__links .btn{margin-top:16px;width:100%;justify-content:center}
}

/* ---------- two-column ledger: what it can do vs what it cannot ---------- */
.ledger{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:clamp(16px,2vw,26px)}
@media(max-width:760px){.ledger{grid-template-columns:minmax(0,1fr)}}
.ledger ul{list-style:none;margin-top:18px}
.ledger li{position:relative;padding-left:28px;margin-bottom:12px;
  font-size:clamp(14.5px,1.25vw,16.5px);line-height:1.5;color:rgba(247,246,242,.74)}
.ledger li:before{content:"";position:absolute;left:0;top:7px;width:13px;height:13px;
  border-radius:50%;border:1.5px solid var(--violet)}
.ledger .no li:before{border-color:rgba(255,255,255,.26)}
.ledger .no li{color:rgba(247,246,242,.46)}

/* ---------- checked list that reads on light AND dark sections ----------
   .ledger is dark-only: its li color is white, so the same markup on a light
   section renders invisible. This is the same mark, defined light-first with a
   dark override, so a list can move between sections without changing class. */
.marks{list-style:none;margin-top:18px}
.marks li{position:relative;padding-left:28px;margin-bottom:12px;
  font-size:clamp(14.5px,1.25vw,16.5px);line-height:1.5;color:var(--g1)}
.marks li:before{content:"";position:absolute;left:0;top:7px;width:13px;height:13px;
  border-radius:50%;border:1.5px solid var(--violet-deep)}
.dark .marks li{color:rgba(247,246,242,.74)}
.dark .marks li:before{border-color:var(--violet)}

/* ---------- download rows ---------- */
.dl{display:flex;align-items:center;gap:clamp(14px,2vw,22px);padding:clamp(18px,2vw,24px) 0;
  border-top:1px solid var(--rule-d)}
.dl:last-of-type{border-bottom:1px solid var(--rule-d)}
.dl__b{flex:1;min-width:0}
.dl__b h3{margin-bottom:6px}
.dl__b p{font-size:clamp(13.5px,1.15vw,15.5px);line-height:1.45}
.dl__m{font-size:12px;letter-spacing:.14em;text-transform:uppercase;font-weight:700;
  color:var(--g3);margin-top:9px;display:block}

/* ---------- passphrase gate ---------- */
.gate{min-height:100svh;display:flex;align-items:center;justify-content:center;
  background:var(--ink);color:var(--paper);padding:var(--pad);position:relative;overflow:hidden}
.gate__in{position:relative;width:100%;max-width:430px;text-align:center}
.gate__in .mark{width:52px;height:52px;margin:0 auto 26px;color:#fff}
.gate form{display:flex;gap:9px;margin-top:26px}
.gate input{flex:1;min-width:0;font-family:var(--sans);font-size:16px;color:var(--paper);
  background:rgba(255,255,255,.05);border:1px solid var(--rule-d);border-radius:100px;
  padding:14px 20px;outline:none;transition:border-color .18s}
.gate input:focus{border-color:var(--violet)}
.gate input::placeholder{color:rgba(247,246,242,.36)}
.gate__err{margin-top:16px;font-size:14px;color:#e0777c;min-height:20px}

@media(max-width:860px){.headrow{grid-template-columns:1fr;align-items:start}}

/* ---------- hero ---------- */
.hero{position:relative;min-height:100svh;display:flex;align-items:flex-end;
  background:var(--ink);color:var(--paper);overflow:hidden;isolation:isolate;padding:0}
.hero__v{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;z-index:-2;opacity:.72}
.hero__scrim{position:absolute;inset:0;z-index:-1;
  background:
    radial-gradient(110% 80% at 8% 92%, rgba(10,10,15,.98) 0%, rgba(10,10,15,.72) 42%, rgba(10,10,15,0) 78%),
    linear-gradient(to top, rgba(10,10,15,.96) 2%, rgba(10,10,15,.34) 46%, rgba(10,10,15,.60) 100%);
}
.hero__in{width:100%;max-width:var(--maxw);margin:0 auto;padding:0 var(--pad) clamp(56px,8vh,104px);
  position:relative}
.hero h1{max-width:15ch;color:#fff}
.hero .lede{margin-top:clamp(20px,2.6vw,30px);max-width:50ch;color:rgba(247,246,242,.85)}
.hero .btns{margin-top:clamp(26px,3.4vw,38px)}
.hero__foot{margin-top:clamp(34px,5vh,58px);display:flex;flex-wrap:wrap;gap:12px 34px;align-items:center}
.hero__foot span{font-size:clamp(12px,1.1vw,13.5px);color:rgba(247,246,242,.5);display:flex;align-items:center;gap:9px}
.hero__foot i{width:5px;height:5px;border-radius:50%;background:var(--violet);display:block;flex:0 0 auto}
.scrollcue{position:absolute;right:var(--pad);bottom:clamp(56px,8vh,104px);
  writing-mode:vertical-rl;font-size:11px;letter-spacing:.24em;text-transform:uppercase;
  color:rgba(247,246,242,.34);font-weight:700}
@media(max-width:700px){.scrollcue{display:none}}

/* ---------- section head ---------- */
.head{max-width:22ch}
.head.wide{max-width:30ch}
.headrow{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:clamp(28px,5vw,72px);align-items:end}
@media(max-width:880px){.headrow{grid-template-columns:minmax(0,1fr);align-items:start}}

/* ---------- grids & cards ---------- */
.grid{display:grid;gap:clamp(16px,2vw,26px)}
.g2{grid-template-columns:repeat(2,minmax(0,1fr))}
.g3{grid-template-columns:repeat(3,minmax(0,1fr))}
.g4{grid-template-columns:repeat(4,minmax(0,1fr))}
@media(max-width:980px){.g3,.g4{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media(max-width:640px){.g2,.g3,.g4{grid-template-columns:minmax(0,1fr)}}

.card{border:1px solid var(--rule);border-radius:16px;padding:clamp(22px,2.4vw,30px);
  background:var(--paper-2);transition:border-color .2s ease,transform .2s ease}
.card:hover{border-color:rgba(107,79,216,.4);transform:translateY(-2px)}
.dark .card{border-color:var(--rule-d);background:rgba(255,255,255,.038)}
.dark .card:hover{border-color:rgba(155,122,255,.44)}
.card h3{margin-bottom:clamp(8px,.9vw,11px)}
.card p{font-size:clamp(14.5px,1.25vw,16.5px);line-height:1.5}
.card .n{font-family:var(--serif);font-size:15px;font-weight:600;color:var(--violet-deep);
  display:block;margin-bottom:14px;letter-spacing:.04em}
.dark .card .n{color:var(--violet)}

/* ---------- go-deeper row ----------
   The six article links under the four cards. Pills, not a bold paragraph:
   the cards are the argument and these are the footnotes. */
.deeper{display:grid;grid-template-columns:auto minmax(0,1fr);gap:14px clamp(22px,3vw,40px);
  align-items:start;padding-top:clamp(22px,2.6vw,32px);border-top:1px solid var(--rule)}
.deeper__l{font-family:var(--serif);font-size:clamp(15px,1.3vw,18px);font-weight:600;
  color:var(--violet-deep);letter-spacing:.02em;padding-top:8px;white-space:nowrap}
.deeper__links{display:flex;flex-wrap:wrap;gap:9px}
.deeper__links a{font-size:13.5px;font-weight:600;color:var(--g1);padding:8px 15px;
  border:1px solid var(--rule);border-radius:100px;background:var(--paper-2);
  transition:border-color .18s,color .18s,transform .18s}
.deeper__links a:hover{color:var(--ink);border-color:rgba(107,79,216,.5);transform:translateY(-1px)}
.deeper__p{grid-column:2;font-size:14px;color:var(--g1);margin-top:2px}
.deeper__p a{color:var(--violet-deep);text-decoration:underline;text-underline-offset:3px}
.dark .deeper{border-top-color:var(--rule-d)}
.dark .deeper__l{color:var(--violet)}
.dark .deeper__links a{color:rgba(247,246,242,.72);border-color:rgba(255,255,255,.17);background:rgba(255,255,255,.038)}
.dark .deeper__links a:hover{color:#fff;border-color:rgba(255,255,255,.42)}
.dark .deeper__p a{color:var(--violet)}
@media(max-width:760px){.deeper{grid-template-columns:minmax(0,1fr)}.deeper__l{white-space:normal;padding-top:0}.deeper__p{grid-column:1}}

/* ---------- feature rows ---------- */
/* The embedded investor demo. The phone itself is drawn by the node inside the frame, so all
   this owns is where it sits and how much room it gets. Height drives the size: the framed page
   scales the device to whatever height it is given, so one value controls the whole thing.
   The 900px breakpoint matches .row so the two stack together rather than at different widths. */
.demo{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,440px);gap:clamp(30px,6vw,72px);align-items:start}
.demo__c p{margin-bottom:18px}
.demo__c p:last-child{margin-bottom:0}
.demo__p{display:flex;flex-direction:column;align-items:center;gap:12px}
.demo__p iframe{width:100%;max-width:440px;height:min(760px,80vh);border:0;display:block;
  background:transparent;transition:height .38s cubic-bezier(.22,.61,.36,1)}
/* 🩸 svh, NOT vh, AND THE ORDER MATTERS. On iOS Safari `vh` is measured against the LARGE
   viewport, the one you only get once the address bar has scrolled away, so a frame sized in vh
   is taller than what is actually on screen and the bottom of the phone sits below the fold.
   Peter, 2026-08-27: "I have to scroll up and down within the frame." `svh` is the SMALL
   viewport, address bar showing, which is the height that is guaranteed visible. The vh rule
   above stays as the fallback for anything that does not know svh and is harmlessly overridden
   where it does. */
.demo__p iframe{height:min(760px,82svh)}
/* 🩸 THE HEIGHT IS OURS IN EVERY STAGE. There used to be a negotiation here: before the account
   existed the frame measured its sign-up panel and posted the number, because a ~400px form
   marooned at the top of a 700px hole looked broken. Since 2026-08-27 evening the sign-in is drawn
   INSIDE the same phone as the app, so there is one height and it is this one. The frame now posts
   height 0 in every stage, the script removes its inline height, and this rule decides. */
.demo__f a{text-decoration:underline}
@media(max-width:900px){
  .demo{grid-template-columns:minmax(0,1fr);gap:34px}
  /* Phone first on a narrow screen: it is the thing they came to see, and the copy reads as a
     caption underneath rather than a wall to get through first. */
  .demo__p{order:-1}
  .demo__p iframe{height:min(780px,78vh)}
  .demo__p iframe{height:min(780px,80svh)}
}
/* Phone. Below 460px the frame switches the device from a scaled 414px object to a fluid one that
   takes whatever column it is given, so the max-width no longer has anything to center inside it.
   Give it the column and give it the screen: the bezel stays, the wasted margin does not. */
@media(max-width:520px){
  .demo__p iframe{max-width:none;height:min(860px,84vh)}
  /* 🩸 THE FRAME IS PHONE-SHAPED, NOT VIEWPORT-SHAPED. Sizing it as a fraction of the viewport
     height made the device inside roughly 1.6:1 where a real iPhone is 2.1:1: short and wide,
     and too short for the sign-in, which then had to shrink its own type to fit. Peter, with the
     two screenshots side by side: "making it smaller makes it not look like a phone. Making the
     vertical box longer makes it look like a phone and makes it so you don't have to scroll."
     Deriving the height from the WIDTH at the device's own ratio fixes both at once, and it is
     the one rule that cannot drift out of proportion on a screen size nobody tested. The vh line
     above stays as the fallback. */
  .demo__p iframe{max-width:none;height:auto;aspect-ratio:414/868}
}
.row{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:clamp(30px,6vw,86px);align-items:center}
.row+.row{margin-top:clamp(56px,8vw,110px)}
.row.flip>*:first-child{order:2}
@media(max-width:900px){.row{grid-template-columns:minmax(0,1fr);gap:32px}.row.flip>*:first-child{order:0}}
.row ul{list-style:none;margin-top:22px}
.row li{position:relative;padding-left:24px;margin-bottom:12px;font-size:clamp(14.5px,1.25vw,17px);line-height:1.5;color:var(--g1)}
.dark .row li{color:rgba(247,246,242,.74)}
.row li:last-child{margin-bottom:0}
.row li:before{content:"";position:absolute;left:0;top:9px;width:8px;height:8px;border-radius:50%;
  background:var(--violet-deep)}
.dark .row li:before{background:var(--violet)}

/* ---------- stat strip ---------- */
.stats{display:grid;grid-template-columns:repeat(4,1fr);gap:clamp(20px,3vw,40px)}
@media(max-width:860px){.stats{grid-template-columns:repeat(2,1fr)}}
.stat b{font-family:var(--serif);font-size:clamp(29px,4vw,54px);font-weight:600;
  letter-spacing:-.025em;display:block;line-height:1;color:#fff}
.stat span{display:block;margin-top:12px;font-size:14.5px;line-height:1.4;color:rgba(247,246,242,.58)}

/* ---------- device / product frame ---------- */
.frame{min-width:0;border:1px solid var(--rule);border-radius:16px;overflow:hidden;background:#fff;
  box-shadow:0 24px 60px -30px rgba(10,10,15,.34)}
.dark .frame{border-color:var(--rule-d);box-shadow:0 30px 80px -34px rgba(0,0,0,.7)}
/* The title bar is the part that says "this is the product, not a picture of
   one", so it carries the mark, the room's name, and who is actually in it. */
.frame__bar{display:flex;align-items:center;gap:9px;padding:10px 14px;background:#f4f3ef;
  border-bottom:1px solid rgba(10,10,15,.09)}
.frame__brand{flex:0 0 auto;display:flex;color:var(--violet-deep)}
.frame__brand svg{width:18px;height:18px}
.frame__t{font-size:12.5px;font-weight:700;color:var(--ink);letter-spacing:-.01em;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0}
.frame__t em{font-style:normal;font-weight:550;color:var(--g3)}
.frame__sp{flex:1 1 auto;min-width:6px}

/* live presence, the same thing the room itself shows */
.frame__here{flex:0 0 auto;display:flex;align-items:center;gap:7px}
.frame__av{display:flex}
/* An overlapped stack looks right and reads wrong: the tile on top clips its
   neighbor's initial. Legibility wins at this size. */
.pav{width:20px;height:20px;border-radius:6px;display:flex;align-items:center;justify-content:center;
  font-size:9px;line-height:1;font-weight:800;color:#fff;background:#6e6890}
.pav+.pav{margin-left:3px}
.pav.m{background:var(--violet-deep)}
.pav.t{background:#3f7f78}
.frame__lab{font-size:9.5px;font-weight:800;letter-spacing:.13em;text-transform:uppercase;color:var(--g3);
  display:inline-flex;align-items:center;gap:5px;white-space:nowrap}
.frame__lab i{width:6px;height:6px;border-radius:50%;background:var(--teal);flex:0 0 auto}
.frame__lab.v i{background:var(--violet-deep)}
.seq.play .frame__lab i{animation:sPulse 2.1s ease-in-out infinite}
/* The bar is the part that says which room this is and who is in it, so it
   keeps every one of those details at every width. The title is the thing
   that gives way, because it is the one that can be read from an ellipsis. */

/* Tabs, because a room is never the only room. The unread pip is the detail
   that makes the rest of the product visible without showing it: work is
   happening somewhere you are not looking. */
.frame__tabs{display:flex;align-items:center;gap:1px;padding:0 8px;background:#faf9f6;
  border-bottom:1px solid rgba(10,10,15,.075);overflow:hidden}
.tabx{flex:0 0 auto;display:flex;align-items:center;gap:6px;padding:9px 10px 8px;
  font-size:11.5px;font-weight:650;color:var(--g3);white-space:nowrap;
  border-bottom:2px solid transparent;margin-bottom:-1px}
.tabx.on{color:var(--violet-deep);font-weight:750;border-bottom-color:var(--violet-deep)}
.tabx i{width:5px;height:5px;border-radius:50%;background:var(--violet);flex:0 0 auto}
.seq.play .tabx i{animation:sPulse 1.9s ease-in-out infinite}
/* Every tab stays, at every width. A room with three tabs on a phone and four
   on a desktop is a different product in the two photographs, so they tighten
   rather than drop out. */
@media(max-width:560px){.frame__tabs{padding:0 5px}
  .tabx{padding:9px 7px 8px;font-size:11px;gap:5px}}

.frame__b{padding:20px}
/* the composer belongs to the frame, not to the thread, so it stays put */
.frame__foot{padding:11px 14px;border-top:1px solid rgba(10,10,15,.08);background:#faf9f6}
.frame__foot .comp{margin-top:0;background:#fff}

/* chat sample */
.msg{display:flex;gap:12px;margin-bottom:16px}
.msg:last-child{margin-bottom:0}
.av{width:29px;height:29px;border-radius:8px;flex:0 0 auto;display:flex;align-items:center;
  justify-content:center;font-size:11px;font-weight:800;color:#fff;background:#6e6890}
.av.m{background:var(--violet-deep)}
.av.t{background:#3f7f78}
.msg__n{font-size:11.5px;font-weight:800;color:var(--ink);margin-bottom:4px}
.msg__n em{font-style:normal;font-weight:500;color:var(--g3);margin-left:7px;font-size:10.5px}
.msg__t{font-size:clamp(13px,1.2vw,14.5px);line-height:1.5;color:var(--g1)}
.msg__t b{color:var(--ink);font-weight:700}
.chips{display:flex;gap:7px;margin-top:10px;flex-wrap:wrap}
.chip{font-size:10.5px;font-weight:700;letter-spacing:.02em;color:var(--violet-deep);
  background:rgba(107,79,216,.09);border:1px solid rgba(107,79,216,.2);border-radius:999px;padding:5px 11px}
.chip.g{color:#2b7a6f;background:rgba(63,156,148,.11);border-color:rgba(63,156,148,.26)}

/* One mock gets the whole column, because watching it build something is the
   part that is worth stopping for. */
.build{max-width:900px;margin:clamp(40px,5vw,64px) auto 0}
.build .msg__t{max-width:74ch}

/* ---------- film block ---------- */
.film{position:relative;border-radius:18px;overflow:hidden;border:1px solid var(--rule-d);background:#000}
.film video{width:100%;height:auto;display:block}

/* ---------- steps ---------- */
.steps{counter-reset:st;display:grid;gap:0}
.step{display:grid;grid-template-columns:88px 1fr;gap:clamp(16px,3vw,40px);
  padding:clamp(24px,3vw,34px) 0;border-top:1px solid var(--rule)}
.dark .step{border-top-color:var(--rule-d)}
.step:last-child{border-bottom:1px solid var(--rule)}
.dark .step:last-child{border-bottom-color:var(--rule-d)}
.step__n{font-family:var(--serif);font-size:clamp(22px,3vw,40px);font-weight:600;
  color:var(--violet-deep);line-height:1;letter-spacing:-.02em}
.dark .step__n{color:var(--violet)}
.step h3{margin-bottom:9px}
@media(max-width:640px){.step{grid-template-columns:1fr;gap:10px}}

/* ---------- quote ---------- */
.quote{font-family:var(--serif);font-size:clamp(22px,3.4vw,44px);line-height:1.22;
  font-weight:600;letter-spacing:-.022em;max-width:24ch}

/* ---------- cta ---------- */
.cta{text-align:center}
.cta h2{max-width:20ch;margin:0 auto}
.cta .lede{margin:24px auto 0;text-align:center}
.cta .btns{justify-content:center;margin-top:34px}

/* ---------- footer ---------- */
.foot{background:var(--ink);color:var(--paper);padding:clamp(52px,6vw,76px) 0 40px}
.dark+.foot .wrap{border-top:1px solid var(--rule-d);padding-top:clamp(46px,5vw,64px)}
.dark+.foot{padding-top:0}
.foot__grid{display:grid;grid-template-columns:1.35fr repeat(4,minmax(0,1fr));gap:clamp(20px,2.4vw,38px)}
@media(max-width:1180px){.foot__grid{grid-template-columns:repeat(4,minmax(0,1fr));gap:clamp(20px,2.6vw,34px)}.foot__brand{grid-column:1/-1;margin-bottom:10px}}
@media(max-width:940px){.foot__grid{grid-template-columns:repeat(2,minmax(0,1fr));gap:clamp(24px,3vw,40px)}}
.foot h2{font-family:var(--sans);line-height:normal;
  font-size:11.5px;letter-spacing:.19em;text-transform:uppercase;font-weight:700;
  color:var(--g3);margin-bottom:16px}
.foot ul{list-style:none}
.foot li{margin-bottom:11px}
.foot li a{font-size:clamp(13.5px,1.15vw,15px);color:rgba(247,246,242,.68);transition:color .18s}
.foot li a:hover{color:#fff}
.foot__brand svg{width:42px;height:42px;color:#fff;margin-bottom:16px}
.foot__bot{margin-top:clamp(40px,5vw,60px);padding-top:24px;border-top:1px solid var(--rule-d);
  display:flex;flex-wrap:wrap;gap:12px 28px;align-items:center}
.foot__bot span{font-size:clamp(11.5px,1.1vw,13px);color:rgba(247,246,242,.48)}
.foot__bot .sp{flex:1}

/* ---------- motif ---------- */
.motif{position:absolute;pointer-events:none;color:var(--violet);opacity:.07;z-index:0}
.motif+*{position:relative;z-index:1}

/* ---------- looping product demos ----------
   The film's motion vocabulary, reused: a soft ease-out for anything arriving,
   a firmer one for anything sweeping across. Every step is driven by its own
   --d delay, so a sequence is authored by reading the delays down the markup.

   Only opacity, transform and clip-path are animated. Nothing here touches
   width or height, so a demo that loops forever still costs nothing to scroll
   past, and the driver in the page tail tears a .seq down entirely once it
   leaves the screen. */
@keyframes sUp{from{opacity:0;transform:translateY(16px)}to{opacity:1;transform:none}}
@keyframes sLeft{from{opacity:0;transform:translateX(-18px)}to{opacity:1;transform:none}}
@keyframes sFade{from{opacity:0}to{opacity:1}}
@keyframes sOut{from{opacity:1}to{opacity:0}}
@keyframes sPop{0%{opacity:0;transform:scale(.86)}60%{opacity:1;transform:scale(1.03)}100%{opacity:1;transform:scale(1)}}
@keyframes sType{to{clip-path:inset(0 0 0 0)}}
@keyframes sBar{to{transform:scaleX(var(--w,1))}}
@keyframes sDots{0%,60%,100%{transform:translateY(0);opacity:.42}30%{transform:translateY(-4px);opacity:1}}
@keyframes sRing{0%{opacity:.5;transform:scale(.55)}100%{opacity:0;transform:scale(1.85)}}
/* down toward the boundary, a pause against it, and back where it came from */
@keyframes sKept{0%{transform:translateY(0);opacity:0}
  20%{opacity:1}52%{transform:translateY(21px);opacity:1}
  70%{transform:translateY(13px)}100%{transform:translateY(0);opacity:0}}

/* The resting state of every demo is the CONVERSATION ALREADY FINISHED, not an
   empty box. The driver adds .armed before it ever adds .play, so if the script
   never runs, or motion is turned down, what is left on the page is the whole
   thing at its end rather than a blank frame. */
.a-type{display:inline-block}
.a-bar{transform:scaleX(var(--w,1));transform-origin:left}
.a-draw{stroke-dasharray:24;stroke-dashoffset:0}
/* the wait states and the lines that get replaced: gone once it has finished */
.a-hold,.a-vanish,.kept,.ring{opacity:0}

.seq.armed .a-up,.seq.armed .a-left,.seq.armed .a-fade,.seq.armed .a-pop{opacity:0}
.seq.armed .a-vanish,.seq.armed .kept,.seq.armed .ring{opacity:1}
.seq.armed .a-type{clip-path:inset(0 100% 0 0)}
.seq.armed .a-bar{transform:scaleX(0)}
.seq.armed .a-draw{stroke-dashoffset:24}

.seq.play .a-up{animation:sUp .52s cubic-bezier(.16,.84,.30,1) var(--d,0s) both}
.seq.play .a-left{animation:sLeft .55s cubic-bezier(.16,.84,.30,1) var(--d,0s) both}
.seq.play .a-fade{animation:sFade .5s cubic-bezier(.16,.84,.30,1) var(--d,0s) both}
.seq.play .a-pop{animation:sPop .5s cubic-bezier(.16,.84,.30,1) var(--d,0s) both}
/* a beat that arrives, then gets out of the way again */
.seq.play .a-hold{animation:sFade .3s ease var(--d,0s) both,sOut .28s ease var(--d2,4s) forwards}
.seq.play .a-vanish{animation:sOut .45s ease var(--d,0s) forwards}
.seq.play .a-type{animation:sType 1.15s steps(32,end) var(--d,0s) both}
.seq.play .a-bar{animation:sBar .9s cubic-bezier(.65,0,.35,1) var(--d,0s) both}
.seq.play .a-press{animation:sPress .42s cubic-bezier(.16,.84,.30,1) var(--d,0s) both}
@keyframes sPress{0%{transform:scale(1)}40%{transform:scale(.82)}100%{transform:scale(1)}}
/* a check that gets drawn rather than switched on */
.seq.play .a-draw{animation:sDraw .42s cubic-bezier(.65,0,.35,1) var(--d,0s) forwards}
@keyframes sDraw{to{stroke-dashoffset:0}}

/* ---------- the thread scrolls, the frame does not grow ----------
   A demo that reserves space for every message it will eventually show ends up
   as tall as the finished conversation, which on a phone is most of a screen
   of white while you wait. So the frame is a fixed height and the thread moves
   inside it, the way the real one does: each beat pulls the view down as it
   lands. Space is still reserved, which is what keeps the scroll arithmetic
   stable and stops anything on the page from jumping. */
.feed{padding:0}
.feed__in{padding:20px}
.seq.armed .feed{position:relative;height:var(--fh,400px);overflow:hidden}
.seq.armed .feed__in{position:absolute;left:0;right:0;top:0;
  transition:transform .62s cubic-bezier(.16,.84,.30,1)}

/* The loop dips out before it starts over, so the seam is something to watch
   rather than a hard cut back to an empty room. */
.seq .frame__b{transition:opacity .42s ease}
.seq.rewind .frame__b{opacity:0}

/* Nothing in a demo is allowed to move the page, so a message that has not
   arrived yet still holds its space. That leaves a hole, and the hole is
   filled by the thing that is genuinely happening: a person typing, or Maison
   assembling an answer. Both are drawn over the reserved area, so the frame
   never jumps when the real message lands. */
/* The message inside a slot is that slot's last child, so it drops its own
   bottom margin and the next speaker crowds it. The gap belongs to the slot. */
.slot{position:relative;margin-bottom:16px}
.slot:last-child{margin-bottom:0}
.skel{position:absolute;inset:0;display:flex;gap:12px;pointer-events:none}
.skel__av{width:29px;height:29px;border-radius:8px;flex:0 0 auto}
.skel__c{flex:1;display:flex;flex-direction:column;gap:10px;padding-top:5px}
.skel__l{height:9px;border-radius:5px}
/* A card on its way in is a block, not a line. Without this the placeholder is
   shorter than the thing it stands in for and the frame is left with a hole. */
.skel__blk{border-radius:12px}
.skel__blk.b1{height:210px}
.skel__av,.skel__l,.skel__blk{background:rgba(10,10,15,.105)}
.seq.play .skel__l,.seq.play .skel__av,.seq.play .skel__blk{animation:sBreathe 1.5s ease-in-out infinite}
.seq.play .skel__c :nth-child(2){animation-delay:.12s}
.seq.play .skel__c :nth-child(3){animation-delay:.24s}
.seq.play .skel__c :nth-child(4){animation-delay:.36s}
.seq.play .skel__c :nth-child(5){animation-delay:.48s}
@keyframes sBreathe{0%,100%{opacity:.62}50%{opacity:1}}
/* Somebody is typing, and it matters who. An anonymous bubble says a machine
   is busy; a name says the room has people in it. */
.tdot{position:absolute;left:41px;top:1px;display:flex;align-items:center;gap:9px}
.tdot__b{display:flex;gap:4px;align-items:center;padding:10px 13px;
  background:rgba(10,10,15,.055);border-radius:13px}
.tdot i{width:5px;height:5px;border-radius:50%;background:var(--g3)}
.tdot__n{font-size:11px;font-weight:600;color:var(--g3);white-space:nowrap}
.seq.play .tdot i{animation:sDots 1.15s ease-in-out infinite}
.seq.play .tdot i:nth-child(2){animation-delay:.14s}
.seq.play .tdot i:nth-child(3){animation-delay:.28s}

/* the composer, so a demo can start where the person starts */
.comp{display:flex;align-items:center;gap:9px;margin-top:15px;padding:7px 8px;
  border:1px solid var(--rule);border-radius:999px;background:#fbfaf7}
.comp__t{flex:1;min-width:0;font-size:12.5px;color:var(--g2);white-space:nowrap;overflow:hidden}
.comp__m,.comp__s{width:26px;height:26px;border-radius:50%;background:var(--violet-deep);
  flex:0 0 auto;display:flex;align-items:center;justify-content:center}
.comp__m{background:rgba(107,79,216,.1)}
.comp__m svg{width:12px;height:12px;fill:var(--violet-deep)}
.comp__s svg{width:10px;height:10px;fill:#fff}

/* The work queue, mid flight. Rows finish one at a time and the header keeps a
   running clock, because the honest version of "it is working on it" is a
   number that moves. */
.work{margin-top:12px;border:1px solid var(--rule);border-radius:12px;padding:12px 14px 14px;background:#fbfaf7}
/* Everything that stands in for an answer while it is being assembled, drawn
   over the space that answer will land in so the frame never moves. It has to
   be about as tall as what it replaces, or the wait reads as a blank room.

   The frame is a different width on a phone than in a two column row, and the
   message it stands in for wraps differently at each one, so the placeholder
   fills the space it is given and anything past the edge is simply clipped.
   Guessing the height per breakpoint was never going to hold. */
.over{position:absolute;left:41px;right:0;top:0;bottom:0;display:flex;flex-direction:column}
.over .work{margin-top:0;flex:0 0 auto}
.over .skel__c{flex:1 1 auto;min-height:0;overflow:hidden}
.skel__c>*{flex:0 0 auto}
@media(max-width:560px){.over{left:0}}
.work__h{display:flex;align-items:center;gap:8px;font-size:10px;letter-spacing:.15em;
  text-transform:uppercase;font-weight:800;color:var(--violet-deep);margin-bottom:9px}
.work__h .sp{flex:1 1 auto;min-width:4px}
.work__h .el{font-size:10.5px;letter-spacing:.02em;text-transform:none;font-weight:600;
  color:var(--g3);font-variant-numeric:tabular-nums;white-space:nowrap}
.wrow{display:flex;align-items:center;gap:10px;margin-top:8px;font-size:11.5px}
.wrow .wt{flex:0 0 auto;font-weight:650;color:var(--g1);min-width:98px}
.wbar{position:relative;flex:1;height:4px;border-radius:2px;background:rgba(10,10,15,.09);overflow:hidden}
.wbar i{position:absolute;inset:0;border-radius:2px;background:var(--violet-deep);transform-origin:left}
/* the same row, finished, laid over the version that was still running */
.wbar i.fin{background:var(--teal);transform:scaleX(1)}
.wm{flex:0 0 auto;color:var(--g3);font-variant-numeric:tabular-nums;min-width:38px;text-align:right}
.wm b{color:#2b7a6f;font-weight:750}
.wrow.done .wbar i{background:var(--teal)}
.wrow.done .wm{color:#2b7a6f;font-weight:750}

/* An answer that lands in a different room than the one it was asked in. */
.routed{display:flex;align-items:center;gap:10px;margin:11px 0 15px 41px;padding:8px 11px;
  border-left:2px solid var(--violet-deep);background:rgba(107,79,216,.05);border-radius:0 9px 9px 0}
.routed span{font-size:11.5px;color:var(--g2);min-width:0}
.routed b{color:var(--violet-deep);font-weight:750}
.routed .chip{margin-left:auto;flex:0 0 auto}
@media(max-width:560px){.routed{margin-left:0;flex-wrap:wrap}.routed .chip{margin-left:0}}

/* What it actually changed. Line counts are the least glamorous possible way
   to say "this was real work", which is exactly why they belong here. */
.diff{margin-top:11px;border:1px solid var(--rule);border-radius:12px;overflow:hidden;background:#fbfaf7}
.diff__h{display:flex;align-items:center;gap:8px;padding:9px 13px;font-size:10px;
  letter-spacing:.15em;text-transform:uppercase;font-weight:800;color:var(--g3);
  border-bottom:1px solid var(--rule)}
.diff__h .sp{flex:1 1 auto;min-width:4px}
.drow{display:flex;align-items:baseline;gap:10px;padding:7px 13px;
  border-top:1px solid rgba(10,10,15,.045)}
.drow:first-of-type{border-top:0}
.drow .f{flex:1 1 auto;min-width:0;font-family:var(--mono);font-size:11px;color:var(--g1);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.drow .add,.drow .del{flex:0 0 auto;font-size:10.5px;font-weight:750;
  font-variant-numeric:tabular-nums}
.drow .add{color:#2b7a6f}
.drow .del{color:var(--g3)}

/* the suite, green */
.tests{display:flex;align-items:center;gap:10px;margin-top:11px;padding:9px 12px;
  border:1px solid rgba(63,156,148,.28);background:rgba(63,156,148,.07);border-radius:10px}
.tests b{font-size:11.5px;font-weight:750;color:#2b7a6f}
.tests span{font-size:11.5px;color:var(--g2)}
.tick{width:16px;height:16px;border-radius:50%;background:var(--teal);flex:0 0 auto;
  display:flex;align-items:center;justify-content:center}
.tick svg{width:9px;height:9px;fill:none;stroke:#fff;stroke-width:3.4;
  stroke-linecap:round;stroke-linejoin:round}

/* one line replacing another in the same slot, without moving anything */
.swap{display:grid}
.swap>*{grid-area:1/1}
.brief__live{margin-left:auto;display:inline-flex;align-items:center;gap:6px;font-size:9.5px;
  letter-spacing:.15em;text-transform:uppercase;font-weight:800;color:var(--violet-deep)}
.brief__live i{width:6px;height:6px;border-radius:50%;background:var(--violet-deep)}
.seq.play .brief__live i{animation:sPulse 1.3s ease-in-out infinite}
@keyframes sPulse{0%,100%{opacity:.35;transform:scale(.78)}50%{opacity:1;transform:scale(1)}}

/* information that goes up to the line and comes back */
.kept{position:absolute;width:7px;height:7px;border-radius:50%;background:var(--violet)}
.seq.play .kept{animation:sKept 2.7s cubic-bezier(.45,0,.35,1) var(--d,0s) infinite}
.ring{position:absolute;border-radius:50%;border:1.5px solid var(--violet);pointer-events:none}
.seq.play .ring{animation:sRing 2.6s ease-out var(--d,0s) infinite}

/* ---------- jump links ----------
   A long page of materials, with the contents said once at the top. */
.jump{display:flex;flex-wrap:wrap;gap:9px;margin-top:clamp(26px,3.2vw,36px)}
.jump a{font-size:13.5px;font-weight:600;color:rgba(247,246,242,.72);
  padding:8px 15px;border:1px solid rgba(255,255,255,.17);border-radius:100px;
  transition:border-color .18s,color .18s}
.jump a:hover{color:#fff;border-color:rgba(255,255,255,.42)}

/* ---------- the book ----------
   The cover is the artwork off page one of the book itself, so it is shown at
   the proportions it was printed at and lit from the side rather than cropped
   into a panel. The shadow is doing the work a physical object would. */
.bookart{display:flex;justify-content:center}
.bookart img{width:min(100%,392px);height:auto;border-radius:3px;
  box-shadow:0 44px 90px -30px rgba(0,0,0,.85),0 0 0 1px rgba(255,255,255,.09);
  transition:transform .5s cubic-bezier(.16,.84,.30,1)}
.bookart img:hover{transform:translateY(-5px)}

.bookfacts{display:flex;flex-wrap:wrap;gap:clamp(22px,3.4vw,48px);
  margin-top:clamp(26px,3vw,34px);padding-top:clamp(22px,2.6vw,28px);
  border-top:1px solid var(--rule-d)}
.bookfacts b{font-family:var(--serif);font-size:clamp(24px,3vw,38px);font-weight:600;
  color:#fff;display:block;letter-spacing:-.02em}
.bookfacts span{display:block;margin-top:6px;font-size:13px;line-height:1.35;
  color:rgba(247,246,242,.52);max-width:14ch}

/* ---------- the audiobook ----------
   Five hours is not a thing anyone finishes at one sitting, so the player is
   built around returning to it: the bar says where you are, the list says how
   far you got, and the position outlives the tab. Lives inside a .dark
   section, which is the only place it is used.

   Nothing in a row changes size while a chapter plays. The progress under a
   row is a scaled bar and the clock is tabular, so five hours of ticking never
   asks the page to lay itself out again. */
.ab{border:1px solid var(--rule-d);border-radius:18px;background:rgba(255,255,255,.038);
  overflow:hidden}
.ab__bar{display:flex;align-items:center;gap:clamp(13px,1.6vw,18px);
  padding:clamp(15px,1.8vw,20px) clamp(15px,2vw,24px);border-bottom:1px solid var(--rule-d)}
.ab__play{flex:0 0 auto;width:clamp(46px,4.4vw,56px);height:clamp(46px,4.4vw,56px);
  border:0;border-radius:50%;background:var(--violet);color:#14101f;cursor:pointer;
  display:flex;align-items:center;justify-content:center;transition:background .18s,transform .18s}
.ab__play:hover{background:#ac90ff;transform:scale(1.04)}
.ab__play svg{width:44%;height:44%;fill:currentColor}
.ab__play .i-pause,.ab.playing .ab__play .i-play{display:none}
.ab.playing .ab__play .i-pause{display:block}
.ab__meta{flex:1;min-width:0}
.ab__lab{display:block;font-size:10.5px;letter-spacing:.16em;text-transform:uppercase;
  font-weight:800;color:var(--violet)}
.ab__ttl{display:block;margin-top:5px;font-family:var(--serif);font-weight:600;
  font-size:clamp(16px,1.8vw,22px);letter-spacing:-.015em;color:#fff;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ab__rate{flex:0 0 auto;display:flex;gap:2px;padding:3px;border-radius:100px;
  background:rgba(255,255,255,.06)}
.abrate{border:0;background:none;cursor:pointer;border-radius:100px;padding:6px 11px;
  font-family:var(--sans);font-size:12px;font-weight:700;color:rgba(247,246,242,.55);
  transition:color .18s,background .18s}
.abrate:hover{color:#fff}
.abrate.on{background:rgba(255,255,255,.13);color:#fff}

.ab__scrub{display:flex;align-items:center;gap:clamp(10px,1.3vw,15px);
  padding:clamp(13px,1.5vw,17px) clamp(15px,2vw,24px);border-bottom:1px solid var(--rule-d);
  transition:opacity .25s}
/* Nothing to scrub until a chapter is loaded, and the row should say so
   rather than sit there showing a time that belongs to nothing. */
.ab:not(.loaded) .ab__scrub{opacity:.4;pointer-events:none}
.ab__sk{flex:0 0 auto;width:34px;height:34px;border-radius:50%;cursor:pointer;
  border:1px solid rgba(255,255,255,.19);background:none;color:rgba(247,246,242,.72);
  font-family:var(--sans);font-size:10.5px;font-weight:800;font-variant-numeric:tabular-nums;
  transition:border-color .18s,color .18s}
.ab__sk:hover{border-color:rgba(255,255,255,.45);color:#fff}
.ab__t{flex:0 0 auto;font-size:12.5px;font-variant-numeric:tabular-nums;
  color:rgba(247,246,242,.55);min-width:44px;text-align:center}
.ab__seek{flex:1;min-width:0;height:4px;border-radius:2px;cursor:pointer;
  -webkit-appearance:none;appearance:none;background:rgba(255,255,255,.15)}
.ab__seek::-webkit-slider-thumb{-webkit-appearance:none;width:14px;height:14px;
  border-radius:50%;background:var(--violet);border:0;cursor:pointer}
.ab__seek::-moz-range-thumb{width:14px;height:14px;border-radius:50%;
  background:var(--violet);border:0;cursor:pointer}
.ab__seek:focus-visible{outline:2px solid var(--violet);outline-offset:5px}
.ab__resume{padding:11px clamp(15px,2vw,24px);margin:0;font-size:12.5px;
  color:var(--violet);background:rgba(155,122,255,.08);
  border-bottom:1px solid var(--rule-d)}

.ab__list{list-style:none;counter-reset:ab;max-height:clamp(380px,52vh,560px);overflow-y:auto}
.abr{display:flex;align-items:stretch;border-bottom:1px solid rgba(255,255,255,.07)}
.abr:last-child{border-bottom:0}
/* The part heading sticks to the top of the scroller: ten hours is a long
   column, and the one thing worth never losing on the way down is which half
   of the book you are in. It is opaque for the same reason. */
.abp{position:sticky;top:0;z-index:2;display:flex;align-items:baseline;gap:12px;
  padding:13px clamp(15px,2vw,24px) 11px;background:#131318;
  border-bottom:1px solid rgba(255,255,255,.09)}
.abp:not(:first-child){border-top:1px solid rgba(255,255,255,.07)}
.abp__n{font-size:11px;letter-spacing:.15em;text-transform:uppercase;
  font-weight:600;color:var(--violet);white-space:nowrap}
.abp__n b{font-weight:600}
.abp__n i{font-style:normal}
.abp__n i::before{content:": "}
.abp__d{margin-left:auto;font-size:11.5px;font-variant-numeric:tabular-nums;
  color:rgba(247,246,242,.42);white-space:nowrap}
.abr__b{position:relative;flex:1;min-width:0;display:flex;align-items:center;gap:14px;
  padding:13px clamp(10px,1.4vw,16px) 13px clamp(15px,2vw,24px);
  border:0;background:none;cursor:pointer;text-align:left;font-family:var(--sans);
  transition:background .18s}
.abr__b:hover{background:rgba(255,255,255,.045)}
/* The row's mark is a play arrow until the row is the one playing, when it
   becomes a speaker. Both live in the same box so nothing shifts, and the row
   already says which chapter it is, so there is no number to compete with. */
.abr__i{flex:0 0 auto;width:26px;height:26px;border-radius:50%;
  border:1px solid rgba(255,255,255,.18);display:flex;align-items:center;justify-content:center;
  color:rgba(247,246,242,.5);transition:border-color .18s,color .18s,background .18s}
.abr__i svg{width:9px;height:9px;fill:currentColor;margin-left:1px}
.abr__b:hover .abr__i{border-color:rgba(255,255,255,.42);color:#fff}
.abr__i i{display:none;width:3px;height:9px;border-radius:2px;background:#14101f;
  box-shadow:5px 0 0 #14101f,-5px 0 0 #14101f}
.abr.on .abr__i{background:var(--violet);border-color:var(--violet);color:#14101f}
.ab.playing .abr.on .abr__i svg{display:none}
.ab.playing .abr.on .abr__i i{display:block;animation:abEq .9s ease-in-out infinite}
.abr__c{flex:1;min-width:0}
.abr__c em{display:block;font-style:normal;font-size:10.5px;letter-spacing:.13em;
  text-transform:uppercase;font-weight:800;color:rgba(247,246,242,.42)}
.abr__c b{display:block;margin-top:3px;font-size:clamp(14px,1.25vw,16px);font-weight:600;
  color:rgba(247,246,242,.86);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.abr.on .abr__c em{color:var(--violet)}
.abr.on .abr__c b{color:#fff}
.abr.done .abr__c b{color:rgba(247,246,242,.5)}
.abr.done .abr__i{border-color:rgba(63,156,148,.5);color:var(--teal)}
.abr__d{flex:0 0 auto;font-size:12.5px;font-variant-numeric:tabular-nums;
  color:rgba(247,246,242,.42)}
.abr__p{position:absolute;left:0;right:0;bottom:0;height:2px;background:var(--violet);
  transform:scaleX(0);transform-origin:left;transition:transform .3s linear}
.abr.done .abr__p{background:var(--teal)}
.abr__dl{flex:0 0 auto;display:flex;align-items:center;padding:0 clamp(14px,1.8vw,20px);
  color:rgba(247,246,242,.3);transition:color .18s}
.abr__dl:hover{color:#fff}
.abr__dl svg{width:15px;height:15px;fill:none;stroke:currentColor;stroke-width:1.5;
  stroke-linecap:round;stroke-linejoin:round}
@keyframes abEq{0%,100%{transform:scaleY(.45)}50%{transform:scaleY(1)}}
@media(max-width:640px){
  .ab__rate{display:none}
  .abr__dl{padding:0 14px}
  .ab__ttl{white-space:normal}
  /* The part number is the whole job on a phone. Its subtitle is what pushed
     the heading onto a second line and shoved the count off the end. */
  .abp__n i{display:none}
}
@media(prefers-reduced-motion:reduce){
  .ab.playing .abr.on .abr__i i{animation:none}
  .bookart img{transition:none}
}

/* ---------- reveal ---------- */
.rv{opacity:0;transform:translateY(18px);transition:opacity .7s cubic-bezier(.22,.61,.36,1),transform .7s cubic-bezier(.22,.61,.36,1)}
.rv.in{opacity:1;transform:none}
@media(prefers-reduced-motion:reduce){
  .rv{opacity:1;transform:none;transition:none}
  html{scroll-behavior:auto}
  .hero__v{display:none}
  /* The unarmed state is already the finished conversation, so there is
     nothing to undo here beyond refusing to run. */
  .seq .frame__b{transition:none}
}

/* ============================================================================
   The conversation (/apply, and its ?for=team and ?for=access modes)

   The whole viewport is the exchange: the nav stays fixed at the top, the log
   takes whatever height is left, and the composer is pinned under it. Only the
   log scrolls, so the composer never walks off the bottom of a phone and the
   page behind it never moves.

   That last sentence used to be a claim rather than a rule. Nothing stopped the
   document itself from scrolling, so on iOS Safari the mic and the input drifted
   under the browser toolbar and you had to scroll to find them. Two things hold
   it now: the page is locked below (.cv-page), and the height comes from
   --cvh, which apply.js writes from visualViewport — the ACTUAL visible box,
   whatever Safari is doing with its chrome at that moment. 100svh stays as the
   pre-script fallback.
   ========================================================================= */
html.cv-page, body.cv-page{height:100%;overflow:hidden;overscroll-behavior:none}
.cv{position:relative;overflow:hidden;height:var(--cvh,100svh);display:flex;flex-direction:column;
  background:var(--ink);color:var(--paper);padding:clamp(62px,7.5vh,76px) var(--pad) 0}
.cv__in{position:relative;z-index:1;width:100%;max-width:820px;margin:0 auto;flex:1;min-height:0;
  display:flex;flex-direction:column}

/* ---------- who you are talking to ---------- */
.cv__head{display:flex;align-items:center;gap:11px;padding:14px 2px 15px;
  border-bottom:1px solid var(--rule-d);flex:0 0 auto}
.cv__orb{width:9px;height:9px;border-radius:50%;background:var(--violet);flex:0 0 auto;
  box-shadow:0 0 0 0 rgba(155,122,255,.55);animation:cvpulse 2.6s ease-out infinite}
@keyframes cvpulse{0%{box-shadow:0 0 0 0 rgba(155,122,255,.5)}70%{box-shadow:0 0 0 9px rgba(155,122,255,0)}100%{box-shadow:0 0 0 0 rgba(155,122,255,0)}}
.cv__who{display:flex;align-items:baseline;gap:9px;flex:1;min-width:0}
.cv__who b{font-size:15px;font-weight:650;letter-spacing:-.015em;color:#fff}
.cv__who em{font-style:normal;font-size:12px;color:rgba(247,246,242,.42);white-space:nowrap;
  overflow:hidden;text-overflow:ellipsis}
.cv__back{font-size:13px;font-weight:550;color:rgba(247,246,242,.55);transition:color .18s;flex:0 0 auto}
.cv__back:hover{color:#fff}
.cv__back:before{content:"";display:inline-block;width:5px;height:5px;margin-right:8px;
  border-left:1.4px solid currentColor;border-bottom:1.4px solid currentColor;transform:rotate(45deg) translateY(-1px)}

/* ---------- the log ---------- */
.cv__log{flex:1;min-height:0;overflow-y:auto;overscroll-behavior:contain;
  padding:clamp(20px,3vh,30px) 2px clamp(12px,2vh,18px);
  display:flex;flex-direction:column;align-items:flex-start;gap:11px;
  scrollbar-width:thin;scrollbar-color:rgba(255,255,255,.16) transparent}
.cv__log::-webkit-scrollbar{width:7px}
.cv__log::-webkit-scrollbar-thumb{background:rgba(255,255,255,.15);border-radius:99px}

.cv__b{max-width:min(88%,60ch);padding:13px 17px;border-radius:17px;
  font-size:clamp(14.5px,1.25vw,16.5px);line-height:1.52;white-space:pre-wrap;
  animation:cvin .42s cubic-bezier(.22,.61,.36,1) both}
@keyframes cvin{from{opacity:0;transform:translateY(9px)}to{opacity:1;transform:none}}
.cv__b--m{background:rgba(255,255,255,.055);border:1px solid rgba(255,255,255,.09);
  color:rgba(247,246,242,.92);border-bottom-left-radius:6px}
.cv__b--u{align-self:flex-end;background:var(--violet-deep);border:1px solid transparent;
  color:#fff;border-bottom-right-radius:6px}

.cv__typing{display:flex;gap:5px;padding:15px 17px;border-radius:17px;border-bottom-left-radius:6px;
  background:rgba(255,255,255,.055);border:1px solid rgba(255,255,255,.09)}
.cv__typing i{width:6px;height:6px;border-radius:50%;background:rgba(247,246,242,.5);
  animation:cvdot 1.25s ease-in-out infinite}
.cv__typing i:nth-child(2){animation-delay:.16s}
.cv__typing i:nth-child(3){animation-delay:.32s}
@keyframes cvdot{0%,60%,100%{opacity:.28;transform:translateY(0)}30%{opacity:1;transform:translateY(-3px)}}

/* ---------- the composer ---------- */
/* The bottom padding clears the home indicator on a notched phone, which would
   otherwise sit across the send button. max(), so a phone without one is unchanged. */
.cv__comp{flex:0 0 auto;display:flex;flex-direction:column;align-items:center;gap:9px;
  padding:clamp(10px,1.6vh,16px) 0 max(clamp(16px,2.6vh,26px), env(safe-area-inset-bottom, 0px))}
.cv__mic{width:52px;height:52px;border-radius:50%;flex:0 0 auto;cursor:pointer;position:relative;
  display:flex;align-items:center;justify-content:center;color:var(--paper);
  background:rgba(255,255,255,.05);border:1px solid var(--rule-d);
  transition:border-color .18s,background .18s,transform .18s,opacity .18s}
.cv__mic svg{width:23px;height:23px}
.cv__mic:hover:not(:disabled){border-color:var(--violet);transform:translateY(-1px)}
.cv__mic:disabled{opacity:.4;cursor:default}
.cv__mic.rec{background:var(--violet);border-color:var(--violet);color:#14101f}
.cv__mic.rec i{position:absolute;inset:-1px;border-radius:50%;border:1.5px solid var(--violet);
  animation:cvring 1.5s ease-out infinite}
@keyframes cvring{from{transform:scale(1);opacity:.8}to{transform:scale(1.5);opacity:0}}
.cv__mic.busy{opacity:.55;cursor:default}
.cv__hint{font-size:12px;color:rgba(247,246,242,.42);text-align:center;min-height:16px}

.cv__row{width:100%;display:flex;align-items:flex-end;gap:9px;
  background:rgba(255,255,255,.05);border:1px solid var(--rule-d);border-radius:22px;
  padding:6px 6px 6px 18px;transition:border-color .18s}
.cv__row:focus-within{border-color:var(--violet)}
.cv__input{flex:1;min-width:0;resize:none;border:0;outline:none;background:none;
  font-family:var(--sans);font-size:16px;line-height:1.5;color:var(--paper);
  padding:10px 0;max-height:132px}
.cv__input::placeholder{color:rgba(247,246,242,.34)}
.cv__input:disabled{opacity:.5}
.cv__send{width:40px;height:40px;flex:0 0 auto;border-radius:50%;border:0;cursor:pointer;
  display:flex;align-items:center;justify-content:center;
  background:var(--violet);color:#14101f;transition:background .18s,opacity .18s}
.cv__send svg{width:17px;height:17px}
.cv__send:hover:not(:disabled){background:#ac90ff}
.cv__send:disabled{opacity:.32;cursor:default}

/* ---------- the sign step ---------- */
.cv__terms{width:100%;max-width:min(94%,62ch);margin-top:6px;padding:clamp(20px,2.6vw,28px);
  border-radius:18px;background:rgba(255,255,255,.045);border:1px solid rgba(255,255,255,.11);
  animation:cvin .45s cubic-bezier(.22,.61,.36,1) both}
.cv__terms>b{display:block;font-family:var(--serif);font-size:clamp(19px,2vw,24px);font-weight:600;
  letter-spacing:-.018em;color:#fff;margin-bottom:9px}
.cv__terms p{font-size:14.5px;color:rgba(247,246,242,.66);margin-bottom:15px}
.cv__terms ul{list-style:none;margin-bottom:20px}
.cv__terms li{position:relative;padding-left:26px;margin-bottom:10px;
  font-size:14.5px;line-height:1.5;color:rgba(247,246,242,.82)}
.cv__terms li:before{content:"";position:absolute;left:0;top:6px;width:12px;height:12px;
  border-radius:50%;border:1.5px solid var(--violet)}
.cv__attach{display:inline-flex;align-items:center;gap:9px;cursor:pointer;
  font-size:14px;font-weight:600;color:var(--paper);
  padding:10px 17px;border-radius:100px;border:1px dashed rgba(255,255,255,.28);
  transition:border-color .18s,background .18s}
.cv__attach:hover{border-color:var(--violet);background:rgba(155,122,255,.07)}
.cv__attach svg{width:16px;height:16px;flex:0 0 auto}
.cv__attach em{font-style:normal;font-weight:400;color:rgba(247,246,242,.45)}
.cv__note{display:block;font-size:12px;color:rgba(247,246,242,.4);margin-top:9px}
.cv__files{margin-top:12px;display:flex;flex-direction:column;gap:7px}
.cv__file{display:flex;align-items:center;gap:10px;font-size:13px;
  color:rgba(247,246,242,.78);background:rgba(255,255,255,.04);
  border-radius:10px;padding:8px 13px}
.cv__file span{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.cv__file em{font-style:normal;font-size:11.5px;color:rgba(247,246,242,.45);flex:0 0 auto}
.cv__file em.ok{color:var(--teal)}
.cv__file em.bad{color:#e0777c}
.cv__sign{display:flex;gap:10px;margin-top:22px;flex-wrap:wrap}
.cv__name{flex:1;min-width:210px;font-family:var(--sans);font-size:15px;color:var(--paper);
  background:rgba(255,255,255,.05);border:1px solid var(--rule-d);border-radius:100px;
  padding:13px 20px;outline:none;transition:border-color .18s}
.cv__name:focus{border-color:var(--violet)}
.cv__name::placeholder{color:rgba(247,246,242,.34)}
.cv__sign .btn{background:var(--violet);color:#14101f}
.cv__sign .btn:hover:not(:disabled){background:#ac90ff}
.cv__sign .btn:disabled{opacity:.38;cursor:default;transform:none}
.cv__fine{display:block;margin-top:16px;font-size:11.5px;line-height:1.5;color:rgba(247,246,242,.38)}
.cv__signed{display:flex;align-items:center;gap:10px;font-size:14.5px;font-weight:600;color:var(--teal)}
.cv__signed svg{width:19px;height:19px;flex:0 0 auto}

/* ---------- the close ---------- */
.cv__done{width:100%;max-width:min(94%,54ch);margin-top:10px;padding:clamp(20px,2.6vw,28px);
  border-radius:18px;text-align:center;
  background:rgba(255,255,255,.045);border:1px solid rgba(255,255,255,.11);
  display:flex;flex-direction:column;align-items:center;gap:11px;
  animation:cvin .45s cubic-bezier(.22,.61,.36,1) both}
.cv__tick{width:42px;height:42px;border-radius:50%;display:flex;align-items:center;justify-content:center;
  background:rgba(155,122,255,.14);color:var(--violet)}
.cv__tick svg{width:21px;height:21px}
.cv__done b{font-family:var(--serif);font-size:clamp(19px,2vw,24px);font-weight:600;
  letter-spacing:-.018em;color:#fff}
.cv__done span{font-size:14.5px;line-height:1.5;color:rgba(247,246,242,.66)}
.cv__done a{margin-top:5px;font-size:14px;font-weight:600;color:var(--violet)}
.cv__done a:hover{color:#ac90ff}

/* A phone keyboard eats half the screen, so the log gives up its breathing room
   before the composer gives up any of its own. */
@media(max-width:560px){
  .cv{padding-left:16px;padding-right:16px}
  .cv__b{max-width:92%}
  .cv__hint{display:none}
  .cv__comp{gap:8px}
}
@media(prefers-reduced-motion:reduce){
  .cv__b,.cv__terms,.cv__done{animation:none}
  .cv__orb,.cv__mic.rec i{animation:none}
}

/* ---------- starting the conversation from the Institute page ---------- */
.opener{display:flex;align-items:flex-end;gap:9px;max-width:560px;margin:clamp(26px,3.4vw,38px) auto 0;
  background:rgba(255,255,255,.05);border:1px solid var(--rule-d);border-radius:22px;
  padding:6px 6px 6px 18px;text-align:left;transition:border-color .18s}
.opener:focus-within{border-color:var(--violet)}
.opener textarea{flex:1;min-width:0;resize:none;border:0;outline:none;background:none;
  font-family:var(--sans);font-size:16px;line-height:1.5;color:var(--paper);
  padding:10px 0;max-height:120px}
.opener textarea::placeholder{color:rgba(247,246,242,.34)}
.opener button{width:40px;height:40px;flex:0 0 auto;border-radius:50%;border:0;cursor:pointer;
  display:flex;align-items:center;justify-content:center;
  background:var(--violet);color:#14101f;transition:background .18s}
.opener button svg{width:17px;height:17px}
.opener button:hover{background:#ac90ff}

/* ============================ THE CONSTITUTION ============================ */
/* A long legal-ish document, so it is set as a reading column rather than as
   marketing: narrower measure, serif headings, and enough vertical air that the
   section breaks are legible when you are skimming for one clause. */
.con{max-width:74ch;font-size:clamp(15.5px,1.35vw,17.5px);line-height:1.66}
.con h2{font-family:var(--serif);font-size:clamp(24px,3vw,36px);line-height:1.16;
  letter-spacing:-.015em;margin:clamp(46px,5vw,72px) 0 clamp(14px,1.6vw,20px)}
.con h2:first-child{margin-top:0}
.con h3{font-size:clamp(17px,1.8vw,21px);line-height:1.3;margin:clamp(30px,3.4vw,44px) 0 12px}
.con h4{font-size:clamp(15.5px,1.5vw,17px);line-height:1.35;margin:26px 0 10px;color:var(--g2)}
.con p{margin:0 0 clamp(14px,1.5vw,19px)}
.con ul,.con ol{margin:0 0 clamp(14px,1.5vw,19px) 1.15em;padding:0}
.con li{margin-bottom:9px}
.con code{font-size:.9em;background:rgba(10,10,15,.055);border:1px solid var(--rule);
  border-radius:5px;padding:1px 5px}
.con__rule{height:1px;background:var(--rule);margin:clamp(30px,3.6vw,48px) 0;border:0}
.con__q{border-left:3px solid var(--violet-deep);margin:0 0 clamp(16px,1.8vw,22px);
  padding:2px 0 2px clamp(16px,1.8vw,22px);color:var(--g2);font-style:italic}
.con__q strong{color:var(--ink);font-style:normal}
/* The omitted section is called out rather than silently dropped: a gap in a
   published constitution should be visible and explained, or publishing it
   means less than it claims. */
.con__omit{border:1px dashed var(--rule);border-radius:14px;
  padding:clamp(20px,2.4vw,30px);margin:clamp(40px,4.6vw,64px) 0}
.con__omit h2{margin:0 0 10px;font-size:clamp(20px,2.3vw,27px)}
.con__omit p{margin:0;color:var(--g2)}
/* ---------- two ways in, side by side ---------- */
/* Same object in both themes, so the dark variant keys off .tier rather than
   off the section it happens to be sitting in today. */
.tiers{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
  gap:clamp(16px,2vw,26px);align-items:stretch}
.tier{display:flex;flex-direction:column;border:1px solid var(--rule);border-radius:16px;
  padding:clamp(24px,2.8vw,36px)}
.dark .tier{border-color:var(--rule-d);background:rgba(255,255,255,.038)}
.dark .tier--lead{border-color:rgba(155,122,255,.42);background:rgba(107,79,216,.13)}
.tier__k{font-size:11px;font-weight:700;letter-spacing:.15em;text-transform:uppercase;
  color:var(--violet-deep)}
.dark .tier__k{color:var(--violet)}
.tier__n{font-family:var(--serif);font-size:clamp(34px,4.4vw,58px);font-weight:600;
  letter-spacing:-.025em;line-height:1;margin-top:clamp(14px,1.6vw,20px)}
.dark .tier__n{color:#fff}
.tier__u{font-size:clamp(13px,1.15vw,15px);margin-top:9px;color:var(--g2)}
.dark .tier__u{color:rgba(247,246,242,.6)}
.tier__p{font-size:clamp(14px,1.2vw,16px);line-height:1.5;margin-top:clamp(16px,1.8vw,22px)}
.dark .tier__p{color:rgba(247,246,242,.74)}
.tier__l{list-style:none;margin-top:clamp(16px,1.8vw,22px);display:grid;gap:9px}
.tier__l li{position:relative;padding-left:19px;font-size:clamp(13px,1.1vw,14.5px);
  line-height:1.45;color:var(--g2)}
.dark .tier__l li{color:rgba(247,246,242,.6)}
.tier__l li:before{content:"";position:absolute;left:0;top:.52em;width:6px;height:6px;
  border-radius:50%;background:var(--violet-deep)}
.dark .tier__l li:before{background:var(--violet)}
.tier .btns{margin-top:auto;padding-top:clamp(22px,2.6vw,30px)}
@media (max-width:820px){.tiers{grid-template-columns:minmax(0,1fr)}}

/* ---------- the skill library, laid out like a store ---------- */
/* A rail of departments, a featured card, then shelves you push sideways. The
   shelf is the App Store's own shape: a two-row grid flowing into columns that
   overflow horizontally, so a long department reads as abundance rather than as
   a list that ran out of page. */
.as{display:grid;grid-template-columns:minmax(0,232px) minmax(0,1fr);
  gap:clamp(18px,2.4vw,34px);align-items:start}

.as__rail{display:grid;gap:3px;position:sticky;top:92px}
.as__hd{display:block;padding:0 12px 12px;font-size:10.5px;font-weight:500;
  letter-spacing:.15em;text-transform:uppercase;color:rgba(247,246,242,.38)}
.as__f{display:flex;align-items:center;gap:11px;width:100%;text-align:left;cursor:pointer;
  background:none;border:0;border-radius:11px;font:inherit;font-weight:400;
  font-size:clamp(13.5px,1.2vw,15px);line-height:1.3;padding:9px 12px;
  color:rgba(247,246,242,.68);transition:background .18s ease,color .18s ease}
.as__f:hover{background:rgba(247,246,242,.055);color:#fff}
.as__f.on{background:rgba(107,79,216,.24);color:#fff}

/* The glyph. A rounded square carrying a drawn mark, one per skill, picked
   from the skill's own words when the library is generated rather than here.
   Two things make it read as an icon instead of a swatch with a letter on it:
   the light falls from the top, and there is a hairline along the top edge. The
   shadow is deliberately small, because forty of them on one shelf is the case
   that matters and a generous shadow turns that into soup.

   The five fills are still the brand triad. Ten drawn marks in ten invented
   hues would be a second palette, and the marks carry the variety now. */
.as__defs{position:absolute;width:0;height:0;overflow:hidden}
.as__g{flex:none;display:grid;place-items:center;border-radius:26%;color:#fff;
  width:29px;height:29px;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.22),0 1px 2px rgba(0,0,0,.3)}
/* The stroke lives here rather than on the sprite: a <use> inherits from where
   it sits in the document, not from where the symbol was defined. */
.as__g svg{display:block;width:58%;height:58%;
  fill:none;stroke:currentColor;stroke-width:1.9;
  stroke-linecap:round;stroke-linejoin:round}
.as__g--a{background:linear-gradient(158deg,#8163e8,#5b40c4)}
.as__g--b{background:linear-gradient(158deg,#4fb3aa,#337f79)}
.as__g--c{background:linear-gradient(158deg,#9d7fd0,#7458a6)}
.as__g--d{background:linear-gradient(158deg,#c4952f,#96701a)}
.as__g--e{background:linear-gradient(158deg,#5b5b7d,#3c3c56)}

.as__hero{border:1px solid rgba(247,246,242,.13);border-radius:18px;
  background:rgba(107,79,216,.13);padding:clamp(22px,2.6vw,34px)}
.as__hero .as__g{width:58px;height:58px;border-radius:23%}
.as__hero .as__g svg{stroke-width:1.4}
.as__hero h3{color:#fff;margin-top:clamp(14px,1.6vw,18px);
  font-size:clamp(21px,2.4vw,31px);letter-spacing:-.015em}
.as__hero p{margin-top:9px;font-size:clamp(14px,1.2vw,16px);line-height:1.5;
  color:rgba(247,246,242,.68);max-width:54ch}

.as__shelf{margin-top:clamp(26px,3vw,38px)}
.as__sh{font-size:clamp(15px,1.4vw,18.5px);font-weight:600;color:#fff;
  padding-bottom:clamp(12px,1.4vw,16px);border-bottom:1px solid rgba(247,246,242,.11)}
/* One row of tiles, flowing sideways, snapping tile to tile. The scrollbar is
   hidden because the overflow is the point and a bar under every shelf reads as
   clutter; the partially visible next tile is what says "keep going".

   A single row rather than two, deliberately. Two rows meant a shelf with three
   skills on it rendered as one column and a large hole, and several shelves are
   genuinely that small. One row is also what a phone home screen looks like,
   which is the thing being borrowed. */
.as__strip{display:grid;grid-auto-flow:column;grid-auto-columns:138px;
  gap:clamp(12px,1.6vw,20px);padding-top:clamp(16px,2vw,22px);
  overflow-x:auto;scroll-snap-type:x proximity;
  scrollbar-width:none;-ms-overflow-style:none;
  margin-right:calc(-1 * var(--pad));padding-right:var(--pad)}
.as__strip::-webkit-scrollbar{display:none}

/* The mark on top and the name under it, centered: the arrangement everybody
   already knows how to read, because it is the one on the device in their hand.
   No pointer cursor and no press state, because there is nowhere for a tile to
   go, and looking clickable is a promise. */
.as__t{display:grid;justify-items:center;align-content:start;gap:11px;
  text-align:center;scroll-snap-align:start}
.as__t .as__g{width:64px;height:64px;border-radius:23%;
  transition:transform .22s cubic-bezier(.2,.8,.3,1)}
.as__t .as__g svg{stroke-width:1.5}
.as__t:hover .as__g{transform:translateY(-3px)}
/* Exactly two lines, whether the name needs them or not, so the tiles in a row
   sit on one baseline instead of stepping up and down. phrasing.py caps a name
   at what fits in two lines here, so nothing is ever cut off. */
.as__t span{font-size:12.5px;line-height:1.34;color:rgba(247,246,242,.74);
  min-height:2.68em;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}

@media(max-width:880px){
  .as{grid-template-columns:minmax(0,1fr)}
  /* The rail becomes a row of chips you swipe, which is where a phone expects
     departments to be, and it keeps the whole library one screen from the top. */
  .as__rail{position:static;grid-auto-flow:column;grid-auto-columns:max-content;
    overflow-x:auto;scrollbar-width:none;gap:7px;
    margin-right:calc(-1 * var(--pad));padding-right:var(--pad)}
  .as__rail::-webkit-scrollbar{display:none}
  .as__hd{display:none}
  .as__f{border:1px solid rgba(247,246,242,.14);border-radius:999px;padding:7px 13px 7px 8px}
  .as__strip{grid-auto-columns:112px;gap:14px}
  .as__t .as__g{width:58px;height:58px}
  /* Three lines here, not two: the column is narrower than on a desktop and the
     same name that fits in two lines there needs three, so keeping the desktop
     clamp would truncate roughly half the shelf. */
  .as__t span{font-size:12px;min-height:4.02em;-webkit-line-clamp:3}
}

/* ---------- the start form ---------- */
/* Someone who has read the price and picked a plan. Short, because every field
   here is a chance to change their mind, and the plan they clicked arrives
   already chosen rather than asked again. */
.form{display:grid;gap:clamp(15px,1.8vw,20px)}
.form__row{display:grid;gap:clamp(15px,1.8vw,20px);grid-template-columns:repeat(2,minmax(0,1fr))}
.form label{display:block;font-size:11px;font-weight:700;letter-spacing:.14em;
  text-transform:uppercase;color:rgba(247,246,242,.5);margin-bottom:9px}
.form input,.form textarea{width:100%;font-family:var(--sans);font-size:16px;line-height:1.45;
  color:var(--paper);background:rgba(255,255,255,.045);border:1px solid var(--rule-d);
  border-radius:11px;padding:13px 15px;transition:border-color .18s ease,background .18s ease}
.form textarea{min-height:118px;resize:vertical}
.form input:focus,.form textarea:focus{outline:0;border-color:var(--violet);
  background:rgba(255,255,255,.06)}
.form input::placeholder,.form textarea::placeholder{color:rgba(247,246,242,.3)}
/* The honeypot. Off-screen rather than display:none, because a bot that reads
   styles skips a hidden field and fills a visible one. */
.form__hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}

/* The plan, as two things you can see at once. A select would hide the one they
   did not click, and the comparison is half of why they are here. */
.pick{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:clamp(10px,1.2vw,14px)}
.pick__o{position:relative}
.pick__o input{position:absolute;opacity:0;width:1px;height:1px}
.pick__o span{display:block;border:1px solid var(--rule-d);border-radius:13px;cursor:pointer;
  padding:clamp(13px,1.5vw,17px);transition:border-color .18s ease,background .18s ease}
.pick__o b{display:block;font-family:var(--serif);font-size:clamp(16px,1.6vw,19px);
  font-weight:600;color:#fff}
.pick__o i{display:block;font-style:normal;font-size:13px;margin-top:5px;
  color:rgba(247,246,242,.55)}
.pick__o span:hover{border-color:rgba(155,122,255,.45)}
.pick__o input:checked+span{border-color:rgba(155,122,255,.6);background:rgba(107,79,216,.16)}
.pick__o input:focus-visible+span{outline:2px solid var(--violet);outline-offset:2px}

.form__note{font-size:13.5px;line-height:1.5;color:rgba(247,246,242,.5)}
.form__err{font-size:14px;color:#e0777c;min-height:21px}
.form__ok{border:1px solid rgba(63,156,148,.4);background:rgba(63,156,148,.1);
  border-radius:14px;padding:clamp(22px,2.6vw,32px)}
.form__ok h3{color:#fff}
.form__ok p{margin-top:10px;color:rgba(247,246,242,.72);font-size:clamp(14px,1.2vw,16px)}
@media(max-width:700px){
  .form__row,.pick{grid-template-columns:minmax(0,1fr)}
}

/* ---------- the installer, as the window you will actually see ---------- */
/* The scary part of buying this is the hour between double-clicking a file and
   having something that works. Words cannot answer that; showing the window
   can. Every row here is a real phase of the real install, in the order it
   really runs, which is also why the model download is not hidden. */
.wiz{display:flex;gap:12px;padding:13px 0;border-top:1px solid var(--rule)}
.wiz:first-child{border-top:0;padding-top:0}
.wiz__k{flex:none;width:21px;height:21px;border-radius:50%;position:relative;
  border:1.5px solid rgba(10,10,15,.17)}
.wiz__k b{position:absolute;inset:-1.5px;border-radius:50%;background:var(--teal);
  display:grid;place-items:center;color:#fff;font-size:11px;font-weight:700;line-height:1}
.wiz__b{flex:1;min-width:0}
.wiz__t{font-size:13px;font-weight:650;color:var(--ink);letter-spacing:-.005em}
.wiz__m{font-size:11.5px;line-height:1.45;color:var(--g2);margin-top:3px}
.wiz__m em{font-style:normal;font-family:var(--mono);font-size:11px;color:var(--ink)}
.wiz__opt{display:flex;gap:7px;margin-top:9px;flex-wrap:wrap}
.wiz__opt span{font-size:11px;border:1px solid var(--rule);border-radius:999px;
  padding:6px 11px;color:var(--g3);white-space:nowrap}
.wiz__opt span.on{border-color:rgba(107,79,216,.5);background:rgba(107,79,216,.09);
  color:var(--violet-deep);font-weight:650}
.wiz__d{margin-top:15px;border-radius:12px;border:1px solid rgba(63,156,148,.35);
  background:rgba(63,156,148,.08);padding:13px 15px}
.wiz__d b{display:block;font-size:13.5px;color:#1f6b60}
.wiz__d i{display:block;font-style:normal;font-size:11.5px;color:var(--g2);margin-top:4px}
/* The window rides alongside the four steps rather than scrolling away from
   the text that describes it. Only where there are two columns to ride beside. */
@media(min-width:901px){.stick{position:sticky;top:92px}}

/* ---------- the phone, because that is where most of it happens ---------- */
/* The bezel is what makes this read as a device on a pale section; the screen
   stays light so every message, work row and chip already built for .frame
   works here without a second theme to keep in step. */
.phone{width:min(304px,100%);margin:0 auto;border-radius:38px;padding:10px;
  background:#0d0d13;border:1px solid rgba(10,10,15,.2);
  box-shadow:0 30px 60px -24px rgba(10,10,15,.45),0 2px 5px rgba(10,10,15,.18)}
.phone__s{position:relative;border-radius:29px;overflow:hidden;background:#fff}
.phone__n{position:absolute;top:8px;left:50%;transform:translateX(-50%);z-index:2;
  width:74px;height:19px;border-radius:999px;background:#0d0d13}
.phone__bar{display:flex;align-items:center;gap:8px;padding:26px 16px 11px;
  background:#f4f3ef;border-bottom:1px solid rgba(10,10,15,.08)}
.phone__bar .frame__brand svg{width:17px;height:17px}
.phone__t{font-size:12.5px;font-weight:700;color:var(--ink);letter-spacing:-.01em}
.phone__t em{font-style:normal;font-weight:550;color:var(--g3)}
.phone__foot{padding:11px 13px 15px;border-top:1px solid rgba(10,10,15,.08);background:#faf9f6}

/* The one control the phone really has. It pulses while it is listening, which
   is the only state a voice interface needs to show. */
.mic{display:flex;align-items:center;gap:10px}
.mic__b{position:relative;flex:none;width:38px;height:38px;border-radius:50%;
  background:var(--violet-deep);display:grid;place-items:center}
.mic__b svg{width:16px;height:16px;fill:#fff}
.mic__r{position:absolute;inset:0;border-radius:50%;border:2px solid var(--violet-deep)}
.seq.play .mic__r{animation:sRing 1.7s ease-out infinite}
.mic__t{font-size:12px;color:var(--g2)}
/* The work rows were built for a desktop frame. In a 300px screen the label
   column eats the bar it is meant to be labeling. */
.phone .wrow{font-size:11px;gap:8px}
.phone .wrow .wt{min-width:62px}
.phone .wm{min-width:30px}

/* ---------- questions ---------- */
/* A reading column rather than a grid of cards. These answers are prose and the
   eye should be able to run straight down them; two columns would turn a page
   somebody is scanning for one number into a puzzle about where to look next. */
.faq{margin-top:clamp(18px,2.4vw,30px);border-top:1px solid var(--rule);max-width:78ch}
.faq__q{padding:clamp(22px,2.6vw,32px) 0;border-bottom:1px solid var(--rule)}
.faq__q h3{margin-bottom:clamp(8px,.9vw,12px)}
.faq__q p{font-size:clamp(15px,1.3vw,17px);line-height:1.62;color:var(--g1)}
.dark .faq,.dark .faq__q{border-color:var(--rule-d)}
.dark .faq__q p{color:rgba(247,246,242,.72)}

/* Available to a screen reader and to a crawler, absent to the eye. Used where
   a page is an application rather than a document and still owes the reader a
   heading: /apply is a conversation, so its <h1> is spoken, not drawn. */
.a11y{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}
