/* Inflection — light, warm paper. Elegant serif, one terracotta accent, and the
   product rendered in the same light as the page it sits on. See DESIGN.md */
:root{
  /* THE LADDER. Depth is lightness and hairlines, never a shadow.
     The steps are tighter than the dark set's were: display gamma compresses
     the bottom of the range, so an ink theme needs wide gaps to read at all.
     Up here an equal ratio is plainly visible, and a wide one shouts.
       --ground  the page               #F4F0E9
       --band    a stage, a rest, foot  #EBE5DB
       --panel   a raised surface       #FBF9F5
       --white   a card on that panel   #FFFFFF
     --ink and --paper are an inverse pair used by ten components (.btn.solid,
     .cons-btn …), so the whole theme flips by swapping their two values — which
     is why nothing here is ever hardcoded. The ground stays in --ink's hue
     family: the photography is warm sand and the accent is terracotta, and a
     cold ground fights both. */
  --ground:#F4F0E9; --band:#EBE5DB; --panel:#FBF9F5; --white:#FFFFFF;
  --paper:#FBF9F5;  --surface:#F4F0E9; --surface2:#EBE5DB;
  --ink:#171310; --ink2:#4C443C; --mut:#7E7469; --faint:#A9A093;
  --line:#E5DED3; --line-2:#D6CCBD;
  --accent:#B4552D; --accent-soft:rgba(180,85,45,.09);
  /* the photograph's veil, as an rgb triple so .art can set its own alpha ramp */
  --art-scrim:251,249,245;
  /* --faint is 4.25:1 on --panel: rules, dots, marks and disabled states only.
     Any small text that carries meaning takes --mut (5.7:1) or better. */
  --serif:"Instrument Serif",Georgia,"Times New Roman",serif;
  --sans:"DM Sans","Helvetica Neue",Arial,sans-serif;
  --mono:"JetBrains Mono",ui-monospace,Menlo,monospace;
  --max:1200px; --pad:clamp(20px,4vw,56px);
  --r:18px;
  --e:cubic-bezier(.22,.8,.24,1);
  color-scheme:light;
}
*{box-sizing:border-box;margin:0;padding:0}
html{scroll-behavior:smooth}
body{background:var(--ground);color:var(--ink2);font-family:var(--sans);font-size:17px;line-height:1.62;-webkit-font-smoothing:antialiased;overflow-x:hidden}
a{color:inherit;text-decoration:none}
::selection{background:var(--accent);color:var(--paper)}
.pad{padding-left:var(--pad);padding-right:var(--pad)}
.wrap{max-width:var(--max);margin:0 auto}

/* type */
h1,h2,h3{color:var(--ink);font-family:var(--serif);font-weight:400;letter-spacing:-.012em;line-height:1.06;text-wrap:balance}
h1 em,h2 em,h3 em{font-style:italic}
.display{font-family:var(--serif);font-weight:400;text-transform:none;letter-spacing:-.015em;line-height:1.06}
.lbl{font-family:var(--sans);font-size:.74rem;font-weight:500;letter-spacing:.02em;color:var(--ink)}
.lbl.m{color:var(--mut)}
.mono{font-family:var(--mono);font-size:.68rem;letter-spacing:.06em;text-transform:uppercase}
.body-up{text-transform:none;font-size:1.06rem;line-height:1.62;font-weight:400;color:var(--ink2)}
.prose{font-size:1.04rem;line-height:1.68;color:var(--ink2);max-width:64ch}
.prose p+p{margin-top:16px}
.prose strong{color:var(--ink);font-weight:700}
.eyebrow{font-size:.78rem;font-weight:500;color:var(--accent);letter-spacing:.02em;display:block;margin-bottom:16px}

/* top bar + nav */

.btn{display:inline-flex;align-items:center;gap:.5em;font-family:var(--sans);font-size:.94rem;font-weight:500;
  padding:.82em 1.5em;border-radius:999px;border:1px solid transparent;cursor:pointer;
  transition:transform .22s var(--e),background .2s,color .2s,border-color .2s}
.btn.solid{background:var(--ink);color:var(--paper)}
.btn.solid:hover{background:#2E2721}
.btn.solid:hover{transform:translateY(-2px)}
.btn.ghost{background:transparent;color:var(--ink);border-color:var(--line)}
.btn.ghost:hover{background:var(--white);border-color:var(--faint)}
.btn.sm{padding:.62em 1.15em;font-size:.86rem}
.btn.light{background:var(--white);color:var(--ink)}

/* hero — see the masthead block further down; this is only the shared frame */
.hero{max-width:var(--max);margin:0 auto;padding-top:clamp(40px,6vw,84px);padding-bottom:clamp(28px,4vw,44px)}

/* photography */
/* full-bleed band with text over image */

/* split image + text */

/* ============================================================
   SECTION HEADS — a left rail the whole page hangs off.
   Everything used to be centred: eyebrow, headline, paragraph, all
   stacked on one axis for nine sections running, with the content
   centred under them. The heading now holds a narrow column at the
   left and the section's content sits beside it. One axis, always
   the same one — no mirroring, nothing to track across the page.
   ============================================================ */
section{padding-top:clamp(46px,6vw,92px);padding-bottom:clamp(46px,6vw,92px)}
section.nb{padding-top:clamp(30px,4vw,56px)}
.sec-top{
  text-align:left;max-width:none;margin:0;
}
/* Some heads wrap their headline and paragraph in a bare <div> and some do not;
   display:contents dissolves the wrapper so both behave identically. */
.sec-top>div{display:contents}
.sec-top .sec-no,.sec-top .lbl.m.sec-no{margin-bottom:12px}
.sec-top h2{font-size:clamp(1.8rem,2.6vw,2.5rem);max-width:16ch;margin:0}
.sec-top .intro{margin:16px 0 0;max-width:42ch;font-size:.98rem}

@media(max-width:860px){
  .sec-top .intro{margin-top:14px}
}
.sec-no{display:block;font-size:.78rem;font-weight:500;color:var(--accent);margin-bottom:14px;letter-spacing:.02em}
/* inner pages mark sections with `lbl m sec-no`, and .lbl.m out-specifies
   .sec-no — without this the page accent never appears */
.lbl.m.sec-no{color:var(--accent)}

/* cards (soft, rounded, warm) */
.cols{display:grid;grid-template-columns:repeat(3,1fr);gap:18px;max-width:var(--max);margin:0 auto}
.cols.two{grid-template-columns:repeat(2,1fr)}
/* BENTO. Four equal cards in a row is a spec sheet; the eye reads one and
   assumes the other three say the same thing at the same volume. Six tracks
   with a 4/2 · 2/4 split gives the block a diagonal and makes the first and
   last card the ones you actually land on. */
.cols.four{grid-template-columns:repeat(6,1fr);gap:14px}
.cols.four>div{display:flex;flex-direction:column}
.cols.four>div:nth-child(1){grid-column:span 4}
.cols.four>div:nth-child(2){grid-column:span 2}
.cols.four>div:nth-child(3){grid-column:span 2}
.cols.four>div:nth-child(4){grid-column:span 4}
.cols.four>div p{margin-top:auto;padding-top:10px}
@media(max-width:1000px){
  .cols.four{grid-template-columns:repeat(2,1fr)}
  .cols.four>div:nth-child(n){grid-column:span 1}
}
@media(max-width:860px){.cols,.cols.two{grid-template-columns:1fr}}
@media(max-width:560px){.cols.four{grid-template-columns:1fr}}
.cols>div{background:var(--white);border:1px solid var(--line);border-radius:var(--r);padding:26px;
  transition:transform .25s var(--e)}
.cols>div:hover{transform:translateY(-3px);}
.cols h3{font-size:clamp(1.25rem,1.7vw,1.55rem);margin:14px 0 8px}
.cols p{font-size:.95rem;color:var(--ink2)}
.cols .n{font-family:var(--sans);font-size:.76rem;font-weight:500;color:var(--accent)}

/* rows */
.rows{max-width:var(--max);margin:0 auto;border-top:1px solid var(--line)}
.row{display:grid;grid-template-columns:auto 1fr auto;gap:clamp(16px,3vw,40px);align-items:baseline;
  padding:26px 4px;border-bottom:1px solid var(--line);transition:background .25s,padding-left .25s var(--e)}
.row:hover{background:var(--white);padding-left:12px}
@media(max-width:700px){.row{grid-template-columns:1fr;gap:6px}.row .tag{display:none}}
.row h3{font-size:clamp(1.25rem,2.2vw,1.6rem)}
.row p{font-size:.96rem;color:var(--ink2);max-width:62ch;margin-top:8px}
.row .tag{font-family:var(--mono);font-size:.64rem;color:var(--faint);white-space:nowrap;text-transform:uppercase}

/* split */
.split{display:grid;grid-template-columns:1fr 1fr;gap:clamp(26px,4vw,60px);align-items:center;max-width:var(--max);margin:0 auto}
@media(max-width:860px){.split{grid-template-columns:1fr;gap:28px}}
.ck-list{list-style:none}
.ck-list li{display:grid;grid-template-columns:auto 1fr;gap:14px;padding:15px 0;border-bottom:1px solid var(--line);font-size:.98rem;color:var(--ink2)}
.ck-list li b{font-family:var(--sans);font-size:.8rem;color:var(--accent);font-weight:600}
.panel{background:var(--white);border:1px solid var(--line);border-radius:var(--r);overflow:hidden}
.panel .p-row{display:flex;justify-content:space-between;align-items:center;gap:12px;padding:16px 20px;border-bottom:1px solid var(--line);font-size:.92rem}
.panel .p-row:last-child{border-bottom:none}
.panel .p-row b{font-family:var(--mono);font-size:.7rem;font-weight:500;color:var(--ink)}
.panel .p-row .inv{background:var(--accent-soft);color:var(--accent);padding:4px 11px;border-radius:999px;font-size:.74rem;font-weight:600}

/* code */
.term{max-width:var(--max);margin:0 auto;border-radius:var(--r);background:var(--band);color:var(--ink2);
  border:1px solid var(--line);padding:26px;
  font-family:var(--mono);font-size:.82rem;line-height:1.7;overflow-x:auto}
.term .c{color:var(--faint)}

/* numbers */
@media(max-width:860px){.nums{grid-template-columns:1fr}}

/* comparison */
.tbl-wrap{max-width:var(--max);margin:0 auto;overflow-x:auto;background:var(--white);border:1px solid var(--line);border-radius:var(--r)}
/* 620, not 700: the table now lives in the body column beside a heading rail
   rather than across the full page, and 700 forced a scrollbar on the one
   comparison the page is built around. */
table{border-collapse:collapse;width:100%;min-width:620px}
/* A two-column table has no reason to force a 700px scroll on a phone — that
   floor exists for the six-column matrix, where the columns really cannot
   compress. `.narrow` opts a table out of it. */
.tbl-wrap.narrow table{min-width:0}
@media(max-width:600px){.tbl-wrap.narrow th,.tbl-wrap.narrow td{padding:13px 14px;font-size:.86rem}}
th,td{text-align:left;padding:15px 16px;font-size:.9rem;border-bottom:1px solid var(--line);vertical-align:top}
thead th{font-size:.76rem;font-weight:600;color:var(--mut);vertical-align:bottom}
tbody th{font-family:var(--serif);font-weight:400;font-size:1.1rem;color:var(--ink);white-space:nowrap}
tbody tr:last-child th,tbody tr:last-child td{border-bottom:none}
tr.me{background:var(--white)}
tr.me th,tr.me td{color:var(--ink);border-color:var(--line-2)}
tr.me th{font-style:italic}
td.c{text-align:center;font-size:.84rem}
.tyes{color:var(--accent);font-weight:600}
tr.me .tyes{color:var(--accent)}
.tno{color:var(--faint)}
tr.me .tno{color:var(--mut)}
.src{font-size:.9rem;color:var(--ink2);line-height:1.75;max-width:76ch;margin:0 auto}
.src a{border-bottom:1px solid var(--line)}

/* pricing */
.plans{display:grid;grid-template-columns:repeat(3,1fr);gap:18px;max-width:var(--max);margin:0 auto}
@media(max-width:900px){.plans{grid-template-columns:1fr}}
.plan{background:var(--white);border:1px solid var(--line);border-radius:var(--r);padding:30px;display:flex;flex-direction:column}
.plan.feat{background:var(--white);color:var(--ink2);border-color:var(--accent)}
.plan.feat h3,.plan.feat .price{color:var(--ink)}
.plan.feat .pl-list li{color:var(--ink2);border-color:var(--line-2)}
.plan h3{font-size:1.5rem}
.plan .who{font-size:.9rem;color:var(--mut);margin-top:8px;min-height:2.8em}
.plan.feat .who{color:var(--mut)}
.plan .price{font-family:var(--serif);font-size:clamp(2.4rem,4.4vw,3.2rem);letter-spacing:-.03em;margin:22px 0 4px;line-height:1;color:var(--ink)}
.plan .price small{font-family:var(--sans);font-size:.86rem;color:var(--mut);letter-spacing:0}
.plan.feat .price small{color:var(--mut)}
.pl-list{list-style:none;margin:20px 0 26px}
.pl-list li{font-size:.92rem;color:var(--ink2);padding:10px 0;border-bottom:1px solid var(--line)}
.plan .btn{margin-top:auto;justify-content:center;align-self:stretch;text-align:center}
.plan.feat .btn{background:var(--ink);color:var(--paper);border-color:var(--ink)}

/* faq */
.faq{max-width:none;margin:0;border-top:1px solid var(--line)}
.faq details{border-bottom:1px solid var(--line)}
.faq summary{padding:22px 0;font-family:var(--serif);font-size:1.3rem;color:var(--ink);cursor:pointer;list-style:none;display:flex;justify-content:space-between;gap:16px}
.faq summary::-webkit-details-marker{display:none}
.faq summary::after{content:"+";color:var(--accent);font-family:var(--sans);font-weight:400}
.faq details[open] summary::after{content:"–"}
.faq .a{padding:0 0 24px;font-size:.98rem;color:var(--ink2);max-width:70ch}

/* closing cta band */
/* footer */
footer{border-top:1px solid var(--line);padding-top:52px;padding-bottom:44px;margin-top:20px}
.fgrid{display:grid;grid-template-columns:1.6fr repeat(4,1fr);gap:28px;max-width:var(--max);margin:0 auto}
@media(max-width:860px){.fgrid{grid-template-columns:1fr 1fr}}
.fgrid h4{font-size:.78rem;font-weight:600;color:var(--mut);margin-bottom:14px}
.fgrid ul{list-style:none;display:flex;flex-direction:column;gap:9px}
.fgrid li a,.fgrid li{font-size:.9rem;color:var(--ink2);transition:color .2s}
.fgrid li a:hover{color:var(--accent)}
.fgrid .soon{font-size:.66rem;color:var(--faint);border:1px solid var(--line);border-radius:999px;padding:1px 7px;margin-left:6px}
.fbot{max-width:var(--max);margin:44px auto 0;padding-top:22px;border-top:1px solid var(--line);display:flex;justify-content:space-between;flex-wrap:wrap;gap:10px;font-size:.86rem;color:var(--mut)}

/* ============================================================
   PER-PAGE THEMES
   Ink and paper never change — that is the brand. What changes is
   the accent and how heavily the photograph is veiled, and both are
   set by the job the page has to do. Pages that must be *read*
   (thesis, compare, security) veil harder so type wins. Pages that
   must be *felt* (home, pricing) let the picture through.
   ============================================================ */
/* One accent, and a slice of the ramp per page.

   There used to be seven per-page accent hues. Three belonged to pages that no
   longer exist, four failed contrast on a dark ground at the size the accent is
   actually used (t-product's #3F6B4A is 3.15:1), and half of every block was
   dead — --card-scrim and --hero-scrim were declared eight times and read zero.
   What survives is a temperature, used only by .grad and section marks, never
   at body scale. */
.t-home   {--ir:linear-gradient(104deg,#8E3A18,#C99A4E)}
.t-product{--ir:linear-gradient(104deg,#C99A4E,#7E9A7B)}
.t-pricing{--ir:linear-gradient(104deg,#B4552D,#C99A4E)}
.t-trust  {--ir:linear-gradient(104deg,#7E9A7B,#5E7C95)}

/* ============================================================
   PAGE FLOW — plain vertical scroll.
   These pages used to be a deck: every section a sticky full-height
   card with the next one rising over it. It cost more than it bought.
   A section taller than the viewport had to be pinned by its bottom
   to stay reachable, mockups got clipped on short screens, and no
   section could be longer than one screen without a workaround. The
   `.stack` class is kept as the hook so no page markup changes; what
   it now means is "this page carries the photograph".
   ============================================================ */
body.stack{overflow-x:clip;position:relative;background:var(--ground)}
/* The photograph is no longer the page ground. It appears twice — behind the
   hero and behind the closing call — and everything between them stands on a
   dotted grid instead. A picture behind body copy is a contrast tax paid on
   every line; a grid is free and does the same job of saying "this is a
   surface, not a document". */
body.stack::before{
  content:"";position:fixed;inset:0;z-index:-1;pointer-events:none;
  background-image:radial-gradient(circle at 1px 1px,var(--dot) 1px,transparent 0);
  background-size:22px 22px;
}
/* A section that carries the artwork. */
.art{position:relative;isolation:isolate}
/* The artwork bleeds the full viewport even when its section is a centred
   max-width column, which is the only way it reads as a backdrop rather than
   a picture someone dropped into the layout. */
.art::before,.art::after{
  content:"";position:absolute;top:0;bottom:0;left:50%;width:100vw;
  transform:translateX(-50%);pointer-events:none;
}
.art::before{z-index:-2;background-image:var(--bg);background-size:cover;background-position:center bottom}
/* Weighted to the top, where the headline sits, but the floor never reaches
   zero: the photography is dark, and on a paper page an unveiled ridge reads as
   a slab dropped into the layout rather than as a backdrop. */
.art::after{z-index:-1;background:linear-gradient(180deg,
  rgba(var(--art-scrim),.94) 0%,rgba(var(--art-scrim),.88) 26%,
  rgba(var(--art-scrim),.78) 52%,rgba(var(--art-scrim),.70) 78%,rgba(var(--art-scrim),.66) 100%)}
body.stack > header.hero,
body.stack > section{
  position:relative;
  padding-top:clamp(56px,8vw,120px);
  padding-bottom:clamp(56px,8vw,120px);
}
/* Each beat owns a screen. min-height, never height: three of these sections
   carry a 1180px console and are taller than any viewport — a fixed height
   would clip them, and the deck this site used to be is exactly how that bug
   shipped last time. Content centres in whatever space is left over. */
body.stack > section{
  min-height:100svh;display:grid;grid-template-columns:minmax(0,1fr);
  gap:0 clamp(28px,4.5vw,80px);align-content:center;
  max-width:calc(var(--max) + var(--pad) * 2);margin-left:auto;margin-right:auto;
}
/* A section with a heading block splits: the heading takes a narrow rail on the
   left and everything else sits beside it, rather than centred underneath. */
body.stack>section:has(>.sec-top),body.stack>section:has(>.tour){
  grid-template-columns:minmax(0,clamp(230px,24vw,340px)) minmax(0,1fr);
}
body.stack>section:has(>.sec-top)>*,body.stack>section:has(>.tour)>*{grid-column:2}
body.stack>section>.sec-top,body.stack>section>.tour{
  grid-column:1;align-self:start;position:sticky;top:clamp(76px,17vh,160px);
}
/* The rail only travels where there is something to travel past. A section whose
   content is one product surface has a single row, so spanning would do nothing
   but stop the stage clearing the rail. */
body.stack>section:not(:has(>.stage))>.sec-top,
body.stack>section:not(:has(>.tour ~ .stage))>.tour{grid-row:1/-1}
/* The console is authored at 1180px and scaled to its container. In the body
   column it would render around 0.7 and put its UI type under 11px, so it takes
   the full width and the rail sits above it. */
body.stack>section>.stage{grid-column:1/-1;margin-top:clamp(26px,3.4vw,44px)}

@media(max-width:900px){
  body.stack > section{min-height:0;grid-template-columns:1fr}
  body.stack>section:has(>.sec-top),body.stack>section:has(>.tour){grid-template-columns:1fr}
  body.stack>section:has(>.sec-top)>*,body.stack>section:has(>.tour)>*{grid-column:1}
  body.stack>section>.sec-top,body.stack>section>.tour{
    grid-column:1;grid-row:auto;position:static;margin-bottom:28px}
  body.stack>section>.stage{grid-column:1}
}
body.stack > header.hero{padding-top:clamp(56px,8vw,120px);padding-bottom:clamp(80px,11vw,170px)}
/* A rule between sections is the only separator now — no card edges,
   no shadows. `.nb` still means "this belongs to the section above". */
body.stack > section + section{border-top:1px solid var(--line)}
body.stack > section.nb{border-top:none;padding-top:clamp(30px,4vw,56px)}
body.stack > section[style*="padding-top:0"]{border-top:none}
body.stack > footer{position:relative;z-index:2;background:var(--band)}

/* ============================================================
   REVEAL — direction-aware, and staggered inside a group.

   It used to be a plain fade in place. Now the motion agrees with
   the layout: a block that lives on the left arrives from the
   left, its mirror arrives from the right, and lists deal
   themselves out one item at a time. --d is set by site.js from
   the element's index among its siblings, so a row of four cards
   lands as four events instead of one.
   ============================================================ */
.rv{opacity:0;transform:translate3d(0,22px,0);
  transition:opacity .75s var(--e),transform .75s var(--e);
  transition-delay:calc(var(--d,0) * 70ms)}
.rv.in{opacity:1;transform:none}

/* heading blocks arrive along the rail they sit on — always from the left */
.sec-top.rv,.tour.rv{transform:translate3d(-26px,10px,0)}
.sec-top.rv.in,.tour.rv.in{transform:none}

/* a mockup resolves rather than slides — it is a photograph, not a card */
.stage.rv,.tbl-wrap.rv{transform:scale(.985)}
.stage.rv.in,.tbl-wrap.rv.in{transform:none}
/* a headline at hero scale, for section headings that carry the same weight */
h2.xl{font-size:clamp(2.6rem,6.4vw,5.2rem);line-height:1.06}
@media(prefers-reduced-motion:reduce){*{animation:none!important;transition:none!important}
  .rv,.rv.in{opacity:1!important;transform:none!important}}

/* ============================================================
   GLASS LAYER
   One fixed photograph per page (set via --bg on <body>), a
   paper scrim for legibility, and frosted surfaces on top.
   ============================================================ */
:root{
  --glass:rgba(251,249,245,.72);
  --glass-2:rgba(255,255,255,.86);
  --glass-line:var(--line);
  --glass-dark:rgba(23,19,16,.9);
  --blur:saturate(1.6) blur(20px);
}
/* The page ground is warm sand, one step deeper than paper. That step is the
   whole depth system now that there are no shadows: sand page → paper panel →
   white card. Anything that needs to lift gets lighter, never a drop shadow.

   There used to be a second photograph here — a fixed, full-viewport copy of
   --bg under a heavy scrim — layered beneath the dot grid and *behind* the
   .art hero's own copy of the same image. Two veiled photographs stacked under
   every section is what made the whole page read as beige mush. The picture now
   appears only where .art puts it: the hero and the closing call. */
body{background:var(--ground)}

/* frosted surfaces */
.cols>div,.nums>div,.panel,.plan,.tbl-wrap{
  background:var(--glass);border-color:var(--glass-line);}
.tab,.btn.ghost,.btn.light{background:var(--glass);border-color:var(--glass-line);
}
.cols>div:hover{background:var(--glass-2);
}
.btn.ghost:hover{background:var(--glass-2);border-color:var(--line-2)}
/* list-style blocks get a pane of their own */
.rows,.faq{background:var(--glass);border:1px solid var(--glass-line);
  border-radius:var(--r);padding:6px clamp(18px,3vw,32px);}
.row:hover{background:var(--panel)}

tr.me{background:var(--white)}
footer{background:var(--band);border-top:1px solid var(--line);
  border-radius:var(--r) var(--r) 0 0;margin-top:40px;padding-left:clamp(18px,3vw,34px);padding-right:clamp(18px,3vw,34px)}
/* every page runs the same masthead: label, headline, sub, buttons */
.hero>.lbl{display:block;margin-bottom:18px}

/* ============================================================
   TEN-MINUTE CLOCK — the hero. Two columns, one clock: what a
   person gets done, and what Inflection gets done, in the same
   ten minutes.
   ============================================================ */
/* two teleprompters running off the same clock — no cards, just type */
@media(min-width:721px){
  .clock-cols::before{content:"";position:absolute;left:50%;top:6px;bottom:6px;width:1px;
    background:linear-gradient(180deg,transparent,var(--line) 22%,var(--line) 78%,transparent)}
}
/* the window the lines scroll through, faded at both ends */
/* The track is driven frame by frame off the clock, so no CSS transition
   here. Every line is the same fixed height and the current one is scaled
   rather than resized — layout never shifts, so the scroll stays smooth. */
/* the line that is happening right now */
.sec-top .cta{display:flex;gap:12px;justify-content:center;flex-wrap:wrap;margin-top:clamp(24px,3.2vw,34px)}
.sec-top.left .cta{justify-content:flex-start}

/* ============================================================
   THESIS VISUALISATIONS
   All CSS/SVG, all animated off the same .rv reveal — no canvas,
   no per-frame work, nothing that can stutter the stack.
   ============================================================ */

/* 01 — the two layers */
#viz-layers{display:grid;gap:clamp(18px,2.6vw,30px);max-width:860px}
.rv.in .lay-bar i{width:var(--w)}

/* 02 — wiring vs perception */
.rv.in .wire-panel .mesh line{stroke-dashoffset:0}
.rv.in .wire-panel.me .hub{opacity:1}
/* stagger the mesh so the tangle draws itself line by line */

/* 04 — the generated interface */
.rv.in .gf{opacity:1;transform:none}

/* 05 — three eras */
/* the dot on the timeline */

/* ============================================================
   SOUND TOGGLE — bottom right, out of the dock's way. Off until
   asked for; the bars only move while something is playing.
   ============================================================ */
.snd{position:fixed;right:clamp(14px,2.4vw,26px);bottom:clamp(14px,2.4vw,26px);z-index:200;
  width:46px;height:46px;border-radius:50%;border:1px solid var(--glass-line);
  background:var(--glass-2);backdrop-filter:var(--blur);color:var(--ink);cursor:pointer;
  display:grid;place-items:center;
  transition:background .2s,color .2s,transform .2s var(--e)}
.snd:hover{transform:scale(1.08)}
.snd.on{background:var(--ink);border-color:var(--ink);color:var(--paper)}
.snd-bars{display:flex;align-items:center;gap:2.5px;height:16px}
.snd-bars i{display:block;width:2.5px;height:5px;border-radius:2px;background:currentColor;
  transition:height .3s var(--e)}
/* resting state reads as a muted equaliser */
.snd.on .snd-bars i{animation:sndbar 1.5s ease-in-out infinite}
.snd.on .snd-bars i:nth-child(2){animation-delay:.25s}
.snd.on .snd-bars i:nth-child(3){animation-delay:.5s}
.snd.on .snd-bars i:nth-child(4){animation-delay:.12s}
@keyframes sndbar{0%,100%{height:4px}50%{height:15px}}
.snd::after{content:attr(data-t);position:absolute;right:calc(100% + 10px);top:50%;
  transform:translateY(-50%) translateX(6px);white-space:nowrap;
  font-family:var(--sans);font-size:.75rem;font-weight:500;
  background:var(--ink);color:var(--paper);padding:5px 11px;border-radius:999px;
  opacity:0;transition:opacity .2s,transform .2s var(--e);pointer-events:none}
.snd:hover::after{opacity:1;transform:translateY(-50%)}
@media(prefers-reduced-motion:reduce){.snd.on .snd-bars i{animation:none;height:9px}}
/* on narrow screens the dock ring reaches the right edge — move out of its way */
@media(max-width:520px){.snd{top:clamp(12px,3vw,18px);bottom:auto}}

/* ============================================================
   DOCK — one horizontal pill, bottom-centre.

   The same object as the product's dock (`.cons-dock` in console.css): icons
   only, except the current page, which expands into a labelled pill. The
   marketing nav and the app nav are now the same thing, which is the point.

   It replaces a radial version that hid every link behind a hover on a wide
   invisible field, and needed ~130 lines of CSS, 44 lines of JS, seven inline
   angles and seven !important overrides to do it. A row is always readable, so
   all of that machinery is gone.
   ============================================================ */
.dock{position:fixed;left:50%;transform:translateX(-50%);bottom:clamp(14px,2.4vw,22px);
  z-index:200;display:flex;gap:6px;align-items:center;
  padding:6px;border:1px solid var(--glass-line);border-radius:16px;
  background:var(--glass);backdrop-filter:var(--blur);max-width:calc(100vw - 24px)}
.dock a{display:flex;align-items:center;gap:8px;height:44px;width:44px;flex:none;
  justify-content:center;border-radius:12px;color:var(--mut);
  transition:color .2s,background .2s}
.dock a svg{width:20px;height:20px;fill:none;stroke:currentColor;stroke-width:1.6;
  stroke-linecap:round;stroke-linejoin:round;flex:none}
.dock a:hover{color:var(--ink)}
.dock a.here{background:var(--surface2);color:var(--ink);width:auto;padding:0 14px 0 12px}
.dock a.here span{font-size:.9rem;font-weight:500;white-space:nowrap}
.dock a:not(.here) span{display:none}
/* the CTA is the one item that is not a page */
.dock .dock-cta{background:var(--ink);color:var(--paper);width:auto;padding:0 16px;
  font-size:.9rem;font-weight:500;margin-left:2px}
.dock .dock-cta:hover{color:var(--paper);background:#2E2721}

@media(max-width:560px){
  .dock{gap:2px;padding:5px}
  .dock a{height:40px;width:40px;border-radius:11px}
  .dock a.here{padding:0 12px 0 10px}
  .dock .dock-cta{padding:0 13px;font-size:.84rem}
}

/* ============================================================
   PRODUCT TOUR — added 2026-08-02
   The page used to argue in prose. Structure borrowed from the
   long-scroll tour pattern: one claim per card, and under every
   claim the product surface that makes it true. Everything here
   is a wireframe of our own UI drawn in the paper palette — no
   screenshots, no logos, no customer data. Mockups that carry
   numbers are labelled `.mk-note` so nothing reads as a metric.
   ============================================================ */

/* hero url capture — "paste your product URL" is literally the onboarding */
.urlbar{display:flex;gap:0;max-width:520px;margin:26px 0 0;border:1px solid var(--line-2);
  border-radius:999px;background:var(--white);overflow:hidden;}
.urlbar input{flex:1;min-width:0;border:0;background:transparent;padding:15px 22px;
  font-family:var(--sans);font-size:.96rem;color:var(--ink);outline:none}
.urlbar input::placeholder{color:var(--faint)}
.urlbar button{border:0;background:var(--ink);color:var(--paper);font-family:var(--sans);
  font-size:.92rem;font-weight:500;padding:0 24px;cursor:pointer;white-space:nowrap;transition:background .2s}
.urlbar button:hover{background:#2E2721}
.urlbar-note{margin:12px auto 0;font-size:.84rem;color:var(--mut);text-align:center}
@media(max-width:520px){.urlbar{flex-direction:column;border-radius:var(--r)}.urlbar button{padding:14px}}

/* the eyebrow pill — a bordered mono chip, centred above the claim */
.eyepill{display:inline-flex;align-items:center;gap:9px;font-family:var(--mono);font-size:.66rem;
  letter-spacing:.09em;text-transform:uppercase;color:var(--ink2);background:var(--white);
  border:1px solid var(--line);border-radius:6px;padding:9px 16px;margin:0 auto 22px}
.eyepill::before{content:"";width:5px;height:5px;background:var(--accent);flex:none}
.tour{max-width:none;margin:0;text-align:left}
.tour h2{font-size:clamp(1.8rem,2.6vw,2.5rem);max-width:16ch;margin:0}
.tour .lede{margin:16px 0 0;max-width:42ch;font-size:.98rem;color:var(--ink2)}
.tour .eyepill{margin:0 0 16px}

/* screen inventory grid */
@media(max-width:700px){.mk-grid{grid-template-columns:repeat(2,1fr)}}

/* ---- click-through capability panel ---- */

/* ---- the engine, on ink ---- */
@media(max-width:900px){.eng-grid{grid-template-columns:repeat(2,1fr)}}
@media(max-width:520px){.eng-grid{grid-template-columns:1fr}}

/* ---- the gap, as bars ---- */
.bars{max-width:760px;margin:0 auto;display:grid;gap:22px}
.bar-r .lab{display:flex;justify-content:space-between;align-items:baseline;gap:14px;margin-bottom:9px}
.bar-r .lab .k{font-size:.95rem;color:var(--ink);font-weight:500}
.bar-r .lab b{font-family:var(--serif);font-size:1.6rem;letter-spacing:-.02em;color:var(--ink);font-weight:400}
.bar-r .t{height:14px;background:var(--surface2);border-radius:999px;overflow:hidden}
.bar-r .t i{display:block;height:100%;background:var(--ink);border-radius:999px;
  width:0;transition:width 1.1s var(--e)}
.bar-r.soft .t i{background:var(--faint)}
.bar-r .why{font-size:.86rem;color:var(--mut);margin-top:9px;max-width:60ch}

/* ============================================================
   VALLEY-CLASS SURFACE — added 2026-08-03
   Gradient is now allowed on this site (see DESIGN.md decision
   log). It is one ramp, drawn from the palette we already had:
   terracotta → amber → sand → sage → slate. It reads iridescent
   without introducing a hue the brand does not own. It is only
   ever used as artwork — headline fills on ink, the engine
   slabs, panel washes. Body copy is never gradient.
   ============================================================ */
:root{
  --dot:#E3DBCF;
  /* The floor is the first AND last stop, so it has to clear the ground at both
     ends of the cycle or an animated headline fades out twice per loop. On
     paper that means going deeper, not lighter. */
  --ir:linear-gradient(104deg,#8E3A18 0%,#B4552D 20%,#C99A4E 44%,#7E9A7B 68%,#5E7C95 88%,#8E3A18 100%);
  --ir-soft:linear-gradient(104deg,rgba(192,118,58,.16),rgba(210,128,63,.14),rgba(228,201,143,.16),rgba(169,192,166,.14),rgba(143,166,194,.14));
  --ink-deep:#100D0B;
}

/* gradient headline fill — artwork only, never body copy */
.grad{background:var(--ir);-webkit-background-clip:text;background-clip:text;
  color:transparent;-webkit-text-fill-color:transparent;background-size:180% 100%;
  animation:irshift 14s linear infinite}
@keyframes irshift{to{background-position:180% 0}}
@media(prefers-reduced-motion:reduce){.grad{animation:none}}

/* ---------- node diagram: what feeds the engine ---------- */
@media(max-width:760px){
  .node{min-height:0;display:flex;flex-direction:column;gap:10px;align-items:center}
  .node svg{display:none}
  .chip{position:static;transform:none}
  .node .hub{position:static;transform:none;margin-top:8px}
}



/* ---------- the exploded engine ---------- */
@media(max-width:900px){.eng2-top{grid-template-columns:1fr;gap:20px;align-items:start}}
@media(max-width:900px){.eng2-grid{grid-template-columns:1fr}}
@media(max-width:900px){.eng2-col .eng2-cell{border-left:none;border-right:none}}

/* the slabs: four plates of one machine, pulled apart */
@media(prefers-reduced-motion:reduce){.slab{transition:none}}

/* ---------- FAQ, two columns with a watermark ---------- */
.faq2{max-width:var(--max);margin:0 auto;display:grid;grid-template-columns:.85fr 1.15fr;
  border:1px solid var(--line);border-radius:16px;overflow:hidden;background:var(--white)}
@media(max-width:900px){.faq2{grid-template-columns:1fr}}
.faq2-l{position:relative;padding:clamp(30px,4vw,56px);overflow:hidden;background:var(--surface)}
.faq2-l h2{font-size:clamp(1.9rem,3.8vw,3rem);line-height:1.06;position:relative;z-index:1}
.faq2-l .mark{position:absolute;right:-14%;bottom:-18%;width:76%;opacity:.5}
.faq2-l .mark svg{width:100%;height:auto;display:block}
.faq2-r details{border-bottom:1px solid var(--line);border-left:1px solid var(--line)}
.faq2-r details:last-child{border-bottom:none}
.faq2-r summary{padding:24px clamp(20px,2.6vw,34px);font-size:1.04rem;font-weight:500;color:var(--ink);
  cursor:pointer;list-style:none;display:flex;justify-content:space-between;gap:18px;align-items:flex-start}
.faq2-r summary::-webkit-details-marker{display:none}
.faq2-r summary::after{content:"+";color:var(--mut);font-weight:400;font-size:1.2rem;line-height:1;flex:none}
.faq2-r details[open] summary::after{content:"\2013"}
.faq2-r .a{padding:0 clamp(20px,2.6vw,34px) 26px;font-size:.94rem;line-height:1.68;color:var(--ink2);max-width:68ch}

/* ---------- closing artwork ---------- */
/* ---------- footer ----------
   The closing call and the footer used to be two stacked blocks making the same
   ask twice, one of them a section-sized "Start free —" and nothing else. They
   are one block now: the page's photograph opens it, the ask sits on the
   picture, and the link columns sit on near-solid ground underneath. */
body.stack > footer{background:transparent;border-top:1px solid var(--line);
  border-radius:0;color:var(--mut);padding-top:clamp(56px,7vw,92px)}
/* The hero's scrim is weighted to the *top*, where a headline sits. A footer
   wants the opposite ramp: the picture opens it, and every link below has to
   stay readable, so the veil closes to near-opaque at the bottom. */
body.stack > footer.art::after{background:linear-gradient(180deg,
  rgba(var(--art-scrim),.80) 0%,rgba(var(--art-scrim),.92) 44%,
  rgba(var(--art-scrim),.98) 100%)}
/* Every footer runs the same picture, regardless of the page's own --bg. The
   footer is one object repeated three times; giving each copy a different
   photograph made it read as three different footers. */
body.stack > footer.art::before{background-image:url('img/ridge.svg');
  background-position:center top}
.foot-cta{max-width:var(--max);margin:0 auto clamp(52px,7vw,92px);text-align:center}
.foot-cta h2{font-size:clamp(1.9rem,4.2vw,3.2rem);max-width:24ch;margin:0 auto}
.foot-cta p{max-width:52ch;margin:20px auto 0;color:var(--ink2)}
.foot-cta .cta{display:flex;gap:12px;margin-top:32px;justify-content:center;flex-wrap:wrap}
body.stack > footer .home{color:var(--ink)}
body.stack > footer h4{color:var(--faint)}
body.stack > footer li,body.stack > footer li a,body.stack > footer p{color:var(--mut)}
body.stack > footer li a:hover{color:var(--ink)}
body.stack > footer .soon{border-color:var(--line);color:var(--faint)}
body.stack > footer .fbot{border-top:1px solid var(--line);color:var(--faint)}

/* ============================================================
   DUNE — day and night, added 2026-08-03
   The site now runs on one idea borrowed from Villeneuve's Dune:
   the same world in two lights. Paper sections are the desert at
   noon — bleached bone, sand, ochre, dust haze, everything warm
   and over-exposed. Ink sections are the desert at night — blue
   black, cold silver-blue light, and spice as the only warm
   thing in the frame. Nothing else changes between them: same
   type, same rules, same components. Only the light.
   ============================================================ */
/* A .dark section is no longer an inversion — the page is already ink. It is a
   deeper plate with the dot grid thinned out, so the rhythm survives without a
   second palette to maintain. */
.dark{background:var(--band);position:relative;isolation:isolate}
.dark::before{content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;opacity:.6;
  background-image:radial-gradient(circle at 1px 1px,var(--line) 1px,transparent 0);background-size:26px 26px}

/* ============================================================
   HERO — masthead left, the ask answering it on the right.

   It was a centred stack: eyebrow, headline, paragraph, field, all
   on one axis. Two columns set the left/right rhythm the rest of
   the page follows, and put the field at the end of the sentence
   rather than underneath it.
   ============================================================ */
.hero{text-align:left}
.hero .eyepill{margin:0 0 clamp(26px,3.4vw,44px)}
.hero-split{
  display:grid;grid-template-columns:minmax(0,1.08fr) minmax(0,.92fr);
  gap:clamp(26px,4vw,72px);align-items:end;
}
.hero-split h1{font-size:clamp(2.4rem,5.4vw,4.6rem);max-width:13ch;line-height:1.02;margin:0}
.hero-aside{padding-bottom:.5em}
.hero .sub{max-width:46ch;margin:0;font-size:1.06rem;color:var(--ink2)}
.hero .cta{display:flex;gap:12px;margin-top:28px;justify-content:flex-start;flex-wrap:wrap}
@media(max-width:900px){
  .hero-split{grid-template-columns:1fr;gap:24px;align-items:start}
  .hero-split h1{max-width:none}
  .hero-aside{padding-bottom:0}
}
.hero-proof{margin:18px 0 0;font-family:var(--mono);font-size:.64rem;letter-spacing:.09em;
  line-height:1.9;text-transform:uppercase;color:var(--mut);max-width:46ch}
.hero-proof b{color:var(--accent);font-weight:500}
/* The scrim is weighted to the top for the headline, and by the time it reaches
   the sub it has thinned to ~.25 — so on a photographic hero the body ramp is
   not carrying itself against the ridge. These two lift one rung each. */
.hero.art .sub{color:#2E2721}
.hero.art .hero-proof{color:#5C534A}

/* ============================================================
   MOCKUP KIT — added 2026-08-03
   The first pass drew label/value rows, which read as a spec
   sheet rather than a product. These are the pieces of an
   actual app surface: a rail, a toolbar, list rows with an
   icon and a trailing state, tick badges, a working spinner.
   Everything is drawn from tokens, so a mockup dropped into a
   .dark section becomes the night version for free.
   ============================================================ */

/* a rounded-square glyph standing in for a screen, a person, a record */

/* state badges */
@keyframes sp{to{transform:rotate(360deg)}}

/* title and meta are separate lines — as spans they were running together */

/* ============================================================
   PERCEPTION — two columns, animated. Added 2026-08-03.
   Six readings converge on the engine. The connectors draw
   themselves, the chips arrive in sequence, and a pulse runs
   down each line into the hub, so the graphic states the claim
   ("all of this feeds one thing") instead of captioning it.
   ============================================================ */
@media(max-width:960px){.two-col{grid-template-columns:1fr;gap:34px}}

/* the reading list */

/* ---- the converging diagram ---- */
.rv.in .node2 svg path{animation:draw .9s var(--e) forwards}
@keyframes draw{to{stroke-dashoffset:0}}
/* a pulse of signal riding each line into the hub */
.rv.in .node2 svg .pulse{animation:pulse 3.4s linear infinite;opacity:1}
@keyframes pulse{0%{stroke-dashoffset:var(--len,400)}60%,100%{stroke-dashoffset:0}}

.rv.in .node2 .chip{animation:chipin .5s var(--e) forwards}
@keyframes chipin{to{opacity:1;transform:translate(-50%,-50%) scale(1)}}

.rv.in .node2 .hub{animation:chipin .6s var(--e) .78s forwards}

@media(prefers-reduced-motion:reduce){
  .node2 svg path,.node2 .chip,.node2 .hub{animation:none!important;opacity:1;stroke-dashoffset:0;
    transform:translate(-50%,-50%)}
  .node2 svg .pulse{display:none}
}
/* the mark is the centre of the graphic — give it presence */

/* The stacked layout has to beat the animation, not just the base rule: an
   `animation-fill-mode: forwards` keyframe holds its final transform, and the
   keyframe is declared on `.rv.in .node2 .chip`, so a plain `.node2 .chip`
   override in the media query loses. Match the specificity or the chips stay
   translated off the left edge on a phone. */
@media(max-width:960px){
  .rv.in .node2 .chip,.rv.in .node2 .hub,
  .node2 .chip,.node2 .hub{animation:none!important;transform:none;opacity:1}
  .node2 .hub{margin:14px auto 0}
}

@media(max-width:960px){
  /* the hub goes static in the stacked layout, so its gradient ring — which is
     an absolutely positioned ::after — resolved against .node2 and drew a frame
     around the whole column. Keep it positioned. */
  .node2 .hub{position:relative}
  /* `.node2 svg{display:none}` hides the connector drawing, but the mark lives
     in an svg too and was going with it. */
  .node2 .hub svg{display:block}
}
/* "Nothing to wire. / It learns your product." is a two-line headline —
   15ch was forcing "product." onto a third line of its own. */
