/* ============================================================================
   kaymen.dev — "Quiet"

   Ported from mockup/v3-quiet.html (2026-08-15). Palette lifted verbatim from
   Kaymen Group LLC/styles.css; glass recipe from Kartov/mockups/tabbar-glass.html.
   One accent, lots of air, contained measure.

   LOCKED decisions live in HANDOFF-REDESIGN-2026-08-15.md §1 — palette, the
   always-labelled 224px glass rail, the wide measure, the page structure.
   Do not re-open them here.

   Layout:
     1. Tokens (+ a legacy bridge for assets/demos.css)
     2. Base, ambience, the rail, the mobile tabbar
     3. Homepage sections — hero/fleet, routing, board, shots, band, cases,
        plans, terms, talk
     4. Sub-pages — /work index, /work/<slug> case studies, long tail, 404
   ============================================================================ */

:root{
  /* --- Kaymen Group palette, unchanged --- */
  --bg:#ffffff;
  --bg-alt:#f4f5f7;
  --ink:#1a1b1e;
  --muted:#5f6368;
  --accent:#2bbcb3;
  --accent-dark:#229e96;
  --accent-soft:rgba(43,188,179,.08);
  --accent-glow:rgba(43,188,179,.18);
  --line:#e2e4e8;
  /* the deep tone from the Kaymen Group card gradients — used once */
  --deep:#16303d;
  --deep-2:#1c2333;

  --display:'Sora',-apple-system,BlinkMacSystemFont,sans-serif;
  --body:'Inter',-apple-system,BlinkMacSystemFont,sans-serif;

  /* contained measure — the site does NOT run to the screen edge.
     LOCKED 2026-08-15: the "wide" setting. */
  --w-prose:760px;   /* headings + paragraphs */
  --w-page:1120px;   /* grids, boards, cards */

  /* LOCKED 2026-08-15: the rail is always labelled, so --rail-w is the
     only width it ever has. Hover-to-collapse was dropped deliberately. */
  --rail-w:224px;
  --rail-gap:40px;   /* clearance between the rail and the content column */
  --rail-off:clamp(26px,3.4vw,68px);   /* minimum clearance from the screen edge */
  --page-pr:clamp(36px,4vw,80px);
  --wrap-pad:22px;
  --page-pl:calc(var(--rail-off) + var(--rail-w) + var(--rail-gap));

  /* --- where the text actually starts, and therefore where the rail belongs ---
     The rail used to be pinned at --rail-off while .wrap auto-centres inside the
     padded column, so the gap grew on the content side only: near-centred at
     1440px, ~97px too far left at 1920px. Deriving the rail's left from the same
     expression as the text edge is the whole fix.

     100vw includes the scrollbar, so this formula lands a few px off on Windows;
     script.js measures the real text edge and overwrites --text-left on load and
     on resize. This is the no-JS fallback, and it is close enough to look right. */
  --text-left:calc(
    var(--page-pl)
    + max(0px, (100vw - var(--page-pl) - var(--page-pr) - var(--w-page)) / 2)
    + var(--wrap-pad)
  );

  /* The rail sits level with the top of the page title rather than floating in
     the middle of the viewport. Vertical centring meant its position depended on
     the window height, so it landed somewhere different on every screen and
     lined up with nothing. This is the fallback; script.js measures the real
     title and overwrites it, so it stays correct if the hero padding changes. */
  --rail-top:171px;

  --ease:cubic-bezier(.4,0,.2,1);
  --spring:cubic-bezier(.34,1.4,.64,1);

  /* --- legacy token bridge ------------------------------------------------
     assets/demos.css is loaded only on case studies that carry a playable
     demo, and it is written against the previous dark theme's variable names.
     Rather than rewrite a file this port does not otherwise touch, map the old
     names onto the new palette. Delete this block if demos.css is ever
     rewritten against the tokens above. */
  --text:var(--ink);
  --text-secondary:#42464c;
  --text-muted:var(--muted);
  --bg-card:#ffffff;
  --bg-card-hover:var(--bg-alt);
  --bg-elevated:var(--bg-alt);
  --border:var(--line);
  --border-light:#eceef1;
  --mono:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
  --radius:16px;
  --radius-sm:11px;
  --radius-xs:6px;
  --transition:all .3s cubic-bezier(.4,0,.2,1);
}

*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
html{scroll-behavior:smooth;scroll-padding-top:40px;overflow-x:clip}
body{
  font-family:var(--body);
  background:var(--bg);
  color:var(--ink);
  line-height:1.65;
  -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
}
a{color:inherit;text-decoration:none}
button{font:inherit;cursor:pointer;border:0;background:none;color:inherit}
ul{list-style:none}
h1,h2,h3,h4{font-family:var(--display);letter-spacing:-.03em;line-height:1.1;font-weight:700}

/* ---------------------------------------------------------------- ambience
   Glass needs something to refract. Three very soft washes, fixed, so the
   rail always has colour passing behind it as you scroll.                  */
.ambient{position:fixed;inset:0;pointer-events:none;z-index:0;overflow:hidden}
.ambient i{position:absolute;border-radius:50%;filter:blur(90px);display:block}
.ambient .g1{width:640px;height:640px;top:-330px;left:-220px;background:rgba(43,188,179,.055)}
.ambient .g2{width:520px;height:520px;top:40%;right:-280px;background:rgba(43,188,179,.04)}
.ambient .g3{width:480px;height:480px;bottom:-280px;left:20%;background:rgba(28,35,51,.03)}

/* ================================================================ THE RAIL
   Floating, glass, always labelled, and level with the top of the page title.
   Never pushes the page: it floats over it.                               */
.rail{
  position:fixed;
  top:var(--rail-top);
  /* a short window must scroll the rail rather than let it run off the bottom */
  max-height:calc(100vh - var(--rail-top) - 24px);
  overflow-y:auto;
  z-index:80;
  width:var(--rail-w);
  padding:10px 9px;
  border-radius:26px;
  display:flex;flex-direction:column;gap:2px;
  transition:box-shadow .38s var(--ease);
  /* overflow-x only: a plain overflow:hidden here would override the
     overflow-y:auto above and clip the rail on a short window instead of
     letting it scroll */
  overflow-x:hidden;

  /* --- the glass itself --- */
  background:rgba(255,255,255,.55);
  backdrop-filter:blur(30px) saturate(190%);
  -webkit-backdrop-filter:blur(30px) saturate(190%);
  box-shadow:
    0 24px 54px -18px rgba(22,48,61,.22),
    0 8px 20px -8px rgba(22,48,61,.10),
    0 0 0 .5px rgba(255,255,255,.70),
    0 0 0 1px rgba(226,228,232,.75),
    inset 0 1px 0 rgba(255,255,255,.90),
    inset 0 -1px 0 rgba(22,48,61,.04);
}
/* held well off the screen edge — it should read as floating, not docked */
/* midway between the screen edge and the text edge — but never nearer the edge
   than --rail-off, which is what holds the layout together below ~1300px where
   .wrap fills the column and there is no slack to centre in */
.rail.left{left:max(var(--rail-off),calc((var(--text-left) - var(--rail-w)) / 2))}
.rail.right{right:max(var(--rail-off),calc((var(--text-left) - var(--rail-w)) / 2))}
/* specular catch across the top — the light-catching bit */
.rail::before{
  content:"";position:absolute;inset:0;border-radius:26px;pointer-events:none;
  background:linear-gradient(180deg,rgba(255,255,255,.65) 0%,rgba(255,255,255,.14) 22%,rgba(255,255,255,0) 48%);
  mix-blend-mode:screen;
}
.rail:hover,.rail:focus-within{
  box-shadow:
    0 34px 70px -20px rgba(22,48,61,.28),
    0 10px 24px -8px rgba(22,48,61,.12),
    0 0 0 .5px rgba(255,255,255,.75),
    0 0 0 1px rgba(226,228,232,.8),
    inset 0 1px 0 rgba(255,255,255,.92);
}

/* brand mark */
/* The lockup: arch with the name under it. The rail's inner width is 206px, so
   this lands at ~169px wide — comfortably inside the display cut's 140px-and-up
   band, which is the nine-segment drawing. Do not shrink it past 140px here;
   below that the gaps fall under a physical pixel and the arch fuses into a
   solid band, which is what the text cut exists to solve. */
/* `lockup-live.svg`, not the one in assets/brand: same geometry, plus the light
   that runs down the course from the keystone out. The keyframes are inside the
   file because page CSS cannot reach into an SVG loaded as an image — which
   also means the global prefers-reduced-motion rule at the foot of this file
   cannot silence it. The file carries its own media query for that, and the
   background-image swaps back to the static lockup as well, since a preference
   query inside an SVG-as-image is not something to bet the behaviour on. */
.rail-brand{
  display:block;flex:none;position:relative;z-index:2;
  height:88px;margin:0 4px 8px;
  background:url("/assets/lockup-live.svg") no-repeat center/contain;
}
/* .mark (the 30px tile) and .rail-wordmark (the text beside it) were the brand
   before the lockup replaced it on 2026-08-16. Nothing on the marketing site
   draws either any more. admin/ and portal/ keep their own copies of .mark in
   their own stylesheets; this is only the marketing site's. */

/* nav */
.rail-nav{position:relative;display:flex;flex-direction:column;gap:2px;z-index:2}
/* the sliding lozenge — this is the thing that "moves along the scroll" */
.lozenge{
  position:absolute;left:0;right:0;height:42px;border-radius:14px;
  background:var(--accent-soft);
  box-shadow:inset 0 0 0 1px rgba(43,188,179,.22),inset 0 1px 0 rgba(255,255,255,.7);
  transition:transform .5s var(--spring),opacity .3s var(--ease);
  pointer-events:none;z-index:-1;
}
.rail-link{
  display:flex;align-items:center;gap:14px;height:42px;padding:0 9px;
  border-radius:14px;color:var(--muted);position:relative;flex:none;
  transition:color .2s var(--ease);
}
.rail-link svg{width:19px;height:19px;flex:none;stroke-width:1.6;transition:transform .3s var(--spring)}
.rail-link span{
  font-size:13.5px;font-weight:500;white-space:nowrap;letter-spacing:-.005em;
}
.rail-link:hover{color:var(--ink)}
.rail-link.on{color:var(--accent-dark);font-weight:600}
.rail-link.on svg{transform:scale(1.06)}
.rail-link.on span{font-weight:600}

/* Client login. Deliberately OUTSIDE .rail-nav, and it has to stay outside for
   two reasons. The lozenge is positioned against .rail-nav's children, so a
   seventh child would give it a link to park on that never becomes current; and
   the rail's grammar is "where am I on this page", which a login is not — it is
   the one item that leaves the page. Bordered rather than plain so it does not
   read as a section that simply never lights up.
   There is no top bar to put it in: this design replaced the header with the
   rail, and inventing a fixed top-right control for one link would fight that
   and crowd a mobile hero the handoff already calls cramped. Under 900px the
   rail is hidden, so the footer carries it instead. */
.rail-login{
  display:flex;align-items:center;gap:12px;margin-top:10px;padding:0 9px;height:38px;
  border:1px solid var(--line);border-radius:12px;color:var(--muted);flex:none;
  transition:color .2s var(--ease),border-color .2s var(--ease),background .2s var(--ease);
}
.rail-login svg{width:17px;height:17px;flex:none;stroke-width:1.7}
.rail-login span{font-size:12.5px;font-weight:600;white-space:nowrap;letter-spacing:-.005em}
.rail-login:hover{color:var(--accent-dark);border-color:rgba(43,188,179,.5);background:var(--accent-soft)}

/* live footer — the status ribbon idea, demoted to a quiet corner */
.rail-foot{
  margin-top:8px;padding-top:10px;border-top:1px solid rgba(226,228,232,.9);
  display:flex;align-items:center;gap:13px;padding-left:9px;padding-right:9px;
  height:38px;flex:none;position:relative;z-index:2;
}
.pulse{width:8px;height:8px;border-radius:50%;background:var(--accent);flex:none;position:relative}
.pulse::after{
  content:"";position:absolute;inset:-4px;border-radius:50%;
  border:1.5px solid var(--accent);opacity:0;animation:ping 2.6s var(--ease) infinite;
}
@keyframes ping{0%{transform:scale(.6);opacity:.7}70%{transform:scale(1.5);opacity:0}100%{opacity:0}}
.rail-foot em{
  font-style:normal;font-size:11.5px;font-weight:600;color:var(--muted);
  white-space:nowrap;letter-spacing:.01em;
}

/* scroll progress — a hairline down the outer edge of the rail */
.rail-prog{
  position:absolute;top:14px;bottom:14px;width:2px;border-radius:2px;
  background:rgba(226,228,232,.8);overflow:hidden;z-index:3;
}
.rail.left .rail-prog{right:3px}
.rail.right .rail-prog{left:3px}
.rail-prog i{
  position:absolute;top:0;left:0;right:0;height:0;display:block;border-radius:2px;
  background:linear-gradient(180deg,var(--accent) 0%,var(--accent-dark) 100%);
}

/* ============================================================ PAGE CONTENT */
.page{position:relative;z-index:1}
/* The rail is always 224px, so the content column must clear
   rail-offset + rail-width + gap or it slides underneath at ~1440px. */
@media (min-width:900px){
  .page{
    padding-left:var(--page-pl);
    padding-right:var(--page-pr);
  }
  body.rail-right .page{
    padding-left:var(--page-pr);
    padding-right:var(--page-pl);
  }
}
.wrap{max-width:var(--w-page);margin:0 auto;padding:0 22px}
.prose{max-width:var(--w-prose)}

section{padding:74px 0}
@media (max-width:900px){section{padding:56px 0}}

.eyebrow{
  font-size:11px;font-weight:700;letter-spacing:.17em;text-transform:uppercase;
  color:var(--accent-dark);margin-bottom:14px;
}
h2.sec{font-size:clamp(1.7rem,3.4vw,2.35rem);font-weight:700}
.sec-sub{color:var(--muted);font-size:15.5px;margin-top:14px;max-width:56ch;line-height:1.7}
/* -44px so the rule lines up with .wrap's inner edge rather than overhanging it */
.rule{height:1px;background:var(--line);border:0;max-width:calc(var(--w-page) - 44px);margin:0 auto}

/* reveal */
.rv{opacity:0;transform:translateY(14px);transition:opacity .7s var(--ease),transform .7s var(--ease)}
.rv.in{opacity:1;transform:none}

/* ------------------------------------------------------------------- hero */
/* NO overflow:hidden here. .hero-fx cancels the page padding with negative
   left/right to reach the screen edges, and overflow:hidden on the parent
   clips exactly that back off — the canvas element still measures 0..1920, so
   it reports full bleed while painting nothing outside the hero box. That is
   why three earlier attempts at this measured clean and still looked wrong.
   body already carries overflow-x:hidden, so nothing escapes sideways. */
.hero{padding-top:104px;padding-bottom:82px;position:relative}
@media (max-width:900px){.hero{padding-top:118px;padding-bottom:60px}}
/* two columns: the argument on the left, what it costs to rent it on the right */
.hero-grid{display:grid;gap:44px;align-items:center;position:relative;z-index:1}
/* 1280, not 1040: the rail takes 224px plus its gaps before the grid gets a
   look in, so at 1040 the text column was 247px and the headline ran to four
   lines. Below this it stacks and the copy gets the full measure. */
@media (min-width:1280px){.hero-grid{grid-template-columns:minmax(0,1.15fr) 360px;gap:48px}}

/* The mesh sits behind everything and must never touch legibility.

   FULL BLEED, and this is the whole reason it looked like it stopped short.
   .page carries --page-pl (the rail's 224px plus its gaps) and --page-pr, so
   .hero itself only spans 329..1843 of a 1920px viewport. A canvas at inset:0
   inherits that and can never reach the screen edges — no amount of extra nodes
   fixes it, because the canvas is the wrong width. Cancelling the padding is
   the fix. Below 900px .page has no padding, so inset:0 is already full bleed. */
.hero-fx{position:absolute;inset:0;z-index:0;pointer-events:none}
@media (min-width:900px){
  .hero-fx{left:calc(-1 * var(--page-pl));right:calc(-1 * var(--page-pr))}
  body.rail-right .hero-fx{left:calc(-1 * var(--page-pr));right:calc(-1 * var(--page-pl))}
}
.hero-fx canvas{display:block;width:100%;height:100%}
/* Below the two-column breakpoint the copy fills the full width, so the mesh
   crosses every line of it and the source node lands on top of a benefit
   block. It is a desktop flourish; on a phone it costs legibility and battery
   for nothing. The ambient blooms stay, so the hero is still not flat. */
/* Faded rather than removed. Hiding it outright was too blunt — it is the
   one thing giving the hero life. At 45% the lines read as texture behind the
   copy instead of crossing it, and script.js moves the source into the top
   corner when the layout stacks so it can no longer land on a benefit block. */
@media (max-width:900px){.hero-fx{opacity:.45}}
/* two soft blooms, the site's own ambient treatment brought up enough to see */
.hero::before,.hero::after{
  content:"";position:absolute;pointer-events:none;z-index:0;border-radius:50%;
}
.hero::before{width:900px;height:900px;top:-380px;left:-160px;background:radial-gradient(circle,rgba(43,188,179,.13),transparent 62%)}
.hero::after{width:760px;height:760px;bottom:-420px;right:-200px;background:radial-gradient(circle,rgba(43,188,179,.10),transparent 64%)}
.chip{
  display:inline-flex;align-items:center;gap:9px;
  background:rgba(255,255,255,.7);
  backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);
  border:1px solid var(--line);border-radius:100px;
  padding:7px 15px 7px 12px;font-size:12.5px;font-weight:600;color:var(--muted);
  box-shadow:0 2px 10px rgba(22,48,61,.05);margin-bottom:30px;
}
.chip b{color:var(--ink);font-weight:700}
/* 4rem, not 4.1: "Own your software." measures 596px at 64px inside the 668px
   column. At 70px it was 652px — a 16px margin that font rendering ate, and the
   line wrapped to make three. Verified 2 lines at 1040 through 2560px. */
.hero h1{
  font-size:clamp(2.2rem,5.2vw,4rem);font-weight:800;letter-spacing:-.045em;line-height:1.05;
}
/* Between the two-column breakpoint and ~1400px the rail has already taken
   224px plus its gaps, so the text column is ~469px at 1280 rather than the
   668px it gets at 1440. 64px type needs 596px and wrapped into three lines
   there. Sized to the column, not the viewport. */
@media (min-width:1280px) and (max-width:1400px){
  .hero h1{font-size:clamp(2.2rem,3.6vw,2.9rem)}
}
.hero h1 span{color:var(--accent)}
/* the struck word: the one moment of motion, on the word the headline turns on */
.hero h1 s{text-decoration:none;position:relative;color:var(--muted);opacity:.55}
.hero h1 s::after{
  content:"";position:absolute;left:-2px;right:-2px;top:54%;height:5px;
  background:var(--accent);border-radius:3px;
  transform-origin:left center;animation:strike .62s cubic-bezier(.65,0,.35,1) .45s both;
}
@keyframes strike{from{transform:rotate(-1.6deg) scaleX(0)}to{transform:rotate(-1.6deg) scaleX(1)}}
@media (prefers-reduced-motion:reduce){
  .hero h1 s::after{animation:none;transform:rotate(-1.6deg)}
}
.hero .lead{
  font-size:clamp(1rem,1.6vw,1.15rem);color:var(--muted);margin-top:24px;
  max-width:50ch;line-height:1.75;
}
.hero .lead b{color:var(--ink);font-weight:600}
.hero .lead-2{margin-top:14px}

/* what they get — the offer, not a second complaint about the competition */
.gets{display:grid;gap:8px;margin-top:22px;list-style:none}
@media (min-width:560px){.gets{grid-template-columns:1fr 1fr}}
@media (min-width:1040px){.gets{grid-template-columns:1fr 1fr 1fr}}
.gets li{
  display:flex;align-items:flex-start;gap:8px;
  border:1px solid rgba(43,188,179,.3);background:var(--accent-soft);
  border-radius:12px;padding:10px 12px;
}
.gets svg{
  width:14px;height:14px;flex:none;margin-top:2px;stroke:var(--accent-dark);
  stroke-width:3.2;fill:none;stroke-linecap:round;stroke-linejoin:round;
}
.gets b{display:block;font-size:13px;font-weight:700;letter-spacing:-.015em;line-height:1.25}
.gets span span{display:block;font-size:11.5px;color:var(--muted);margin-top:1px;line-height:1.35}

/* the panel: renting it, inverted to deep so the money argument has weight, and
   the way out of it rendered as a white block breaking the dark. The metaphor
   does the work — locked in is dark, owning it is not. */
.stack{border:1px solid rgba(255,255,255,.1);border-radius:20px;overflow:hidden;background:var(--deep);box-shadow:0 22px 60px rgba(22,48,61,.28)}
.stack .sh{
  display:flex;align-items:baseline;justify-content:space-between;gap:10px;
  padding:15px 22px 12px;border-bottom:1px solid rgba(255,255,255,.12);
  font-size:10.5px;font-weight:700;letter-spacing:.13em;text-transform:uppercase;color:rgba(255,255,255,.5);
}
.stack .sh i{font-style:normal;letter-spacing:0;text-transform:none;font-size:11.5px;font-weight:500}
.srow{display:flex;align-items:center;justify-content:space-between;gap:14px;padding:9px 22px;font-size:13.5px}
.srow b{font-weight:400;color:rgba(255,255,255,.82)}
.srow span{font-family:var(--display);font-weight:700;font-size:13.5px;color:rgba(255,255,255,.55);font-variant-numeric:tabular-nums}
.stot{padding:13px 22px 14px;border-top:1px solid rgba(255,255,255,.12);background:rgba(255,255,255,.04)}
.stot b{font-family:var(--display);font-size:30px;font-weight:800;letter-spacing:-.045em;font-variant-numeric:tabular-nums;display:block;color:#fff}
.stot b span{font-family:var(--body);font-size:13px;font-weight:500;letter-spacing:0;color:rgba(255,255,255,.55)}
.stot > span{display:block;font-size:12.5px;color:rgba(255,255,255,.55);margin-top:3px;line-height:1.5}
/* The labour line: brighter and a shade larger than .sgrow on purpose. It is the
   panel's argument — the licences are the small number and the person is the big
   one — where .sgrow below it is a footnote about growth. Styling them the same
   would bury the point in the fine print. */
.swork{padding:12px 22px 13px;font-size:12.5px;color:rgba(255,255,255,.74);border-top:1px solid rgba(255,255,255,.12);background:rgba(255,255,255,.03);line-height:1.6}
.swork b{color:#fff;font-weight:600}
.sgrow{padding:11px 22px;font-size:12px;color:rgba(255,255,255,.55);border-top:1px solid rgba(255,255,255,.12);line-height:1.55}
.sgrow b{color:#fff;font-weight:600}
.sown{padding:18px 20px 20px;background:#fff;margin:10px;border-radius:14px;box-shadow:0 10px 30px rgba(0,0,0,.22)}
.sown .k{font-size:10.5px;font-weight:700;letter-spacing:.13em;text-transform:uppercase;color:var(--accent-dark)}
.sown .v{font-family:var(--display);font-size:28px;font-weight:800;letter-spacing:-.045em;color:var(--accent-dark);margin-top:5px;line-height:1.1}
.sown .v small{font-family:var(--body);font-size:13px;font-weight:500;color:var(--muted);letter-spacing:0}
.sown .n{font-size:12.5px;color:var(--muted);margin-top:7px;line-height:1.6}
.sown .n b{color:var(--ink);font-weight:600}
.actions{display:flex;gap:12px;margin-top:38px;flex-wrap:wrap}
.btn{
  display:inline-flex;align-items:center;gap:8px;
  padding:13px 24px;border-radius:11px;font-family:var(--body);
  font-size:14px;font-weight:600;transition:all .3s var(--ease);
}
.btn-primary{background:var(--accent);color:#fff;box-shadow:0 4px 16px var(--accent-glow)}
.btn-primary:hover{background:var(--accent-dark);transform:translateY(-1px);box-shadow:0 8px 26px var(--accent-glow)}
.btn-primary:disabled{opacity:.55;cursor:default;transform:none;box-shadow:none}
.btn-ghost{border:1.5px solid var(--line);color:var(--ink);background:rgba(255,255,255,.6)}
.btn-ghost:hover{border-color:var(--accent);color:var(--accent-dark)}

/* ------------------------------------------------------------ fleet panel
   The pricing evidence, drawn. Each row is a live system; the bars are
   active days per month over the last twelve — the measured series the
   retainer ladder was derived from. Same glass language as the rail.      */
.fleet{
  border-radius:22px;padding:18px 18px 14px;position:relative;overflow:hidden;
  background:rgba(255,255,255,.62);
  backdrop-filter:blur(26px) saturate(180%);
  -webkit-backdrop-filter:blur(26px) saturate(180%);
  box-shadow:
    0 26px 60px -20px rgba(22,48,61,.24),
    0 8px 20px -8px rgba(22,48,61,.09),
    0 0 0 .5px rgba(255,255,255,.7),
    0 0 0 1px rgba(226,228,232,.8),
    inset 0 1px 0 rgba(255,255,255,.9);
}
.fleet::before{
  content:"";position:absolute;inset:0;border-radius:22px;pointer-events:none;mix-blend-mode:screen;
  background:linear-gradient(180deg,rgba(255,255,255,.6) 0%,rgba(255,255,255,.1) 26%,rgba(255,255,255,0) 52%);
}
.fleet-head{
  display:flex;align-items:center;justify-content:space-between;
  padding-bottom:12px;margin-bottom:6px;border-bottom:1px solid rgba(226,228,232,.85);
  position:relative;z-index:2;
}
.fleet-head b{font-family:var(--display);font-size:12.5px;font-weight:700;letter-spacing:-.01em}
.fleet-head span{font-size:10.5px;font-weight:600;color:var(--muted);letter-spacing:.04em;text-transform:uppercase}
.frow{
  display:grid;grid-template-columns:8px 1fr auto;gap:11px;align-items:center;
  padding:9px 2px;position:relative;z-index:2;border-radius:8px;
  transition:background .25s var(--ease);
}
.frow:hover{background:rgba(43,188,179,.06)}
.frow .fn{font-size:12.5px;font-weight:600;letter-spacing:-.01em;line-height:1.25}
.frow .fn i{font-style:normal;display:block;font-size:9.5px;font-weight:600;color:var(--muted);letter-spacing:.09em;text-transform:uppercase;margin-top:3px}
/* the sparkline */
.spark{display:flex;align-items:flex-end;gap:2.5px;height:26px}
.spark b{
  width:4px;border-radius:1.5px;background:var(--accent);opacity:.32;display:block;
  transform-origin:bottom;animation:breathe 4.5s var(--ease) infinite;
}
.spark b.hi{opacity:.85}
/* a month with no commits is a flat tick, not a short bar — otherwise "nothing
   happened" and "one day of work" draw almost identically */
.spark b.z{opacity:.14;animation:none;background:var(--muted)}
@keyframes breathe{0%,100%{transform:scaleY(1)}50%{transform:scaleY(1.13)}}
.fleet-foot{
  margin-top:8px;padding-top:11px;border-top:1px solid rgba(226,228,232,.85);
  font-size:10.5px;color:var(--muted);line-height:1.45;position:relative;z-index:2;
}
.fleet-foot b{color:var(--ink);font-weight:600}

/* ----------------------------------------------------------------- board */
.board{margin-top:26px;border-top:1px solid var(--line)}
/* mobile: dot in its own narrow column, everything else stacked beside it */
.brow{
  display:grid;grid-template-columns:10px 1fr;gap:6px 13px;
  padding:15px 4px;border-bottom:1px solid var(--line);align-items:start;
  transition:background .25s var(--ease);
}
.brow .nm,.brow .wt,.brow .yr{grid-column:2}
@media (min-width:760px){
  .brow{grid-template-columns:10px 1.1fr 1.9fr auto;gap:20px;align-items:center;padding:16px 10px}
  .brow .nm,.brow .wt,.brow .yr{grid-column:auto}
}
.brow:hover{background:rgba(244,245,247,.7)}
.dot{width:7px;height:7px;border-radius:50%;background:var(--accent);flex:none;margin-top:7px;box-shadow:0 0 0 3px var(--accent-soft)}
@media (min-width:760px){.dot{margin-top:0}}
.brow .nm{font-size:14.5px;font-weight:600;letter-spacing:-.01em}
.brow .nm i{
  font-style:normal;display:block;color:var(--muted);font-weight:600;font-size:10px;
  letter-spacing:.11em;text-transform:uppercase;margin-top:4px;
}
.brow .wt{color:var(--muted);font-size:13.5px;line-height:1.5}
.brow .yr{font-size:11.5px;font-weight:700;color:var(--accent-dark);white-space:nowrap;letter-spacing:.03em}

/* ----------------------------------------------------------- shot strip
   Real screenshots of live product, in browser chrome. Only our OWN
   products here — no client shot goes in without the naming call.       */
.shots{display:grid;gap:16px;margin-top:34px}
@media (min-width:820px){.shots{grid-template-columns:repeat(3,1fr)}}
/* Below the three-up breakpoint these were three 900x562 DESKTOP captures
   stacked at phone width — 963px of screenshot at 390px, 1,671px at 768px, and
   not a word of any of them readable. Swipe instead: same pattern as .ask-grid.
   It does not make a back office legible at 320px and is not meant to — the job
   of these on a phone is to show that real systems with real interfaces exist,
   and one card plus a peek says that in a third of the height. Genuine
   legibility would need mobile-specific crops, i.e. a second set of assets.
   overflow-x lives on this element alone: `html` carries overflow-x:clip, and
   making a second scroll container out of anything taller breaks sticky. */
@media (max-width:819px){
  .shots{
    display:flex;overflow-x:auto;overscroll-behavior-x:contain;
    scroll-snap-type:x mandatory;padding-bottom:6px;scrollbar-width:none;
  }
  .shots::-webkit-scrollbar{display:none}
  .shot{flex:0 0 82%;scroll-snap-align:start}
  /* The lift is a pointer affordance. Inside a swipe strip it only ever fires
     from a stray touch and leaves one card sitting proud of its neighbours. */
  .shot:hover{transform:none;box-shadow:none;border-color:var(--line)}
}
.shot{
  border-radius:14px;overflow:hidden;background:#fff;border:1px solid var(--line);
  transition:all .35s var(--ease);
}
.shot:hover{transform:translateY(-4px);box-shadow:0 22px 50px rgba(22,48,61,.13);border-color:rgba(43,188,179,.4)}
.shot-bar{
  height:28px;background:var(--bg-alt);border-bottom:1px solid var(--line);
  display:flex;align-items:center;gap:5px;padding:0 11px;
}
.shot-bar i{width:7px;height:7px;border-radius:50%;background:#d3d6dc;display:block}
.shot-bar em{
  font-style:normal;font-size:9.5px;color:var(--muted);font-weight:600;
  margin-left:8px;letter-spacing:.02em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
}
/* height:auto is load-bearing — the img's `height` attribute is a
   presentational hint, and without this it wins over aspect-ratio. */
.shot img{display:block;width:100%;height:auto;aspect-ratio:16/10;object-fit:cover;object-position:top center;background:var(--bg-alt)}
.shot figcaption{padding:13px 15px;font-size:12px;color:var(--muted);line-height:1.45}
.shot figcaption b{display:block;color:var(--ink);font-size:13px;font-weight:600;margin-bottom:3px;letter-spacing:-.01em}

/* ------------------------------------------------------------ stats band */
.band{background:var(--deep);color:#fff;border-radius:22px;overflow:hidden;margin-top:36px}
.stats{display:grid;grid-template-columns:1fr 1fr}
@media (min-width:760px){.stats{grid-template-columns:repeat(4,1fr)}}
.stat{padding:26px 22px;border-right:1px solid rgba(255,255,255,.09);border-bottom:1px solid rgba(255,255,255,.09)}
@media (min-width:760px){.stat{padding:32px 26px;border-bottom:0}}
.stat:last-child{border-right:0}
.stat .n{
  font-family:var(--display);font-size:34px;font-weight:800;letter-spacing:-.045em;
  color:var(--accent);line-height:1;font-variant-numeric:tabular-nums;
}
.stat .l{font-size:12.5px;margin-top:9px;line-height:1.4;color:rgba(255,255,255,.66)}
.stat .l i{font-style:normal;display:block;margin-top:4px;color:rgba(255,255,255,.42);font-size:11.5px}

/* ------------------------------------------------------------------ work
   `.case` is scoped under `.cases` on purpose: the case-study PAGE also
   uses `<article class="case">` as its root, and must not inherit the
   teaser card's border, padding and background.                          */
.cases{display:grid;gap:14px;margin-top:32px}
@media (min-width:820px){.cases{grid-template-columns:repeat(2,1fr)}}
.cases .case{
  border:1px solid var(--line);border-radius:18px;padding:26px 24px;background:#fff;
  transition:all .3s var(--ease);display:flex;flex-direction:column;
}
.cases .case:hover{transform:translateY(-3px);box-shadow:0 18px 46px rgba(22,48,61,.09);border-color:rgba(43,188,179,.45)}
.cases .case .tag{font-size:10.5px;font-weight:700;letter-spacing:.12em;text-transform:uppercase;color:var(--accent-dark)}
.cases .case h3{font-size:17.5px;font-weight:700;margin-top:11px;letter-spacing:-.025em;line-height:1.25;transition:color .3s var(--ease)}
.cases .case:hover h3{color:var(--accent-dark)}
.cases .case .tl{font-size:13.5px;color:var(--muted);margin-top:10px;line-height:1.55;flex-grow:1}
.cases .hard{
  margin-top:18px;padding:14px 16px;border-radius:12px;
  background:var(--bg-alt);border-left:2px solid var(--accent);
}
.cases .hard b{font-size:10.5px;font-weight:700;letter-spacing:.11em;text-transform:uppercase;color:var(--muted);display:block;margin-bottom:5px}
.cases .hard p{font-size:13px;line-height:1.5;font-weight:500}
.cases .case .meta{display:flex;justify-content:space-between;align-items:center;margin-top:18px;padding-top:14px;border-top:1px solid var(--line);font-size:11.5px;color:var(--muted);font-weight:600}
.cases .case .meta .live{display:flex;align-items:center;gap:7px;color:var(--accent-dark)}
.cases .case .meta .rd{display:flex;align-items:center;gap:5px;color:var(--accent-dark);transition:gap .25s var(--ease)}
.cases .case:hover .meta .rd{gap:9px}
.cases .case .meta .rd svg{width:12px;height:12px}

/* -------------------------------------------------------------- the picker
   Replaced BOTH #need (the three routing cards) and #price (the eleven-row
   estimate builder) on 2026-08-16. They asked the same question — "which of
   these are you" — and both ended in a price, so the homepage asked it twice
   for 2,046px, 29% of the page. This is one section in their place at ~835px.

   Two controls, one state. The sentence is the one to notice; the pills are the
   fallback for anyone who does not, and they mirror each other because both
   read from the same `askSel` in script.js. */
.ask-say{
  font-family:var(--display);font-size:clamp(1.5rem,3vw,2.1rem);font-weight:700;
  letter-spacing:-.035em;line-height:1.34;max-width:26ch;margin-top:2px;
}
/* the phrase is a <button> inside the heading. Underline + chevron is the
   standard "this is editable" signal; without it the line reads as decoration
   and the whole mechanism goes undiscovered. */
.ask-say .pick{
  display:inline;font:inherit;letter-spacing:inherit;color:var(--accent-dark);
  background:none;border:0;border-bottom:2px solid var(--accent);border-radius:3px;
  padding:0 3px;margin:0 -1px;cursor:pointer;text-align:left;
  transition:background .2s var(--ease);
}
.ask-say .pick:hover{background:var(--accent-soft)}
.ask-say .pick:focus-visible{outline:2px solid var(--accent);outline-offset:3px}
.ask-say .pick::after{content:'⌄';font-size:.62em;margin-left:7px;opacity:.7;position:relative;top:-.2em}

.ask-note{color:var(--muted);font-size:14.5px;margin-top:12px;max-width:64ch;line-height:1.65;min-height:48px}

/* the three differentiators #need used to hide behind a click, flattened to one
   row so they cost ~26px instead of ~80px */
.ask-ticks{list-style:none;display:flex;flex-wrap:wrap;gap:7px 20px;margin-top:12px}
.ask-ticks li{display:flex;align-items:center;gap:6px;font-size:12.5px;color:var(--muted)}
.ask-ticks li::before{
  content:'';width:13px;height:13px;flex:none;border-radius:50%;
  background:var(--accent-soft) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23229e96' stroke-width='3.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6L9 17l-5-5'/%3E%3C/svg%3E") center/9px no-repeat;
}

.ask-hint{
  display:flex;align-items:center;gap:7px;font-size:11px;font-weight:700;
  letter-spacing:.13em;text-transform:uppercase;color:var(--muted);margin-top:22px;
}
.ask-hint::after{content:'';flex:1;height:1px;background:var(--line)}

.ask-chips{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:9px;margin-top:14px}
@media (max-width:1000px){.ask-chips{grid-template-columns:repeat(3,minmax(0,1fr))}}
@media (max-width:640px){.ask-chips{grid-template-columns:repeat(2,minmax(0,1fr))}}
.ask-chip{
  border:1px solid var(--line);border-radius:13px;padding:12px 15px;background:#fff;
  cursor:pointer;text-align:left;transition:all .2s var(--ease);
}
.ask-chip:hover{border-color:#d0d3d9}
.ask-chip.on{border-color:rgba(43,188,179,.55);background:var(--accent-soft)}
.ask-chip b{display:block;font-size:13.5px;font-weight:600;letter-spacing:-.01em;line-height:1.35}
.ask-chip span{
  display:block;font-family:var(--display);font-size:12.5px;font-weight:700;
  letter-spacing:-.02em;color:var(--muted);margin-top:5px;font-variant-numeric:tabular-nums;
}
.ask-chip.on span{color:var(--accent-dark)}
/* the escape hatch reads as a different kind of thing, not a fifth price tier */
.ask-chip.alt{border-style:dashed}
.ask-chip.alt.on{border-style:solid}

/* build on the left, monthly on the right, split by a rule: the distinction the
   whole section exists to make is that one is once and one is forever */
.ask-out{display:flex;align-items:baseline;gap:18px;flex-wrap:wrap;margin-top:26px;padding-top:22px;border-top:1px solid var(--line)}
.ask-out .n{font-family:var(--display);font-size:36px;font-weight:800;letter-spacing:-.05em;font-variant-numeric:tabular-nums;line-height:1}
.ask-out .sep{color:var(--line);font-size:24px}
.ask-out .m{font-family:var(--display);font-size:25px;font-weight:800;letter-spacing:-.04em;font-variant-numeric:tabular-nums;line-height:1}
.ask-out .n span,.ask-out .m span{
  display:block;font-family:var(--body);font-size:12.5px;font-weight:500;
  color:var(--muted);letter-spacing:0;margin-top:5px;max-width:34ch;
}
.ask-out .btn{margin-left:auto}
@media (max-width:700px){.ask-out .btn{margin-left:0;width:100%;justify-content:center}}

/* The comparison grid — four rungs side by side, so "what does each include?"
   stops needing a click and a memory.

   FOUR COLUMNS, NEVER FIVE. The pilot is not a package and is not in here, so
   this row does not line up with .ask-chips above it. That is correct and worth
   leaving alone: the chips are ways to pick, these are things you can buy.

   The money is the LAST line of each card and muted on purpose. Promote it to
   the heading and this becomes a SaaS tier table, which is the frame the rest of
   the page argues against — and it would put $15,000 in front of somebody before
   they had read what any of it is for. */
.ask-all{margin-top:6px}
/* position:relative so the cards measure their offsetLeft against the strip and
   script.js can centre the chosen one by setting scrollLeft. No visual effect. */
.ask-grid{position:relative;display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:10px;margin-top:14px;align-items:stretch}
@media (max-width:1000px){.ask-grid{grid-template-columns:repeat(2,minmax(0,1fr))}}
/* Stacked, these four cards are 949px on a 390px phone — longer than the whole
   section was before they existed. So below 560px they swipe instead, which is
   the same answer the shots strip needs and does not exist yet.
   overflow-x on THIS element only: `html` carries overflow-x:clip and making a
   second scroll container out of anything taller would break sticky. */
@media (max-width:560px){
  .ask-grid{
    display:flex;grid-template-columns:none;overflow-x:auto;overscroll-behavior-x:contain;
    scroll-snap-type:x mandatory;padding-bottom:6px;scrollbar-width:none;
  }
  .ask-grid::-webkit-scrollbar{display:none}
  .ask-card{flex:0 0 79%;scroll-snap-align:start}
}
.ask-card{
  display:flex;flex-direction:column;border:1px solid var(--line);border-radius:14px;
  padding:15px 16px 14px;background:#fff;cursor:pointer;text-align:left;
  transition:border-color .2s var(--ease),background .2s var(--ease);
}
.ask-card:hover{border-color:#d0d3d9}
.ask-card.on{border-color:rgba(43,188,179,.55);background:var(--accent-soft)}
.ask-card > b{font-size:13.5px;font-weight:700;letter-spacing:-.01em;line-height:1.35}
.ask-card ul{list-style:none;margin-top:11px;display:flex;flex-direction:column;gap:7px}
.ask-card li{position:relative;padding-left:17px;font-size:12px;color:var(--muted);line-height:1.5}
.ask-card li::before{
  content:'';position:absolute;left:0;top:4px;width:11px;height:11px;
  background:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23229e96' stroke-width='3.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6L9 17l-5-5'/%3E%3C/svg%3E") center/11px no-repeat;
}
/* margin-top:auto pins the two footer lines to the bottom, so the money sits on
   one baseline across all four cards however uneven the tick lists are */
.ask-card .pl{
  display:block;font-style:normal;font-size:12px;color:var(--muted);line-height:1.5;
  margin-top:auto;padding-top:12px;
}
.ask-card .pl span{
  display:block;font-size:9.5px;font-weight:700;letter-spacing:.13em;
  text-transform:uppercase;color:var(--muted);opacity:.75;margin-bottom:3px;
}
.ask-card .mn{
  display:block;font-style:normal;font-family:var(--display);font-size:12px;font-weight:700;
  letter-spacing:-.01em;color:var(--muted);margin-top:10px;padding-top:10px;
  border-top:1px solid var(--line);font-variant-numeric:tabular-nums;
}
.ask-card.on .mn{color:var(--accent-dark);border-top-color:rgba(43,188,179,.3)}

.ask-fine{font-size:12.5px;color:var(--muted);margin-top:18px;line-height:1.7;max-width:72ch}
.ask-fine b{color:var(--ink);font-weight:600}

.ask-veil{position:fixed;inset:0;z-index:55}
.ask-pop{
  position:fixed;z-index:60;background:#fff;border:1px solid var(--line);border-radius:15px;
  box-shadow:0 18px 50px rgba(22,48,61,.16);padding:8px;width:min(430px,calc(100vw - 36px));
  max-height:70vh;overflow-y:auto;
}
.ask-pop button{
  display:block;width:100%;padding:11px 13px;border-radius:10px;border:0;background:none;
  font:inherit;font-size:13.5px;font-weight:500;line-height:1.45;color:inherit;
  text-align:left;cursor:pointer;transition:background .15s;
}
.ask-pop button:hover{background:var(--bg-alt)}
.ask-pop button.on{background:var(--accent-soft);color:var(--accent-dark);font-weight:600}
.ask-pop button i{display:block;font-style:normal;font-size:11.5px;color:var(--muted);margin-top:2px}
.ask-pop button.on i{color:var(--accent-dark);opacity:.8}
.ask-pop .hd{
  font-size:10px;font-weight:700;letter-spacing:.13em;text-transform:uppercase;
  color:var(--muted);padding:9px 13px 6px;
}

.fine{font-size:12.5px;color:var(--muted);margin-top:26px;line-height:1.65;max-width:64ch}

/* ----------------------------------------------------------------- terms */
.terms{display:grid;gap:2px;margin-top:30px;border-radius:16px;overflow:hidden;border:1px solid var(--line)}
.term{display:flex;gap:15px;padding:18px 22px;background:#fff;align-items:flex-start;transition:background .25s var(--ease)}
.term:nth-child(even){background:var(--bg-alt)}
.term:hover{background:var(--accent-soft)}
.term .tick{
  width:20px;height:20px;border-radius:50%;flex:none;margin-top:1px;
  background:var(--accent-soft);color:var(--accent-dark);
  display:flex;align-items:center;justify-content:center;
}
.term .tick svg{width:11px;height:11px;stroke-width:3}
.term p{font-size:14px;line-height:1.55}
.term p b{font-weight:600}

/* --------------------------------------------------------------- contact */
.talk{
  border-radius:24px;background:var(--deep);color:#fff;padding:52px 40px;margin-top:20px;
  position:relative;overflow:hidden;
}
@media (max-width:700px){.talk{padding:38px 26px}}
.talk::after{
  content:"";position:absolute;width:420px;height:420px;border-radius:50%;
  background:rgba(43,188,179,.16);filter:blur(80px);top:-160px;right:-120px;pointer-events:none;
}
.talk h2{font-size:clamp(1.6rem,3.2vw,2.1rem);position:relative;font-weight:700}
.talk p{color:rgba(255,255,255,.62);margin-top:14px;font-size:15px;max-width:44ch;position:relative;line-height:1.7}
.talk .actions{position:relative}
.btn-light{background:#fff;color:var(--deep)}
.btn-light:hover{background:var(--accent);color:#fff;transform:translateY(-1px)}
.btn-outline{border:1.5px solid rgba(255,255,255,.24);color:#fff}
.btn-outline:hover{border-color:var(--accent);color:var(--accent)}

/* The idea form. Not in the mockup — the mockup's two buttons were
   placeholders (href="#") and the site has a working, spam-protected
   /api/contact endpoint behind this form. Kept in the page's language
   rather than dropped. */
.talk-form{
  margin-top:18px;border:1px solid var(--line);border-radius:20px;background:#fff;
  padding:30px 32px;box-shadow:0 14px 40px rgba(22,48,61,.05);
}
@media (max-width:700px){.talk-form{padding:24px 20px}}
.talk-form h3{font-size:17px;font-weight:700;letter-spacing:-.02em}
.talk-form > p{font-size:13.5px;color:var(--muted);margin-top:7px;line-height:1.6;max-width:52ch}
.tf-grid{display:grid;gap:14px;margin-top:20px}
@media (min-width:700px){.tf-grid{grid-template-columns:1fr 1fr}}
.tf-field{display:flex;flex-direction:column;gap:6px}
.tf-field.full{grid-column:1/-1}
.tf-field label{font-size:11.5px;font-weight:600;color:var(--muted);letter-spacing:.02em}
.tf-field label i{font-style:normal;font-weight:500;opacity:.7}
.tf-field input,.tf-field textarea{
  font-family:var(--body);font-size:14px;color:var(--ink);
  border:1px solid var(--line);border-radius:10px;padding:11px 13px;
  background:var(--bg-alt);transition:all .25s var(--ease);resize:vertical;
}
.tf-field input:focus,.tf-field textarea:focus{
  outline:0;border-color:var(--accent);background:#fff;box-shadow:0 0 0 3px var(--accent-soft);
}
.tf-field input::placeholder,.tf-field textarea::placeholder{color:#a3a8b0}
.tf-actions{display:flex;align-items:center;gap:16px;flex-wrap:wrap;margin-top:20px}
.tf-alt{font-size:12.5px;color:var(--muted)}
.tf-alt a{color:var(--accent-dark);font-weight:600;border-bottom:1px solid rgba(43,188,179,.35)}
.tf-alt a:hover{border-color:var(--accent)}
.success-msg,.error-msg{margin-top:14px;padding:11px 14px;border-radius:10px;font-size:13px;font-weight:500}
.success-msg{background:var(--accent-soft);color:var(--accent-dark);border:1px solid rgba(43,188,179,.3)}
.error-msg{background:rgba(214,69,69,.07);color:#b23b3b;border:1px solid rgba(214,69,69,.25)}

footer{padding:36px 0 46px;border-top:1px solid var(--line);margin-top:80px}
.foot{display:flex;justify-content:space-between;align-items:center;gap:16px;flex-wrap:wrap;font-size:12.5px;color:var(--muted)}
.foot nav{display:flex;gap:20px;flex-wrap:wrap}
.foot nav a{transition:color .2s var(--ease)}
.foot nav a:hover{color:var(--accent-dark)}
.foot .fm b{color:var(--ink);font-weight:700}
.foot .fm span{color:var(--accent)}

/* ========================================================= MOBILE TABBAR
   Same glass, horizontal. Apple bottom-bar behaviour.                    */
/* ------------------------------------------------------- the brand on mobile
   The rail is display:none under 900px and it was the only element on the page
   carrying the mark, so below that width the site showed no logo anywhere —
   on the homepage and on every sub-page. This is the rail's brand block on its
   own, in the tabbar's glass, pinned opposite it at the top of the screen.

   Deliberately not a sixth tab: the bar has five slots, all of them
   destinations, and a logo is not one. It reuses .mark, so the tile can never
   drift from the rail's. */
.brandbar{display:none}
@media (max-width:900px){
  /* The text cut, not the display cut. At 104px wide the nine-segment drawing
     fuses into a solid band, so this is the five-segment one with wider gaps —
     they are three drawings, not one scaled. A rounded rect rather than a pill,
     because the lockup is 1.92:1 and stacked, so it needs height a pill
     cannot give it. */
  .brandbar{
    display:block;
    position:fixed;top:12px;left:12px;z-index:80;
    width:148px;height:74px;padding:0;border-radius:22px;
    /* one declaration: image over colour. Two `background:` lines would mean
       the second silently wins and the lockup never paints.
       118px sits mid-band for the text cut (56–140px) rather than at its floor;
       at 104px the larger type of this cut crowds the arch legs. */
    background:url("/assets/lockup-live-text.svg") no-repeat center/118px auto,
               rgba(255,255,255,.55);
    backdrop-filter:blur(34px) saturate(200%);
    -webkit-backdrop-filter:blur(34px) saturate(200%);
    box-shadow:
      0 16px 34px -14px rgba(22,48,61,.24),
      0 6px 14px -6px rgba(22,48,61,.10),
      0 0 0 .5px rgba(255,255,255,.7),
      0 0 0 1px rgba(226,228,232,.7),
      inset 0 1px 0 rgba(255,255,255,.9);
  }
  /* Fixed means it covered whatever was under it for the entire page — it was
     sitting on a case-study title and on the pricing eyebrow in Ohav's
     screenshots. Retract on the way down, return on the way up. */
  .brandbar{transition:transform .32s var(--ease),opacity .32s var(--ease)}
  body.nav-down .brandbar{transform:translateY(-120%);opacity:0}
  .brandbar::before{
    content:"";position:absolute;inset:0;border-radius:22px;pointer-events:none;mix-blend-mode:screen;
    background:linear-gradient(180deg,rgba(255,255,255,.6) 0%,rgba(255,255,255,.12) 30%,rgba(255,255,255,0) 58%);
  }
  /* The chip occupies 12–86px, so the hero needs more room than the 78px it had.
     Sub-page heroes are set by .work-hero/.case-hero further down the file — a
     padding-top here would be overridden by their shorthand. */
  .hero{padding-top:118px}
}

.tabbar{display:none}
@media (max-width:900px){
  .rail{display:none}
  .tabbar{
    display:flex;position:fixed;left:12px;right:12px;bottom:14px;height:62px;z-index:80;
    border-radius:999px;padding:0 6px;align-items:center;
    background:rgba(255,255,255,.55);
    backdrop-filter:blur(34px) saturate(200%);
    -webkit-backdrop-filter:blur(34px) saturate(200%);
    box-shadow:
      0 20px 44px -16px rgba(22,48,61,.26),
      0 8px 18px -6px rgba(22,48,61,.12),
      0 0 0 .5px rgba(255,255,255,.7),
      0 0 0 1px rgba(226,228,232,.7),
      inset 0 1px 0 rgba(255,255,255,.9);
  }
  .tabbar::before{
    content:"";position:absolute;inset:0;border-radius:999px;pointer-events:none;mix-blend-mode:screen;
    background:linear-gradient(180deg,rgba(255,255,255,.6) 0%,rgba(255,255,255,.12) 30%,rgba(255,255,255,0) 58%);
  }
  .tab{
    flex:1;height:52px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:3px;
    color:var(--muted);position:relative;z-index:2;transition:color .2s var(--ease);
  }
  .tab svg{width:19px;height:19px;stroke-width:1.6}
  .tab em{font-style:normal;font-size:9.5px;font-weight:600;letter-spacing:.01em}
  .tab.on{color:var(--accent-dark)}
  .tab.on::before{
    content:"";position:absolute;width:52px;height:42px;border-radius:15px;z-index:-1;
    background:var(--accent-soft);box-shadow:inset 0 0 0 1px rgba(43,188,179,.22),inset 0 1px 0 rgba(255,255,255,.7);
  }
  body{padding-bottom:84px}
}

/* ============================================================================
   SUB-PAGES — /work and /work/<slug>

   Same tokens, same measure, same rail. These sections have no counterpart in
   the mockup (which is the homepage only), so they are written in its language
   rather than lifted from it.
   ============================================================================ */

.case-narrow{max-width:var(--w-prose)}

.work-hero,.case-hero{padding:118px 0 56px;position:relative;z-index:1}
/* 118px, not 86px: the mobile brand chip occupies 12–86px and 86px left the
   first line touching it. This is the rule that governs sub-page heroes — a
   padding-top in the .brandbar block above would be overridden by this
   shorthand. */
@media (max-width:900px){.work-hero,.case-hero{padding:118px 0 44px}}
.work-hero h1,.case-hero h1{
  font-size:clamp(2.1rem,5vw,3.1rem);font-weight:800;letter-spacing:-.04em;
  line-height:1.08;margin-top:6px;
}
.work-hero h1 em,.case-hero h1 em{font-style:normal;color:var(--accent)}
.work-hero p{font-size:16px;color:var(--muted);line-height:1.75;max-width:60ch;margin-top:18px}
.work-index{padding-top:34px}
.notfound-hero .actions{margin-top:30px}

/* --- case study page ------------------------------------------------------- */

.case-back{
  display:inline-flex;align-items:center;gap:6px;font-size:12.5px;font-weight:600;
  color:var(--muted);margin-bottom:26px;transition:color .2s var(--ease);
}
.case-back:hover{color:var(--accent-dark)}
.case-meta{
  display:flex;align-items:center;flex-wrap:wrap;gap:8px;
  font-size:10.5px;font-weight:700;letter-spacing:.13em;text-transform:uppercase;color:var(--muted);
}
.case-meta .case-area{color:var(--accent-dark)}
.case-dot{opacity:.4}
.case-client{font-size:12.5px;color:var(--muted);margin-top:10px}
.case-client b{color:var(--ink);font-weight:600}
.case-tagline{font-size:19px;font-weight:500;line-height:1.5;margin-top:18px;max-width:52ch}
.case-summary{font-size:15px;color:var(--muted);line-height:1.75;margin-top:16px;max-width:60ch}
.case-live{margin-top:24px}
.case-scale{
  display:flex;flex-wrap:wrap;gap:36px;margin-top:38px;padding-top:26px;
  border-top:1px solid var(--line);
}
.case-scale-item{display:flex;flex-direction:column;gap:4px}
.case-scale-value{
  font-family:var(--display);font-size:26px;font-weight:800;letter-spacing:-.04em;line-height:1;
}
.case-scale-label{font-size:12px;color:var(--muted)}

.case-body{padding-bottom:20px}

/* at-a-glance pair sitting above the fold of the write-up */
.case-glance{display:grid;gap:26px;margin-top:44px}
@media (min-width:760px){.case-glance{grid-template-columns:1fr 1fr;gap:34px}}
.glance-col h2{font-size:15px;font-weight:700;letter-spacing:-.01em;margin-bottom:14px}
.glance-list{display:grid;gap:11px}
.glance-list li{position:relative;padding-left:20px;font-size:13.5px;color:var(--muted);line-height:1.6}
.glance-list li::before{
  content:"";position:absolute;left:0;top:8px;width:6px;height:6px;border-radius:2px;background:var(--line);
}
.glance-check li::before{background:var(--accent);opacity:.75}

.case-outcome{margin-top:44px;padding:26px 28px;border-radius:18px;background:var(--bg-alt);border:1px solid var(--line)}
@media (max-width:700px){.case-outcome{padding:22px 20px}}
.case-outcome h2{font-size:15px;font-weight:700;margin-bottom:16px}
.case-list{display:grid;gap:13px}
.case-list li{position:relative;padding-left:22px;font-size:14px;color:var(--muted);line-height:1.65}
.case-list li::before{
  content:"";position:absolute;left:0;top:8px;width:7px;height:7px;border-radius:2px;background:var(--line);
}
.case-list-check li::before{background:var(--accent);opacity:.8}
.case-list strong,.case-section strong{color:var(--ink);font-weight:600}
.case-stack{display:flex;flex-wrap:wrap;gap:7px;margin-top:22px;padding-top:20px;border-top:1px solid var(--line)}
.case-stack span{
  font-size:11px;font-weight:600;color:var(--muted);background:#fff;
  border:1px solid var(--line);border-radius:100px;padding:5px 11px;
}

/* ------------------------------------------------- what this shape of work costs
   Sits after Outcome and before the long write-up: by then the reader believes
   the work, and cost is the next question they were going to ask anyway. It
   quotes the same ladder as /#price, from content/pricing.js, so the two pages
   cannot drift apart. */
.case-cost{margin-top:34px;padding:26px 28px;border:1px solid var(--line);border-radius:18px;background:#fff}
.case-cost h2{font-size:15px;font-weight:700;margin-bottom:12px}
.cc-days{font-size:13.5px;color:var(--muted);line-height:1.6;max-width:60ch}
.cc-days b{color:var(--ink);font-weight:600}
.cc-rows{display:grid;gap:1px;margin-top:20px;background:var(--line);border:1px solid var(--line);border-radius:14px;overflow:hidden}
@media (min-width:640px){.cc-rows{grid-template-columns:1fr 1fr}}
.cc-row{background:#fff;padding:16px 18px;display:flex;flex-direction:column;gap:7px}
.cc-row.cc-us{background:var(--accent-soft)}
.cc-who{
  font-size:10px;font-weight:700;letter-spacing:.13em;text-transform:uppercase;color:var(--muted);
}
.cc-us .cc-who{color:var(--accent-dark)}
.cc-fig b{
  display:block;font-family:var(--display);font-size:21px;font-weight:800;
  letter-spacing:-.04em;line-height:1.15;font-variant-numeric:tabular-nums;
}
.cc-us .cc-fig b{color:var(--accent-dark)}
.cc-fig span{display:block;font-size:12px;color:var(--muted);margin-top:5px;line-height:1.5}
.cc-fine{font-size:11.5px;color:var(--muted);margin-top:16px;line-height:1.6;max-width:72ch}
.cc-fine a{color:var(--accent-dark);font-weight:600}

/* the long write-up, collapsed by default */
.case-longform{margin-top:34px;border:1px solid var(--line);border-radius:18px;background:#fff;overflow:hidden}
.case-longform summary{
  list-style:none;cursor:pointer;padding:20px 24px;display:flex;flex-direction:column;gap:4px;
  transition:background .25s var(--ease);
}
.case-longform summary::-webkit-details-marker{display:none}
.case-longform summary:hover{background:var(--bg-alt)}
.lf-title{font-family:var(--display);font-size:14.5px;font-weight:700;letter-spacing:-.02em;display:flex;align-items:center;gap:9px}
.lf-title::before{content:"+";color:var(--accent-dark);font-weight:800;font-size:15px}
.case-longform[open] .lf-title::before{content:"\2212"}
.lf-sub{font-size:12.5px;color:var(--muted);padding-left:20px}
.lf-body{padding:6px 24px 28px;border-top:1px solid var(--line)}
@media (max-width:700px){.case-longform summary{padding:18px 18px}.lf-body{padding:6px 18px 24px}}
.case-section{margin-top:30px}
.case-section h3{
  display:flex;align-items:baseline;gap:12px;font-size:16px;font-weight:700;
  letter-spacing:-.02em;margin-bottom:14px;
}
.case-num{font-size:10.5px;font-weight:700;letter-spacing:.13em;color:var(--accent-dark)}
.case-section p{font-size:14px;color:var(--muted);line-height:1.8;margin-bottom:14px}
.case-section code{
  font-family:var(--mono);font-size:.88em;padding:2px 6px;border-radius:5px;
  background:var(--bg-alt);border:1px solid var(--line);color:var(--ink);
}

/* the hard part — deliberately the most distinct block on the page */
.case-hard{
  margin-top:34px;padding:26px 26px 22px;border-radius:16px;
  background:var(--bg-alt);border:1px solid var(--line);border-left:3px solid var(--accent);
}
@media (max-width:700px){.case-hard{padding:20px 18px}}
.case-hard-tag{
  font-size:10.5px;font-weight:700;letter-spacing:.13em;text-transform:uppercase;
  color:var(--accent-dark);margin-bottom:9px;
}
.case-hard h3{font-size:18px;font-weight:700;letter-spacing:-.025em;line-height:1.25;margin-bottom:16px;display:block}
.case-hard p{color:#4a4e55}
.case-lesson{
  margin-top:18px;padding:16px 18px;border-radius:12px;background:#fff;border:1px solid var(--line);
}
.case-lesson-label{
  display:block;font-size:10.5px;font-weight:700;letter-spacing:.13em;text-transform:uppercase;
  color:var(--muted);margin-bottom:7px;
}
.case-lesson p{font-size:13.5px;line-height:1.65;color:var(--ink);margin:0;font-weight:500}

.case-nav{padding:0 0 20px}
.case-nav-inner{display:grid;gap:12px}
@media (min-width:700px){.case-nav-inner{grid-template-columns:1fr 1fr}}
.case-nav-item{
  border:1px solid var(--line);border-radius:14px;padding:16px 18px;background:#fff;
  display:flex;flex-direction:column;gap:4px;transition:all .3s var(--ease);
}
.case-nav-item:hover{border-color:rgba(43,188,179,.45);box-shadow:0 12px 30px rgba(22,48,61,.07)}
.case-nav-item.next{text-align:right}
.case-nav-dir{font-size:10.5px;font-weight:700;letter-spacing:.13em;text-transform:uppercase;color:var(--muted)}
.case-nav-name{font-family:var(--display);font-size:14.5px;font-weight:700;letter-spacing:-.02em}

/* --- long tail (kept on /work, not on the homepage) ------------------------ */

.more-toggle{margin-top:8px;border:1px solid var(--line);border-radius:18px;background:#fff;overflow:hidden}
.more-toggle summary{
  list-style:none;cursor:pointer;padding:18px 22px;display:flex;align-items:center;
  justify-content:space-between;gap:14px;flex-wrap:wrap;transition:background .25s var(--ease);
}
.more-toggle summary::-webkit-details-marker{display:none}
.more-toggle summary:hover{background:var(--bg-alt)}
.more-summary-text{font-family:var(--display);font-size:14.5px;font-weight:700;letter-spacing:-.02em;display:flex;align-items:center;gap:9px}
.more-summary-text::before{content:"+";color:var(--accent-dark);font-weight:800;font-size:15px}
.more-toggle[open] .more-summary-text::before{content:"\2212"}
.more-count{font-size:11.5px;font-weight:600;color:var(--muted)}
.more-grid{display:grid;gap:26px;padding:6px 22px 24px;border-top:1px solid var(--line)}
@media (min-width:760px){.more-grid{grid-template-columns:repeat(3,1fr);gap:30px;padding-top:22px}}
.more-col h4{font-size:11px;font-weight:700;letter-spacing:.13em;text-transform:uppercase;color:var(--accent-dark);margin-bottom:14px}
.more-col ul{display:grid;gap:13px}
.more-col li{display:flex;flex-direction:column;gap:2px}
.more-name{font-size:13.5px;font-weight:600;letter-spacing:-.01em;display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.more-name a{border-bottom:1px solid var(--line);transition:all .2s var(--ease)}
.more-name a:hover{color:var(--accent-dark);border-color:var(--accent)}
.more-badge{
  font-size:9px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;
  color:var(--accent-dark);background:var(--accent-soft);border-radius:4px;padding:3px 6px;
}
.more-note{font-size:12.5px;color:var(--muted);line-height:1.5}
.more-footnote{font-size:12px;color:var(--muted);line-height:1.6;padding:0 22px 22px;max-width:70ch}

/* --- shared closing CTA band ---------------------------------------------- */

.cta-band-inner{
  border-radius:24px;background:var(--deep);color:#fff;padding:46px 40px;
  position:relative;overflow:hidden;
}
@media (max-width:700px){.cta-band-inner{padding:34px 24px}}
.cta-band-inner::after{
  content:"";position:absolute;width:420px;height:420px;border-radius:50%;
  background:rgba(43,188,179,.16);filter:blur(80px);top:-170px;right:-130px;pointer-events:none;
}
.cta-band-inner h2{font-size:clamp(1.5rem,3vw,2rem);font-weight:700;position:relative}
.cta-band-inner p{color:rgba(255,255,255,.62);margin-top:13px;font-size:14.5px;max-width:52ch;position:relative;line-height:1.7}
.cta-band-actions{display:flex;gap:12px;margin-top:30px;flex-wrap:wrap;position:relative}

@media (prefers-reduced-motion:reduce){
  *{animation-duration:.01ms!important;transition-duration:.01ms!important}
  html{scroll-behavior:auto}
  /* The `*` above cannot reach inside an SVG loaded as an image, so the moving
     lockup has to be swapped for the still one rather than stopped. Only the
     image layer: .brandbar's shorthand carries a background-colour in its last
     layer and a full `background:` here would drop it. */
  .rail-brand{background-image:url("/assets/brand/kaymen-lockup.svg")}
  .brandbar{background-image:url("/assets/brand/kaymen-lockup-text.svg")}
}
