/* ===================================================================================================
   OneFirmOS landing — blueprint design language.

   Ported from onefirmos-blueprint_19.html. Same tokens, same type scale, same hairline-and-square
   construction, applied to the landing page's existing copy and sections.

   Deliberately a SEPARATE stylesheet from landing-esqrd.css rather than an edit of it. The two are
   opposite treatments — dark/atmospheric vs light/technical — so mixing them means one set of rules
   permanently fighting the other, and reverting means unpicking a diff. Kept apart, the landing page
   swaps designs by changing which <link> and <script> it loads, and going back is the same two lines.

   The construction rules, so additions stay consistent:
     • Structure is drawn with 1px hairlines, never shadows or rounded corners. Nothing has a radius
       except the small dots.
     • Headings are uppercase, tight (-.02em, line-height .98) and fluid via clamp().
     • Small print is uppercase with wide tracking (.14em–.24em) — labels, counters, table headers.
     • Emerald is the only accent that marks state or position. Violet and steel are data colours.
     • Grid borders use the border-right:0/border-bottom:0 + per-cell borders trick, so internal rules
       are single-width and the outer frame never doubles up.
   =================================================================================================== */

:root{
  /* Structure. Not brandable — these are the paper and the ink the whole design is drawn on, and the
     hairlines are alpha values off the ink so they stay correct whatever the accents become. */
  --paper:#F4F4F1; --panel:#FAFAF8; --ink:#18202B; --mute:#5B6673; --faint:#A7A7A2;
  --line:rgba(24,32,43,.13); --line2:rgba(24,32,43,.07);
  --slate:#94A3B8;

  /* ── THE FOUR BRAND COLOURS ──────────────────────────────────────────────────────────────────────
     These are the only colour literals on the page, and site.js overwrites all four at runtime from
     super-admin → Website → Branding (`colors.primary / .secondary / .neutral / .fourth`). The values
     below are the defaults, used until that fetch lands and if it never does.

       --navy    primary    buttons, the log-in chip
       --em      secondary  the accent that marks state: label dots, corner ticks, hovers, the rail
       --steel   neutral    mid data colour
       --violet  fourth     the far end of the gradient
     ──────────────────────────────────────────────────────────────────────────────────────────────── */
  --navy:#083A4F;
  /* OneFirm's own teal, not the blueprint demo's emerald. This is the accent that draws every label
     square, corner tick, icon (they stroke with currentColor) and link hover, so an emerald default
     put green squares and green icons across pages whose brand is navy — the "random green" that
     kept coming back. Super-admin's secondary colour still overrides this at runtime via site.js;
     this is only what shows before that fetch lands, and if it never does. */
  --em:#407E8C;
  --steel:#5B8AA6;
  --violet:#A98BFF;

  /* ── DERIVED — var() expressions, never literals ─────────────────────────────────────────────────
     This is the whole trick, and it is easy to get wrong. A custom property is substituted where it is
     USED, not where it is declared, so a gradient written in terms of var(--violet) re-resolves the
     moment JS overrides --violet. Had --grad kept its four hex literals, a rebrand would have recoloured
     the dots and the buttons and left the headline gradient on the old palette — a half-applied rebrand,
     which looks worse than none. Anything that mixes brand colours belongs here, in this form.
     ──────────────────────────────────────────────────────────────────────────────────────────────── */
  --teal:var(--em);
  --aqua:var(--steel);
  --deep:#06222E;   /* primary, darkened — replaced by color-mix below where supported */
  /* THREE stops, each a different brand colour — secondary → neutral → fourth.
     History, because this has now been wrong in both directions. The blueprint shipped a FOUR-stop ramp
     that doubled back on emerald (violet → em → steel → em); driven from super-admin that read as a muddy
     rainbow, because the doubling-back made the eye cross the same hues twice. Collapsing it to two stops
     fixed the mud but silently dropped a brand colour — whichever of neutral/fourth is the warm one just
     vanished from the headline.
     Three distinct stops, in order, no repeats: every brand colour appears once, the eye travels each hue
     once, and nothing is dropped. Interpolated in OKLAB below so the blend keeps its chroma. */
  --grad:linear-gradient(100deg,var(--em),var(--steel) 48%,var(--violet));

  --f:'Inter',system-ui,-apple-system,sans-serif;
  --pad:44px;
}
/* Button hover = the primary, darkened. Tracks a rebrand instead of sitting on a fixed near-black that
   would clash with a warm or light primary. The literal above stands in where color-mix is unsupported. */
@supports (color: color-mix(in srgb, red 50%, blue)){
  :root{ --deep:color-mix(in srgb, var(--navy) 76%, #000); }
}
/* Interpolate the headline gradient in OKLAB where supported.
   sRGB interpolation dips through grey between two colours of different hue — with four unrelated brand
   colours that reads as a muddy rainbow rather than an ombre. OKLAB keeps chroma up across the blend, so
   the ramp stays clean whatever four colours the firm picks. The sRGB version above is the fallback. */
@supports (background: linear-gradient(in oklab, red, blue)){
  :root{ --grad:linear-gradient(100deg in oklab, var(--em), var(--steel) 48%, var(--violet)); }
}
*{box-sizing:border-box}
/* `hidden` must win over any display a class sets. site.js uses the hidden ATTRIBUTE to keep the logo
   <img> out of the page until the branding fetch returns one, and `.brandlogo{display:block}` was
   quietly overriding it — so every page rendered a broken-image icon in the header and footer. */
[hidden]{display:none!important}
html{scroll-behavior:smooth;overflow-x:hidden;scroll-padding-top:82px}
/* overflow-x stays on <html> only — putting it on <body> makes body a scroll container and silently
   kills every position:sticky inside it, including the header. */
body{margin:0;background:var(--paper);color:var(--ink);font-family:var(--f);
  font-size:16px;line-height:1.55;-webkit-font-smoothing:antialiased}
button{font:inherit;color:inherit;background:none;border:0;cursor:pointer}
a{color:inherit}
img{max-width:100%}
.wrap{max-width:1320px;margin:0 auto;padding:0 var(--pad);width:100%;position:relative}
@media(max-width:820px){:root{--pad:20px}}
.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}

/* ── type ───────────────────────────────────────────────────────────── */
.lbl{font-size:11.5px;letter-spacing:.24em;text-transform:uppercase;color:var(--mute);
  font-weight:500;margin:0}
/* inline-block, not a flex child: as a flex item this depended on .lbl keeping display:flex, and
   anything that reset that display dropped the square onto its own line above the text. */
.lbl i{width:8px;height:8px;background:var(--em);display:inline-block;vertical-align:middle;
  margin-right:10px;flex:none;position:relative;top:-1px}
.lbl.ghost i{background:none;border:1px solid var(--em)}
h1,h2,h3{margin:0;font-weight:700;text-transform:uppercase;letter-spacing:-.02em;line-height:.98}
h1{font-size:clamp(40px,7.2vw,86px)}
h2{font-size:clamp(28px,4.4vw,54px)}
h3{font-size:clamp(19px,2vw,25px);letter-spacing:-.01em}
.lede{color:var(--mute);font-size:17px;max-width:60ch;margin:16px 0 0;line-height:1.6}
.grad{background:var(--grad);-webkit-background-clip:text;background-clip:text;color:transparent}
.count{position:absolute;top:0;right:var(--pad);font-size:11.5px;letter-spacing:.2em;
  color:var(--faint);font-weight:500}
.count b{color:var(--em);font-weight:500}
.mono{font-variant-numeric:tabular-nums}

/* ── nav ────────────────────────────────────────────────────────────── */
header.nav{position:sticky;top:0;z-index:60;background:rgba(244,244,241,.88);
  backdrop-filter:blur(14px) saturate(1.2);border-bottom:1px solid var(--line);
  display:block;padding:0}
header.nav .navin{display:flex;align-items:center;justify-content:space-between;height:66px;gap:20px;
  max-width:1320px;margin:0 auto;padding:0 var(--pad)}
.brand{display:flex;align-items:baseline;gap:9px;font-weight:800;font-size:19px;
  letter-spacing:-.02em;text-decoration:none}
.brandwm b{color:var(--em);font-weight:800}
.brand em{font-style:normal;font-size:9.5px;letter-spacing:.2em;color:var(--faint);font-weight:500}
.brandlogo{height:26px;width:auto;display:block}
.lk{display:flex;gap:22px;align-items:center}
.lk a{font-size:11.5px;letter-spacing:.16em;text-transform:uppercase;text-decoration:none;
  color:var(--ink);opacity:.82;transition:opacity .2s,color .2s}
.lk a:hover,.lk a.on{opacity:1;color:var(--em)}
.btn{font-size:11.5px;letter-spacing:.16em;text-transform:uppercase;padding:10px 17px;
  border:1px solid var(--ink);text-decoration:none;display:inline-block;transition:.2s;
  white-space:nowrap;background:none;color:var(--ink)}
.btn:hover{background:var(--ink);color:var(--paper)}
.btn.p,.lk a.b.login{background:var(--navy);border-color:var(--navy);color:#fff}
.btn.p:hover,.lk a.b.login:hover{background:var(--deep);border-color:var(--deep);color:#fff}
.lk a.b{border:1px solid var(--ink);padding:9px 15px;opacity:1}
.lk a.b:hover{background:var(--ink);color:var(--paper)}
.menu-btn{display:none;font-size:20px;line-height:1;padding:8px 10px;border:1px solid var(--line)}
@media(max-width:1120px){
  .lk{position:fixed;inset:66px 0 auto 0;background:var(--paper);border-bottom:1px solid var(--line);
    flex-direction:column;align-items:stretch;gap:0;padding:8px var(--pad) 18px;display:none}
  .lk.open{display:flex}
  .lk a{padding:13px 0;border-bottom:1px solid var(--line2);font-size:12.5px}
  .lk a.b{border:1px solid var(--ink);text-align:center;margin-top:12px;padding:12px}
  .menu-btn{display:block}
}

/* ── section shell ──────────────────────────────────────────────────── */
section{position:relative;padding:104px 0;border-top:1px solid var(--line)}
section:first-of-type{border-top:0}
.head{position:relative;margin-bottom:38px}
.head .lbl{margin-bottom:18px}
.two{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:46px;align-items:start}
/* grid items default to min-width:auto, which lets wide content push the page sideways instead of
   scrolling inside its own box */
.two>*,.grid3>*,.grid2>*,.stat>*,.stackg>*{min-width:0}
@media(max-width:980px){
  .two{grid-template-columns:1fr;gap:28px}
}
@media(max-width:820px){section{padding:72px 0}}

/* ── map / panel frame ──────────────────────────────────────────────── */
.map{position:relative;max-width:100%;border:1px solid var(--line);background:var(--panel);
  overflow:hidden}
.map::after{content:"";position:absolute;inset:0;pointer-events:none;
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.7)}
.mapbar{display:flex;align-items:center;justify-content:space-between;gap:14px;
  padding:11px 16px;border-bottom:1px solid var(--line);background:rgba(244,244,241,.7);
  font-size:10.5px;letter-spacing:.2em;text-transform:uppercase;color:var(--mute);flex-wrap:wrap}
.mapbar b{color:var(--ink);font-weight:600}
.corner{position:absolute;width:9px;height:9px;border:1px solid var(--em);opacity:.5;z-index:3}
.corner.tl{top:-1px;left:-1px;border-right:0;border-bottom:0}
.corner.tr{top:-1px;right:-1px;border-left:0;border-bottom:0}
.corner.bl{bottom:-1px;left:-1px;border-right:0;border-top:0}
.corner.br{bottom:-1px;right:-1px;border-left:0;border-top:0}
canvas{display:block}

/* ── legend / chips ─────────────────────────────────────────────────── */
.legend{display:flex;flex-wrap:wrap;gap:8px 18px;margin-top:18px}
.key{display:flex;align-items:center;gap:8px;font-size:11px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--mute)}
.key i{width:9px;height:9px;display:block;flex:none}

/* ── hero ───────────────────────────────────────────────────────────── */
.hero{padding:0;border-top:0;min-height:min(92vh,860px);display:flex;align-items:center;
  overflow:hidden;position:relative}
#stars{position:absolute;inset:0;width:100%;height:100%;z-index:0}
.heroin{position:relative;z-index:2;padding:96px var(--pad) 84px;max-width:1320px;margin:0 auto;
  width:100%}
.heroin h1{max-width:15ch;margin-top:20px}
.heroin .lede{margin-top:22px}
.cta{display:flex;gap:12px;margin-top:30px;flex-wrap:wrap}
.scrollcue{display:flex;align-items:center;gap:12px;margin-top:52px;font-size:10.5px;
  letter-spacing:.24em;text-transform:uppercase;color:var(--faint)}
.scrollcue span.track{display:block;width:54px;height:1px;background:var(--line);
  position:relative;overflow:hidden}
.scrollcue span.track::after{content:"";position:absolute;inset:0;width:18px;background:var(--em);
  animation:sweep 2.4s linear infinite}
@keyframes sweep{from{transform:translateX(-20px)}to{transform:translateX(56px)}}
@media(prefers-reduced-motion:reduce){.scrollcue span.track::after{animation:none}}

/* the six live figures that float over the hero field */
.fdps{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:1px;margin-top:44px;
  border:1px solid var(--line);background:var(--line);max-width:760px}
.fdp{background:rgba(250,250,248,.9);padding:14px 16px}
.fdp .l{display:flex;align-items:center;gap:8px;font-size:10px;letter-spacing:.18em;
  text-transform:uppercase;color:var(--mute)}
.fdp .l i{width:7px;height:7px;display:block;flex:none}
.fdp .v{font-size:23px;font-weight:700;letter-spacing:-.02em;margin-top:7px;
  font-variant-numeric:tabular-nums}
@media(max-width:700px){.fdps{grid-template-columns:repeat(2,minmax(0,1fr))}}

/* ── minimap rail ───────────────────────────────────────────────────── */
.rail{position:fixed;left:16px;top:50%;transform:translateY(-50%);z-index:50;
  display:flex;flex-direction:column;gap:2px;padding:10px 8px;
  background:rgba(250,250,248,.82);border:1px solid var(--line);backdrop-filter:blur(10px)}
.rail a{display:flex;align-items:center;gap:9px;text-decoration:none;padding:5px 6px;
  font-size:9.5px;letter-spacing:.16em;text-transform:uppercase;color:var(--faint);transition:.2s}
.rail a u{text-decoration:none;width:18px;height:2px;background:var(--line);display:block;
  transition:.25s}
.rail a em{font-style:normal;max-width:0;overflow:hidden;white-space:nowrap;transition:max-width .3s}
.rail:hover a em{max-width:130px}
.rail a:hover,.rail a.on{color:var(--ink)}
.rail a.on u{background:var(--em);width:26px}
@media(max-width:1500px){.rail{display:none}}

/* ── numbered rows (the platform list) ──────────────────────────────── */
.rows{border-top:1px solid var(--line)}
.row{display:grid;grid-template-columns:78px minmax(0,1fr) 40px;gap:24px;align-items:start;
  padding:26px 0;border-bottom:1px solid var(--line);text-decoration:none;
  transition:background .22s,padding .22s}
.row:hover{background:rgba(24,32,43,.022);padding-left:12px;padding-right:12px}
.row .no{font-size:11.5px;letter-spacing:.2em;color:var(--faint);padding-top:4px}
.row .rt{font-size:clamp(17px,1.7vw,22px);font-weight:700;text-transform:uppercase;
  letter-spacing:-.01em;line-height:1.1}
.row .rd{color:var(--mute);font-size:14.5px;line-height:1.62;margin-top:9px;max-width:70ch}
.row .ar{font-size:18px;color:var(--faint);text-align:right;padding-top:2px;transition:.22s}
.row:hover .ar{color:var(--em);transform:translateX(4px)}
@media(max-width:700px){
  .row{grid-template-columns:52px minmax(0,1fr);gap:16px}
  .row .ar{display:none}
}

/* ── layer columns (the stack) ──────────────────────────────────────── */
.stackg{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));border:1px solid var(--line);
  border-right:0;border-bottom:0}
.stackg .col{border-right:1px solid var(--line);border-bottom:1px solid var(--line);padding:0}
.stackg .ch{display:flex;align-items:center;gap:9px;padding:15px 20px;
  border-bottom:1px solid var(--line);font-size:11px;letter-spacing:.2em;text-transform:uppercase;
  color:var(--ink);font-weight:600}
.stackg .ch i{width:8px;height:8px;display:block;flex:none;background:var(--em)}
.stackg .cn{display:flex;justify-content:space-between;padding:9px 20px;
  border-bottom:1px solid var(--line2);font-size:10px;letter-spacing:.2em;color:var(--faint);
  text-transform:uppercase}
.stackg .it{display:flex;justify-content:space-between;align-items:baseline;gap:14px;
  padding:13px 20px;border-bottom:1px solid var(--line2);font-size:14px}
.stackg .it:last-child{border-bottom:0}
.stackg .it b{font-weight:600}
.stackg .it span{font-size:10.5px;letter-spacing:.16em;text-transform:uppercase;color:var(--faint)}
@media(max-width:820px){.stackg{grid-template-columns:1fr}}

/* ── stats ──────────────────────────────────────────────────────────── */
.stats{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));border:1px solid var(--line);
  border-right:0;border-bottom:0}
.stat{border-right:1px solid var(--line);border-bottom:1px solid var(--line);padding:24px 22px}
.stat .n{font-size:clamp(30px,3.4vw,44px);font-weight:700;letter-spacing:-.03em;line-height:1;
  font-variant-numeric:tabular-nums}
.stat .l{font-size:10.5px;letter-spacing:.2em;text-transform:uppercase;color:var(--mute);
  margin-top:13px}
.stat .d{font-size:13px;color:var(--faint);margin-top:9px;line-height:1.55}
@media(max-width:1000px){.stats{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media(max-width:560px){.stats{grid-template-columns:1fr}}

/* ── readout panels (about) ─────────────────────────────────────────── */
/* .grid3 is THREE columns — the name is the contract, and the blueprint's own figures (the residency
   panel on the pricing page, for one) put three cells in it and expect three across. It was briefly set
   to two here to suit the home page's four-panel About block, which left the residency panel's third
   cell stranded on a row of its own. Blocks that want two columns use .grid2. */
.grid3,.grid2{display:grid;border:1px solid var(--line);border-right:0;border-bottom:0}
.grid3{grid-template-columns:repeat(3,minmax(0,1fr))}
.grid2{grid-template-columns:repeat(2,minmax(0,1fr))}
.grid3>div,.grid2>div{border-right:1px solid var(--line);border-bottom:1px solid var(--line);padding:26px 24px}
@media(max-width:980px){.grid3{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media(max-width:820px){.grid3,.grid2{grid-template-columns:1fr}}
.cell-lbl{display:flex;align-items:center;gap:9px;font-size:10.5px;letter-spacing:.2em;
  text-transform:uppercase;color:var(--mute);margin-bottom:14px}
.cell-lbl i{width:9px;height:9px;display:block;flex:none;background:var(--em)}
.cell p{margin:0 0 12px;font-size:14.5px;color:var(--mute);line-height:1.62}
.cell p:last-child{margin-bottom:0}
.cell p.pt{color:var(--ink);font-weight:600}

/* ── the pulse wave ─────────────────────────────────────────────────── */
.hbwave{width:100%;height:190px;display:block}

/* ── contact ────────────────────────────────────────────────────────── */
.demo-start form{display:flex;gap:12px;flex-wrap:wrap;margin-top:26px;align-items:stretch}
.demo-start input[type=email]{flex:1 1 300px;max-width:420px;padding:13px 16px;font:inherit;
  font-size:15px;border:1px solid var(--ink);background:var(--panel);color:var(--ink)}
.demo-start input[type=email]::placeholder{color:var(--faint)}
.demo-start input[type=email]:focus{outline:2px solid var(--em);outline-offset:2px}
.demo-start button{cursor:pointer}
.hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}
.form-msg{margin-top:14px;font-size:13px;color:var(--mute);min-height:20px}
.form-msg.err{color:#B4232A}
.form-msg.ok{color:var(--em)}

/* Policy links. site.js fills #footLegal from /api/public/policies — whatever is written and published
   in super-admin → Website → Policies appears here on its own, so Privacy needs no markup of its own.
   It renders as <a>…</a><span class="sep">·</span><a>…</a>, and the separator had no rule, so multiple
   policies ran together as one word. */
#footLegal{display:inline-flex;flex-wrap:wrap;gap:0 8px;justify-content:inherit}
#footLegal a{color:var(--mute);text-decoration:none;border-bottom:1px solid transparent;transition:.18s}
#footLegal a:hover{color:var(--em);border-bottom-color:var(--em)}
#footLegal .sep{color:var(--line);margin:0 2px}
#footLegal:empty{display:none}

/* ── reveal on scroll ───────────────────────────────────────────────── */
.reveal{opacity:0;transform:translateY(14px);transition:opacity .6s ease,transform .6s ease}
.reveal.in{opacity:1;transform:none}
@media(prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  .reveal{opacity:1;transform:none;transition:none}
}

:focus-visible{outline:2px solid var(--em);outline-offset:3px}

/* ── print ──────────────────────────────────────────────────────────── */
@media print{
  header.nav,.rail,.scrollcue,#stars,.hbwave{display:none!important}
  section{padding:24px 0;break-inside:avoid}
  body{background:#fff}
}

/* ── book-a-demo modal ──────────────────────────────────────────────────────────────────────────────
   site.js injects this markup at runtime (BOOK_MODAL_HTML) — it is not in landing.html, so it is easy
   to miss when swapping stylesheets. The old design's rules for it lived in landing-esqrd.css; unlinking
   that file without bringing these across leaves the booking flow completely unstyled, which is the one
   part of this page that directly costs a sale. Restyled to the blueprint rather than copied over.
   ================================================================================================== */
.book-modal{position:fixed;inset:0;z-index:200;display:none;align-items:center;justify-content:center;
  padding:24px}
.book-modal.open{display:flex}
.book-backdrop{position:absolute;inset:0;background:rgba(10,22,38,.42);backdrop-filter:blur(3px)}
.book-card{position:relative;z-index:1;display:grid;grid-template-columns:288px minmax(0,1fr);
  width:min(940px,100%);max-height:min(88vh,760px);overflow:auto;background:var(--paper);
  border:1px solid var(--ink);box-shadow:0 30px 80px rgba(10,22,38,.28)}
@media(max-width:760px){.book-card{grid-template-columns:1fr}}
.book-x{position:absolute;top:8px;right:10px;z-index:2;font-size:22px;line-height:1;padding:6px 10px;
  color:var(--mute)}
.book-x:hover{color:var(--ink)}
.book-info{padding:28px 26px;border-right:1px solid var(--line);background:var(--panel)}
@media(max-width:760px){.book-info{border-right:0;border-bottom:1px solid var(--line)}}
.book-logo{max-height:28px;width:auto;margin-bottom:16px}
.book-host{font-size:10.5px;letter-spacing:.24em;text-transform:uppercase;color:var(--mute)}
.book-title{margin:10px 0 16px;font-size:20px;text-transform:uppercase;letter-spacing:-.01em;
  line-height:1.05}
.book-meta{display:flex;align-items:center;gap:9px;font-size:12.5px;color:var(--mute);margin-bottom:8px}
.book-ic{color:var(--em)}
.book-blurb{margin:18px 0 0;font-size:13px;line-height:1.6;color:var(--mute);
  border-top:1px solid var(--line2);padding-top:16px}
.book-main{padding:28px 26px;min-width:0}
.book-step-h{font-size:11px;letter-spacing:.2em;text-transform:uppercase;color:var(--mute);
  margin-bottom:18px}
.book-cols{display:grid;grid-template-columns:minmax(0,1fr) 190px;gap:26px;align-items:start}
@media(max-width:620px){.book-cols{grid-template-columns:1fr}}
.book-cal-head{display:flex;align-items:center;justify-content:space-between;gap:12px;
  font-size:12px;letter-spacing:.16em;text-transform:uppercase;font-weight:600;margin-bottom:12px}
.cal-nav{padding:4px 10px;border:1px solid var(--line);font-size:14px;line-height:1;color:var(--mute)}
.cal-nav:hover{border-color:var(--ink);color:var(--ink)}
.book-cal-dow,.book-cal-grid{display:grid;grid-template-columns:repeat(7,minmax(0,1fr));gap:3px}
.book-cal-dow{font-size:9.5px;letter-spacing:.14em;text-transform:uppercase;color:var(--faint);
  margin-bottom:6px;text-align:center}
.cal-cell{aspect-ratio:1;display:flex;align-items:center;justify-content:center;font-size:13px;
  border:1px solid transparent;color:var(--faint);font-variant-numeric:tabular-nums}
.cal-cell.avail{border-color:var(--line);color:var(--ink);cursor:pointer}
.cal-cell.avail:hover{border-color:var(--em);color:var(--em)}
.cal-cell.sel{background:var(--ink);border-color:var(--ink);color:var(--paper)}
.book-times-label{font-size:10.5px;letter-spacing:.2em;text-transform:uppercase;color:var(--mute);
  margin-bottom:10px}
.book-times-list{display:flex;flex-direction:column;gap:6px;max-height:280px;overflow:auto}
.book-times-list button{padding:10px;border:1px solid var(--line);font-size:13px;
  font-variant-numeric:tabular-nums;transition:.18s}
.book-times-list button:hover{border-color:var(--em);color:var(--em)}
.book-times-list button.sel{background:var(--ink);border-color:var(--ink);color:var(--paper)}
.book-back{font-size:10.5px;letter-spacing:.2em;text-transform:uppercase;color:var(--mute);
  margin-bottom:14px;padding:0}
.book-back:hover{color:var(--em)}
.book-chosen{border:1px solid var(--line);background:var(--panel);padding:12px 14px;font-size:13.5px;
  color:var(--mute);margin-bottom:20px}
.book-chosen strong{color:var(--ink)}
.book-field{display:block;margin-bottom:16px}
.book-field>span{display:block;font-size:10.5px;letter-spacing:.2em;text-transform:uppercase;
  color:var(--mute);margin-bottom:7px}
.book-field>span em{font-style:normal;color:var(--faint);letter-spacing:.1em}
.book-field input,.book-field textarea{width:100%;padding:11px 13px;font:inherit;font-size:14.5px;
  border:1px solid var(--line);background:var(--panel);color:var(--ink);resize:vertical}
.book-field input:focus,.book-field textarea:focus{outline:2px solid var(--em);outline-offset:1px;
  border-color:var(--ink)}
/* site.js writes btn-primary / btn-lg, which this sheet doesn't otherwise define */
.btn-primary{background:var(--navy);border:1px solid var(--navy);color:#fff;
  font-size:11.5px;letter-spacing:.16em;text-transform:uppercase;padding:12px 20px;
  display:inline-block;text-decoration:none;transition:.2s}
.btn-primary:hover{background:var(--deep);border-color:var(--deep);color:#fff}
.btn-lg{padding:14px 24px;width:100%}
.book-done{text-align:center;padding:36px 8px}
.book-check{width:46px;height:46px;margin:0 auto 18px;border:1px solid var(--em);color:var(--em);
  display:flex;align-items:center;justify-content:center;font-size:22px}
.book-done h3{margin-bottom:10px}
.book-done p{color:var(--mute);font-size:14px;margin:0 0 22px}

/* ── the footer ─────────────────────────────────────────────────────────────────────────────────────
   <footer> is the flex row itself — wordmark left, the .s column right. It briefly had a .footin
   wrapper, which nested a flex inside a flex and collapsed the whole thing into one left column.
   There is no wrapper; do not add one.
   ─────────────────────────────────────────────────────────────────────────────────────────────── */
footer{border-top:1px solid var(--line);padding:40px clamp(20px,5vw,60px);
  display:flex;justify-content:space-between;align-items:center;gap:20px;flex-wrap:wrap;
  background:var(--paper);color:var(--faint);font-size:12.5px;position:relative;z-index:2}
footer .brandwm{font-size:16px;font-weight:800;letter-spacing:-.02em;color:var(--ink);opacity:.85}
footer .brandwm b{color:var(--em)}
footer img.brandlogo{height:24px;opacity:.85}
/* .s is a WRAPPING HORIZONTAL ROW of mono caps, not a right-aligned column. This was the difference
   between the footer as it shipped and the one that replaced it: `flex-direction:column` +
   `text-align:right` + `align-items:flex-start` above turned one clean strip into a stack. */
footer .s{display:flex;gap:20px;flex-wrap:wrap;font-family:var(--mono,'Inter',system-ui,sans-serif);
  letter-spacing:.16em;text-transform:uppercase;font-size:11px;color:var(--mute)}
footer .s a{color:var(--mute);text-decoration:none}
footer .s a:hover{color:var(--em)}
@media(max-width:700px){footer{gap:18px;align-items:flex-start}footer .s{gap:10px 18px}}

/* Gradient-word safety: without background-clip:text, .grad would render as invisible text
   inside a gradient box. Mirrors the .gold guard in landing-esqrd.css. */
@supports not ((-webkit-background-clip:text) or (background-clip:text)){
  .grad{background:none !important;-webkit-text-fill-color:var(--em) !important;color:var(--em)}
}
