/* ================================================================================================
   FERROW — ferrow.ai        site/kit.css · the public site's one stylesheet · zero external requests
   ================================================================================================

   WHY ONE FILE. The app surfaces (web/index.html, src/ui/app.html) each carry their palette inline
   because each is a single page. The site is four pages, and four inline copies of a palette is four
   chances to drift. So the site declares the kit ONCE, here, and every page links it. There is no
   second place to change a colour, which is the only way a four-page site keeps one face.

   AUTHORITY: ~/ruzylo/brain/brain/brand/ferrow-brandkit.html (FROZEN, "Daylight"). Every value below
   is a kit hex under the same local name the two app surfaces already use — a person who set Ferrow
   up in their terminal should recognise this site in the first half second, and that recognition is
   made of exact hexes, not of a similar mood. test/site-kit.test.mjs fails if any of it drifts, and
   it scans EVERY file in site/ for stray hexes, not just this token block.

   DESIGN: THE FIELD LEDGER, CONTINUED — NOT RE-DESIGNED. One furrow line running the page, work
   struck across it as chords, no cards, no boxes, hairline rules, one accent that means something,
   and the 10px tracked monospace label as the single repeated gesture. A marketing site is still a
   ledger: each claim is a row, and each row has to be true.

   MOTION. The furrow draws itself once, in 900ms, and then stops. Chords extend on hover by 14px.
   That is the entire motion system. Anything that moves while you are trying to read is a thing the
   page is doing to you rather than for you, and this product's whole argument is about who is in
   control. @media (prefers-reduced-motion:reduce) removes even those two.
   ================================================================================================ */

/* ---- light: the kit's Daylight palette, verbatim ------------------------------------------------
     --ground    #F5FAFF  KIT Mist   recessed ground, the page
     --plate     #FFFFFF  KIT Paper  the reading surface
     --rule      #DCEBFA  KIT line   hairline (the kit's Structure spec: "Hairline 1px #DCEBFA")
     --hairline  #C2DDF5  KIT line-2 the furrow line at rest, and the ghost of an un-drawn chord
     --ink       #0A1A33  KIT Ink    17.38:1 on Paper
     --ink-soft  #3E5573  KIT Ink-2  7.63:1 — body copy at reading length
     --ink-faint #64748F  KIT Haze   4.73:1 on Paper, 4.51:1 on Mist. Legal on Paper and Mist ONLY
     --light     #3EA0FF  KIT Signal fill/decoration only, never information
     --working   #0B5FCC  KIT Furrow 5.96:1 — links, buttons, the worked line, coloured body text
     --halt      #B3261E  KIT Halt   6.54:1 — stopped, failed, refused, removed, reverted
     --verified  #1F7A5C  KIT Verified 5.25:1 — passed, shipped, reconciled. The only green.

   There is no warm value and no fifth blue. A new value is a commission and must arrive with its
   ratio already computed — the kit's own standing order. */
/* THE DISPLAY CUT. Fraunces, SIL Open Font License 1.1 — the licence ships beside it in
   site/fonts/OFL.txt, and the woff2 is a COMMITTED BUILD ASSET, not a CDN reference: the site that
   says "no telemetry" cannot fetch a font from someone else's server, and site/_headers pins
   default-src 'self' so it could not if it wanted to. One variable file, latin subset, 67KB, weight
   400-700 with an optical-size axis. It is the one thing on this site that is not a system font, and
   it is the whole brand differentiator (doctrine R5: nobody in the corpus ships a system stack on
   the headline; two of five differentiate with a serif). H1 and H2 only — see --lockup below. */
@font-face{
  font-family:'Fraunces';
  src:url('/fonts/fraunces-latin.woff2?v=48282a41') format('woff2');
  font-weight:400 700;
  font-style:normal;
  font-display:swap;
}

:root{
  --ground:#F5FAFF; --plate:#FFFFFF; --rule:#DCEBFA; --hairline:#C2DDF5;
  --ink:#0A1A33; --ink-soft:#3E5573; --ink-faint:#64748F;
  --light:#3EA0FF; --working:#0B5FCC; --halt:#B3261E; --verified:#1F7A5C;
  --field:rgba(11,95,204,.05);
  /* --panel  the demonstration's surface. In Daylight it is Paper, like every other reading
              surface. Under OS dark it becomes the brand blue — see the dark block for why.
     --cta    the primary button's fill, and --cta-ink the label on it. Daylight is UNCHANGED: the
              filled button is still Furrow blue with Paper type, exactly as the kit prescribes.
              Only the dark treatment moves, to near-white (doctrine R2). */
  --panel:#FFFFFF; --cta:#0B5FCC; --cta-ink:#FFFFFF;
  /* the hairlines INSIDE the demonstration plate. In Daylight the plate is Paper and the ordinary
     lines are already right. Under OS dark the plate is the brand blue, so its lines are the kit's
     own on-ink pair (#1D3050 / #2B4468) — the plate does not follow the room. */
  --panel-rule:#DCEBFA; --panel-hair:#C2DDF5;
  /* TWO CUTS, TWO JOBS (doctrine R5). --display is the serif, and it is spent ONLY on h1 and h2 —
     the two places a reader looks first. --lockup is the kit's own Avenir lockup stack, unchanged
     and still authoritative for the wordmark, the buttons, h3 and the numerals; it is what the
     brand kit specifies for the lockup and it has not been renamed away, only narrowed to the role
     it actually holds. --ui carries every word of body text. --ledger carries every eyebrow. */
  --display:'Fraunces',Georgia,'Times New Roman',serif;
  --lockup:'Avenir Next',Avenir,Futura,'Century Gothic','Segoe UI',system-ui,sans-serif;
  --ui:-apple-system,BlinkMacSystemFont,'SF Pro Text','Helvetica Neue',Inter,'Segoe UI',system-ui,sans-serif;
  --ledger:'SF Mono',SFMono-Regular,'IBM Plex Mono',Menlo,Consolas,'Liberation Mono',monospace;
  --measure:74ch;
  --ease:cubic-bezier(.2,.7,.3,1);
  /* site splash tokens (the splash section is at the foot of this file). Fixed brand values — they
     do NOT flip with theme; only --ground/--ink under the mark do, so the reveal is seamless. The
     kit's blue is --working; these carry the splash's own names so the motion block reads cleanly.
     --sp-furrow #0B5FCC = KIT Furrow, --sp-signal #3EA0FF = KIT Signal, both kit-approved hexes. */
  --sp-furrow:#0B5FCC; --sp-signal:#3EA0FF;
  --sp-e-draw:cubic-bezier(.4,0,.2,1); --sp-e-out:cubic-bezier(.16,1,.3,1); --sp-e-io:cubic-bezier(.65,0,.35,1);

  /* ---- the sequence's dials ---------------------------------------------------------------------
     Every value here has a resting default that makes the page look RIGHT with no script at all.
     home.mjs only ever moves them; it never has to create them, which is why site-kit.test's
     "every var() resolves to a token it declares" can stay green while the page is animated.

     --d / --dur          per-element delay and duration, set by the rules below, multiplied by the
                          two scales. Declared here so a rule that forgets one still animates.
     --fdraw              how much of the furrow is drawn, 0..1. The entrance hands it 0.20; the
                          scroll handler carries it the rest of the way, always a little AHEAD of
                          the reader. Its resting value is 1: with no script the line is complete.
     --px / --py          pointer parallax, -1..1, applied to the ATMOSPHERE only — never to text. */
  --fdraw:1; --px:0; --py:0;
  /* --atmos-o  the atmosphere's opacity, written from the hero's scroll position (1 at rest, so a
                page with no script still carries the light).
     --i        a child's index within a revealing section, written by home.mjs for the stagger. */
  --atmos-o:1; --i:0;
  /* the hand-off: where the entrance mark has to fly to, and how small it gets. home.mjs measures
     the nav mark and writes these three; the defaults are a harmless no-op. */
}

/* ---- OS dark: the room, re-grounded -------------------------------------------------------------
   Ferrow has no dark BRAND — the brand is Daylight. What it has is a prescribed treatment for when
   the OPERATING SYSTEM is dark, and on 2026-08-11 that treatment was re-grounded on the owner's
   mandate (bus 38826/38829) against docs/research/ai-site-design-doctrine.md (d68683f), which
   measured the five leading AI sites' real renders and found ours the only one painting its brand
   colour on the wall.

   THE ONE MOVE: the blue comes off the ground and becomes the light in the room. Doctrine R1 — every
   winner's ground is near-black and near-NEUTRAL — measured off the live DOM: Cursor rgb(20,18,11),
   x.ai rgb(10,10,10), OpenAI rgb(0,0,0), Claude rgb(20,20,19); 0-9 points of warmth, never a hue.
   (Those four are quoted in rgb() rather than in hex deliberately: the whitelist in
   test/site-kit.test.mjs scans every hex in every authored file, comments included, and it is right
   to — a colour cited in prose today is a colour pasted into a rule tomorrow.) All chroma lives in
   the accents, then. Ferrow's
   old #0A1A33 ground carried 41 points of blue over red at 2x Cursor's luminance, so nothing on the
   page could be lit — a themed document rather than a dark room with a product in it. #0A1A33 is not
   retired: it is DEMOTED to --panel, the demonstration's surface, where the same brand blue now
   reads as the product's own light against a neutral wall.

     --ground   #0B0D10  commissioned. Near-neutral cool black, luminance 0.0040 — inside the
                         corpus band (0.000-0.0052) and 2.6x darker than the old ground. White
                         19.46:1, Sky 10.42:1, Signal 7.05:1, Verified 7.99:1, Halt 8.13:1.
     --plate    #14171B  commissioned. One step above the ground, luminance 0.0077 — 1.07:1 against
                         it, a surface you can feel rather than see. White on it 18.18:1.
     --rule     #1E2229  commissioned. The hairline, 1.22:1 on ground. Never text.
     --hairline #2A3038  commissioned. One step above rule, 1.46:1. Decorative rule only.
     --panel    #0A1A33  KIT Ink, DEMOTED from ground to panel. The demonstration's plate and the
                         card interiors — white on it is still 17.38:1, and its 41 points of blue
                         chroma now read as a lit surface against a neutral room.
     --cta      #F2F4F6  commissioned. The primary button's fill: near-white, 17.65:1 on ground
                         (doctrine R2 — every primary in the corpus wins on VALUE, not on hue).
     --cta-ink  #0B0D10  the label on it. Same 17.65:1, read the other way.
     --ink      #FFFFFF  KIT Paper. 19.46:1 on the new ground.
     --ink-soft #A9C2DE  KIT — the kit's on-ink secondary text. 10.62:1 (was 9.48:1).
     --ink-faint #7C97B8 derived between soft and rule. 6.47:1 (was 5.77:1) — AA, and now AAA for
                         the 10px tracked mono it carries.
     --light    #7FC4FF  KIT Sky. 10.42:1 — now a SIGNAL colour: the furrow's lit tip, active
                         states, the caret, the motes. It is no longer a button fill.
     --working  #3EA0FF  KIT Signal. 7.05:1 — links, the worked line, the diff gutter mid-write.
     --halt     #EB8E89  KIT Halt, lightness only (L 41%->73%). 8.13:1.
     --verified #30BB8D  KIT Verified, lightness only (L 30%->46%). 7.99:1.

   Every ratio above is computed against the NEW ground, not inherited from the old one. Daylight is
   untouched and remains canon: the mandate moved the dark treatment only.

   TWO WAYS IN, ONE ANSWER. The system's preference is honoured with no toggle on the page, exactly
   as the app surfaces do — a setting is a thing to get wrong and the system already knows. The
   :root[data-theme] pair exists only so a host shell that has already resolved a theme can state it;
   nothing in this site writes that attribute. */
@media (prefers-color-scheme:dark){
  :root{
    --ground:#0B0D10; --plate:#14171B; --rule:#1E2229; --hairline:#2A3038;
    --ink:#FFFFFF; --ink-soft:#A9C2DE; --ink-faint:#7C97B8;
    --light:#7FC4FF; --working:#3EA0FF; --halt:#EB8E89; --verified:#30BB8D;
    --field:rgba(127,196,255,.10);
    --panel:#0A1A33; --cta:#F2F4F6; --cta-ink:#0B0D10;
    --panel-rule:#1D3050; --panel-hair:#2B4468;
  }
}
:root[data-theme="dark"]{
  --ground:#0B0D10; --plate:#14171B; --rule:#1E2229; --hairline:#2A3038;
  --ink:#FFFFFF; --ink-soft:#A9C2DE; --ink-faint:#7C97B8;
  --light:#7FC4FF; --working:#3EA0FF; --halt:#EB8E89; --verified:#30BB8D;
  --field:rgba(127,196,255,.10);
  --panel:#0A1A33; --cta:#F2F4F6; --cta-ink:#0B0D10;
  --panel-rule:#1D3050; --panel-hair:#2B4468;
}
:root[data-theme="light"]{
  --ground:#F5FAFF; --plate:#FFFFFF; --rule:#DCEBFA; --hairline:#C2DDF5;
  --ink:#0A1A33; --ink-soft:#3E5573; --ink-faint:#64748F;
  --light:#3EA0FF; --working:#0B5FCC; --halt:#B3261E; --verified:#1F7A5C;
  --field:rgba(11,95,204,.05);
  --panel:#FFFFFF; --cta:#0B5FCC; --cta-ink:#FFFFFF;
  --panel-rule:#DCEBFA; --panel-hair:#C2DDF5;
}

/* ---- ground ------------------------------------------------------------------------------------ */
*{box-sizing:border-box}
/* `hidden` is an attribute the HTML says is true, and a layout rule further down this file must not
   be able to overrule it. It could: .section sets display:grid, which beats the UA's [hidden] rule
   on specificity, and that is how /welcome's "This checkout" block — hidden in the markup, unhidden
   by welcome.mjs only when a session id is present — rendered as an empty bar on every visit that
   had no session. One line here rather than a per-element workaround at each call site. */
[hidden]{display:none !important}
html{-webkit-text-size-adjust:100%}
body{
  margin:0;background:var(--ground);color:var(--ink);font-family:var(--ui);
  font-size:16px;line-height:1.6;-webkit-font-smoothing:antialiased;overflow-x:hidden;
}
a{color:var(--working);text-decoration:none}
a:hover{text-decoration:underline;text-underline-offset:3px}
:focus-visible{outline:2px solid var(--light);outline-offset:3px;border-radius:2px}
img,svg{max-width:100%}

/* The one repeated typographic gesture, unchanged from the app surfaces. */
.label{
  font-family:var(--ledger);font-size:10px;letter-spacing:.16em;text-transform:uppercase;
  color:var(--ink-faint);font-weight:500;
}
.label.on{color:var(--working)}
.label.ok{color:var(--verified)}
.label.no{color:var(--halt)}

/* Skip link: the first tab stop on every page. Off-screen until it is focused. */
.skip{position:absolute;left:-9999px;top:0}
.skip:focus{left:8px;top:8px;z-index:9;background:var(--plate);padding:8px 12px;border:1px solid var(--rule)}

/* ---- the furrow: one line running the page ------------------------------------------------------
   Fixed to the left gutter, behind everything. It is the same gesture the app puts down its rail, at
   the scale a reading page can carry — but it is no longer a one-off flourish that draws and stops.
   The entrance hands it the light, and from then on it is a PROGRESS line: home.mjs writes --fdraw
   from the scroll position plus a lead, so the line is always drawn a little further than you have
   read. The tip is the light itself, sitting at the head of the drawn part.

   Its resting state is complete (--fdraw:1) so a page with no script still carries a finished line.
   On a phone the gutter is 20px rather than 96, so the line narrows rather than disappearing: the
   whole idea of the page is that the furrow runs beside you, and a phone is where most people will
   meet it. */
#furrow{position:fixed;left:0;top:0;width:96px;height:100vh;pointer-events:none;z-index:0}
#furrow path{fill:none;stroke:var(--hairline);stroke-width:1.25}
#furrow path.worked{stroke:var(--working);stroke-width:1.6;stroke-dasharray:1 1;
  stroke-dashoffset:calc(1 - var(--fdraw))}
/* The tip is a two-percent lit segment of the SAME path, parked at the head of the drawn part. A
   segment rather than a dot because #furrow is drawn with preserveAspectRatio="none": a circle would
   render as a 0.5px-wide sliver in the 20px phone gutter, and a segment of the line cannot. It only
   exists while a script is driving --fdraw — on a resting page the line is already complete, and a
   tip sitting at the end of a finished line reads as a bug rather than as a position. */
#furrow path.tip{stroke:var(--light);stroke-width:2.8;stroke-linecap:round;opacity:0;
  stroke-dasharray:.02 1;stroke-dashoffset:calc(.02 - var(--fdraw));
  filter:drop-shadow(0 0 6px color-mix(in srgb,var(--light) 80%,transparent))}
.furrow-live #furrow path.tip{opacity:.95}
.furrow-live #furrow path.worked{filter:drop-shadow(0 0 5px color-mix(in srgb,var(--working) 34%,transparent))}
@keyframes draw{to{stroke-dashoffset:0}}

/* ---- shell ------------------------------------------------------------------------------------- */
.wrap{position:relative;z-index:1;max-width:1140px;margin:0 auto;padding:0 clamp(20px,5vw,64px)}

/* ---- nav --------------------------------------------------------------------------------------- */
/* THE NAV STAYS. It was a banner that scrolled away, on a site whose pages are long enough that a
   reader four screens into /docs had no way back to /pricing without going to the top first. It is
   sticky now, and the treatment is the one Apple's current system language earns its keep with: the
   ground at 82 parts, blurred, so the furrow and the type behind it read THROUGH the bar rather than
   being covered by it. The blur is a progressive enhancement — a browser without it gets the same
   bar at the same opacity, which is legible, just less pretty. */
.nav{display:flex;align-items:baseline;gap:clamp(18px,4vw,40px);flex-wrap:wrap;
  padding:26px 0 22px;border-bottom:1px solid var(--rule);
  position:sticky;top:0;z-index:5}
/* The bar itself is inside the 1140px measure, so its BACKDROP is a pseudo-element that reaches the
   full width of the window — otherwise the page would scroll visibly past the ends of a floating
   plank. It sits behind the nav's own content and is inert. */
.nav::after{content:'';position:absolute;inset:0 auto 0 50%;width:100vw;margin-left:-50vw;
  z-index:-1;background:color-mix(in srgb,var(--ground) 84%,transparent);
  -webkit-backdrop-filter:saturate(1.6) blur(14px);backdrop-filter:saturate(1.6) blur(14px);
  border-bottom:1px solid var(--rule)}
/* the rule under the bar is drawn by the backdrop, so the element's own border would double it */
.nav{border-bottom-color:transparent}
.mark{display:flex;align-items:center;gap:11px;margin-right:auto}
.mark svg{width:30px;height:30px;display:block;overflow:visible;flex:0 0 auto}
/* the wordmark is the kit's own lockup spec: display face, 600, -.03em, sentence case. */
.wordmark{font-family:var(--lockup);font-size:23px;letter-spacing:-.03em;font-weight:600;line-height:1;padding-top:2px;color:var(--ink)}
.nav a.navlink{color:var(--ink-soft);font-size:15px}
.nav a.navlink:hover{color:var(--ink);text-decoration:none}
.nav a.navlink[aria-current="page"]{color:var(--ink)}
.nav a.navlink[aria-current="page"]::before{content:'';display:inline-block;width:12px;height:1px;
  background:var(--working);vertical-align:middle;margin-right:8px;transform:rotate(-7deg)}
/* The right-end slot. Empty on purpose until the account flow has a URL to point at; the .btn.small
   rule below is already the shape the "Sign up" button will take, so landing it is one <a>. */
.nav-slot{display:flex;align-items:center;gap:10px;min-height:1px}
.nav-slot:empty{display:none}

/* ---- the reading plate -------------------------------------------------------------------------- */
main{display:block;padding-bottom:20px}
.head{padding:clamp(48px,9vw,104px) 0 clamp(30px,5vw,52px);max-width:26ch}
/* THE HEADLINE SHRANK, AND THAT IS THE POINT (doctrine R6). Headline size is inversely proportional
   to how much product you can show: Cursor sets 26px because it gives 60% of the fold to a running
   demo; Ferrow was setting 76px — the largest H1 in the whole measured corpus — on the page with the
   least to look at. Now that the fold carries a demonstration, the words can stop shouting. Secondary
   pages (/pricing, /docs, /download, /welcome) take 52-60px; the home hero takes 44-52.
   Weight 400: Fraunces is a variable face and its low weights are where its character lives, and the
   two sites in the corpus that differentiate with a serif both set it light (Claude 330, Perplexity
   350). At 600 it reads as a system Georgia bold, which is the one thing a commissioned cut must not
   do. --display is spent HERE and on h2, and nowhere else. */
h1{font-family:var(--display);font-size:clamp(36px,5.6vw,60px);line-height:1.04;margin:14px 0 0;
  font-weight:400;letter-spacing:-.024em;color:var(--ink);font-optical-sizing:auto}
.head .sub{color:var(--ink-soft);margin-top:20px;max-width:56ch;font-size:clamp(17px,2vw,20px);line-height:1.5}
.head{max-width:none}

/* ---- hero actions: the one thing to do, and the gentle way in ------------------------------------
   A first-time visitor needs an action above the fold. Two, and exactly two: one filled, one ghost,
   the same shape (doctrine R3, R4).

   THE PILL, AND THE VALUE CONTRAST (doctrine R2/R4, owner mandate 2026-08-11 · bus 38826/38829).
   Four of the five leading AI sites set their hero CTAs at border-radius:9999px, and every one of
   the five wins its primary on VALUE — near-white on near-black — never on hue. Ferrow's old primary
   was a mid-value blue button on a blue field, which is hue contrast dressed up as emphasis. So the
   fill is now --cta: Furrow blue in Daylight (unchanged, and correct on a white page), near-white
   #F2F4F6 under OS dark. Blue does not disappear; it is reassigned to signal, motion and state,
   where a colour that means something belongs.

   The face is --lockup, not --display. The serif is spent on h1 and h2 only — a button is a control,
   and a control set in a display serif reads as a pull-quote you can click. */
.actions{display:flex;flex-wrap:wrap;gap:12px;margin-top:30px}
.btn{font-family:var(--lockup);font-weight:600;font-size:15px;letter-spacing:-.012em;line-height:1;
  padding:13px 22px;border-radius:9999px;border:1px solid var(--hairline);color:var(--ink);
  transition:border-color .18s var(--ease),background .18s var(--ease),color .18s var(--ease)}
.btn:hover{text-decoration:none;border-color:var(--working);background:var(--field);color:var(--ink)}
.btn.primary{background:var(--cta);border-color:var(--cta);color:var(--cta-ink)}
.btn.primary:hover{filter:brightness(.94);background:var(--cta);border-color:var(--cta);color:var(--cta-ink)}
/* The nav-slot size. Sized for a nav bar rather than a hero: same face, same radius, same border
   language, two steps down. */
.btn.small{font-size:13.5px;padding:8px 15px}
@media (max-width:520px){.actions{flex-direction:column;align-items:stretch}.btn{text-align:center}}

/* A section is a row of the ledger: a rule above it, a label in the margin, the work beside it. */
.section{border-top:1px solid var(--rule);padding:clamp(28px,4.5vw,44px) 0;
  display:grid;grid-template-columns:minmax(120px,196px) minmax(0,1fr);gap:clamp(16px,4vw,44px)}
.section>.label{padding-top:6px}
.section .body{min-width:0;max-width:var(--measure)}
h2{font-family:var(--display);font-weight:400;font-size:clamp(24px,3.1vw,32px);line-height:1.16;
  letter-spacing:-.018em;margin:0 0 14px;color:var(--ink);font-optical-sizing:auto}
h3{font-family:var(--lockup);font-weight:600;font-size:20px;line-height:1.2;letter-spacing:-.02em;
  margin:0 0 6px;color:var(--ink)}
p{margin:0 0 15px;color:var(--ink-soft);max-width:68ch}
p.lead{color:var(--ink);font-size:18px}
p:last-child{margin-bottom:0}
strong{color:var(--ink);font-weight:600}

/* ---- chords: a claim struck across the line ------------------------------------------------------
   No cards. A claim is a row with a hairline above it and a chord in the gutter that extends when you
   reach for it. The chord is the only thing on this page that moves in response to a pointer. */
.chords{list-style:none;margin:0;padding:0}
.chords li{position:relative;border-top:1px solid var(--rule);padding:18px 0 16px}
.chords li:first-child{border-top:0;padding-top:2px}
.chords li::before{content:'';position:absolute;left:-26px;top:27px;width:0;height:1px;
  background:var(--working);transform:rotate(-7deg);transition:width .18s var(--ease)}
.chords li:hover::before,.chords li:focus-within::before{width:16px}
.chords li:first-child::before{top:11px}
.chords p{margin:0}

/* ---- editions: two columns that stay two facts on a phone ---------------------------------------- */
.editions{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:clamp(20px,4vw,48px);
  max-width:var(--measure)}
.edition{min-width:0}
.edition h3{margin-bottom:2px}
.edition .price{font-family:var(--lockup);font-size:34px;font-weight:600;letter-spacing:-.03em;
  color:var(--ink);margin:14px 0 2px;line-height:1.1}
.edition .per{color:var(--ink-faint);font-size:15px}
.edition dl{margin:20px 0 0;padding:0}
/* the lifetime band: a full-width third row under the two editions, its facts flowing into columns
   so it reads as the coda of the ledger rather than an orphaned cell. div-wrapped dt/dd pairs are
   the HTML5-legal grouping. */
.edition.wide{grid-column:1/-1;border-top:1px solid var(--rule);padding-top:22px}
.edition.wide dl{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:0 40px}
.edition.wide dl>div>dt:first-child{margin-top:14px;padding-top:12px;border-top:1px solid var(--rule)}
.edition dt{margin-top:14px;padding-top:12px;border-top:1px solid var(--rule)}
.edition dd{margin:4px 0 0;color:var(--ink-soft)}

/* ---- facts table (spec rows) --------------------------------------------------------------------- */
.facts{margin:0;max-width:var(--measure)}
.fact{display:grid;grid-template-columns:minmax(120px,220px) minmax(0,1fr);gap:14px;
  padding:13px 0;border-top:1px solid var(--rule);align-items:baseline}
.fact:first-child{border-top:0}
.fact .v{color:var(--ink-soft);min-width:0}
.fact .v strong{color:var(--ink)}

/* ---- terminal lines ------------------------------------------------------------------------------ */
code{font-family:var(--ledger);font-size:.9em;background:var(--field);padding:1px 5px;border-radius:2px;
  color:var(--ink);overflow-wrap:break-word}
pre{font-family:var(--ledger);font-size:13.5px;line-height:1.6;margin:0 0 16px;padding:14px 16px;
  background:var(--field);border-left:1px solid var(--rule);overflow-x:auto;color:var(--ink)}
pre code{background:none;padding:0;font-size:inherit}
pre .c{color:var(--ink-faint)}
pre .o{color:var(--ink-soft)}

/* THE COPY BUTTON (audit-completion-1 §4.3 · P1-14). site/copy.mjs appends one to command blocks
   only — never to a block of output. It sits inside the <pre>, top-right, quiet until you want it:
   a control on a command should not compete with the command. The button is absolutely positioned,
   so `pre` has to establish a containing block, and the block needs room on the right for it. */
pre.has-copy{position:relative;padding-right:92px}
.copy{position:absolute;top:8px;right:8px;font-family:var(--lockup);font-size:12px;font-weight:600;
  letter-spacing:-.01em;line-height:1;min-height:36px;padding:0 13px;border-radius:9999px;
  border:1px solid var(--hairline);background:var(--plate);color:var(--ink-soft);cursor:pointer;
  transition:color .18s var(--ease),border-color .18s var(--ease),opacity .18s var(--ease);opacity:.7}
.copy:hover{color:var(--ink);border-color:var(--working);opacity:1}
.copy:focus-visible{opacity:1;color:var(--ink)}
/* Copied: the same blue the furrow uses for work that has happened. */
.copy.done{color:var(--working);border-color:var(--working);opacity:1}
/* The legacy clipboard path needs a real element in the document to select from; it must not be
   display:none, or the selection is empty, so it is parked off-screen for the one frame it lives. */
.copy-shuttle{position:fixed;top:0;left:-9999px;opacity:0;pointer-events:none}

/* The install line: the one thing on the page shaped like a button, because it is the one thing you
   are meant to do. It is text you copy, so it is a <pre>, not a link that lies about being a command. */
.cta{margin-top:6px;max-width:var(--measure)}
.cta pre{background:var(--plate);border:1px solid var(--rule);border-left:2px solid var(--working);
  font-size:15px;padding:16px 18px}
.cta .note{color:var(--ink-faint);font-size:14px;margin:0}
/* One step of air after a block that ended in a rule. Named for what it is, so nobody reaches for
   an inline style attribute — the CSP allows those, but a stylesheet nobody can bypass is the point. */
.after{margin-top:22px}

/* ---- FAQ ------------------------------------------------------------------------------------------ */
.faq{max-width:var(--measure)}
.faq details{border-top:1px solid var(--rule);padding:0}
.faq summary{cursor:pointer;list-style:none;padding:15px 0;color:var(--ink);font-size:17px;
  display:flex;gap:12px;align-items:baseline}
.faq summary::-webkit-details-marker{display:none}
.faq summary::before{content:'+';font-family:var(--ledger);color:var(--ink-faint);font-size:14px;flex:0 0 12px}
.faq details[open] summary::before{content:'–'}
.faq details[open] summary{color:var(--ink);padding-bottom:6px}
.faq .a{padding:0 0 18px 24px}
.faq .a p{margin-bottom:12px}

/* ---- notice: a state, never a decoration ---------------------------------------------------------- */
.notice{border-left:2px solid var(--working);padding:12px 0 12px 16px;margin:20px 0 0;max-width:var(--measure)}
.notice.halt{border-left-color:var(--halt)}
.notice.halt .label{color:var(--halt)}
.notice.ok{border-left-color:var(--verified)}
.notice.ok .label{color:var(--verified)}
.notice p{margin:6px 0 0}

/* ---- docs prose ------------------------------------------------------------------------------------ */
.prose{max-width:70ch}
.prose h2{margin-top:36px}
.prose h2:first-child{margin-top:0}
.prose h3{margin-top:26px}
.prose ul{margin:0 0 16px;padding-left:20px;color:var(--ink-soft)}
.prose li{margin:5px 0}
.prose li strong{color:var(--ink)}

/* ---- footer ----------------------------------------------------------------------------------------- */
footer{border-top:1px solid var(--rule);margin-top:clamp(40px,7vw,88px);padding:30px 0 46px;
  display:flex;gap:clamp(18px,4vw,44px);flex-wrap:wrap;align-items:baseline}
footer nav{display:flex;gap:22px;flex-wrap:wrap}
footer a{font-size:14px;color:var(--ink-soft)}
footer a:hover{color:var(--ink)}
footer .who{margin-left:auto;color:var(--ink-faint);font-size:14px;max-width:46ch}
footer .who p{color:inherit;margin:0;font-size:inherit}

@media (max-width:900px){
  /* The gutter is 20px here, not 96, so the furrow narrows into it rather than being switched off.
     preserveAspectRatio="none" squeezes the curve's 24 units of horizontal wander down to about
     five pixels, which is exactly the amount of life a phone-width line should have. */
  #furrow{width:20px}
  #furrow path{stroke-width:1.6}
  .section{grid-template-columns:1fr;gap:12px}
  .section>.label{padding-top:0}
  .chords li::before{display:none}
  footer .who{margin-left:0;flex-basis:100%}
}
@media (prefers-reduced-motion:reduce){
  *{animation:none!important;transition:none!important}
  #furrow path.worked{stroke-dashoffset:0}
}

/* ==================================================================================================
   THE FURROW OF LIGHT DRAWS THE FIELD AWAKE          (home page · 2026-08-11)
   ==================================================================================================
   The ledger above is unchanged. What follows is the one WORLD the home page executes: a single
   orchestrated arrival in which the light that draws the mark never stops — it hands off to the nav,
   turns down the gutter as the furrow, and keeps drawing ahead of the reader for the rest of the
   page. Everything here is additive and gated on a class that site/home.mjs puts on <html>:

     .furrow-live  a script is driving --fdraw, so the line has a lit tip
     .rv-on      sections reveal on scroll
     .beat-on    the hero's demonstration is playing

   THE RESTING PAGE IS THE FINISHED PAGE. Nothing below hides content by default. With JavaScript
   blocked, with reduced motion, or with a module that failed to parse, every one of those classes is
   simply absent and the browser renders the composed poster: type at full opacity, the furrow drawn
   end to end, the demonstration showing its final state. That is the rule that makes an animated
   page safe, and it is why every animation here uses `both` fill rather than a hidden base state.

   PERFORMANCE IS THE AESTHETIC. Every animated property below is transform, opacity, filter or an
   SVG stroke-dashoffset on ONE path. Nothing animates width, height, top or left on a laid-out box.
   The only canvas on the site draws 40-odd soft motes into a backing store capped at 1.6 megapixels.
   The hardware floor is a 2-core 2015 MacBook Pro and it is the machine this was tuned on.
   ================================================================================================== */

/* ---- a text alternative nobody sees ---------------------------------------------------------------
   The demonstration is theatre: aria-hidden, because a screen reader stepping through a typing
   animation is being told a story in the wrong medium. This is the same content as prose, in the
   reading order it belongs in. Not display:none — that would take it away from the readers it is
   for. */
.vo{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;
  clip-path:inset(50%);white-space:nowrap;border:0}

/* ---- the atmosphere ------------------------------------------------------------------------------
   One fixed layer behind everything: a shaft of light raking across the field, a slow bloom where it
   enters, and the motes it catches. It is the only place on this site that is not flat, and that is
   the deliberate risk — a ledger drawn in light rather than a ledger drawn on paper. It fades out as
   you leave the hero (--atmos-o, written by home.mjs) so it never competes with reading.

   The parallax is 8px at the very most and lands only on these three layers. Text does not move when
   you move the mouse; that is a thing pages do to readers, and this product's argument is about who
   is in control. */
#atmos{position:fixed;inset:0;z-index:0;pointer-events:none;overflow:hidden;
  opacity:var(--atmos-o);transition:opacity 900ms var(--ease);will-change:opacity}
.atmos-shaft{position:absolute;inset:-14% -20%;
  background:linear-gradient(104deg,
    transparent 26%,
    color-mix(in srgb,var(--light) 13%,transparent) 44%,
    color-mix(in srgb,var(--light) 5%,transparent) 57%,
    transparent 72%);
  transform:translate3d(calc(var(--px) * 8px),calc(var(--py) * 6px),0)}
.atmos-bloom{position:absolute;inset:0;
  background:radial-gradient(58% 44% at 16% 18%,
    color-mix(in srgb,var(--light) 20%,transparent) 0%, transparent 66%);
  transform:translate3d(calc(var(--px) * -6px),calc(var(--py) * -4px),0);
  animation:atmos-breathe 11s var(--sp-e-io) infinite alternate}
@keyframes atmos-breathe{from{opacity:.7}to{opacity:1}}
#atmos-motes{position:absolute;inset:0;width:100%;height:100%;display:block;
  transform:translate3d(calc(var(--px) * 5px),calc(var(--py) * 4px),0)}
@media (prefers-color-scheme:dark){
  /* Sky on Ink carries further than Signal on Mist, so the same picture wants less of it. */
  .atmos-shaft{background:linear-gradient(104deg,transparent 26%,
    color-mix(in srgb,var(--light) 9%,transparent) 44%,
    color-mix(in srgb,var(--light) 4%,transparent) 57%,transparent 72%)}
  .atmos-bloom{background:radial-gradient(58% 44% at 16% 18%,
    color-mix(in srgb,var(--light) 13%,transparent) 0%, transparent 66%)}
}

/* ---- the hero -------------------------------------------------------------------------------------
   THE TRADE (doctrine R6/R8, owner mandate 2026-08-11). The fold used to be words: an eyebrow, the
   biggest headline in the measured corpus, a 46-word paragraph, two buttons, and then a list. Five of
   five leading AI sites put the product WORKING in the fold instead — it is the least negotiable rule
   in the document — and Cursor pays for its demo by setting its H1 at 26px. This is that trade, made.

   The split is 45/55: what the product IS on the left, the product DOING it on the right, and the
   right side is the larger half because it is the argument. Everything below the fold returns to the
   ledger's single measured column.

   The 46-word paragraph was not cut. It is excellent copy and it moved to "Why this one", where a
   reader has already opted in. What stands here is one sentence of twelve words. */
.hero{position:relative;padding:clamp(30px,5vh,64px) 0 clamp(38px,6vh,74px)}
.hero-grid{display:grid;gap:clamp(24px,3.4vw,40px)}
.hero h1{font-size:clamp(34px,4.6vw,52px);line-height:1.02;letter-spacing:-.026em;margin:14px 0 0}
.hero h1 .ln{display:block;overflow:hidden;padding-bottom:.08em;margin-bottom:-.08em}
.hero h1 .ln>span{display:block}
.hero .sub{color:var(--ink-soft);margin:18px 0 0;max-width:40ch;
  font-size:clamp(16.5px,1.4vw,18.5px);line-height:1.55}
.hero .actions{margin-top:26px}
/* THE ACCESS LINE. Thirteen pixels of --ink-faint doing more competitive work than any feature
   bullet on the page: the corpus's flagship product is seven screens behind a $200-300/mo tier and
   spends a whole section softening that, and Ferrow's answer is that there is no gate to soften.
   Its wording is verified against the shipped code, not against the marketing — see the comment
   beside it in site/index.html, which cites the file and line that make it true. */
.access{margin:16px 0 0;color:var(--ink-faint);font-size:13px;line-height:1.5;max-width:46ch}
.hero-lede{display:grid;grid-template-columns:minmax(0,45fr) minmax(0,55fr);
  gap:clamp(26px,4vw,52px);align-items:center}
.hero-say{min-width:0}
.hero-demo{position:relative;min-width:0;scroll-margin-top:24px}

/* ---- the demonstration ------------------------------------------------------------------------------
   THE FOURTH BEAT IS THE WHOLE PRODUCT. Cursor, x.ai, Claude and OpenAI all demonstrate an agent
   doing work. Not one of them can demonstrate TAKING THE WORK BACK, because not one of them keeps a
   ledger of what it wrote. So the loop is four beats and the last one is `ferrow undo`: the diff
   reverses on screen, the ledger row greys out, the file returns to what it was.

   It is DRAWN, not filmed (doctrine R9). No poster frame, no play button, no buffering, no bandwidth,
   no consent to negotiate — and, because it is drawn by this stylesheet, it cannot drift from what
   the app actually looks like the way a screen recording silently does.

   THE PLATE IS WHERE THE BLUE WENT. #0A1A33 used to be the whole page's ground, which is why nothing
   on the page could be lit. It is now --panel: this surface, and only this surface. The brand blue
   reads as the product's own light against a neutral room, which is Claude's inverted-plate move
   made in Ferrow's own colour rather than in cream. */
.demo{--rule:var(--panel-rule);--hairline:var(--panel-hair);
  background:var(--panel);border:1px solid var(--rule);border-radius:10px;
  padding:14px 16px 16px;max-width:560px;overflow:hidden;
  box-shadow:0 34px 70px -40px color-mix(in srgb,var(--ink) 52%,transparent),
             0 0 0 1px color-mix(in srgb,var(--light) 8%,transparent)}
/* Under OS dark the plate IS the brand blue, so its inner type is on-ink type regardless of theme —
   the panel does not follow the room. In Daylight the panel is Paper and the ordinary inks are
   already correct, so only the dark side needs saying. */
.demo-bar{display:flex;gap:14px;align-items:center;justify-content:space-between;
  padding-bottom:11px;border-bottom:1px solid var(--rule)}
.chip{border:1px solid var(--hairline);border-radius:9999px;padding:3px 9px;color:var(--ink-soft)}

/* beat one — the vault. Three real paths in the ledger mono, each with its state on the right. */
.dfiles{list-style:none;margin:11px 0 0;padding:0}
.dfiles li{position:relative;display:flex;gap:12px;justify-content:space-between;align-items:baseline;
  padding:7px 0;border-top:1px solid var(--rule)}
.dfiles li:first-child{border-top:0}
.dn{font-family:var(--ledger);font-size:12.5px;color:var(--ink);overflow-wrap:anywhere}
.dfiles li.on .dn{color:var(--light)}
.dfiles li::before{content:'';position:absolute;left:-12px;top:15px;width:9px;height:1px;
  background:var(--light);transform:rotate(-7deg) scaleX(0);transform-origin:left center;
  transition:transform .4s var(--sp-e-out)}
.dfiles li.on::before{transform:rotate(-7deg) scaleX(1)}
/* The per-file STATUS is part of the write, not part of the folder. It arrives with the ledger row
   and it leaves with the undo — because a panel that still reads "edited" after `ferrow undo` has
   just contradicted the sentence it exists to prove. At rest (no script) all three are shown, which
   is the composed still of the whole story. */
.dstat{transition:opacity .38s var(--ease)}

/* beat two — the write. A diff gutter in --working, the added line typing itself in. The removed
   line is only ever shown during the reversal, which is the only moment it is true. */
/* One line's worth of room, held constant: the added line and the struck line are mutually
   exclusive, so the box must not resize when one replaces the other — a panel that changes height
   mid-loop drags every element under it and is the one thing here that would cost layout. */
.ddiff{margin-top:12px;padding-top:11px;border-top:1px solid var(--rule);min-height:2.5em}
.dline{display:flex;gap:10px;align-items:baseline;font-family:var(--ledger);font-size:12.5px;
  line-height:1.5;padding:2px 0}
.dgut{flex:0 0 10px;color:var(--ink-faint);text-align:center;user-select:none}
.dline.add{color:var(--ink)}
.dline.add .dgut{color:var(--working)}
.dline.add{box-shadow:inset 2px 0 0 var(--working);padding-left:8px;margin-left:-10px}
.dline.cut{color:var(--ink-faint);text-decoration:line-through;
  box-shadow:inset 2px 0 0 var(--halt);padding-left:8px;margin-left:-10px}
.dline.cut .dgut{color:var(--halt)}
.dtxt{min-width:0;overflow-wrap:anywhere}

/* beat three — the ledger row. The tick is the only green on the panel and it means one thing. */
.dledger{margin-top:12px;padding-top:11px;border-top:1px solid var(--rule);
  display:flex;gap:10px;align-items:baseline}
.dtick{color:var(--verified);font-size:13px;line-height:1;flex:0 0 auto}
.dledger .dn{color:var(--ink-soft)}

/* beat four — the command. It is a real command; `ferrow undo` is what a person types. */
.dcmd{margin-top:12px;padding-top:11px;border-top:1px solid var(--rule);
  display:flex;gap:9px;align-items:baseline;font-family:var(--ledger);font-size:12.5px}
.dcmd .dprompt{color:var(--working)}
.dcmd .dtxt{color:var(--ink);min-height:1.2em}

/* THE RESTING PAGE IS THE FINISHED PAGE. Everything above renders composed with no script at all:
   the files listed, the line written, the ledger stamped, the command sitting there ready. Only
   `.beat-on` — which home.mjs adds, and only when motion is wanted — stages any of it down. */
@keyframes dblink{50%{opacity:0}}
@keyframes dstamp{from{opacity:0;transform:translateY(5px)}to{opacity:1;transform:none}}
.beat-on .demo .dfiles li,
.beat-on .demo .dledger,
.beat-on .demo .dcmd{opacity:0;transform:translateY(6px);
  transition:opacity .42s var(--sp-e-out),transform .42s var(--sp-e-out),color .35s var(--ease)}
.beat-on .demo .dline.add{opacity:0;transition:opacity .34s var(--ease),box-shadow .34s var(--ease)}
.beat-on .demo .dline.cut{display:none}
.beat-on .demo .chip,.beat-on .demo .dstat{opacity:0;transition:opacity .5s var(--ease)}

.beat-on .demo.b-list .dfiles li{opacity:1;transform:none}
.beat-on .demo.b-list .dfiles li:nth-child(2){transition-delay:.08s}
.beat-on .demo.b-list .dfiles li:nth-child(3){transition-delay:.16s}
.beat-on .demo.b-list .chip{opacity:1;transition-delay:.34s}

.beat-on .demo.b-write .dline.add{opacity:1}
.beat-on .demo.b-write .dtyping::after{content:'';display:inline-block;width:6px;height:.9em;
  background:var(--light);vertical-align:-.09em;margin-left:2px;animation:dblink 1.05s steps(2) infinite}

.beat-on .demo.b-logged .dledger{opacity:1;transform:none;animation:dstamp .44s var(--sp-e-out) both}
.beat-on .demo.b-logged .dstat{opacity:1}
.beat-on .demo.b-logged .dfiles li:nth-child(2) .dstat{transition-delay:.09s}
.beat-on .demo.b-logged .dfiles li:nth-child(3) .dstat{transition-delay:.18s}

.beat-on .demo.b-undo .dcmd{opacity:1;transform:none}
.beat-on .demo.b-undo .dcmd .dtxt::after{content:'';display:inline-block;width:6px;height:.9em;
  background:var(--light);vertical-align:-.09em;margin-left:2px;animation:dblink 1.05s steps(2) infinite}
/* THE REVERSAL. The added line goes; the removed line appears struck through in --halt for one
   breath; the ledger row greys to --ink-faint and loses its tick; the highlighted file goes back to
   being an ordinary file. Then it all rests, and the loop starts again. */
.beat-on .demo.b-revert .dline.add{opacity:0}
.beat-on .demo.b-revert .dline.cut{display:flex}
.beat-on .demo.b-revert .dledger{opacity:.45}
.beat-on .demo.b-revert .dledger .dtick{color:var(--ink-faint)}
.beat-on .demo.b-revert .dstat{opacity:0;transition-delay:0s}
.beat-on .demo.b-revert .dfiles li.on .dn{color:var(--ink)}
.beat-on .demo.b-revert .dfiles li.on::before{transform:rotate(-7deg) scaleX(0)}
.beat-on .demo.b-revert .dcmd .dtxt::after{animation:none;opacity:0}

/* ---- capability cards: three parallel proofs ---------------------------------------------------------
   x.ai's move (doctrine, § x.ai "three demo cards"): three capabilities proved at a glance side by
   side, rather than one hero shot asked to argue for all of them. Each carries a small DRAWN proof —
   an SVG of the thing itself — because a paragraph that says "full undo" is the weakest available
   form of the claim and a reversing arrow over a ledger row is not. */
/* THE TWO SECTIONS THAT LEAVE THE LEDGER. Every other section on the site is a ledger row: a label
   in a 196px gutter, the work beside it, the whole thing inside a 74ch measure. That is right for
   prose and wrong for a row of three cards — at 1440 it left the plan grid about 780px, which
   auto-fit resolved as TWO cards and an orphan on the next line. The page's whole argument is that
   there are three cards and there are always three cards, so these two rows take the full width and
   wear their label above instead of beside. They are the only two that do. */
.section.caps-row,.section.plans-row{grid-template-columns:1fr;gap:clamp(14px,2vw,20px)}
.section.caps-row>.label,.section.plans-row>.label{padding-top:0}
.caps-row .body,.plans-row .body{max-width:none}
.caps{display:grid;grid-template-columns:repeat(auto-fit,minmax(230px,1fr));gap:clamp(16px,2.4vw,26px);
  max-width:none;margin:0}
.cap{border:1px solid var(--rule);border-radius:10px;padding:18px 18px 20px;background:var(--plate);
  min-width:0}
.cap svg{display:block;width:100%;height:60px;margin-bottom:14px;overflow:visible}
.cap h3{font-size:17px;margin-bottom:5px}
.cap p{font-size:14.5px;margin:0;color:var(--ink-soft)}

/* ---- plan cards: three, always -------------------------------------------------------------------------
   Six purchasable configurations, three cards, one global pill and one in-card control (doctrine
   R10 — Cursor renders four cards for ~eight SKUs by exactly this method). The card ORDER is fixed:
   name → positioning → price → BUTTON → features (R13: a decided buyer acts without scrolling a list
   they have already accepted). Price at display scale, unit as caption (R12). Recommendation is
   expressed by button fill and nothing else — no badge, no ribbon, no scaled card, and the corpus
   contains no "MOST POPULAR" anywhere (R11). */
.seg{display:inline-flex;gap:2px;padding:3px;border:1px solid var(--hairline);border-radius:9999px;
  background:var(--plate)}
.seg label{font-family:var(--lockup);font-size:13.5px;font-weight:600;letter-spacing:-.01em;
  line-height:1;padding:9px 18px;border-radius:9999px;color:var(--ink-soft);cursor:pointer;
  user-select:none;transition:background .18s var(--ease),color .18s var(--ease)}
.seg label:hover{color:var(--ink)}
.seg.mini label{font-size:12px;padding:7px 13px}
.seg-row{display:flex;align-items:center;gap:16px;flex-wrap:wrap;margin:0 0 clamp(22px,3vw,32px)}
.seg-row .note{color:var(--ink-faint);font-size:13.5px;margin:0;max-width:38ch}

/* ---- THE TWO SEGMENTED CONTROLS, WITHOUT A LINE OF JAVASCRIPT ------------------------------------
   Both are radio inputs plus the `~` sibling combinator. That choice is not cleverness for its own
   sake — it is what makes the page reprice correctly with scripting disabled, keeps every checkout
   URL a real link a person can middle-click or copy, and removes the window in which a module has
   not arrived yet and the price on screen is the wrong one. A pricing page whose numbers depend on a
   script is a pricing page that can show the wrong number.

   The inputs are FOCUSABLE, not display:none — a segmented control you cannot reach with a keyboard
   is not a control. They are clipped to a pixel and their focus ring is drawn on the label instead,
   which is the thing a sighted keyboard user is actually looking at.

   DEFAULT-VISIBLE, EXPLICITLY HIDDEN. Every variant is in the markup and shown; the :checked rules
   remove the ones you did not pick. With no stylesheet at all a reader sees every price and every
   link, which is a worse-looking page and a completely honest one — the failure mode of the other
   order is a card with no price and no button. */
.vr{position:absolute;width:1px;height:1px;opacity:0;margin:0;padding:0;border:0;
  clip-path:inset(50%);pointer-events:none}
.billing{position:relative}

/* the billing axis: Monthly | Yearly, repricing the grid in place */
#bill-m:checked ~ .seg-row .seg label[for="bill-m"],
#bill-y:checked ~ .seg-row .seg label[for="bill-y"]{background:var(--cta);color:var(--cta-ink)}
#bill-m:focus-visible ~ .seg-row .seg label[for="bill-m"],
#bill-y:focus-visible ~ .seg-row .seg label[for="bill-y"]{outline:2px solid var(--light);outline-offset:3px}
#bill-m:checked ~ .seg-row .y-only,#bill-m:checked ~ .plans .y-only,
#bill-y:checked ~ .seg-row .m-only,#bill-y:checked ~ .plans .m-only{display:none}

/* the in-card axis: the three prepaid packs, which used to be three more buttons down a scroll */
#pack-10:checked ~ .seg label[for="pack-10"],
#pack-25:checked ~ .seg label[for="pack-25"],
#pack-50:checked ~ .seg label[for="pack-50"]{background:var(--cta);color:var(--cta-ink)}
#pack-10:focus-visible ~ .seg label[for="pack-10"],
#pack-25:focus-visible ~ .seg label[for="pack-25"],
#pack-50:focus-visible ~ .seg label[for="pack-50"]{outline:2px solid var(--light);outline-offset:3px}
#pack-10:checked ~ .p25,#pack-10:checked ~ .p50,
#pack-10:checked ~ .actions .p25,#pack-10:checked ~ .actions .p50,
#pack-25:checked ~ .p10,#pack-25:checked ~ .p50,
#pack-25:checked ~ .actions .p10,#pack-25:checked ~ .actions .p50,
#pack-50:checked ~ .p10,#pack-50:checked ~ .p25,
#pack-50:checked ~ .actions .p10,#pack-50:checked ~ .actions .p25{display:none}

/* align-items:stretch, not start. Three cards of three different heights read as three drafts of a
   card; one height reads as a decision. The feature lists are different lengths and that is fine —
   the space falls at the bottom of the shorter ones, where nothing is competing for it. */
.plans{display:grid;grid-template-columns:repeat(auto-fit,minmax(268px,1fr));
  gap:clamp(16px,2.2vw,24px);align-items:stretch;max-width:none}
.plan{border:1px solid var(--rule);border-radius:12px;padding:22px 22px 24px;background:var(--plate);
  min-width:0;display:flex;flex-direction:column}
/* THE QUIET LADDER. Claude marks its tiers with a glyph that grows a node per tier; ours grows a
   furrow line per tier, in the site's own motif. It is a second silent signal and it never speaks. */
.plan .rungs{display:flex;gap:4px;margin-bottom:14px;height:8px;align-items:center}
.plan .rungs i{display:block;width:16px;height:1.5px;background:var(--working);transform:rotate(-7deg);
  border-radius:1px}
.plan h3{font-size:19px;margin-bottom:3px}
.plan .pos{color:var(--ink-faint);font-size:14px;margin:0 0 16px}
.plan .price{font-family:var(--lockup);font-size:clamp(38px,4.4vw,48px);font-weight:600;
  letter-spacing:-.035em;color:var(--ink);line-height:1;margin:0}
.plan .price .per{font-family:var(--ui);font-size:15px;font-weight:400;letter-spacing:0;
  color:var(--ink-faint);margin-left:5px}
/* Two lines' worth, held, so the three buy buttons land on one line across the grid — the row a
   decided reader's eye travels along should be straight. */
.plan .subline{color:var(--ink-faint);font-size:13.5px;line-height:1.45;margin:9px 0 0;min-height:2.9em}
.plan .actions{margin:18px 0 0}
.plan .actions .btn{width:100%;text-align:center}
.plan .feat{list-style:none;margin:20px 0 0;padding:18px 0 0;border-top:1px solid var(--rule)}
.plan .feat li{position:relative;padding:0 0 0 20px;margin:0 0 9px;color:var(--ink-soft);font-size:14.5px}
.plan .feat li::before{content:'';position:absolute;left:0;top:.62em;width:10px;height:1px;
  background:var(--working);transform:rotate(-7deg)}
.plan .feat li:last-child{margin-bottom:0}
.plan .chain{color:var(--ink-faint);font-size:13px;margin:0 0 12px;
  font-family:var(--ledger);letter-spacing:.02em}
/* The in-card control that absorbed three SKUs. It sits inside Managed, above its button, and the
   only thing it changes is the button's destination and one line of copy. */
.packs{margin:16px 0 0;padding:14px 0 0;border-top:1px solid var(--rule)}
.packs>.label{display:block;margin-bottom:9px}
.packs .note{color:var(--ink-faint);font-size:13px;margin:9px 0 0;min-height:2.5em}
.packs .actions{margin-top:11px}
.packs .actions .btn{width:auto}
.plan .feat li.chain-item{margin-bottom:13px}
.plan .feat li.chain-item::before{display:none}
.plan .feat li.chain-item{padding-left:0}
/* The closing trust mark. Set in the ledger mono at reading size because it is the page's last
   sentence and the one a person repeats to somebody else. */
.close{font-family:var(--ledger);font-size:14.5px;line-height:1.55;color:var(--ink);
  border-left:2px solid var(--verified);padding-left:16px;margin:22px 0 0;max-width:58ch}

/* ---- sections arriving ------------------------------------------------------------------------------
   The furrow draws ahead of the reader; a section catches up to it. The label slides in from the
   gutter, the body rises, and the chords strike ACROSS the line one after another — the same gesture
   the mark makes, at the scale of a paragraph. content-visibility keeps the work off the main thread
   until the section is nearly on screen; `auto` in contain-intrinsic-size means each section
   remembers its real height after the first pass, so the scrollbar does not breathe. */
.section{content-visibility:auto;contain-intrinsic-size:auto 520px}
.chords li::before{width:26px;transform:rotate(-7deg) scaleX(0);transform-origin:left center;
  transition:transform .18s var(--ease)}
.chords li:hover::before,.chords li:focus-within::before{width:26px;transform:rotate(-7deg) scaleX(.6)}
@keyframes strike{0%{transform:rotate(-7deg) scaleX(0)}56%{transform:rotate(-7deg) scaleX(1)}
  100%{transform:rotate(-7deg) scaleX(.3)}}
@keyframes rise{from{opacity:0;transform:translateY(18px)}to{opacity:1;transform:none}}
@keyframes slidein{from{opacity:0;transform:translateX(-12px)}to{opacity:1;transform:none}}
.rv-on .rv{opacity:0;transform:translateY(16px);
  transition:opacity .66s var(--sp-e-out),transform .66s var(--sp-e-out)}
.rv-on .rv.in{opacity:1;transform:none}
.rv-on .rv>.label{opacity:0;transform:translateX(-12px);
  transition:opacity .5s var(--sp-e-out) .12s,transform .5s var(--sp-e-out) .12s}
.rv-on .rv.in>.label{opacity:1;transform:none}
.rv-on .rv.in .chords li::before{animation:strike 720ms var(--sp-e-out) calc(var(--i) * 90ms + 200ms) both}
.rv-on .rv.in .fact{animation:rise 520ms var(--sp-e-out) calc(var(--i) * 52ms + 140ms) both}
.rv-on .rv.in .cap{animation:rise 620ms var(--sp-e-out) calc(var(--i) * 90ms + 160ms) both}

/* The candour section carries the page's second-largest type on purpose: a pre-1.0 product that
   leads with what does NOT work yet is making its strongest claim, and it should look like one. */
.candour h2{font-size:clamp(27px,4vw,42px)}
.candour .states .fact{padding:15px 0}


@media (max-width:900px){
  /* One column, and the demonstration comes straight after the buttons rather than beside them —
     the phone gets the same sequence, in the order a thumb reads it. Verified by rendering at 390. */
  .hero-lede{grid-template-columns:1fr;gap:26px;align-items:start}
  .hero{padding-top:clamp(20px,4vh,40px)}
  .hero .actions{margin-top:22px}
  .demo{max-width:none}
  /* The plan grid holds three cards to about 900px and then stacks. It never becomes two-and-one:
     an orphaned third card reads as an afterthought, and Lifetime is the recommended plan. */
  .plans{grid-template-columns:1fr}
  .caps{grid-template-columns:1fr}
}
@media (max-width:640px){
  /* The nav wraps here. Without this the Sign up button lands in the middle of the second row,
     beside "Docs", which reads as a fifth navigation link rather than as the one thing to do. */
  .nav-slot{margin-left:auto}
}
@media (max-width:520px){
  .hero h1{letter-spacing:-.038em}
  .demo{padding:13px 15px 15px}
  .dnotes li{flex-wrap:wrap;gap:2px 12px}
  /* A COMMAND MUST BE READABLE WHOLE ON A PHONE (audit-completion-1 P1-14). `pre` scrolls
     horizontally, which is right for a printed table and wrong for the install line: at 390px its
     46 characters put the URL tail — the only part that varies — off the right edge, so the reader
     cannot even see what they are being asked to run. Command blocks wrap; OUTPUT blocks keep the
     scroll, because a wrapped ledger table is unreadable in a different way. */
  .cta pre,pre[data-copy]{white-space:pre-wrap;overflow-wrap:anywhere}
}
/* THUMB-SIZED TARGETS (audit-completion-1 P1-13). The nav "Sign up" button computed to ~30px tall
   and the nav links to ~20px, against a 44px iOS / 48dp Android floor — on the surface whose whole
   job on a phone is to get one tap. Padding only, and only where a finger is the pointer: a mouse
   does not need a 44px link and the desktop nav's rhythm is deliberate. */
@media (max-width:640px),(pointer:coarse){
  .nav a.navlink{display:inline-flex;align-items:center;min-height:44px}
  .btn{min-height:48px;display:inline-flex;align-items:center;justify-content:center}
  .btn.small{min-height:44px;padding:0 18px;font-size:14px}
  /* The copy button is the other thing a thumb has to hit, and it sits inside a box with a scroll. */
  .copy{min-height:44px;padding:0 16px;opacity:1}
  pre.has-copy{padding-right:104px}
  /* The footer became load-bearing on 2026-08-11 (audit-completion-2 P0-A/P0-B): it is now the only
     route to /support, /terms, /privacy and /refunds, and it went from four links to eight. A 20px
     tall row of eight links is the wrong thing to hand a person on a phone who is trying to find out
     how to get their money back. Same padding-only treatment the nav got, same 44px floor. */
  footer nav a{display:inline-flex;align-items:center;min-height:44px}
  footer nav{gap:14px 22px}
}
@media (prefers-reduced-motion:reduce){
  /* The dignified still. No curtain, no drifting light, no typing — the composed poster frame, with
     the demonstration showing the whole four-beat story at once (files listed, the line written, the
     ledger stamped, the undo command sitting there ready) and the furrow drawn end to end.
     Everything is readable and nothing has to happen first. */
  .atmos-bloom{opacity:.85}
  .demo .dline.cut{display:none}
}

/* ==================================================================================================
   THE ARRIVAL, THE ROW LIGHT, AND THE REVERSAL            (site-wide · 2026-08-12)
   ==================================================================================================
   Three additions, one idea. The light that draws the mark hands off to the gutter, travels down the
   page as the furrow, strikes each row as the reader reaches it — and, once, runs BACKWARDS.

   NOTHING BELOW HIDES CONTENT BY DEFAULT. Every rule is gated on a class site/field.mjs puts on
   <html> (`enter-on`, `rv-on`, `beat-on`) and every animation uses `both` fill from a state the
   class itself creates. Blocked JavaScript, a parse error, reduced motion, a late module: none of
   the classes appear and the browser renders the composed page. That is the rule that makes an
   animated page safe, and it is checked by looking at the page with scripting off.

   PERFORMANCE IS THE AESTHETIC. Every animated property here is transform, opacity, filter or an SVG
   stroke-dashoffset on one path. Nothing animates width, height, top, left or box-shadow on a
   laid-out box. The hardware floor is a 2-core 2015 MacBook Pro.
   ================================================================================================== */

/* ---- the arrival ---------------------------------------------------------------------------------
   ONE GESTURE: strike, rise, resolve. The beat table lives in site/field.mjs beside the class that
   fires it; these are the same numbers, spent as delays.

      60ms  the bloom lights and the shaft rakes in
     120ms  the mark's centre chord extends past the ring, AND headline line one starts to rise
     200ms  headline line two
     220ms  THE STRIKE. the furrow tip lands in the gutter, one bright frame, and the line draws
     260ms  the demonstration plate lifts
     300 / 360 / 420ms   the sentence, the buttons, the access line
     900ms  RESOLVE. the class comes off, the scroll handler takes the line, the demonstration starts.

   THE FIRST DRAFT OF THIS TABLE WAS A CURTAIN WEARING A DIFFERENT HAT, AND A 390px RENDER CAUGHT IT.
   It held for 140ms, brought the headline in at 560 and 660, and did not resolve until 1500 — so a
   phone screenshot taken at one second showed an eyebrow and an empty fold. That is exactly the
   defect Chris cut the old curtain for (bus 39158): the message is not allowed to be late, however
   pretty the reason. Everything is now inside 900ms and the headline is legible from 120.

   The headline moves on TRANSFORM ONLY — it is masked and slides, never faded — so it is on screen
   and readable through the whole of its own arrival rather than materialising at the end of it.
   Causal, never simultaneous: each beat is triggered by the one before it arriving somewhere. */
@keyframes ar-fade{from{opacity:0}to{opacity:1}}
@keyframes ar-rise{from{opacity:0;transform:translateY(14px)}to{opacity:1;transform:none}}
@keyframes ar-line{from{transform:translateY(104%)}to{transform:none}}
@keyframes ar-plate{from{opacity:0;transform:translateY(24px) scale(.986)}to{opacity:1;transform:none}}
@keyframes ar-chord{from{stroke-dashoffset:36}to{stroke-dashoffset:0}}
/* The furrow's own draw. dashoffset is 1 - fdraw, so 0.94 to 0.80 is the line running from six
   hundredths of the page to a fifth of it — where the scroll handler picks it up. */
@keyframes ar-furrow{from{stroke-dashoffset:.94}to{stroke-dashoffset:.80}}
/* THE IMPACT FRAME. One short bloom on the tip at the strike, decaying over the next fifth of a
   second — the cheapest and strongest punch available, and the only place on this site that flares. */
@keyframes ar-tip{
  0%{opacity:0;stroke-dashoffset:.92}
  9%{opacity:1;filter:drop-shadow(0 0 20px color-mix(in srgb,var(--light) 92%,transparent))}
  30%{filter:drop-shadow(0 0 6px color-mix(in srgb,var(--light) 80%,transparent))}
  100%{opacity:.95;stroke-dashoffset:.78}
}

.enter-on .atmos-shaft{animation:ar-fade 760ms var(--ease) 60ms both}
.enter-on .atmos-bloom{animation:ar-fade 560ms var(--ease) 60ms both,
  atmos-breathe 11s var(--sp-e-io) 620ms infinite alternate}
.enter-on .mark svg line:last-of-type{stroke-dasharray:36;
  animation:ar-chord 340ms var(--sp-e-draw) 120ms both}
.enter-on.furrow-live #furrow path.worked{animation:ar-furrow 760ms var(--sp-e-out) 220ms both}
.enter-on.furrow-live #furrow path.tip{animation:ar-tip 760ms var(--sp-e-out) 220ms both}

/* the home hero. The eyebrow and the headline never drop below full opacity — the eyebrow is one
   word and fading it buys nothing, and the headline slides inside its mask. */
.enter-on .hero h1 .ln>span{animation:ar-line 520ms var(--sp-e-out) both}
.enter-on .hero h1 .ln:nth-child(1)>span{animation-delay:120ms}
.enter-on .hero h1 .ln:nth-child(2)>span{animation-delay:200ms}
.enter-on .hero .sub{animation:ar-rise 380ms var(--sp-e-out) 300ms both}
.enter-on .hero .actions{animation:ar-rise 380ms var(--sp-e-out) 360ms both}
.enter-on .hero .access{animation:ar-rise 380ms var(--sp-e-out) 420ms both}
.enter-on .hero-demo{animation:ar-plate 620ms var(--sp-e-out) 260ms both}

/* every other page's head, which is the same gesture with nothing to demonstrate beside it */
.enter-on .head h1{animation:ar-rise 460ms var(--sp-e-out) 120ms both}
.enter-on .head .sub{animation:ar-rise 400ms var(--sp-e-out) 260ms both}
.enter-on .head .actions{animation:ar-rise 380ms var(--sp-e-out) 340ms both}

/* ---- the row light --------------------------------------------------------------------------------
   A section is a row of the field, and the rule above it is the line the light strikes as the reader
   arrives. It runs left to right in 900ms and then settles to a faint worked tint, so a page you
   have read looks like a field that has been worked rather than one that is being worked.
   One pseudo-element, one transform, one opacity. It is the gesture that makes /terms feel like the
   same product as the home page. */
.section{position:relative}
.rv-on .rv::before{content:'';position:absolute;left:0;right:0;top:-1px;height:1px;
  background:var(--working);transform-origin:left center;transform:scaleX(0);opacity:0}
.rv-on .rv.in::before{animation:row-light 900ms var(--sp-e-out) 60ms both}
@keyframes row-light{
  0%{transform:scaleX(0);opacity:0}
  20%{opacity:1}
  62%{transform:scaleX(1);opacity:.9}
  100%{transform:scaleX(1);opacity:.18}
}

/* ---- the reversal -----------------------------------------------------------------------------------
   THE SIGNATURE MOMENT. Four sites in the measured corpus can show an agent doing work. None of them
   can show taking the work back. This is that beat given its own frame: as `ferrow log revert` lands,
   one band of light runs BACKWARDS across the plate — right to left, against the direction everything
   else on this site travels — and the write is unmade behind it.

   It is one absolutely-positioned gradient moved by transform. It costs one composited layer for
   620ms per cycle and nothing at all for the rest. */
.dsweep{position:absolute;inset:0;pointer-events:none;opacity:0;border-radius:inherit;
  background:linear-gradient(90deg,
    transparent 0%,
    color-mix(in srgb,var(--light) 4%,transparent) 30%,
    color-mix(in srgb,var(--light) 32%,transparent) 48%,
    color-mix(in srgb,var(--light) 4%,transparent) 62%,
    transparent 92%);
  transform:translateX(62%)}
@keyframes unmake{
  0%{opacity:0;transform:translateX(62%)}
  16%{opacity:1}
  58%{opacity:1}
  100%{opacity:0;transform:translateX(-62%)}
}
.beat-on .demo.b-revert .dsweep{animation:unmake 620ms var(--sp-e-io) both}

/* ---- the capability field -------------------------------------------------------------------------
   The site used to name nine things the product does. It ships thirty-odd commands, and the ones it
   was leaving out — signed skills, MCP in both directions, a browser with per-skill grants,
   schedules, workflows, an approval queue, a kill switch — are the ones a reader deciding between
   this and a chat window actually needs. They are grouped, because a flat list of twenty rows is a
   specification and not an argument. Each group is a ledger heading; each row is still a row. */
.group{margin-top:clamp(26px,3.4vw,38px)}
.group:first-child{margin-top:0}
.group>.label{display:block;margin-bottom:9px;color:var(--working)}
.group>.gsub{color:var(--ink-faint);font-size:14px;margin:0 0 10px;max-width:58ch}

/* ---- micro-interactions -----------------------------------------------------------------------------
   The details nobody consciously sees. A card lifts two pixels and its edge finds the furrow colour;
   a button lifts one. Both are 180ms, both use the one easing curve this site has, and both are
   transforms. Consistency here is the tell a second visit checks. */
.cap,.plan{transition:border-color .18s var(--ease),transform .18s var(--ease),
  box-shadow .18s var(--ease)}
.cap:hover,.plan:hover{border-color:var(--hairline);transform:translateY(-2px);
  box-shadow:0 20px 38px -30px color-mix(in srgb,var(--ink) 46%,transparent)}
.btn{transition:border-color .18s var(--ease),background .18s var(--ease),
  color .18s var(--ease),transform .18s var(--ease)}
.btn:hover{transform:translateY(-1px)}
.btn:active{transform:none}

@media (max-width:900px){
  /* The sticky bar is worth two rows of a phone screen at most. It keeps its blur and its rule. */
  .nav{padding:16px 0 14px}
}
@media (prefers-reduced-motion:reduce){
  /* THE DIGNIFIED STILL, EXTENDED. `*{animation:none!important}` above already stops every one of
     these; what is left is making sure nothing is stuck in a staged state. The row light never
     draws, the reversal band never appears, and the page is the composed poster it always was. */
  .rv-on .rv::before{display:none}
  .dsweep{display:none}
}
