/* Obilant — shared stylesheet.
   Extracted from index.html when the site grew past one page. Every page
   links this; nothing here is page-specific except the hero and the gate,
   which simply have no elements to match on the other pages. */

/* ===================================================================
   Obilant v2.

   One surface. The tan sheet runs unbroken from the header to the last
   price, and the footer is the only place the colour changes. Structure
   comes from hairlines, never from a change of background — v1 alternated
   tan and near-black between sections and that is what made it read as a
   slideshow rather than as a page.

   Type carries a rule worth knowing before editing: JetBrains Mono is for
   anything an auditor could check — frameworks, control counts, prices,
   the email. Inter Tight is for anything a person says. Mixing those two
   up is what makes a page like this feel arbitrary.
=================================================================== */
:root{
  --void:#0A0908;  --paper:#C9B49B;  --paper-lit:#E4D6C4;
  --ink:#1A1613;   --ink-dim:#5E534A; --ink-faint:#7F7466;
  --cream:#F2EBE1; --amber:#E08A2B;  --amber-lit:#F5B05A;
  /* --amber stays bright because it is decoration -- the scan lines carry no
     information. A focus ring does, and at 2.68:1 on white it failed the 3:1
     in WCAG 1.4.11: a keyboard user could not reliably see where they were.
     Split rather than darkened, so the motif keeps its colour. */
  --focus:#C4761F;
  /* The surface went white at the owner's request. Cards are white too, so
     the page is separated from them by a hairline and a soft shadow rather
     than by a change of colour. The hard offset shadow that was here before
     read as retro next to a form; modern wants diffuse and shallow. */
  --sheet:#FFFFFF;
  --edge:rgba(26,22,19,.13);
  --lift:0 1px 2px rgba(26,22,19,.05), 0 8px 24px -8px rgba(26,22,19,.10);
  --lift-sm:0 1px 2px rgba(26,22,19,.05), 0 4px 14px -6px rgba(26,22,19,.08);
  --radius:10px;
  --field:#FDFDFC;
  /* Was #DFDBD4, which is 1.38:1 on white. WCAG 1.4.11 wants 3:1 for the
     boundary of a form control, and at 1.38 the input edge was decoration
     rather than something you could locate. #9F9486 keeps the warm cast. */
  --field-line:#998E81;
  --line:rgba(26,22,19,.16); --line-d:rgba(255,255,255,.10);
  --e:cubic-bezier(.16,1,.3,1);
  --wrap:1240px;
  --gut:38px;
}
*{box-sizing:border-box;margin:0}
html{background:#FFFFFF;-webkit-font-smoothing:antialiased;scroll-behavior:smooth}
body{background:#FFFFFF;color:var(--ink);overflow-x:hidden;
  font:400 16px/1.65 "Inter Tight",system-ui,-apple-system,sans-serif}
a{color:inherit;text-decoration:none}
h1,h2,h3{margin:0;font-weight:600;letter-spacing:-.038em;line-height:1}
::selection{background:var(--amber);color:#12100E}
:focus-visible{outline:2px solid var(--focus);outline-offset:3px}

.m{font-family:"JetBrains Mono",ui-monospace,SFMono-Regular,monospace}
.wrap{max-width:var(--wrap);margin:0 auto;padding:0 var(--gut)}

/* Eyebrow: mono, wide-tracked, always paired with a short leader rule so it
   reads as a field label on a form rather than as decoration. */
.eyebrow{display:flex;align-items:center;gap:14px;
  font:500 10px/1 "JetBrains Mono",monospace;letter-spacing:.28em;
  text-transform:uppercase;color:var(--ink-dim)}
.eyebrow::before{content:"";width:26px;height:1px;background:var(--ink-dim);
  flex:none;opacity:.45}

/* ================= header ================= */
/* A white bar on the tan, on its own wider wrap so it reads as chrome rather
   than as sparse marks floating in the page. */
header{position:fixed;inset:0 0 auto;z-index:60;padding:22px 0;
  background:rgba(255,255,255,.86);backdrop-filter:blur(14px);
  -webkit-backdrop-filter:blur(14px);border-bottom:1px solid var(--edge);
  transition:background .4s var(--e),backdrop-filter .4s var(--e)}
header .wrap{display:flex;align-items:center;gap:30px;max-width:1520px}
header.stuck{background:rgba(255,255,255,.94);backdrop-filter:blur(14px);
  -webkit-backdrop-filter:blur(14px);
  box-shadow:0 10px 26px rgba(26,22,19,.07)}
/* Superseded by the border above; kept out of the way rather than removed from
   the markup, where it is an empty span. */
header .hrule{display:none}

.brand{display:flex;align-items:center;gap:11px}
.brand img{width:28px;height:auto;filter:invert(1) brightness(.12)}
.brand span{font-size:19.5px;font-weight:600;letter-spacing:-.03em;color:var(--ink)}
.quote{font:500 11.5px/1 "JetBrains Mono",monospace;letter-spacing:.24em;
  text-transform:uppercase;color:var(--ink-dim);
  padding-left:26px;border-left:1px solid var(--edge)}
nav{margin-left:auto;display:flex;gap:30px;align-items:center}
nav a{font-size:15px;font-weight:500;color:var(--ink-dim);transition:color .3s var(--e)}
nav a:hover{color:var(--ink)}
nav a.cta{border:1px solid var(--ink);color:var(--ink);padding:11px 22px;
  transition:background .3s var(--e),color .3s var(--e)}
nav a.cta:hover{background:var(--ink);color:#fff}
@media(max-width:820px){ .quote{display:none} }
@media(max-width:560px){ nav a.ghostnav{display:none} nav{gap:18px} }

/* ================= the scan =================
   The signature. A hairline crosses a section and leaves — it never rests
   there. What it leaves behind is the divider rule, which draws in behind
   it, so the sweep reads as the thing that builds the structure of the page
   rather than as an effect laid on top of it. */
.scan{position:absolute;left:0;right:0;top:0;height:1px;pointer-events:none;
  background:linear-gradient(90deg,transparent,var(--amber) 12%,var(--amber-lit) 50%,var(--amber) 88%,transparent);
  opacity:0;z-index:5}
section.in > .scan{animation:scan-down .62s var(--e) forwards}
@keyframes scan-down{
  0%  {transform:translateY(0);      opacity:0}
  14% {opacity:.85}
  78% {opacity:.5}
  100%{transform:translateY(var(--scan-h,320px)); opacity:0}
}
/* The counterpart, crossing left to right and exiting the far edge. Used
   once, in the hero — a second one anywhere else turns a signature into a
   tic. */
.scan-x{position:absolute;top:0;bottom:0;left:0;width:1px;pointer-events:none;
  background:linear-gradient(180deg,transparent,var(--amber) 20%,var(--amber) 80%,transparent);
  opacity:0;z-index:5}
section.in > .scan-x{animation:scan-across .78s var(--e) .12s forwards}
@keyframes scan-across{
  0%  {transform:translateX(0);     opacity:0}
  16% {opacity:.7}
  80% {opacity:.35}
  100%{transform:translateX(100vw); opacity:0}
}

/* The divider the sweep leaves behind. Collapsed only under .js — otherwise
   a visitor with scripting off loses every divider on the page, and the rules
   are the only structure this design has. */
.rule{display:block;height:1px;background:var(--line);transform-origin:left center}
.js .rule{transform:scaleX(0)}
.js .in .rule{transform:scaleX(1);transition:transform .55s var(--e) .12s}

/* ================= reveal =================
   The resting DOM is the truth: with no JS at all every word is on screen.
   The inline script in <head> adds .js, and only then does anything start
   hidden. Motion is decoration; the page is readable without it. */
.js .rv{opacity:0;transform:translateY(14px)}
.js .in .rv{opacity:1;transform:none;
  transition:opacity .5s var(--e),transform .5s var(--e)}
.js .in .rv:nth-child(2){transition-delay:.06s}
.js .in .rv:nth-child(3){transition-delay:.12s}
.js .in .rv:nth-child(4){transition-delay:.18s}
.js .in .rv:nth-child(5){transition-delay:.24s}
.js .in .rv:nth-child(6){transition-delay:.30s}

section{position:relative;scroll-margin-top:92px}

/* ================= hero =================
   The mark is two mirrored crescents about a vertical axis, so splitting it
   down that axis is not an effect applied to the logo — it is the logo taken
   apart. The copy lands in the gap; sheets orbit between the crescents and
   the words. Sequence and failure handling live in assets/hero.js. */
#hero{padding:min(19vh,150px) 0 clamp(46px,7vh,84px);min-height:min(92vh,880px);
  display:flex;flex-direction:column;justify-content:center}
#hero .eyebrow{margin-bottom:clamp(24px,3.4vh,38px);justify-content:center}
#hero .eyebrow::after{content:"";width:26px;height:1px;background:var(--ink-dim);
  flex:none;opacity:.45}
h1{font-size:clamp(38px,6.2vw,84px);line-height:.97;max-width:14ch;margin-inline:auto}

/* --- the stage: crescents + sheets, behind the copy --- */
.stage{position:absolute;inset:0;pointer-events:none;overflow:hidden;
  --mark:clamp(245px,31.5vw,425px);
  --mark-h:calc(var(--mark)*.883);   /* logo.png is 512x452 */
  --split:clamp(180px,26.5vw,365px)}
#sheets{position:absolute;left:50%;top:var(--stage-y,46%);transform:translate(-50%,-50%);
  width:min(1180px,96vw);height:min(560px,62vh);z-index:2;
  opacity:0;transition:opacity 1.2s var(--e)}
#sheets.on{opacity:1}

/* Each half is a window onto its side of the mark. The span inside is the
   full-width mark, masked — masking rather than <img> so the colour is a
   background-color that can transition cream -> ink during the landing. */
.mark{position:absolute;top:var(--stage-y,46%);width:calc(var(--mark)/2 + 1px);
  height:var(--mark-h);overflow:hidden;z-index:1;display:none}
@supports (mask-image:url(/x)) or (-webkit-mask-image:url(/x)){ .mark{display:block} }
.mark i{position:absolute;top:0;width:var(--mark);height:100%;display:block;
  background-color:rgba(26,22,19,.20);
  -webkit-mask:url(/assets/logo.png) no-repeat center/contain;
          mask:url(/assets/logo.png) no-repeat center/contain;
  transition:background-color .5s var(--e)}
.mark-l{left:calc(50% - var(--mark)/2);transform:translate(calc(-1*var(--split)),-50%)}
.mark-r{left:50%;transform:translate(var(--split),-50%)}
.mark-l i{left:0}
.mark-r i{right:0}

/* Zero-height, never painted. Its width is --split, so offsetWidth hands
   hero.js the resolved clamp() value without it parsing CSS. */
.gap-probe{position:absolute;left:0;top:0;width:var(--split);height:0;
  visibility:hidden;pointer-events:none}

.hero-copy{position:relative;z-index:3;text-align:center}

/* Phones: the crescents shrink and close in so they frame the headline
   rather than crowding it, and the sheets are skipped entirely (hero.js
   never creates a WebGL context below 700px). */
@media(max-width:700px){
  .stage{--mark:min(42vw,210px);--split:min(26vw,132px)}
  #hero{min-height:auto;padding-top:min(15vh,110px)}
  /* The hero is short enough on a phone that the crescents land behind the
     body copy rather than the headline, so they drop back further. */
  .mark i{background-color:rgba(26,22,19,.12)}
}
/* Each line is wiped open as the sweep passes rather than faded in as a
   block — the point of the motif is that the line is doing the reading. */
/* padding + negative margin so the wipe can clip the line above without
   also clipping the descender in "blocking". */
.line{display:block;overflow:hidden;padding-bottom:.09em;margin-bottom:-.09em}
.line > i{display:block;font-style:normal;transform:translateY(102%)}
.js .line > i{transition:transform .72s var(--e)}
.js.g-copy .line:nth-child(1) > i{transform:none;transition-delay:.04s}
.js.g-copy .line:nth-child(2) > i{transform:none;transition-delay:.12s}
.js.g-copy .line:nth-child(3) > i{transform:none;transition-delay:.20s}
html:not(.js) .line > i{transform:none}

#hero .sub{margin:32px auto 0;max-width:52ch;font-size:clamp(17px,1.55vw,20px);
  line-height:1.6;color:var(--ink-dim)}
.actions{margin-top:clamp(30px,4.4vh,46px);display:flex;gap:14px;flex-wrap:wrap;
  align-items:center;justify-content:center}
.btn{border-radius:var(--radius);display:inline-flex;align-items:center;gap:10px;padding:17px 30px;
  font:500 15.5px/1 "Inter Tight",sans-serif;
  background:var(--ink);color:#fff;border:1px solid var(--ink);
  transition:background .3s var(--e),color .3s var(--e)}
.btn:hover{background:transparent;color:var(--ink)}
.btn.ghost{background:transparent;color:var(--ink);border-color:var(--line)}
.btn.ghost:hover{border-color:var(--ink)}

/* The framework strip closes the hero: mono, ruled, and the four names the
   whole business is organised around. */
.strip{margin-top:clamp(56px,9vh,96px)}
.strip .rule{display:none}
.strip ul{list-style:none;padding:0;margin:0;display:grid;
  grid-template-columns:repeat(4,1fr);gap:16px}
.strip li{border-radius:var(--radius);padding:22px 24px 24px;background:var(--sheet);
  border:1px solid var(--edge);box-shadow:var(--lift-sm)}
.strip .fw{font:500 15.5px/1 "JetBrains Mono",monospace;letter-spacing:-.01em;color:var(--ink)}
.strip .fwd{margin-top:10px;font:400 13px/1.5 "JetBrains Mono",monospace;color:var(--ink-dim)}
@media(max-width:760px){ .strip ul{grid-template-columns:1fr 1fr;gap:12px} }

/* ================= the gate =================
   A void panel over the finished page for ~1.6s while the mark forms and
   splits. Everything here is an override *away* from the resting state:
   with JS off the .g-* classes never appear, the panel is display:none, and
   the hero is already in its landed position. Nothing is hidden by default. */
#gate{display:none;position:fixed;inset:0;z-index:90;background:var(--void);
  pointer-events:none}
.js #gate{display:block}
.js.g-land #gate{opacity:0;transition:opacity .52s var(--e)}
.js.g-done #gate{display:none}
.js.gating{overflow:hidden}
.js.gating body{overflow:hidden}

/* Before the split the halves sit together, cream on the void, and lifted
   above the panel. */
.js:not(.g-done) #hero{z-index:95}
.js:not(.g-copy) #hero .rv{opacity:0;transform:translateY(14px)}
.js:not(.g-land) .mark i{background-color:var(--cream)}
.js:not(.g-split) .mark-l{transform:translate(0,-50%)}
.js:not(.g-split) .mark-r{transform:translate(0,-50%)}
.js:not(.g-mark) .mark{opacity:0}
.js .mark{opacity:1;transition:opacity .5s var(--e),transform .74s var(--e)}
.js:not(.g-mark) .mark-l,.js:not(.g-mark) .mark-r{transform:translate(0,-50%) scale(.94)}

/* The copy waits in the wings until the panel has gone. */
.js:not(.g-copy) .hero-copy{opacity:0;transform:translateY(12px)}
.js .hero-copy{transition:opacity .6s var(--e),transform .6s var(--e)}

/* The failsafe path snaps rather than animates. A recovery from "the module
   that runs this never loaded" should put the finished page on screen at
   once; transitioning into it just means depending on more of the same
   machinery that already failed. */
.js.g-snap .hero-copy,
.js.g-snap .mark,
.js.g-snap .mark i,
.js.g-snap .line > i,
.js.g-snap #hero .rv,
.js.g-snap #gate{transition:none !important;animation:none !important}

/* ================= generic section ================= */
.band{padding:clamp(76px,11vh,132px) 0 0}
.head{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.15fr);
  gap:clamp(28px,5vw,80px);align-items:start;margin-top:clamp(48px,7vh,78px)}
.head h2{font-size:clamp(28px,3.9vw,50px);max-width:18ch;line-height:1.04}
.head p{font-size:clamp(15.5px,1.35vw,17.5px);color:var(--ink-dim);max-width:52ch}
.head .eyebrow{margin-bottom:20px}
.head > p{margin-top:31px}   /* eyebrow line-box + its margin */
@media(max-width:860px){ .head{grid-template-columns:1fr;gap:24px} .head > p{margin-top:0} }

/* ================= how it runs ================= */
.steps{margin-top:clamp(52px,7vh,84px);display:grid;grid-template-columns:repeat(3,1fr);
  gap:20px}
.step{border-radius:var(--radius);padding:32px 28px 34px;background:var(--sheet);
  border:1px solid var(--edge);box-shadow:var(--lift)}
/* Numbered because this genuinely is a sequence — intake, then build, then
   the record that comes out of both. */
.step .n{font:500 11px/1 "JetBrains Mono",monospace;letter-spacing:.2em;color:var(--ink)}
.step h3{margin-top:20px;font-size:clamp(19px,1.75vw,23px);letter-spacing:-.03em;
  line-height:1.22;max-width:19ch}
.step p{margin-top:14px;font-size:14.5px;line-height:1.62;color:var(--ink-dim);max-width:34ch}
@media(max-width:860px){ .steps{grid-template-columns:1fr;gap:16px} }

/* ================= coverage register ================= */
.reg{margin-top:clamp(46px,6vh,72px);display:flex;flex-direction:column;gap:14px}
.reg .row{border-radius:var(--radius);display:grid;grid-template-columns:minmax(0,1.05fr) minmax(0,1.5fr) 168px;
  gap:24px;align-items:baseline;padding:24px 26px;background:var(--sheet);
  border:1px solid var(--edge);box-shadow:var(--lift)}
.reg .nm{font:500 clamp(18px,2vw,26px)/1 "JetBrains Mono",monospace;
  letter-spacing:-.02em;color:var(--ink)}
.reg .ds{font-size:15px;color:var(--ink-dim)}
.reg .ct{font:400 12px/1 "JetBrains Mono",monospace;letter-spacing:.14em;
  text-transform:uppercase;color:var(--ink-dim);white-space:nowrap;text-align:right}
@media(max-width:760px){
  .reg .row{grid-template-columns:1fr;gap:8px;padding:20px 22px}
  .reg .ct{text-align:left}
}

/* ================= about ================= */
.about{margin-top:clamp(46px,6vh,72px);display:grid;
  grid-template-columns:minmax(0,1.45fr) minmax(0,1fr);gap:20px;align-items:start}
.about .card{padding:clamp(30px,3.4vw,44px);background:var(--sheet);
  border:1px solid var(--edge);box-shadow:var(--lift)}
.about .card p{font-size:clamp(15.5px,1.35vw,17px);line-height:1.66;color:var(--ink-dim);
  max-width:58ch}
.about .card p + p{margin-top:18px}
.about .card p strong{color:var(--ink);font-weight:500}
.about .card p.who{font:500 clamp(20px,2.1vw,27px)/1.2 "Inter Tight",sans-serif;
  letter-spacing:-.03em;color:var(--ink);margin:0 0 22px;max-width:none}

/* The checkable facts, in mono — same rule as everywhere else on the page. */
.creds{border-radius:var(--radius);background:var(--sheet);border:1px solid var(--edge);box-shadow:var(--lift);
  padding:clamp(26px,2.6vw,32px);display:flex;flex-direction:column;gap:0}
.creds h3{font:500 10px/1 "JetBrains Mono",monospace;letter-spacing:.26em;
  text-transform:uppercase;color:var(--ink-dim);margin-bottom:20px}
.creds dl{margin:0;display:flex;flex-direction:column;gap:0}
.creds div{padding:14px 0;border-top:1px solid var(--line)}
.creds div:first-of-type{border-top:0;padding-top:0}
.creds dt{font:400 11px/1 "JetBrains Mono",monospace;letter-spacing:.16em;
  text-transform:uppercase;color:var(--ink-dim)}
.creds dd{margin:8px 0 0;font:500 15px/1.35 "JetBrains Mono",monospace;color:var(--ink)}
@media(max-width:860px){ .about{grid-template-columns:1fr} }

/* ================= price ================= */
/* The one deliberate exception to the one-surface rule, made at the owner's
   request: the tiers sit on a sheet of paper laid on the tan desk, the same
   white the hero's orbiting sheets are drawn on. It stays a single panel with
   the columns still divided by rules — three separate floating cards would be
   three new surfaces rather than one. */
.tiers{margin-top:clamp(50px,7vh,80px);display:grid;grid-template-columns:repeat(3,1fr);
  gap:20px}
/* max-width without margin-inline:auto left both cards jammed against the
   left gutter with a card's worth of dead space beside them. It only became
   visible when the third tier came out -- at three columns the grid filled
   the wrap, so the missing centring never showed. */
.tiers-2{grid-template-columns:repeat(2,1fr);max-width:820px;margin-inline:auto}
@media(max-width:860px){ .tiers-2{grid-template-columns:1fr;max-width:none} }
.tier{border-radius:var(--radius);padding:34px 30px 36px;background:var(--sheet);
  border:1px solid var(--edge);box-shadow:var(--lift);
  display:flex;flex-direction:column}
.tier .nm{font:500 11px/1 "JetBrains Mono",monospace;letter-spacing:.24em;
  text-transform:uppercase;color:var(--ink-dim)}
.tier .amt{margin-top:26px;font:500 clamp(32px,3.6vw,46px)/1 "JetBrains Mono",monospace;
  letter-spacing:-.045em;color:var(--ink)}
.tier .per{margin-top:10px;font:400 11px/1 "JetBrains Mono",monospace;
  letter-spacing:.2em;text-transform:uppercase;color:var(--ink-dim)}
.tier p{margin-top:24px;font-size:14.5px;line-height:1.62;color:var(--ink-dim);
  max-width:32ch;flex:1}
.tier .go{margin-top:30px;display:inline-flex;align-items:center;gap:9px;
  font:500 13.5px/1 "Inter Tight",sans-serif;color:var(--ink);
  border-bottom:1px solid var(--line);padding-bottom:7px;align-self:flex-start;
  transition:border-color .3s var(--e),gap .3s var(--e)}
.tier .go:hover{border-color:var(--ink);gap:14px}
.note{margin-top:clamp(38px,5vh,56px);max-width:60ch;font-size:15px;
  line-height:1.65;color:var(--ink-dim)}
.note b{font-weight:500;color:var(--ink)}
@media(max-width:860px){ .tiers{grid-template-columns:1fr;gap:16px} }

/* ================= footer =================
   The only colour change on the page. */
footer{background:var(--void);color:var(--cream);
  padding:clamp(64px,9vh,104px) 0 40px;margin-top:clamp(60px,9vh,110px)}
footer .top{display:grid;grid-template-columns:minmax(0,1.6fr) repeat(2,minmax(0,1fr));
  gap:clamp(30px,5vw,64px);align-items:start}
footer .brand span{color:var(--cream)}
footer .brand img{filter:none}
footer .tag{margin-top:18px;font-size:15px;color:#B6ADA2;max-width:30ch}
footer .mail{margin-top:22px;display:inline-block;
  font:400 13.5px/1 "JetBrains Mono",monospace;color:var(--cream);
  border-bottom:1px solid rgba(255,255,255,.28);padding-bottom:6px;
  transition:border-color .3s var(--e)}
footer .mail:hover{border-color:var(--amber)}
footer h4{margin:0 0 18px;font:500 10px/1 "JetBrains Mono",monospace;
  letter-spacing:.26em;text-transform:uppercase;color:#948B81}
footer ul{list-style:none;padding:0;margin:0;display:grid;gap:11px}
footer ul li{font-size:14px;color:#B6ADA2}
footer ul a{color:#B6ADA2;transition:color .3s var(--e)}
footer ul a:hover{color:var(--cream)}
footer .bot{margin-top:clamp(48px,7vh,80px);padding-top:24px;
  border-top:1px solid var(--line-d);display:flex;justify-content:space-between;
  gap:18px;flex-wrap:wrap;
  font:400 11px/1.6 "JetBrains Mono",monospace;color:#948B81}
footer :focus-visible{outline-color:var(--amber-lit)}
@media(max-width:760px){
  footer .top{grid-template-columns:1fr 1fr}
  footer .brandcol{grid-column:1/-1}
}

@media(max-width:600px){ :root{--gut:20px} }

/* ===================================================================
   Sub-pages: pricing, about, contact, client access.

   These have no hero and no gate, so they open directly under the fixed
   header and need their own top offset. Everything else is the same
   system as the home page — same sheet, same edge, same lift.
=================================================================== */
.page-head{padding:calc(84px + clamp(52px,8vh,96px)) 0 0}
.page-head .eyebrow{margin-bottom:22px}
.page-head h1{font-size:clamp(34px,5vw,64px);line-height:1.0;max-width:18ch;
  margin-inline:0;text-align:left}
.page-head .lede{margin-top:26px;max-width:60ch;
  font-size:clamp(16.5px,1.5vw,19px);line-height:1.62;color:var(--ink-dim)}

/* ---- pricing table ---- */
.plans{margin-top:clamp(44px,6vh,72px);display:grid;
  grid-template-columns:repeat(3,1fr);gap:20px}
/* Two plans, not three: let them breathe rather than stretch full width. */
.plans-2{grid-template-columns:repeat(2,1fr);max-width:840px;margin-inline:auto}  /* same omission as .tiers-2 -- see the note there */
@media(max-width:900px){ .plans-2{grid-template-columns:1fr;max-width:none} }
.plan{border-radius:var(--radius);background:var(--sheet);border:1px solid var(--edge);box-shadow:var(--lift);
  padding:34px 30px 36px;display:flex;flex-direction:column}
.plan .nm{font:500 11px/1 "JetBrains Mono",monospace;letter-spacing:.24em;
  text-transform:uppercase;color:var(--ink-dim)}
.plan .amt{margin-top:24px;font:500 clamp(34px,3.8vw,48px)/1 "JetBrains Mono",monospace;
  letter-spacing:-.045em;color:var(--ink)}
.plan .per{margin-top:10px;font:400 11px/1 "JetBrains Mono",monospace;
  letter-spacing:.2em;text-transform:uppercase;color:var(--ink-dim)}
.plan .who{margin-top:22px;font-size:14.5px;line-height:1.6;color:var(--ink-dim);
  min-height:4.8em}
.plan ul{list-style:none;padding:0;margin:24px 0 0;display:flex;
  flex-direction:column;gap:11px;flex:1}
.plan li{font-size:14.5px;line-height:1.5;color:var(--ink-dim);
  padding-left:20px;position:relative}
.plan li::before{content:"";position:absolute;left:0;top:.55em;width:9px;height:1px;
  background:var(--ink)}
.plan li.no{color:var(--ink-faint)}
.plan li.no::before{background:var(--ink-faint);opacity:.5}
.plan .go{margin-top:30px;display:inline-flex;align-items:center;gap:9px;
  font:500 14px/1 "Inter Tight",sans-serif;color:var(--ink);
  border-bottom:1px solid var(--line);padding-bottom:7px;align-self:flex-start;
  transition:border-color .3s var(--e),gap .3s var(--e)}
.plan .go:hover{border-color:var(--ink);gap:14px}
@media(max-width:900px){ .plans{grid-template-columns:1fr;gap:16px}
  .plan .who{min-height:0} }

/* ---- what is and is not included ---- */
.matrix{border-radius:var(--radius);margin-top:clamp(46px,6vh,72px);overflow-x:auto;
  background:var(--sheet);border:1px solid var(--edge);box-shadow:var(--lift)}
.matrix table{border-collapse:collapse;width:100%;min-width:640px}
.matrix th,.matrix td{text-align:left;padding:15px 20px;
  border-bottom:1px solid var(--line);font-size:14.5px;color:var(--ink-dim)}
.matrix thead th{font:500 10px/1 "JetBrains Mono",monospace;letter-spacing:.22em;
  text-transform:uppercase;color:var(--ink-dim);white-space:nowrap}
.matrix tbody th{font-weight:500;color:var(--ink);width:42%}
.matrix td{text-align:center;font-family:"JetBrains Mono",monospace;font-size:13px}
.matrix tr:last-child th,.matrix tr:last-child td{border-bottom:0}
.matrix .yes{color:var(--ink)}
.matrix .no{color:var(--ink-faint)}

/* ---- prose blocks ---- */
.prose{margin-top:clamp(40px,5vh,64px);display:grid;
  grid-template-columns:minmax(0,1.5fr) minmax(0,1fr);gap:24px;align-items:start}
.prose .card{border-radius:var(--radius);background:var(--sheet);border:1px solid var(--edge);
  box-shadow:var(--lift);padding:clamp(28px,3.2vw,42px)}
.prose .card h2{font-size:clamp(20px,2.2vw,27px);letter-spacing:-.03em;
  line-height:1.2;margin-bottom:18px}
.prose .card h3{font-size:16.5px;letter-spacing:-.02em;margin:26px 0 10px}
.prose .card p{font-size:15.5px;line-height:1.68;color:var(--ink-dim);max-width:62ch}
.prose .card p + p{margin-top:16px}
.prose .card strong{color:var(--ink);font-weight:500}
@media(max-width:900px){ .prose{grid-template-columns:1fr} }

/* ---- contact ---- */
.ways{margin-top:clamp(40px,5vh,64px);display:grid;
  grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:20px}
.way{border-radius:var(--radius);background:var(--sheet);border:1px solid var(--edge);box-shadow:var(--lift);
  padding:30px 28px 32px;display:flex;flex-direction:column}
.way h2{font-size:18px;letter-spacing:-.025em;margin-bottom:12px}
.way p{font-size:14.5px;line-height:1.6;color:var(--ink-dim);flex:1}
/* Selectable, because a mailto link silently does nothing on a machine with
   no mail client configured — which is exactly how this button "did not work". */
.pick{margin-top:20px;display:block;font:500 15px/1.4 "JetBrains Mono",monospace;
  color:var(--ink);background:var(--paper-lit);border:1px solid var(--line);
  padding:13px 15px;word-break:break-all;user-select:all;-webkit-user-select:all}
.way .sub{margin-top:12px;font-size:13px;color:var(--ink-dim);flex:none}

.notice{border-radius:var(--radius);margin-top:clamp(40px,5vh,60px);padding:24px 26px;background:var(--sheet);
  border:1px solid var(--edge);box-shadow:var(--lift);max-width:70ch}
.notice h2{font-size:17px;letter-spacing:-.02em;margin-bottom:12px}
.notice p{font-size:15px;line-height:1.65;color:var(--ink-dim)}
.notice p + p{margin-top:14px}
.notice strong{color:var(--ink);font-weight:500}

.tail{margin:clamp(56px,8vh,96px) 0 clamp(40px,6vh,72px)}

/* ---- enquiry form ----
   Rebuilt away from browser defaults. The complaint was that it looked like a
   1990s dialog, and it did: unstyled inputs, a fieldset border around the
   checkboxes, and labels sitting inline beside their fields. Labels now sit
   above their input, everything is left aligned in one column, and the field
   itself carries the weight instead of a box drawn around a group. */
.formwrap{margin-top:clamp(36px,4.5vh,56px);display:grid;
  grid-template-columns:minmax(0,1.3fr) minmax(0,1fr);
  gap:28px;align-items:start}
@media(max-width:920px){ .formwrap{grid-template-columns:1fr} }

.formcard{background:var(--sheet);border:1px solid var(--edge);
  box-shadow:var(--lift);padding:clamp(26px,3vw,40px);text-align:left}

.frow{display:grid;grid-template-columns:1fr 1fr;gap:18px}
@media(max-width:560px){ .frow{grid-template-columns:1fr} }

.field{display:flex;flex-direction:column;text-align:left}
.field + .field,.frow + .field,.field + .frow,.frow + .frow{margin-top:20px}
/* ...but not inside a row: adjacent siblings there sit side by side, and the
   margin was pushing the right-hand label a line lower than the left. */
.frow > .field + .field{margin-top:0}

/* Sentence case, not tracked-out mono caps. A form is read quickly and
   uppercase micro-type is the slowest thing to scan. */
.field label{font:500 13.5px/1.3 "Inter Tight",system-ui,sans-serif;
  letter-spacing:0;text-transform:none;color:var(--ink);margin-bottom:8px}
.req{color:var(--ink-faint);font-weight:400}

.field input,.field select,.field textarea{
  width:100%;padding:13px 15px;border-radius:8px;
  font:400 15px/1.45 "Inter Tight",system-ui,sans-serif;color:var(--ink);
  background:var(--field);border:1px solid var(--field-line);
  transition:border-color .18s var(--e),box-shadow .18s var(--e),background .18s var(--e);
  -webkit-appearance:none;appearance:none}
.field textarea{min-height:118px;resize:vertical}
.field input::placeholder,.field textarea::placeholder{color:#A9A199}
.field input:hover,.field select:hover,.field textarea:hover{border-color:#C6C0B7}
.field input:focus,.field select:focus,.field textarea:focus{
  outline:none;background:#fff;border-color:var(--ink);
  box-shadow:0 0 0 3px rgba(26,22,19,.08)}

/* The default arrow is the most dated thing on a form. */
.field select{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8'%3E%3Cpath d='M1 1.5 6 6.5 11 1.5' fill='none' stroke='%235E534A' stroke-width='1.6' stroke-linecap='round'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right 15px center;padding-right:40px}

/* No fieldset border. The legend reads as a label like any other. */
fieldset{border:0;padding:0;margin:22px 0 0;min-width:0}
legend{font:500 13.5px/1.3 "Inter Tight",system-ui,sans-serif;letter-spacing:0;
  text-transform:none;color:var(--ink);padding:0;margin-bottom:12px}

.checks{display:grid;grid-template-columns:1fr 1fr;gap:8px}
@media(max-width:620px){ .checks{grid-template-columns:1fr} }
.check{display:flex;align-items:center;gap:11px;font-size:14.5px;line-height:1.35;
  color:var(--ink-dim);cursor:pointer;padding:11px 13px;border-radius:8px;
  border:1px solid var(--field-line);background:var(--field);
  transition:border-color .18s var(--e),background .18s var(--e)}
.check:hover{border-color:#C6C0B7;background:#fff}
.check input{width:17px;height:17px;margin:0;flex:none;accent-color:var(--ink);
  cursor:pointer}
.check:has(input:checked){border-color:var(--ink);background:#fff}
.check:focus-within{border-color:var(--ink);box-shadow:0 0 0 3px rgba(26,22,19,.08)}

.hp{position:absolute!important;left:-9999px!important;width:1px!important;
  height:1px!important;overflow:hidden!important}

.formcard .btn{margin-top:26px;border:0;cursor:pointer;font-family:inherit;
  padding:15px 30px;font-size:15px}
.formcard .btn[disabled]{opacity:.5;cursor:progress}
.formnote{margin-top:16px;font-size:13.5px;line-height:1.55;color:var(--ink-dim);
  max-width:52ch}
.msg{margin-top:18px;padding:14px 16px;border-radius:8px;border:1px solid var(--edge);
  background:var(--field);font-size:14.5px;line-height:1.55;display:none}
.msg.on{display:block}
.msg.bad{border-color:var(--focus);background:rgba(224,138,43,.08);color:var(--ink)}
.msg.good{border-color:var(--ink);color:var(--ink)}

.pick{margin-top:18px;display:block;font:500 15px/1.4 "JetBrains Mono",monospace;
  color:var(--ink);background:var(--field);border:1px solid var(--field-line);
  border-radius:8px;padding:13px 15px;word-break:break-all;
  user-select:all;-webkit-user-select:all}

/* ---- sign in ----
   Structure follows the reference: providers first, divider, then credentials.
   Rendered in this site's language rather than the reference's, because a
   sign-in page that looks like another company's is where a careful person
   starts wondering who they are handing a password to. */
.oauths{display:flex;flex-direction:column;gap:10px}
.oauth{display:flex;align-items:center;gap:12px;width:100%;
  padding:13px 18px;border-radius:8px;cursor:pointer;
  font:500 15px/1 "Inter Tight",system-ui,sans-serif;
  color:var(--ink);background:#fff;border:1px solid var(--field-line);
  transition:border-color .18s var(--e),box-shadow .18s var(--e),background .18s var(--e)}
.oauth:hover{border-color:#C6C0B7;background:var(--field)}
.oauth:focus-visible{outline:none;border-color:var(--ink);
  box-shadow:0 0 0 3px rgba(26,22,19,.08)}
.oauth-mark{display:flex;width:18px;height:18px;flex:none}
.oauth.gh{background:var(--ink);color:#fff;border-color:var(--ink)}
.oauth.gh:hover{background:#000;border-color:#000}

.or{display:flex;align-items:center;gap:14px;margin:22px 0;
  font:400 13px/1 "Inter Tight",sans-serif;color:var(--ink-faint)}
.or::before,.or::after{content:"";flex:1;height:1px;background:var(--edge)}

.forgot{margin-top:14px;font-size:13.5px}
.forgot a{color:var(--ink-dim);text-decoration:underline;
  text-underline-offset:3px;text-decoration-color:var(--edge)}
.forgot a:hover{color:var(--ink);text-decoration-color:var(--ink)}
#toggle-wrap a{color:var(--ink);text-decoration:underline;text-underline-offset:3px}


/* The .band.tint rule that lived here is gone -- the owner asked for the cream
   back out, so the page is white end to end again and the footer is the only
   colour change on it. The .ai3 / .acard rules below stay: they are the AI
   section's layout, not its background. */

.ai3{margin-top:clamp(44px,6vh,68px);display:grid;
  grid-template-columns:repeat(3,1fr);gap:18px}
@media(max-width:860px){ .ai3{grid-template-columns:1fr;gap:14px} }
.acard{background:var(--sheet);border:1px solid var(--edge);
  border-radius:var(--radius);padding:28px 26px 30px;box-shadow:var(--lift-sm)}
.acard .nm{font:500 11px/1 "JetBrains Mono",monospace;letter-spacing:.2em;
  text-transform:uppercase;color:var(--ink-faint)}
.acard h3{margin-top:16px;font-size:17px;line-height:1.35;letter-spacing:-.01em}
.acard p{margin-top:12px;font-size:14.5px;line-height:1.62;color:var(--ink-dim)}
.aifoot{margin-top:clamp(34px,4.5vh,52px);padding-top:26px;
  border-top:1px solid var(--edge);font-size:14.5px;line-height:1.66;
  color:var(--ink-dim);max-width:760px}
.aifoot b{color:var(--ink);font-weight:600}


/* ============ client portal ============ */

/* The UA stylesheet's [hidden]{display:none} is beaten by any author rule that
   sets display -- and .pt-note, .pt-filter and .pt-list all set display:flex.
   The result was hide() appearing to do nothing: the portal showed "Checking
   your session" and "not open yet" stacked on top of each other. Scoped to the
   portal rather than global so it cannot surprise anything else on the site. */
#portal [hidden]{display:none !important}
.pt-note{display:flex;align-items:center;gap:12px;padding:26px 0;
  font-size:15px;color:var(--ink-dim)}
.pt-spin{width:14px;height:14px;border-radius:50%;flex:none;
  border:2px solid var(--edge);border-top-color:var(--ink);
  animation:ptspin .7s linear infinite}
@keyframes ptspin{to{transform:rotate(360deg)}}

.pt-panel{background:var(--sheet);border:1px solid var(--edge);
  border-radius:var(--radius);box-shadow:var(--lift-sm);
  padding:34px 32px 36px;max-width:640px}
.pt-panel h2{font-size:19px;line-height:1.3;letter-spacing:-.01em}
.pt-panel p{margin-top:14px;font-size:14.5px;line-height:1.65;color:var(--ink-dim)}
.pt-panel a{color:var(--ink);text-decoration:underline;text-underline-offset:3px}
.pt-panel .pt-small{font-size:13.5px;color:var(--ink-faint)}
.pt-bad{border-color:rgba(180,60,40,.32)}

.pt-bar{display:flex;align-items:flex-end;justify-content:space-between;gap:20px;
  padding-bottom:20px;border-bottom:1px solid var(--edge)}
.pt-org{font-size:17px;font-weight:600;letter-spacing:-.01em}
.pt-who{margin-top:5px;font:400 12px/1 "JetBrains Mono",monospace;color:var(--ink-faint)}
.pt-out{background:none;border:1px solid var(--edge);border-radius:8px;
  padding:9px 15px;font:inherit;font-size:13.5px;color:var(--ink-dim);
  cursor:pointer;transition:border-color .18s var(--e),color .18s var(--e)}
.pt-out:hover{border-color:var(--ink);color:var(--ink)}

.pt-filter{margin-top:22px;display:flex;flex-wrap:wrap;gap:8px}
.pt-chip{background:none;border:1px solid var(--edge);border-radius:999px;
  padding:6px 14px;font:400 12px/1.4 "JetBrains Mono",monospace;
  color:var(--ink-dim);cursor:pointer;transition:all .18s var(--e)}
.pt-chip.is-on{background:var(--ink);border-color:var(--ink);color:var(--cream)}

.pt-list{margin-top:22px;display:flex;flex-direction:column;gap:10px}
.pt-doc{display:flex;align-items:center;justify-content:space-between;gap:18px;
  background:var(--sheet);border:1px solid var(--edge);border-radius:var(--radius);
  box-shadow:var(--lift-sm);padding:20px 22px;
  transition:border-color .18s var(--e),transform .18s var(--e)}
.pt-doc:hover{border-color:rgba(26,22,19,.26);transform:translateY(-1px)}
.pt-doc-t{min-width:0}
.pt-doc-nm{font-size:15px;font-weight:500;letter-spacing:-.005em;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pt-doc-mt{margin-top:6px;font:400 11.5px/1 "JetBrains Mono",monospace;
  color:var(--ink-faint);text-transform:uppercase;letter-spacing:.1em}
.pt-get{flex:none;background:var(--ink);border:1px solid var(--ink);border-radius:8px;
  padding:10px 18px;font:inherit;font-size:13.5px;color:var(--cream);cursor:pointer;
  transition:opacity .18s var(--e)}
.pt-get:hover{opacity:.86}
.pt-get:disabled{opacity:.5;cursor:default}

@media(max-width:600px){
  .pt-doc{flex-direction:column;align-items:stretch;gap:14px}
  .pt-get{width:100%}
  .pt-bar{flex-direction:column;align-items:stretch;gap:14px}
}


/* ============ legal pages ============ */
.upd{font:400 12px/1 "JetBrains Mono",monospace;color:var(--ink-faint);
  letter-spacing:.06em;margin-bottom:30px}
.prose .card h3{margin-top:34px;font-size:17px;line-height:1.3;letter-spacing:-.01em}
.plainlist{margin:14px 0 0;padding-left:20px;display:flex;flex-direction:column;gap:9px}
.plainlist li{font-size:14.5px;line-height:1.62;color:var(--ink-dim)}
.plainlist li strong{color:var(--ink);font-weight:600}
/* The list is a flex column, so its children's margins do not collapse outward
   and the paragraph after it sat flush against the last bullet. */
.plainlist + p{margin-top:16px}
.formnote.consent{margin-top:10px;padding-top:12px;border-top:1px solid var(--edge)}
.formnote.consent a{color:var(--ink);text-decoration:underline;text-underline-offset:3px}
