/* =========================================================================
   PROJECT AUDIT PRO — the site stylesheet
   Shared by the home page and every sub-page, so the nav, the type scale, the
   cards, the motion and both themes are defined once.
   ========================================================================= */
:root{
  --navh:64px;                      /* re-measured from the real nav by site.js */
  --ink:#12263a; --ink-2:#1a3047; --ink-3:#233b54; --line:#2b333f;
  --lime:#c6e34a; --lime-deep:#5c7a1e;
  --paper:#ffffff; --soft:#f6f7f9;
  --text:#12151a; --muted:#5c6674;
  --card-bg:#ffffff; --card-border:#e6e9ee; --card-border-soft:#f1f3f7;
  --track-bg:#eef1f5; --chip-tint:#eef7d6;
  --red:#dc2626; --orange:#ea6a2a; --blue:#3b82f6;
  --green:#16a34a; --amber:#b45309; --purple:#7c3aed;
  --font:-apple-system,BlinkMacSystemFont,"Segoe UI",Inter,Roboto,Helvetica,Arial,sans-serif;
  --r:10px;
  --shadow:0 1px 2px rgba(16,24,40,.06),0 8px 24px rgba(16,24,40,.08);
  --max:1290px;
  /* one motion vocabulary for the whole page: this curve, and durations from
     .35 / .6 / .8s. Nothing on the page eases any other way. */
  --ease:cubic-bezier(.25,.1,.25,1);
}
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]){
    --paper:#12263a; --soft:#171b22; --text:#e8ecf1; --muted:#98a3b3;
    --card-bg:#1a1f27; --card-border:#2b333f; --card-border-soft:#232a34;
    --track-bg:#232a34; --chip-tint:rgba(198,227,74,.15);
    --shadow:0 1px 2px rgba(0,0,0,.3),0 8px 24px rgba(0,0,0,.35);
  }
}
:root[data-theme="dark"]{
  --paper:#12263a; --soft:#171b22; --text:#e8ecf1; --muted:#98a3b3;
  --card-bg:#1a1f27; --card-border:#2b333f; --card-border-soft:#232a34;
  --track-bg:#232a34; --chip-tint:rgba(198,227,74,.15);
  --shadow:0 1px 2px rgba(0,0,0,.3),0 8px 24px rgba(0,0,0,.35);
}

*{box-sizing:border-box}
html{scroll-behavior:smooth;overflow-x:clip}
body{margin:0;font-family:var(--font);background:var(--soft);color:var(--text);
  -webkit-font-smoothing:antialiased;font-size:16px;line-height:1.6;overflow-x:clip}
img{max-width:100%;height:auto;display:block}
a{color:var(--lime-deep);text-decoration:none}
:root[data-theme="dark"] a:not(.btn){color:var(--lime)}
@media (prefers-color-scheme: dark){:root:not([data-theme="light"]) a:not(.btn){color:var(--lime)}}
h1,h2,h3{letter-spacing:-.02em;font-weight:800;margin:0 0 .5em;line-height:1.15}
h1{font-size:clamp(32px,6.2vw,62px);font-weight:700;letter-spacing:-.025em;line-height:1.15}
h2{font-size:clamp(24px,4vw,36px)}
h3{font-size:19px;letter-spacing:-.01em}
p{margin:0 0 1em}
.wrap{max-width:var(--max);margin:0 auto;padding:0 20px}
.tnum{font-variant-numeric:tabular-nums}
.muted{color:var(--muted)}

/* ---------- nav ----------
   Matches projectauditpro.com's own nav exactly: fixed 62px row (never
   resizes), translucent navy with a blur behind it, a hairline border, and
   only the background/shadow deepening on scroll — nothing changes size. */
header.nav{position:sticky;top:0;z-index:60;background:rgba(18,38,58,.96);
  backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px);
  border-bottom:1px solid #232a34;padding-top:env(safe-area-inset-top);
  transition:background .35s var(--ease),box-shadow .35s var(--ease)}
header.nav.small{background:rgba(18,38,58,.98);box-shadow:0 8px 24px rgba(0,0,0,.35)}
/* The hero's glow gradient sits close under the nav, and a sharp edge shows
   where content passes from "blurred behind the nav" to "not" as you scroll
   past it — a seam that moves and brightens depending on scroll position.
   A soft fade glued to the nav's own bottom edge smooths that transition at
   any scroll offset, the same way the reference site's does. */
header.nav::after{content:"";position:absolute;left:0;right:0;top:100%;height:34px;
  background:linear-gradient(rgba(18,38,58,.55),rgba(18,38,58,0));pointer-events:none}
header.nav .wrap{display:flex;align-items:center;gap:26px;height:62px}
/* One column for the whole site. The bar, the header band and every section
   under it share a left edge, so the wordmark sits directly above the
   headline — it used to be inset 140px from it, which nobody noticed while
   the headline sat a long way down the band and which was glaring the moment
   the headline came up to meet it. */
@media(min-width:1440px){:root{--max:1400px}}
header.nav .brand{display:flex;align-items:center;gap:9px}
header.nav .brand svg{display:block;width:187px;height:56px}
nav.links{display:flex;gap:22px;margin-left:auto;align-items:center}
nav.links a{color:#aab3c0;font-size:14px;font-weight:500}
nav.links a:hover{color:#fff}
.navActions{display:flex;align-items:center;gap:9px}
.theme-toggle{display:inline-flex;align-items:center;justify-content:center;width:36px;height:36px;
  border-radius:9px;border:1px solid #2b333f;background:transparent;color:#aab3c0;cursor:pointer;transition:.15s;padding:0}
.theme-toggle:hover{background:#232a34;color:#fff}
.theme-toggle svg{width:17px;height:17px}
.btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;
  border:1px solid var(--line);background:var(--ink-2);color:#fff;padding:11px 17px;
  border-radius:var(--r);font-weight:700;font-size:15px;cursor:pointer;transition:.15s;
  white-space:nowrap;min-height:46px}
.btn:hover{background:var(--ink-3)}
.btn.primary{background:var(--lime);border-color:var(--lime);color:#12151a}
.btn.primary:hover{background:#d9f07a}
.btn.outline{background:transparent;border-color:#4a5563;color:#fff}
.btn.outline:hover{background:rgba(255,255,255,.08)}
.btn.lg{padding:14px 24px;font-size:16px;min-height:52px}
.btn.ghost{background:transparent;border-color:var(--card-border);color:var(--text)}
.navActions .btn{padding:8px 15px;font-size:14px;min-height:0;border-radius:10px}
/* ---------- the phone menu ----------
   Sixteen destinations do not fit across a phone, and a sideways-scrolling
   strip hides half of them behind a gesture nobody makes. Below 860px the
   links become a proper menu: a button in the bar, a panel that drops under
   it with every destination at a full tap target, and a scrim over the page
   behind it. It opens and closes from the button, the Escape key, a tap
   outside it, or following any link in it. */
.menuBtn{display:none;align-items:center;justify-content:center;width:42px;height:42px;
  border-radius:10px;border:1px solid #2b333f;background:transparent;color:#e8ecf1;
  cursor:pointer;padding:0;flex:0 0 auto}
.menuBtn:hover{background:#232a34}
.menuBtn i{position:relative;display:block;width:18px;height:2px;border-radius:2px;
  background:currentColor;transition:background .2s var(--ease)}
.menuBtn i::before,.menuBtn i::after{content:"";position:absolute;left:0;width:18px;height:2px;
  border-radius:2px;background:currentColor;
  transition:transform .28s var(--ease),top .2s var(--ease)}
.menuBtn i::before{top:-6px}
.menuBtn i::after{top:6px}
.menuBtn[aria-expanded="true"] i{background:transparent}
.menuBtn[aria-expanded="true"] i::before{top:0;transform:rotate(45deg)}
.menuBtn[aria-expanded="true"] i::after{top:0;transform:rotate(-45deg)}
.navScrim{position:fixed;inset:0;z-index:55;background:rgba(6,12,20,.55);
  opacity:0;pointer-events:none;transition:opacity .28s var(--ease)}
body.menu-open .navScrim{opacity:1;pointer-events:auto}

@media(max-width:860px){
  header.nav .wrap{gap:12px;height:58px}
  header.nav .brand svg{width:150px;height:45px}
  .navActions{margin-left:auto;gap:8px}
  .menuBtn{display:inline-flex}
  nav.links{position:absolute;left:0;right:0;top:100%;z-index:61;
    display:block;margin:0;padding:6px 16px calc(14px + env(safe-area-inset-bottom));
    background:#12263a;border-bottom:1px solid #232a34;
    box-shadow:0 18px 40px rgba(0,0,0,.45);
    max-height:calc(100svh - 58px);overflow-y:auto;
    opacity:0;visibility:hidden;transform:translateY(-10px);
    transition:opacity .26s var(--ease),transform .3s var(--ease),visibility .3s}
  header.nav.open nav.links{opacity:1;visibility:visible;transform:none}
  nav.links a{display:flex;align-items:center;min-height:52px;padding:0 6px;
    font-size:16.5px;font-weight:600;color:#dfe5ec;
    border-bottom:1px solid rgba(255,255,255,.07)}
  nav.links a:last-child{border-bottom:0}
  header.nav nav.links a.on{color:var(--lime)}
  header.nav .links a.on::after{display:none}
  /* the links animate in one after another once the panel is open */
  header.nav.open nav.links a{animation:menuIn .34s var(--ease) backwards}
  header.nav.open nav.links a:nth-child(1){animation-delay:.03s}
  header.nav.open nav.links a:nth-child(2){animation-delay:.06s}
  header.nav.open nav.links a:nth-child(3){animation-delay:.09s}
  header.nav.open nav.links a:nth-child(4){animation-delay:.12s}
  header.nav.open nav.links a:nth-child(5){animation-delay:.15s}
  header.nav.open nav.links a:nth-child(6){animation-delay:.18s}
}
/* Below about 390px the bar ran out of room and the menu button was pushed
   off the right edge — on a 360-wide phone the menu was unreachable. The
   wordmark, the gaps and the sign-in button all come in a notch so the four
   things in the bar fit down to 320. */
@media(max-width:400px){
  header.nav .wrap{gap:8px;padding-left:14px;padding-right:12px}
  header.nav .brand{min-height:44px}
  header.nav .brand svg{width:112px;height:34px}
  .navActions{gap:5px}
  .navActions .btn{padding:9px 11px;font-size:13.5px}
  /* the toggle may shrink; the menu button stays a full tap target */
  .theme-toggle{width:40px;height:40px}
  nav.links{padding-left:14px;padding-right:14px}
}
@keyframes menuIn{from{opacity:0;transform:translateX(-10px)}to{opacity:1;transform:none}}
@media (prefers-reduced-motion: reduce){
  header.nav.open nav.links a{animation:none}
  nav.links,.menuBtn i,.menuBtn i::before,.menuBtn i::after,.navScrim{transition:none}
}

/* ---------- hero ---------- */
/* The header fills the screen: everything below the nav and nothing else, with
   the copy and the window centred in it. min-height, not height, so a long
   headline or a phone in landscape grows the band rather than being cut off.
   svh rather than vh so the mobile browser's disappearing toolbar does not
   make the first screenful taller than the screen. */
.hero{background:
  radial-gradient(900px 520px at 12% -12%,rgba(198,227,74,.20),transparent 62%),
  radial-gradient(760px 520px at 108% 108%,rgba(198,227,74,.14),transparent 60%),var(--ink);
  color:#fff;padding:30px 0 150px;overflow:hidden;
  display:flex;align-items:center;position:relative;
  min-height:calc(100vh - var(--navh));
  min-height:calc(100svh - var(--navh))}
/* The copy and the window start on the same line. Centring each of them in
   the row independently put the headline below the top of the window beside
   it, which read as the text sitting too low with dead space above it. */
.heroRow{position:relative;z-index:1;display:grid;grid-template-columns:minmax(0,1fr) minmax(0,700px);
  gap:40px;align-items:start;width:100%}
@media(min-width:1440px){
  .heroRow{grid-template-columns:minmax(0,1fr) minmax(0,810px);gap:36px}
}
@media(max-width:960px){.heroRow{grid-template-columns:1fr;align-items:stretch}}
@media(max-width:760px){.hero{padding:34px 0 46px}.phero{padding:34px 0 46px}}
.hero h1{color:#fff;max-width:17ch;font-size:clamp(32px,5vw,54px)}
.hero .lede{font-size:clamp(16.5px,2.1vw,19px);color:#c3ccd8;max-width:60ch;margin-bottom:26px}
.hero .cta{display:flex;gap:12px;flex-wrap:wrap;margin-bottom:26px}
/* the sub-page and closing rows are the same pair of buttons, laid out the
   same way — they used to be loose inline elements */
.phero .cta{display:flex;gap:12px;flex-wrap:wrap;margin-bottom:4px}
.close .cta{display:flex;gap:12px;flex-wrap:wrap;justify-content:center}
/* On a phone the two buttons stacked, each its own width, and read as one
   call to action with an afterthought under it. They sit side by side now,
   an equal half each, so the pair is balanced across the column and the
   second one is as easy to reach as the first. */
@media(max-width:600px){
  .hero .cta,.phero .cta,.close .cta{flex-wrap:nowrap;gap:10px;width:100%}
  .hero .cta .btn,.phero .cta .btn,.close .cta .btn{
    flex:1 1 0;min-width:0;padding-left:10px;padding-right:10px;font-size:15px;
    text-align:center}
}
@media(max-width:360px){
  .hero .cta .btn,.phero .cta .btn,.close .cta .btn{font-size:14px;letter-spacing:-.01em}
}
.hero .trust{font-size:14px;color:#98a3b3;margin:0 0 12px}
.hero .trust b{color:#e8ecf1}

/* A full-screen header has to say there is something under it. A small
   chevron at the foot of the band, breathing once every couple of seconds —
   it is not a control, so it is drawn rather than marked up. */
.hero::after,.phero::after{content:"";position:absolute;left:50%;bottom:22px;z-index:1;
  width:13px;height:13px;margin-left:-7px;pointer-events:none;
  border-right:2px solid rgba(255,255,255,.42);border-bottom:2px solid rgba(255,255,255,.42);
  border-radius:0 0 3px 0;transform:rotate(45deg);
  animation:cue 2.4s var(--ease) infinite}
@keyframes cue{
  0%,100%{transform:translateY(0) rotate(45deg);opacity:.34}
  50%{transform:translateY(7px) rotate(45deg);opacity:.85}
}
@media(max-height:640px),(max-width:760px){.hero::after,.phero::after{display:none}}
@media (prefers-reduced-motion: reduce){.hero::after,.phero::after{animation:none;opacity:.5}}

/* ---------- squared paper ----------
   A drawing-office grid laid over the navy: a fine 44px square with a heavier
   one every fifth line, both at a few per cent so it reads as texture rather
   than as a pattern. It is masked so it is strongest under the nav and gone
   before the copy needs to be read over it. */
.heroGrid{position:absolute;inset:0;z-index:0;pointer-events:none;
  background-image:
    linear-gradient(rgba(255,255,255,.05) 1px,transparent 1px),
    linear-gradient(90deg,rgba(255,255,255,.05) 1px,transparent 1px),
    linear-gradient(rgba(198,227,74,.075) 1px,transparent 1px),
    linear-gradient(90deg,rgba(198,227,74,.075) 1px,transparent 1px);
  background-size:44px 44px,44px 44px,220px 220px,220px 220px;
  background-position:-1px -1px,-1px -1px,-1px -1px,-1px -1px;
  -webkit-mask-image:radial-gradient(125% 100% at 50% -10%,#000 22%,rgba(0,0,0,.4) 58%,transparent 90%);
  mask-image:radial-gradient(125% 100% at 50% -10%,#000 22%,rgba(0,0,0,.4) 58%,transparent 90%)}
@media(max-width:760px){
  .heroGrid{background-size:34px 34px,34px 34px,170px 170px,170px 170px}
}
/* the same paper under the closing panel, so the two navy bands match */
.close{position:relative;overflow:hidden}
.close>.wrap{position:relative;z-index:1}

/* soft glow blobs drifting behind the hero copy — the reference site's
   "premium" signal: depth from a slow-moving glow, not a static gradient */
.heroBlobs{position:absolute;inset:0;overflow:hidden;pointer-events:none;z-index:0}
.blob{position:absolute;border-radius:50%;filter:blur(70px);opacity:.28;background:var(--lime);
  animation:drift 17s ease-in-out infinite}
.blob-a{width:420px;height:420px;top:-140px;left:-100px}
.blob-b{width:360px;height:360px;bottom:-160px;right:-80px;animation-delay:-8.5s}
@keyframes drift{0%,100%{transform:translate(0,0)}50%{transform:translate(34px,-26px)}}

/* word-by-word hero heading reveal, one shared vocabulary with the rest of
   the page's motion (same ease as .rise below) */
.hero h1 .hw{display:inline-block;opacity:0;transform:translateY(14px);
  animation:wordIn .8s var(--ease) forwards}
@keyframes wordIn{to{opacity:1;transform:none}}

.floaty{animation:floaty 6s ease-in-out infinite}
@keyframes floaty{0%,100%{transform:translateY(0)}50%{transform:translateY(-10px)}}
.strip{padding:18px 0;background:var(--ink-2);border-top:1px solid var(--line);
  border-bottom:1px solid var(--line)}
.stripRow{display:flex;gap:10px 30px;flex-wrap:wrap;justify-content:center;
  font-size:13.5px;color:#aab3c0}
.stripRow b{color:#e8ecf1}
@media(max-width:700px){.stripRow{justify-content:flex-start;flex-wrap:nowrap;overflow-x:auto;
  padding-bottom:2px}}

/* ---------- floating window (hero + tour) ---------- */
.floatwin{border-radius:14px;overflow:hidden;border:1px solid #2b3a4b;
  box-shadow:0 20px 70px rgba(0,0,0,.5);background:#0e1117}
.floatwin .fbar{height:36px;background:#161b22;display:flex;align-items:center;gap:7px;
  padding:0 13px;border-bottom:1px solid #22303f}
.floatwin .fbar i{width:9px;height:9px;border-radius:50%;background:#3b4756;display:block}
.floatwin .fbar span{margin-left:5px;color:#aab3c0;font-size:12px;font-weight:600;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* The window is turned a few degrees towards the copy beside it and lit from
   that side, so it sits IN the hero rather than being pasted on top of it. The
   tilt lives on the wrapper and the drift on the window, because both are
   transforms and one would otherwise cancel the other. */
.heroTilt{perspective:1700px;perspective-origin:0% 50%}
.heroWin{max-width:none;margin:18px 0 0;
  transform:rotateY(-8deg) rotateX(2.4deg) rotate(.5deg);
  transform-origin:0% 50%;
  box-shadow:
    -2px 0 0 rgba(255,255,255,.05),
    28px 26px 40px -22px rgba(0,0,0,.55),
    62px 62px 90px -34px rgba(0,0,0,.62),
    110px 96px 150px -50px rgba(0,0,0,.55);
  transition:transform .8s var(--ease),box-shadow .8s var(--ease)}
.heroTilt:hover .heroWin{transform:rotateY(-4deg) rotateX(1.2deg) rotate(.2deg) scale(1.012)}
@media(max-width:1100px){.heroWin{transform:rotateY(-5deg) rotateX(1.6deg)}}
@media(max-width:960px){
  .heroTilt{perspective:none}
  .heroWin{margin:30px auto 0;max-width:700px;transform:none;
    box-shadow:0 26px 64px -18px rgba(0,0,0,.6)}
  .heroTilt:hover .heroWin{transform:none}
}
@media(max-width:520px){.heroWin{margin-top:24px}}
.shotWrap{background:var(--ui-bg,#fff);line-height:0}
/* The window used to hold a screenshot, which had to be blown up and cropped
   on a phone to stay legible. It is drawn now, so it reflows instead: the kit's
   own container queries drop the tiles to two columns and the charts to one. */
.shotWrap .uiwrap{line-height:1.45;display:block}
/* The screenshot was a 1240x820 capture of the app, so the window has always
   been that shape and the hero's whole composition is built around it. The
   drawing has to hold the same box: the ratio is pinned here, and the type
   scale below is set so the screen fills it rather than being cropped to fit.
   Below 640 the window stacks and runs tall, which is where the screenshot
   used to be blown up and cropped instead. */
@media(min-width:641px){
  .shotWrap{aspect-ratio:1240/820;overflow:hidden}
  .shotWrap .uiwrap,.shotWrap .uiwrap>*{height:100%}
  .shotWrap .uiwrap>*{font-size:clamp(7.4px,1.35cqi,10.9px)}
}

/* ---------- sections ---------- */
section{padding:68px 0}
section.alt{background:var(--paper)}
.eyebrow{font-size:12px;font-weight:800;text-transform:uppercase;letter-spacing:.09em;
  color:var(--lime-deep);margin:0 0 10px}
:root[data-theme="dark"] .eyebrow{color:var(--lime)}
@media (prefers-color-scheme: dark){:root:not([data-theme="light"]) .eyebrow{color:var(--lime)}}
.section-head{max-width:64ch;margin-bottom:40px}
.section-head p{color:var(--muted);font-size:17px;margin:0}

.feature{display:grid;grid-template-columns:1fr 1fr;gap:46px;align-items:center;
  padding:34px 0;border-top:1px solid var(--card-border)}
.feature:first-of-type{border-top:0}
.feature .art{order:2}
.feature.flip .art{order:0}
.feature h3{font-size:23px;letter-spacing:-.02em}
.feature p{color:var(--muted);margin:0}
.feature .num{display:inline-grid;place-items:center;width:30px;height:30px;border-radius:8px;
  background:var(--chip-tint);color:var(--lime-deep);font-weight:800;font-size:14px;margin-bottom:12px}
:root[data-theme="dark"] .feature .num{color:var(--lime)}
@media(max-width:820px){
  .feature{grid-template-columns:1fr;gap:22px;padding:28px 0}
  .feature .art,.feature.flip .art{order:0}
}
.art-box{background:var(--card-bg);border:1px solid var(--card-border);border-radius:14px;
  overflow:hidden;box-shadow:var(--shadow)}
/* the feature art is a screenshot of the app, so the frame keeps out of its
   way — a dark hairline and the same rounding, nothing else */
.shotBox{background:#0e1117;border-color:#2b3a4b;line-height:0}
.shotBox img{width:100%;height:auto}

/* ---------- feature figures ----------
   These used to be screenshots of the working app — every register, every
   figure, legible on a public page. They are drawings now: the idea of the
   thing, in the brand's own palette, showing nobody's project. */
.art-fig{background:var(--fig-bg);border:1px solid var(--card-border);border-radius:16px;
  padding:10px;overflow:hidden;
  --fig-bg:#fbfcfa; --fig-grid:#e4e9ee; --fig-line:#12263a; --fig-card:#ffffff;
  --fig-head:#12263a; --fig-text:#12263a; --fig-muted:#6b7686; --fig-wall:#eef1f4;
  --fig-tint:#f4f9e4; --fig-lime:#a6c93a; --fig-red:#d0342c; --fig-amber:#c07c12;
  --fig-orange:#d2691e; --fig-green:#2e8b57; --fig-blue:#2563eb; --fig-purple:#7c3aed}
.art-fig .fig{display:block;width:100%;height:auto}
:root[data-theme="dark"] .art-fig,
.art-fig.on-dark{
  --fig-bg:#151a21; --fig-grid:#232b36; --fig-line:#8f9cad; --fig-card:#1c222b;
  --fig-head:#0e141c; --fig-text:#e8ecf1; --fig-muted:#98a3b3; --fig-wall:#1a212a;
  --fig-tint:rgba(198,227,74,.12); --fig-lime:#c6e34a; --fig-red:#ef5350;
  --fig-amber:#e0a022; --fig-orange:#f08b3c; --fig-green:#4caf7d;
  --fig-blue:#6c9bff; --fig-purple:#a78bfa}
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]) .art-fig{
    --fig-bg:#151a21; --fig-grid:#232b36; --fig-line:#8f9cad; --fig-card:#1c222b;
    --fig-head:#0e141c; --fig-text:#e8ecf1; --fig-muted:#98a3b3; --fig-wall:#1a212a;
    --fig-tint:rgba(198,227,74,.12); --fig-lime:#c6e34a; --fig-red:#ef5350;
    --fig-amber:#e0a022; --fig-orange:#f08b3c; --fig-green:#4caf7d;
    --fig-blue:#6c9bff; --fig-purple:#a78bfa}
}
/* the pins settle in a beat after the row arrives */
.art-fig .figPin>g{opacity:0;transform:translateY(-10px);
  transition:opacity .5s var(--ease),transform .5s var(--ease)}
.rise.in .art-fig .figPin>g{opacity:1;transform:none}
.rise.in .art-fig .figPin>g:nth-child(2){transition-delay:.12s}
.rise.in .art-fig .figPin>g:nth-child(3){transition-delay:.24s}
@media (prefers-reduced-motion: reduce){
  .art-fig .figPin>g{opacity:1;transform:none;transition:none}
}

/* ---------- steps ---------- */
/* five across for a five-step run; a seven-step one reads better four and
   three than five and a stranded two */
.steps{display:grid;grid-template-columns:repeat(5,1fr);gap:16px;counter-reset:step}
.steps:has(>.step:nth-child(7)){grid-template-columns:repeat(4,1fr)}
.step{background:var(--card-bg);border:1px solid var(--card-border);border-radius:14px;
  padding:20px 18px;box-shadow:var(--shadow)}
.step b{display:grid;place-items:center;width:30px;height:30px;border-radius:50%;
  background:var(--ink);color:var(--lime);font-size:14px;margin-bottom:12px}
.step h3{font-size:16px;margin-bottom:6px}
.step p{color:var(--muted);font-size:14px;margin:0}
/* both of these have to name the seven-step variant too, or its own rule —
   which carries more specificity than a bare .steps — keeps four columns all
   the way down to a phone */
@media(max-width:980px){
  .steps,.steps:has(>.step:nth-child(7)){grid-template-columns:repeat(2,1fr)}}
@media(max-width:560px){
  .steps,.steps:has(>.step:nth-child(7)){grid-template-columns:1fr}}

/* ---------- who / pricing / faq ---------- */
.pills{display:flex;gap:9px;flex-wrap:wrap}
.pills span{background:var(--card-bg);border:1px solid var(--card-border);border-radius:999px;
  padding:9px 15px;font-size:14.5px;font-weight:600;box-shadow:var(--shadow)}
.prices{display:grid;grid-template-columns:repeat(3,1fr);gap:18px;align-items:start}
@media(max-width:900px){.prices{grid-template-columns:1fr}}
.price{background:var(--card-bg);border:1px solid var(--card-border);border-radius:16px;
  padding:26px 22px;box-shadow:var(--shadow);display:flex;flex-direction:column;height:100%}
.price.best{border-color:var(--lime);border-width:2px;position:relative}
.price.best::after{content:"Best value";position:absolute;top:-11px;left:22px;background:var(--lime);
  color:#12151a;font-size:11.5px;font-weight:800;padding:3px 11px;border-radius:999px;
  text-transform:uppercase;letter-spacing:.05em}
.price .amt{font-size:40px;font-weight:800;letter-spacing:-.03em;line-height:1;
  font-variant-numeric:tabular-nums}
.price .per{color:var(--muted);font-size:14px;margin:6px 0 18px}
.price ul{list-style:none;padding:0;margin:0 0 22px;flex:1}
.price li{padding:7px 0 7px 26px;position:relative;font-size:14.5px;border-top:1px solid var(--card-border-soft)}
.price li:first-child{border-top:0}
.price li::before{content:"";position:absolute;left:2px;top:13px;width:11px;height:6px;
  border-left:2.5px solid var(--lime-deep);border-bottom:2.5px solid var(--lime-deep);
  transform:rotate(-45deg)}
:root[data-theme="dark"] .price li::before{border-color:var(--lime)}
.price .btn{width:100%}

details.faq{background:var(--card-bg);border:1px solid var(--card-border);border-radius:12px;
  margin-bottom:10px;box-shadow:var(--shadow)}
details.faq summary{cursor:pointer;padding:17px 20px;font-weight:700;font-size:16px;
  list-style:none;display:flex;align-items:center;gap:12px;min-height:56px}
details.faq summary::-webkit-details-marker{display:none}
details.faq summary::after{content:"+";margin-left:auto;font-size:22px;font-weight:400;
  color:var(--muted);line-height:1}
details.faq[open] summary::after{content:"−"}
details.faq .a{padding:0 20px 18px;color:var(--muted);font-size:15px}
details.faq .a p:last-child{margin:0}

/* ---------- close + footer ---------- */
.close{background:
  radial-gradient(700px 400px at 50% -30%,rgba(198,227,74,.20),transparent 65%),var(--ink);
  color:#fff;text-align:center}
.close h2{color:#fff}
.close p{color:#c3ccd8;max-width:52ch;margin:0 auto 26px}
footer{background:var(--ink-2);color:#98a3b3;padding:40px 0;font-size:14px}
footer .wrap{display:flex;gap:26px;flex-wrap:wrap;align-items:flex-start}
footer img{height:22px;margin-bottom:12px}
footer a{color:#c3ccd8}
footer a:hover{color:#fff}
footer .col{min-width:170px}
footer .col b{display:block;color:#e8ecf1;margin-bottom:8px;font-size:13px}
footer .col a{display:block;padding:3px 0}
footer .legal{width:100%;border-top:1px solid #2b3a4b;padding-top:18px;margin-top:10px;font-size:13px;
  display:flex;flex-wrap:wrap;gap:4px 18px;align-items:baseline}
/* who made it sits to the right of the copyright on a wide screen and under
   it on a phone, rather than running on as one sentence */
footer .legal .made{margin-left:auto}
@media(max-width:640px){footer .legal .made{margin-left:0}}

/* ---------- motion ---------- */
.rise{opacity:0;transform:translateY(18px);
  transition:opacity .6s var(--ease),transform .6s var(--ease)}
.rise.in{opacity:1;transform:none}
@media (prefers-reduced-motion: reduce){
  html{scroll-behavior:auto}
  .rise{opacity:1;transform:none;transition:none}
  *{animation-duration:.01ms!important;transition-duration:.01ms!important}
}
.skip{position:absolute;left:-9999px}
.skip:focus{left:12px;top:12px;z-index:100;background:var(--lime);color:#12151a;
  padding:10px 16px;border-radius:8px;font-weight:700}

/* ---------- touch screens ----------
   Apple asks for 44pt and Google for 48dp on anything you tap. On a phone the
   footer links, the theme switch and the sign-in button were all under that,
   which is why they were fiddly to hit. Nothing moves on a mouse. */
@media (pointer:coarse){
  .navActions .btn{min-height:44px;padding:11px 17px}
  .theme-toggle{width:44px;height:44px}
  .menuBtn{width:44px;height:44px}
  footer .col a{padding:11px 0}
  footer .legal a{display:inline-flex;align-items:center;min-height:44px;padding:0 2px;margin:0 -2px}
  .skip{min-height:44px;display:inline-flex;align-items:center}
  nav .navLinks a{padding:11px 10px}
}

/* =========================================================================
   SUB-PAGES
   The feature pages, the guides and the who-it's-for pages. Same nav, same
   type scale, same motion as the home page — a shorter masthead instead of
   the hero, a breadcrumb, and a prose column for the long-form ones.
   ========================================================================= */
.pageHero{position:relative;background:
  radial-gradient(900px 420px at 18% -20%,rgba(198,227,74,.16),transparent 62%),var(--ink);
  color:#fff;padding:58px 0 56px;overflow:hidden}
.pageHero::after{content:"";position:absolute;inset:0;pointer-events:none;
  background-image:linear-gradient(rgba(255,255,255,.045) 1px,transparent 1px),
    linear-gradient(90deg,rgba(255,255,255,.045) 1px,transparent 1px);
  background-size:44px 44px;
  -webkit-mask-image:radial-gradient(760px 400px at 22% 10%,#000,transparent 72%);
  mask-image:radial-gradient(760px 400px at 22% 10%,#000,transparent 72%)}
.pageHero>.wrap{position:relative;z-index:1;max-width:920px}
.pageHero h1{font-size:clamp(30px,5vw,48px);margin:0 0 14px;color:#fff}
.pageHero .lede{color:#c3ccd8;font-size:clamp(16px,2vw,19px);max-width:60ch;margin:0 0 22px}
.pageHero .eyebrow{color:var(--lime)}
.crumb{display:flex;flex-wrap:wrap;gap:8px;align-items:center;font-size:13.5px;
  color:#8ea0b4;margin-bottom:16px}
.crumb a{color:#c3ccd8}
.crumb a:hover{color:#fff}
.crumb span{opacity:.55}

.prose{max-width:78ch}
.prose h2{margin-top:38px;font-size:clamp(22px,3vw,28px)}
.prose h3{margin-top:26px;font-size:18.5px}
.prose p,.prose li{font-size:16.5px;line-height:1.7}
.prose ul,.prose ol{padding-left:22px;margin:0 0 1.2em}
.prose li{margin-bottom:7px}
.prose blockquote{margin:24px 0;padding:16px 20px;border-left:3px solid var(--lime);
  background:var(--card-bg);border-radius:0 12px 12px 0;color:var(--text)}
.prose blockquote p:last-child{margin:0}
.callbox{background:var(--card-bg);border:1px solid var(--card-border);border-radius:14px;
  padding:20px 22px;box-shadow:var(--shadow);margin:26px 0}
.callbox b{display:block;margin-bottom:6px}
.callbox p:last-child{margin:0}

.cards3{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:18px}
.cards2{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:18px}
@media(max-width:900px){.cards3,.cards2{grid-template-columns:1fr}}
.card{background:var(--card-bg);border:1px solid var(--card-border);border-radius:14px;
  padding:24px;box-shadow:var(--shadow);
  transition:transform .16s var(--ease),box-shadow .16s var(--ease)}
.card:hover{transform:translateY(-3px);box-shadow:0 4px 10px rgba(16,24,40,.05),0 18px 40px rgba(16,24,40,.09)}
.card h3{margin-bottom:8px}
.card p:last-child{margin:0;color:var(--muted);font-size:15px}
.card .ic{width:38px;height:38px;border-radius:11px;background:var(--chip-tint);
  display:grid;place-items:center;color:var(--lime-deep);margin-bottom:14px}
:root[data-theme="dark"] .card .ic{color:var(--lime)}
@media (prefers-color-scheme: dark){:root:not([data-theme="light"]) .card .ic{color:var(--lime)}}
a.card{display:block;color:inherit}
a.card .more{display:inline-block;margin-top:12px;font-weight:700;color:var(--lime-deep);font-size:14.5px}
:root[data-theme="dark"] a.card .more{color:var(--lime)}
@media (prefers-color-scheme: dark){:root:not([data-theme="light"]) a.card .more{color:var(--lime)}}

.tocList{display:flex;flex-wrap:wrap;gap:10px;margin:0 0 8px;padding:0;list-style:none}
.tocList a{background:var(--card-bg);border:1px solid var(--card-border);border-radius:999px;
  padding:8px 15px;font-size:14px;font-weight:600;color:var(--text);display:inline-block}
.tocList a:hover{border-color:var(--lime-deep)}

.checkList{list-style:none;padding:0;margin:0;max-width:80ch}
.checkList li{position:relative;padding:9px 0 9px 30px;font-size:16px;
  border-top:1px solid var(--card-border-soft)}
.checkList li:first-child{border-top:0}
.checkList li::before{content:"";position:absolute;left:4px;top:17px;width:11px;height:6px;
  border-left:2.5px solid var(--lime-deep);border-bottom:2.5px solid var(--lime-deep);
  transform:rotate(-45deg)}
:root[data-theme="dark"] .checkList li::before{border-color:var(--lime)}
@media (prefers-color-scheme: dark){:root:not([data-theme="light"]) .checkList li::before{border-color:var(--lime)}}
header.nav .links a.on{color:#fff}
header.nav .links a.on::after{content:"";display:block;height:2px;border-radius:2px;
  background:var(--lime);margin-top:5px}

/* a breadcrumb link and a link inside prose are still things a thumb has to
   hit — the padding grows the target without moving the line it sits on */
@media (pointer:coarse){
  .crumb a{padding:11px 4px;margin:0 -4px}
  .prose a,.callbox a,.prose p a{padding:13px 2px;margin:0 -2px}
}

/* .btn.outline is drawn for the dark hero — on a light card it needs the
   page's own ink, or it is white on white */
.price .btn.outline,.card .btn.outline,.prose .btn.outline{
  border-color:var(--card-border);color:var(--text)}
.price .btn.outline:hover,.card .btn.outline:hover,.prose .btn.outline:hover{
  background:var(--track-bg);border-color:var(--lime-deep)}
.moreLink{font-weight:700;font-size:15px;display:inline-block}
@media (pointer:coarse){ .moreLink{padding:13px 2px;margin:0 -2px} }

/* =========================================================================
   THE UI KIT
   Not screenshots: the app's own components, rebuilt here in HTML and CSS at
   marketing scale, carrying invented data for an invented job. They look like
   the product because they are built from the same design, and they show
   nobody's project because there is no project behind them.
   ========================================================================= */
.uiwrap{--ui-bg:#ffffff;--ui-soft:#f6f7f9;--ui-line:#e6e9ee;--ui-line-2:#f1f3f7;
  --ui-ink:#12263a;--ui-text:#12151a;--ui-muted:#5c6674;--ui-field:#ffffff;
  --ui-sb:#ffffff;--ui-sb-text:#5c6674;--ui-active:#eef7d6;--ui-active-text:#3f5a12;
  --ui-red:#dc2626;--ui-amber:#b45309;--ui-green:#16a34a;--ui-blue:#3b82f6;
  --ui-purple:#7c3aed;--ui-lime:#c6e34a;--ui-lime-deep:#5c7a1e;
  --ui-tint-red:#fdf2f2;--ui-tint-amber:#fdf6ec;--ui-tint-blue:#eef4ff;
  --ui-tint-lime:#f4f9e4;--ui-tint-grey:#fafbfc;
  container-type:inline-size}
/* The mockups are drawn once, in ems, and scaled to whatever width the window
   they sit in happens to be — so a header window and a feature-row window are
   the same picture at two sizes, the way two crops of one screenshot would be,
   rather than the same type size squeezed into different amounts of room. The
   ratio is the app's own: 11px of type to a 700px window. The size lives on
   the child because an element cannot query its own container. */
.uiwrap>*{font-size:clamp(7.4px,1.571cqi,12.6px);line-height:1.45;color:var(--ui-text)}
@container (max-width:430px){ .uiwrap>*{font-size:clamp(8.2px,2.5cqi,10.5px)} }
:root[data-theme="dark"] .uiwrap{
  --ui-bg:#1a1f27;--ui-soft:#151a21;--ui-line:#2b333f;--ui-line-2:#232a34;
  --ui-ink:#0e141c;--ui-text:#e8ecf1;--ui-muted:#98a3b3;--ui-field:#151a21;
  --ui-sb:#161b22;--ui-sb-text:#98a3b3;--ui-active:rgba(198,227,74,.14);--ui-active-text:#c6e34a;
  --ui-red:#ef5350;--ui-amber:#e0a022;--ui-green:#4caf7d;--ui-blue:#6c9bff;
  --ui-purple:#a78bfa;--ui-tint-red:rgba(239,83,80,.12);--ui-tint-amber:rgba(224,160,34,.12);
  --ui-tint-blue:rgba(108,155,255,.12);--ui-tint-lime:rgba(198,227,74,.10);
  --ui-tint-grey:rgba(255,255,255,.03)}
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]) .uiwrap{
    --ui-bg:#1a1f27;--ui-soft:#151a21;--ui-line:#2b333f;--ui-line-2:#232a34;
    --ui-ink:#0e141c;--ui-text:#e8ecf1;--ui-muted:#98a3b3;--ui-field:#151a21;
    --ui-sb:#161b22;--ui-sb-text:#98a3b3;--ui-active:rgba(198,227,74,.14);--ui-active-text:#c6e34a;
    --ui-red:#ef5350;--ui-amber:#e0a022;--ui-green:#4caf7d;--ui-blue:#6c9bff;
    --ui-purple:#a78bfa;--ui-tint-red:rgba(239,83,80,.12);--ui-tint-amber:rgba(224,160,34,.12);
    --ui-tint-blue:rgba(108,155,255,.12);--ui-tint-lime:rgba(198,227,74,.10);
    --ui-tint-grey:rgba(255,255,255,.03)}
}

/* ---------- the window it all sits in ---------- */
.uiwin{border-radius:1.273em;overflow:hidden;background:var(--ui-bg);
  border:1px solid rgba(255,255,255,.10);
  box-shadow:0 2px 0.545em rgba(8,15,26,.28),0 2.364em 5.455em -18px rgba(8,15,26,.55)}
/* the same bar the home page's window wears — three grey lights and the
   address in it — one chrome across every window on the site, scaling with
   the window the way the rest of the drawing does */
.uibar{display:flex;align-items:center;gap:0.636em;height:3.273em;padding:0 1.182em;background:#161b22;
  border-bottom:1px solid #22303f}
.uibar i{width:0.818em;height:0.818em;border-radius:50%;background:#3b4756;flex:0 0 auto}
.uibar span{margin-left:0.455em;color:#aab3c0;font-size:1.091em;font-weight:600;letter-spacing:.01em;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.uibody{display:flex;min-height:0;background:var(--ui-soft)}

/* ---------- the app's own sidebar ---------- */
.uisb{flex:0 0 11.091em;background:var(--ui-sb);border-right:1px solid var(--ui-line);
  padding:0.909em 0.727em;display:flex;flex-direction:column;gap:1px}
.uisb .brandrow{display:flex;align-items:center;gap:0.545em;padding:2px 0.364em 0.909em}
.uisb .brandrow svg{width:1.18em;height:1.18em;flex:0 0 auto}
.uisb .brandrow b{font-size:0.909em;letter-spacing:-.01em;color:var(--ui-text)}
.uinav{display:flex;align-items:center;gap:0.636em;padding:0.545em 0.636em;border-radius:0.636em;
  color:var(--ui-sb-text);font-weight:600;font-size:0.955em;white-space:nowrap}
.uinav svg{width:1.182em;height:1.182em;flex:0 0 auto;opacity:.7}
.uinav.on{background:var(--ui-active);color:var(--ui-active-text);font-weight:750}
.uinav.on svg{opacity:1}
.uinav .bdg{margin-left:auto;background:var(--ui-red);color:#fff;border-radius:90.818em;
  min-width:1.364em;height:1.364em;font-size:0.818em;font-weight:800;display:grid;place-items:center;padding:0 0.364em}
.uinav .bdg.a{background:var(--ui-amber)}.uinav .bdg.p{background:var(--ui-purple)}
.uimain{flex:1 1 auto;min-width:0;padding:1.091em;display:flex;flex-direction:column;gap:0.909em}
@container (max-width: 430px){ .uisb{display:none} .uimain{padding:0.909em} }

/* ---------- panels, headings, chips ---------- */
.uipanel{background:var(--ui-bg);border:1px solid var(--ui-line);border-radius:0.909em;padding:1em 1.091em}
.uih{display:flex;align-items:center;gap:0.727em;margin-bottom:0.818em}
.uih h4{margin:0;font-size:1.136em;font-weight:800;letter-spacing:-.015em;color:var(--ui-text)}
.uih h4::after{content:"";display:block;width:2em;height:2.5px;border-radius:2px;
  background:var(--ui-lime);margin-top:0.455em}
.uih .sp{flex:1}
.uibtn{border:1px solid var(--ui-line);background:var(--ui-bg);color:var(--ui-text);
  border-radius:0.545em;padding:0.364em 0.727em;font-size:0.909em;font-weight:700;white-space:nowrap}
.uibtn.pri{background:var(--ui-lime);border-color:var(--ui-lime);color:#12151a}
.uibtn.org{background:var(--ui-red);border-color:var(--ui-red);color:#fff}
.uichip{display:inline-flex;align-items:center;gap:0.364em;border-radius:90.818em;padding:2px 0.636em;
  font-size:0.864em;font-weight:800;letter-spacing:.01em;white-space:nowrap}
.uichip::before{content:"";width:0.364em;height:0.364em;border-radius:50%;background:currentColor}
.uichip.red{background:var(--ui-tint-red);color:var(--ui-red)}
.uichip.amber{background:var(--ui-tint-amber);color:var(--ui-amber)}
.uichip.blue{background:var(--ui-tint-blue);color:var(--ui-blue)}
.uichip.green{background:var(--ui-tint-lime);color:var(--ui-green)}
.uichip.purple{background:var(--ui-tint-blue);color:var(--ui-purple)}
.uichip.grey{background:var(--ui-tint-grey);color:var(--ui-muted)}

/* ---------- the register table ---------- */
.uitbl{width:100%;border-collapse:collapse;font-size:0.955em;table-layout:fixed}

.uitbl th{background:var(--ui-ink);color:#fff;text-align:left;padding:0.545em 0.727em;font-size:0.818em;
  font-weight:800;text-transform:uppercase;letter-spacing:.05em;white-space:nowrap}
.uitbl th:first-child{border-top-left-radius:0.636em}
.uitbl th:last-child{border-top-right-radius:0.636em}
.uitbl td{padding:0.636em 0.727em;border-top:1px solid var(--ui-line-2);vertical-align:middle;
  color:var(--ui-text)}
.uitbl tbody tr:nth-child(even){background:var(--ui-tint-grey)}
.uitbl tbody tr.urgent{background:var(--ui-tint-red)}
.uitbl .ref{font-weight:800;color:var(--ui-text);white-space:nowrap}
.uitbl .sub{color:var(--ui-muted);font-size:0.864em}
.uitbl td{overflow-wrap:anywhere}
.uitbl td.c-date{white-space:nowrap}
.uitbl td>.uichip{max-width:100%;overflow:hidden}

.uisel{display:inline-flex;align-items:center;gap:0.364em;white-space:nowrap;font-size:0.864em;border:1px solid var(--ui-line);
  border-radius:0.545em;padding:3px 0.545em;font-weight:700;background:var(--ui-field);max-width:100%;
  overflow:hidden;text-overflow:ellipsis}
.uisel i{width:0.545em;height:0.545em;border-radius:50%;background:currentColor;flex:0 0 auto}
.uisel::after{content:"";width:0;height:0;border-left:3px solid transparent;
  border-right:3px solid transparent;border-top:0.364em solid var(--ui-muted);margin-left:2px}

/* ---------- KPI tiles ---------- */
.uikpis{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:0.727em}
@container (max-width: 430px){ .uikpis{grid-template-columns:repeat(2,minmax(0,1fr))} }
.uikpi{background:var(--ui-bg);border:1px solid var(--ui-line);border-left:3px solid var(--ui-muted);
  border-radius:0.818em;padding:0.727em 0.818em}
.uikpi b{display:block;font-size:1.727em;font-weight:800;letter-spacing:-.03em;line-height:1.05;
  font-variant-numeric:tabular-nums;color:var(--ui-text)}
.uikpi span{display:block;font-size:0.773em;font-weight:800;letter-spacing:.06em;
  text-transform:uppercase;color:var(--ui-muted);margin-top:3px}
.uikpi em{display:block;font-style:normal;font-size:0.864em;color:var(--ui-muted);margin-top:2px}
.uikpi.red{border-left-color:var(--ui-red)} .uikpi.red b{color:var(--ui-red)}
.uikpi.amber{border-left-color:var(--ui-amber)} .uikpi.amber b{color:var(--ui-amber)}
.uikpi.blue{border-left-color:var(--ui-blue)} .uikpi.blue b{color:var(--ui-blue)}
.uikpi.green{border-left-color:var(--ui-green)} .uikpi.green b{color:var(--ui-green)}
.uikpi.purple{border-left-color:var(--ui-purple)} .uikpi.purple b{color:var(--ui-purple)}

/* ---------- bars ---------- */
.uibars{display:grid;gap:0.455em}
.uibar-row{display:grid;grid-template-columns:minmax(5.273em,36%) 1fr auto;gap:0.727em;align-items:center;
  font-size:0.909em;color:var(--ui-text)}
/* a trade name is one line with an ellipsis, not two lines that make every
   row in the chart a different height */
.uibar-row>div:first-child{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* The bar is drawn at its full length and slides out from behind the left end
   of the track, which the track clips. It looks exactly like growing — the
   rounded cap leads the way — but it is a transform, and a transform is
   handled by the compositor.
   It used to animate `width`. That runs on the main thread, so it competes
   with everything else happening on the page: measured frame by frame, the
   bar moved on 35 of 80 frames in jumps between 4px and 20px. Frame-time
   benchmarks show nothing, because the main thread IS hitting its frames —
   it is the animation that is being starved, not the page. */
.uitrack{background:var(--ui-track,var(--ui-line-2));border-radius:90.818em;height:0.545em;overflow:hidden}
.uifill{height:100%;border-radius:90.818em;background:var(--ui-lime-deep);
  width:var(--w,50%);transform:translateX(-100%);
  transition:transform .95s cubic-bezier(.22,.61,.36,1)}
.in .uifill{transform:translateX(0)}
.uibar-row b{font-variant-numeric:tabular-nums;font-weight:750;min-width:1.455em;text-align:right}

/* a bar that means something of its own takes its own colour */
.uifill-grey{background:var(--ui-muted)}
.uifill-blue{background:var(--ui-blue)}
.uifill-amber{background:var(--ui-amber)}
.uifill-red{background:var(--ui-red)}
.uifill-green{background:var(--ui-green)}

/* ---------- the home page's header window ----------
   The project it is open on, the critical non-conformance the dashboard puts
   in front of you, and the two charts side by side. Sized in em like the rest
   of the kit, so the same picture works in the header and in a feature row. */
.uiproj{display:flex;align-items:flex-start;gap:0.909em;margin-bottom:0.818em;
  padding:0.636em 0.818em;background:var(--ui-bg);border:1px solid var(--ui-line);
  border-left:3px solid var(--ui-lime-deep);border-radius:0.636em}
.uiproj b{font-size:1.045em;font-weight:800;letter-spacing:-.02em;color:var(--ui-text);
  margin-right:0.455em}
.uiproj em{display:block;font-style:normal;font-size:0.818em;color:var(--ui-muted);margin-top:2px}
.uiproj-r{margin-left:auto;display:flex;align-items:center;gap:0.455em;white-space:nowrap;
  font-size:0.864em;color:var(--ui-muted)}
.uicrit{margin-top:0.818em;padding:0.636em 0.818em;border-radius:0.636em;
  background:var(--ui-tint-red);border-left:3px solid var(--ui-red)}
.uicrit>b{display:block;font-size:0.773em;font-weight:800;letter-spacing:.06em;
  text-transform:uppercase;color:var(--ui-red);margin-bottom:0.364em}
.uicrit>div{display:flex;gap:0.727em;align-items:baseline;font-size:0.909em;
  color:var(--ui-text);padding:0.136em 0}
.uicrit>div span{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.uicrit>div i{margin-left:auto;font-style:normal;font-weight:750;color:var(--ui-lime-deep);
  text-decoration:underline}
.uicols{display:grid;grid-template-columns:1fr 1fr;gap:0.727em;margin-top:0.818em}
@container (max-width:560px){ .uicols{grid-template-columns:1fr} }
.uinote{margin-top:0.545em;font-size:0.818em;color:var(--ui-muted);line-height:1.45}

/* ---------- the drawing, with pins ---------- */
.uiplan{position:relative;background:var(--ui-bg);border:1px solid var(--ui-line);
  border-radius:0.909em;overflow:hidden;aspect-ratio:16/10}
.uiplan svg{display:block;width:100%;height:100%}
.uipin{transform-origin:50% 100%;opacity:0;transform:translateY(-16px) scale(.9)}
.in .uipin{opacity:1;transform:none;transition:opacity .45s var(--ease),transform .55s cubic-bezier(.2,1.25,.4,1);
  transition-delay:var(--d,0s)}

/* ---------- the check sheet ---------- */
.uiline{border:1px solid var(--ui-line);border-left:3px solid var(--ui-line);border-radius:0.818em;
  padding:0.727em 0.909em;background:var(--ui-bg);display:grid;gap:0.545em}
.uiline.pass{border-left-color:var(--ui-green)}
.uiline.fail{border-left-color:var(--ui-red);background:var(--ui-tint-red)}
.uiline .t{font-weight:750;font-size:1em;color:var(--ui-text)}
.uiline .m{display:grid;grid-template-columns:auto 1fr;gap:1px 0.727em;font-size:0.864em;color:var(--ui-muted)}
.uiline .m b{font-weight:700}
.uires{display:flex;gap:0.455em}
.uires span{flex:1;text-align:center;border:1px solid var(--ui-line);border-radius:0.545em;
  padding:0.364em 0;font-size:0.909em;font-weight:750;color:var(--ui-muted);background:var(--ui-field)}
.uires span.on-pass{background:var(--ui-green);border-color:var(--ui-green);color:#fff}
.uires span.on-fail{background:var(--ui-red);border-color:var(--ui-red);color:#fff}

/* ---------- the handover gates ---------- */
.uigate{display:flex;align-items:flex-start;gap:0.727em;padding:0.545em 0;font-size:0.955em}
.uigate .gi{flex:0 0 auto;width:1.545em;height:1.545em;border-radius:50%;display:grid;place-items:center;
  background:var(--ui-green);color:#fff;font-size:0.818em;font-weight:800}
.uigate.fail .gi{background:var(--ui-red)}
.uigate b{color:var(--ui-text);font-weight:750}
.uigate div{color:var(--ui-muted)}
.uiring{--p:0;position:relative;width:7.091em;height:7.091em;border-radius:50%;flex:0 0 auto;
  background:conic-gradient(var(--ui-lime-deep) calc(var(--p)*1%),var(--ui-line-2) 0);
  transition:--p 1.2s cubic-bezier(.25,.1,.25,1)}
.uiring::after{content:attr(data-label);position:absolute;inset:0.727em;border-radius:50%;
  background:var(--ui-bg);display:grid;place-items:center;font-size:1.364em;font-weight:800;
  letter-spacing:-.02em;color:var(--ui-text);font-variant-numeric:tabular-nums}
@property --p{syntax:'<number>';inherits:false;initial-value:0}

/* ---------- a fire stopping record ---------- */
.uishots{display:grid;grid-template-columns:1fr 1fr;gap:0.636em}
.uishot{aspect-ratio:4/3;border-radius:0.727em;border:1px solid var(--ui-line);overflow:hidden;
  position:relative;background:
    linear-gradient(135deg,var(--ui-tint-grey),transparent 60%),var(--ui-soft)}
.uishot::after{content:attr(data-tag);position:absolute;left:0.545em;bottom:0.545em;background:rgba(14,20,28,.82);
  color:#fff;font-size:0.773em;font-weight:800;letter-spacing:.05em;padding:2px 0.545em;border-radius:0.364em}
.uishot svg{position:absolute;inset:0;width:100%;height:100%}
.uiev{display:flex;align-items:center;gap:0.545em;font-size:0.909em;color:var(--ui-muted)}
.uiev i{width:0.818em;height:0.818em;border-radius:2px;background:var(--ui-green)}
.uiev i.off{background:var(--ui-line)}

/* The record is a before and an after of the same hole, so the drawing says
   what happened between them: the open gap breathes, then the batt packs in
   from the bottom, the mastic beads go round each service and the label goes
   on the wall. It runs once, when the record comes into view. */
.uishot svg{overflow:visible}
.fsGap{animation:fsGap 2.6s var(--ease) infinite}
@keyframes fsGap{0%,100%{opacity:.5}50%{opacity:1}}
.fsBatt{opacity:0;transform:scaleY(.04);transform-box:fill-box;transform-origin:50% 100%;
  transition:opacity .45s var(--ease),transform .9s cubic-bezier(.25,.1,.25,1)}
.in .fsBatt{opacity:1;transform:none;transition-delay:.25s}
.fsBead{opacity:0;transform:scale(.5);transform-box:fill-box;transform-origin:50% 50%;
  transition:opacity .4s var(--ease),transform .5s cubic-bezier(.2,1.3,.4,1)}
.in .fsBead{opacity:.85;transform:none;transition-delay:.95s}
.fsLabel{opacity:0;transform:translateY(-7px);transform-box:fill-box;
  transition:opacity .4s var(--ease),transform .5s cubic-bezier(.2,1.3,.4,1)}
.in .fsLabel{opacity:1;transform:none;transition-delay:1.2s}
/* the evidence squares fill in one after another as the record lands */
.uiev i{opacity:0;transform:scale(.4);
  transition:opacity .3s var(--ease),transform .35s cubic-bezier(.2,1.3,.4,1)}
.uiev.in i{opacity:1;transform:none}
.uiev.in i:nth-of-type(1){transition-delay:1.35s}
.uiev.in i:nth-of-type(2){transition-delay:1.45s}
.uiev.in i:nth-of-type(3){transition-delay:1.55s}
.uiev.in i:nth-of-type(4){transition-delay:1.65s}
.uiev.in i:nth-of-type(5){transition-delay:1.75s}
@media (prefers-reduced-motion: reduce){
  .fsGap{animation:none;opacity:1}
  .fsBatt,.fsBead,.fsLabel,.uiev i{opacity:1;transform:none;transition:none}
  .fsBead{opacity:.85}
}

/* ---------- a page of the report ---------- */
/* the page is shown as the top of a document rather than a whole A4 sheet —
   a full-height portrait page in a feature row dwarfs everything beside it */
/* The sheet is paper in the light theme and a dark page in the dark one. It
   used to be pinned light in both — and a white A4 sheet on a dark page is the
   brightest thing on the screen by a distance. Everything inside it now reads
   from these few tokens rather than hard-coded greys, so the two themes cannot
   drift apart again. The masthead keeps its navy and lime: that is the
   document's letterhead, and it sits correctly on either. */
.uidoc{--doc-paper:#fff;--doc-ink:#12263a;--doc-muted:#667283;--doc-rule:#eef1f4;
  --doc-rule-strong:#12263a;--doc-foot:#e3e7ec;--doc-foot-ink:#7a8697;
  --doc-ok:#2e7d32;--doc-bad:#c62828;
  background:var(--doc-paper);border:1px solid var(--ui-line);border-radius:0.727em;overflow:hidden;
  height:27.273em;display:flex;flex-direction:column}
.uiwin .uidoc{border:0;border-radius:0;height:29.091em}
:root[data-theme="dark"] .uidoc{
  --doc-paper:#1a1f27;--doc-ink:#e8ecf1;--doc-muted:#98a3b3;--doc-rule:#252c37;
  --doc-rule-strong:rgba(255,255,255,.30);--doc-foot:#2b333f;--doc-foot-ink:#98a3b3;
  --doc-ok:#4caf7d;--doc-bad:#ef5350}
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]) .uidoc{
    --doc-paper:#1a1f27;--doc-ink:#e8ecf1;--doc-muted:#98a3b3;--doc-rule:#252c37;
    --doc-rule-strong:rgba(255,255,255,.30);--doc-foot:#2b333f;--doc-foot-ink:#98a3b3;
    --doc-ok:#4caf7d;--doc-bad:#ef5350}
}
.uidoc .mast{background:#12263a;color:#fff;padding:0.818em 0.909em}
.uidoc .mast b{display:block;font-size:0.955em;font-weight:800;letter-spacing:-.01em}
.uidoc .mast em{display:block;font-style:normal;font-size:0.727em;color:#9fb0c2;margin-top:2px}
.uidoc .mast .rule{height:2px;background:#c6e34a;width:3.636em;margin-top:0.545em;border-radius:2px}
.uidoc .body{flex:1;padding:0.818em 0.909em;display:grid;gap:0.273em;align-content:start;
  font-size:0.818em;color:var(--doc-ink);line-height:1.5}
/* a labelled line: what it is on the left, what it says on the right */
.uidoc .dr{display:flex;align-items:baseline;gap:0.727em;padding:0.318em 0;
  border-bottom:1px solid var(--doc-rule)}
.uidoc .dk{color:var(--doc-muted);flex:0 0 42%}
.uidoc .dv{font-weight:700;margin-left:auto;text-align:right}
/* a small table of the register the page is a print of */
.uidoc .dh,.uidoc .dt{display:grid;grid-template-columns:26% 1fr 26%;gap:0.545em;
  padding:0.273em 0}
.uidoc .dh{margin-top:0.545em;border-bottom:1.5px solid var(--doc-rule-strong);color:var(--doc-muted);
  font-weight:800;font-size:0.88em;text-transform:uppercase;letter-spacing:.05em}
.uidoc .dt{border-bottom:1px solid var(--doc-rule)}
.uidoc .dt span:first-child{font-weight:700}
.uidoc .dt span:last-child{text-align:right;color:var(--doc-muted)}
.uidoc .dnote{margin-top:0.636em;color:var(--doc-muted);font-size:0.94em}
/* the two signatures at the foot of a certificate */
.uidoc .dsig{display:grid;grid-template-columns:1fr 1fr;gap:0.909em;margin-top:0.909em}
.uidoc .dsig>div{display:grid;gap:0.182em}
.uidoc .dsig i{display:block;height:1.9em;border-bottom:1.5px solid var(--doc-rule-strong)}
.uidoc .dsig span{color:var(--doc-muted);font-size:0.94em}
.uidoc .dsig em{font-style:normal;font-weight:700}
.uidoc .foot{border-top:1px solid var(--doc-foot);padding:0.545em 0.909em;display:flex;gap:0.545em;
  font-size:0.682em;color:var(--doc-foot-ink)}
.uidoc .foot span:last-child{margin-left:auto}

/* ---------- a phone ---------- */
/* a phone has to be phone-shaped: without a ceiling it fills the column and
   reads as another window rather than as something in somebody's hand */
.uiphone{max-width:23em;margin:0 auto;
  border-radius:1.818em;border:0.545em solid #0e1622;background:var(--ui-soft);overflow:hidden;
  box-shadow:0 2px 0.545em rgba(8,15,26,.3),0 2em 4.545em -16px rgba(8,15,26,.55)}
.uiphone .top{display:flex;align-items:center;gap:0.545em;background:var(--ui-sb);
  border-bottom:1px solid var(--ui-line);padding:0.727em 0.818em}
.uiphone .top .mk{width:1.182em;height:0.818em;border-top:1.6px solid var(--ui-muted);
  border-bottom:1.6px solid var(--ui-muted);position:relative}
.uiphone .top .mk::after{content:"";position:absolute;left:0;right:0;top:3px;
  border-top:1.6px solid var(--ui-muted)}
.uiphone .top svg{width:1.18em;height:1.18em;flex:0 0 auto}
.uiphone .top b{font-size:0.864em;color:var(--ui-text)}
.uiphone .top i{margin-left:auto;width:0.636em;height:0.636em;border-radius:50%;background:var(--ui-green)}
.uiphone .scr{padding:0.818em;display:grid;gap:0.636em}
.uifab{margin:0 0.818em 0.818em auto;background:var(--ui-lime);color:#12151a;font-weight:800;font-size:0.909em;
  border-radius:0.909em;padding:0.636em 1.091em;width:max-content;
  box-shadow:0 3px 0.909em rgba(16,24,40,.2)}

/* =========================================================================
   MOTION
   One easing, one duration scale, three triggers: enter the viewport, hover,
   or scroll position. Everything here is off under prefers-reduced-motion.
   ========================================================================= */
/* a group whose children arrive one after another */
.stagger>*{opacity:0;transform:translateY(16px);
  transition:opacity .55s var(--ease),transform .55s var(--ease)}
.stagger.in>*{opacity:1;transform:none}
.stagger.in>*:nth-child(1){transition-delay:.00s}
.stagger.in>*:nth-child(2){transition-delay:.07s}
.stagger.in>*:nth-child(3){transition-delay:.14s}
.stagger.in>*:nth-child(4){transition-delay:.21s}
.stagger.in>*:nth-child(5){transition-delay:.28s}
.stagger.in>*:nth-child(6){transition-delay:.35s}
.stagger.in>*:nth-child(7){transition-delay:.42s}
.stagger.in>*:nth-child(8){transition-delay:.49s}

/* the headline arrives a word at a time, as the home page's does */
.words span{display:inline-block;opacity:0;transform:translateY(.5em);
  animation:wordUp .7s var(--ease) forwards}
@keyframes wordUp{to{opacity:1;transform:none}}

/* a number that counts up to itself */
.count{font-variant-numeric:tabular-nums}

/* the floating window: it tilts in space and drifts */
.winTilt{perspective:1700px;perspective-origin:50% 50%}
.winFloat{transform:rotateY(-7deg) rotateX(2.2deg) rotate(.4deg);transform-origin:50% 50%;
  transition:transform .9s var(--ease),box-shadow .9s var(--ease);
  animation:winDrift 9s ease-in-out infinite}
.winTilt:hover .winFloat{transform:rotateY(-3deg) rotateX(1deg) scale(1.015);animation-play-state:paused}
@keyframes winDrift{0%,100%{translate:0 0}50%{translate:0 -10px}}
.winFlip .winFloat{transform:rotateY(7deg) rotateX(2.2deg) rotate(-.4deg)}
.winFlip:hover .winFloat{transform:rotateY(3deg) rotateX(1deg) scale(1.015)}
@media(max-width:900px){
  .winTilt{perspective:none}
  .winFloat,.winFlip .winFloat{transform:none;animation:none}
}

/* the glow behind a dark band */
.glowA,.glowB{position:absolute;border-radius:50%;filter:blur(72px);pointer-events:none;
  opacity:.5;animation:glowDrift 16s ease-in-out infinite}
.glowA{width:460px;height:460px;background:rgba(198,227,74,.30);top:-170px;right:-90px}
.glowB{width:380px;height:380px;background:rgba(59,130,246,.22);bottom:-190px;left:-80px;
  animation-delay:-7s}
@keyframes glowDrift{0%,100%{transform:translate(0,0)}50%{transform:translate(26px,-30px)}}

/* a strip of trade names sliding past */
.marquee{overflow:hidden;-webkit-mask-image:linear-gradient(90deg,transparent,#000 8%,#000 92%,transparent);
  mask-image:linear-gradient(90deg,transparent,#000 8%,#000 92%,transparent)}
.marquee ul{display:flex;gap:44px;list-style:none;margin:0;padding:0;width:max-content;
  animation:slide 38s linear infinite}
.marquee:hover ul{animation-play-state:paused}
.marquee li{font-size:14px;font-weight:700;letter-spacing:-.01em;color:var(--muted);white-space:nowrap}
@keyframes slide{from{transform:translateX(0)}to{transform:translateX(-50%)}}

/* a band of numbers on the dark ground */
.statBand{background:
  radial-gradient(760px 340px at 12% -40%,rgba(198,227,74,.16),transparent 62%),var(--ink);
  color:#fff;border-radius:20px;padding:34px 30px;
  border:1px solid rgba(255,255,255,.10);
  box-shadow:0 20px 50px -22px rgba(8,15,26,.55)}
.statGrid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:22px}
@media(max-width:760px){.statGrid{grid-template-columns:repeat(2,minmax(0,1fr));gap:20px}}
.statGrid b{display:block;font-size:clamp(28px,4vw,40px);font-weight:800;letter-spacing:-.03em;
  line-height:1;color:#fff;font-variant-numeric:tabular-nums}
.statGrid span{display:block;font-size:13.5px;color:#9fb0c2;margin-top:7px}
.statGrid em{color:var(--lime);font-style:normal}

@media (prefers-reduced-motion: reduce){
  .stagger>*{opacity:1;transform:none;transition:none}
  .words span{opacity:1;transform:none;animation:none}
  .winFloat{animation:none}
  .glowA,.glowB{animation:none}
  .marquee ul{animation:none}
  .uifill{transition:none;transform:none}
  .uipin{opacity:1;transform:none}
  .uiring{transition:none}
}

/* =========================================================================
   THE SUB-PAGE HERO
   The same treatment the home page's header has — dark ground, squared paper,
   a drifting glow — with the copy on the left and a floating window on the
   right carrying the screen that page is about.
   ========================================================================= */
.phero{position:relative;background:var(--ink);color:#fff;overflow:hidden;
  padding:30px 0 150px;
  display:flex;align-items:center;
  min-height:calc(100vh - var(--navh));
  min-height:calc(100svh - var(--navh));
  background-image:
    radial-gradient(900px 520px at 12% -12%,rgba(198,227,74,.20),transparent 62%),
    radial-gradient(760px 520px at 108% 108%,rgba(198,227,74,.14),transparent 60%)}
.phero>.wrap{width:100%}
/* a legal page has no window beside the copy — a screenful of empty navy in
   front of terms somebody is trying to read is not a header, it is a wall */
.phero.short{min-height:0;padding:44px 0 46px}
.phero.short::after{display:none}
.phero.short .pheroRow{grid-template-columns:minmax(0,80ch)}
.phero::before{content:"";position:absolute;inset:0;pointer-events:none;
  background-image:linear-gradient(rgba(255,255,255,.05) 1px,transparent 1px),
    linear-gradient(90deg,rgba(255,255,255,.05) 1px,transparent 1px);
  background-size:44px 44px;
  -webkit-mask-image:radial-gradient(820px 440px at 20% 12%,#000,transparent 74%);
  mask-image:radial-gradient(820px 440px at 20% 12%,#000,transparent 74%)}
.phero>.wrap{position:relative;z-index:1}
/* the same two columns the home page's header has, at the same widths */
.pheroRow{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,700px);gap:40px;
  align-items:start;width:100%;position:relative;z-index:1}
@media(min-width:1440px){.pheroRow{grid-template-columns:minmax(0,1fr) minmax(0,810px);gap:36px}}
@media(max-width:960px){.pheroRow{grid-template-columns:1fr;gap:30px;align-items:stretch}}
/* and the column comes in with it, so the headline gets the room instead.
   Guarded, because a browser without :has still narrows the card itself above
   — it would simply sit at the right of a wider track. */
@media(min-width:961px){
  .pheroRow:has(.priceArt){grid-template-columns:minmax(0,1fr) minmax(0,580px)}
}
.phero h1{font-size:clamp(30px,4.6vw,50px);margin:0 0 15px;color:#fff;line-height:1.1}
.phero .lede{color:#c3ccd8;font-size:clamp(15.5px,1.8vw,18.5px);max-width:52ch;margin:0 0 22px}
.phero .eyebrow{color:var(--lime)}
.phero .crumb{margin-bottom:14px}
/* ---------- the header window, identical to the home page's ----------
   Same frame, same bar, same angle, same light. The tilt lives on the wrapper
   and the drift on the window, because both are transforms and one would
   otherwise cancel the other. */
.pheroWin{position:relative;perspective:1700px;perspective-origin:0% 50%}
.pheroWin .winFloat{transform:rotateY(-8deg) rotateX(2.4deg) rotate(.5deg);
  transform-origin:0% 50%;
  transition:transform .8s var(--ease),box-shadow .8s var(--ease)}
.pheroWin:hover .winFloat{transform:rotateY(-4deg) rotateX(1.2deg) rotate(.2deg) scale(1.012)}
/* Every header window is the home page's window: the same width, and the same
   height too — 572 to its 810, held as a ratio so it survives any column
   width. Screens with less in them than the register simply have app left
   over underneath, which is what a screenshot of them would show. */
.pheroWin .uiwin{display:flex;flex-direction:column;min-height:70.6cqw}
.pheroWin .uibody{flex:1 1 auto}
.pheroWin .uiwin{border:1px solid #2b3a4b;background:#0e1117;
  box-shadow:
    -2px 0 0 rgba(255,255,255,.05),
    28px 26px 40px -22px rgba(0,0,0,.55),
    62px 62px 90px -34px rgba(0,0,0,.62),
    110px 96px 150px -50px rgba(0,0,0,.55)}
@media(max-width:1100px){
  .pheroWin .winFloat{transform:rotateY(-5deg) rotateX(1.6deg)}
}
@media(max-width:960px){
  .pheroWin{max-width:700px;margin:0 auto;width:100%;perspective:none}
  .pheroWin .winFloat,.pheroWin:hover .winFloat{transform:none;animation:none}
  /* stacked under the copy the window is only as tall as the screen in it —
     a phone-width window held to that ratio would crop the register */
  .pheroWin .uiwin{box-shadow:0 26px 64px -18px rgba(0,0,0,.6);min-height:0}
}

/* the facts under the copy */
/* ---------- the facts under the copy ----------
   Four boxes two-up ran the copy column eighty pixels past the foot of the
   window beside it, which is what made the header look unbalanced. They are
   a single strip now — one line of figures divided by hairlines, no boxes —
   which is a third of the height and leaves the window as the tallest thing
   in the band, where it belongs. */
.factRow{display:flex;margin-top:24px;max-width:640px;
  border-top:1px solid rgba(255,255,255,.14)}
.fact{flex:1 1 0;min-width:0;padding:14px 16px 0 0}
.fact+.fact{padding-left:16px;border-left:1px solid rgba(255,255,255,.14)}
.fact b{display:block;font-size:17.5px;font-weight:800;letter-spacing:-.02em;color:#fff;
  font-variant-numeric:tabular-nums;line-height:1.15}
.fact span{display:block;font-size:12px;color:#9fb0c2;margin-top:3px;line-height:1.35}
@media(max-width:1100px){
  .fact b{font-size:16px}
  .fact span{font-size:11.5px}
}
@media(max-width:600px){
  /* on a phone four columns of two-word labels are unreadable — two up */
  .factRow{flex-wrap:wrap;max-width:none;border-top:0}
  .fact{flex:1 1 calc(50% - 8px);padding:12px 0 0;
    border-top:1px solid rgba(255,255,255,.14)}
  .fact+.fact{padding-left:0;border-left:0}
  .fact:nth-child(even){padding-left:16px;border-left:1px solid rgba(255,255,255,.14)}
}

/* =========================================================================
   SECTION FURNITURE
   ========================================================================= */
/* The copy needs about 60 characters and no more; everything past that belongs
   to the window, so the art column takes the wider share and the row runs to
   the same width the headers do rather than the narrower text measure. */
.showRow{display:grid;grid-template-columns:minmax(0,42%) minmax(0,1fr);gap:44px;
  align-items:center;padding:38px 0}
.showRow+.showRow{border-top:1px solid var(--card-border-soft)}
/* a flipped row swaps the two column WIDTHS as well as the order — otherwise
   every other window is drawn at the copy's width and the page alternates
   between a wide picture and a narrow one */
.showRow.flip{grid-template-columns:minmax(0,1fr) minmax(0,42%)}
.showRow.flip>.showArt{order:-1}
@media(max-width:960px){
  /* `.showRow.flip` outranks a bare `.showRow` — a media query adds no
     specificity — so the flipped rows stayed two columns on a phone and their
     window was squeezed into 40% of the screen and clipped off the edge. The
     flip has to be undone here by name. */
  .showRow,.showRow.flip{grid-template-columns:1fr;gap:24px;padding:26px 0}
  .showRow.flip>.showArt{order:0}
}
.showRow .num{display:inline-grid;place-items:center;width:30px;height:30px;border-radius:9px;
  background:var(--chip-tint);color:var(--lime-deep);font-weight:800;font-size:14px;margin-bottom:12px}
:root[data-theme="dark"] .showRow .num{color:var(--lime)}
@media (prefers-color-scheme: dark){:root:not([data-theme="light"]) .showRow .num{color:var(--lime)}}
.showRow h3{font-size:clamp(20px,2.5vw,26px);letter-spacing:-.02em;margin-bottom:10px}
.showRow p{color:var(--muted);font-size:16px;max-width:46ch}
.showArt{position:relative}
.showArt::after{content:"";position:absolute;inset:auto -6% -8% -6%;height:60%;
  background:radial-gradient(60% 100% at 50% 100%,rgba(18,38,58,.10),transparent 70%);
  pointer-events:none;z-index:-1}

.split{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:26px;align-items:center}
@media(max-width:900px){.split{grid-template-columns:1fr;gap:22px}}

.quoteBand{border-left:3px solid var(--lime);background:var(--card-bg);
  border-radius:0 16px 16px 0;padding:24px 28px;box-shadow:var(--shadow);max-width:80ch}
.quoteBand p{font-size:clamp(17px,2.2vw,21px);line-height:1.5;letter-spacing:-.015em;margin:0 0 10px}
.quoteBand cite{font-style:normal;font-size:13.5px;color:var(--muted)}

/* ---------- the hero screenshot follows the theme ----------
   The drawn mockups theme themselves from --ui-* tokens; the hero window is an
   actual screenshot, so the page carries one of each and shows the right one.
   Not <picture> with a media query: that follows the operating system, and the
   site has its own light/dark switch that has to win. */


/* =========================================================================
   THE CONTENTS OF A WINDOW FILL IN
   The windows themselves floated in, but everything inside them was there from
   the first frame. Now the screen fills in: the tiles, the register rows, the
   gates, the lines of a document.

   They FADE and do not move. The window is already travelling — it floats up
   as it arrives — and translating its contents at the same time means every
   part is moving against a container that is itself moving. That reads as
   restless rather than smooth, and it is the reason the second animation was
   worth taking out rather than tuning. The movement belongs to the window; the
   filling-in belongs to what is in it, along with the bars growing and the
   figures counting, which are the parts that actually say "this is working".

   The step is the site's own ~0.06s, and the whole screen is one group, so a
   window taller than the viewport does not fill in halfway and stop.
   ========================================================================= */
.anim .uiwrap .uikpi,
.anim .uiwrap .uigate,
.anim .uiwrap .uibar-row,
.anim .uiwrap .uicrit>div,
.anim .uiwrap .uidoc .dr,
.anim .uiwrap .uidoc .dt,
.anim .uiwrap .uidoc .dsig>div,
.anim .uiwrap .uishot,
.anim .uiwrap .uitbl tbody tr{opacity:0;transition:opacity .45s var(--ease)}
.uiwrap.in .uikpi,
.uiwrap.in .uigate,
.uiwrap.in .uibar-row,
.uiwrap.in .uicrit>div,
.uiwrap.in .uidoc .dr,
.uiwrap.in .uidoc .dt,
.uiwrap.in .uidoc .dsig>div,
.uiwrap.in .uishot,
.uiwrap.in .uitbl tbody tr{opacity:1}

/* A bar grows as its own row appears. They all used to start together while
   the rows faded in one after another, so the bottom bar had finished before
   anything of that row was on screen — the two halves of the same movement
   running out of step, which is what reads as unsteady rather than slow. */
.uiwrap.in .uibar-row:nth-child(1) .uifill{transition-delay:.10s}
.uiwrap.in .uibar-row:nth-child(2) .uifill{transition-delay:.16s}
.uiwrap.in .uibar-row:nth-child(3) .uifill{transition-delay:.22s}
.uiwrap.in .uibar-row:nth-child(4) .uifill{transition-delay:.28s}
.uiwrap.in .uibar-row:nth-child(5) .uifill{transition-delay:.34s}
.uiwrap.in .uibar-row:nth-child(6) .uifill{transition-delay:.40s}
.uiwrap.in .uibar-row:nth-child(7) .uifill{transition-delay:.46s}
.uiwrap.in .uibar-row:nth-child(8) .uifill{transition-delay:.52s}

/* one after another, a row at a time */
.uiwrap.in .uikpi:nth-child(1),.uiwrap.in .uitbl tbody tr:nth-child(1),
.uiwrap.in .uigate:nth-child(1),.uiwrap.in .uibar-row:nth-child(1),
.uiwrap.in .uicrit>div:nth-child(2),.uiwrap.in .uidoc .dr:nth-child(1),
.uiwrap.in .uidoc .dt:nth-child(1),.uiwrap.in .uishot:nth-child(1){transition-delay:.10s}
.uiwrap.in .uikpi:nth-child(2),.uiwrap.in .uitbl tbody tr:nth-child(2),
.uiwrap.in .uigate:nth-child(2),.uiwrap.in .uibar-row:nth-child(2),
.uiwrap.in .uicrit>div:nth-child(3),.uiwrap.in .uidoc .dr:nth-child(2),
.uiwrap.in .uidoc .dt:nth-child(2),.uiwrap.in .uishot:nth-child(2){transition-delay:.16s}
.uiwrap.in .uikpi:nth-child(3),.uiwrap.in .uitbl tbody tr:nth-child(3),
.uiwrap.in .uigate:nth-child(3),.uiwrap.in .uibar-row:nth-child(3),
.uiwrap.in .uidoc .dr:nth-child(3),.uiwrap.in .uidoc .dt:nth-child(3){transition-delay:.22s}
.uiwrap.in .uikpi:nth-child(4),.uiwrap.in .uitbl tbody tr:nth-child(4),
.uiwrap.in .uigate:nth-child(4),.uiwrap.in .uibar-row:nth-child(4),
.uiwrap.in .uidoc .dr:nth-child(4),.uiwrap.in .uidoc .dt:nth-child(4){transition-delay:.28s}
.uiwrap.in .uikpi:nth-child(5),.uiwrap.in .uitbl tbody tr:nth-child(5),
.uiwrap.in .uibar-row:nth-child(5),.uiwrap.in .uidoc .dr:nth-child(5),
.uiwrap.in .uidoc .dt:nth-child(5){transition-delay:.34s}
.uiwrap.in .uikpi:nth-child(6),.uiwrap.in .uitbl tbody tr:nth-child(6),
.uiwrap.in .uibar-row:nth-child(6),.uiwrap.in .uidoc .dr:nth-child(6),
.uiwrap.in .uidoc .dt:nth-child(6){transition-delay:.40s}
.uiwrap.in .uikpi:nth-child(7),.uiwrap.in .uitbl tbody tr:nth-child(7),
.uiwrap.in .uibar-row:nth-child(7){transition-delay:.46s}
.uiwrap.in .uikpi:nth-child(8),.uiwrap.in .uibar-row:nth-child(8){transition-delay:.52s}

/* nothing hides if the visitor has asked for no motion, and nothing hides if
   the script never runs — a window must never be a blank rectangle */
@media (prefers-reduced-motion: reduce){
  .uiwrap .uikpi,.uiwrap .uitbl tbody tr,.uiwrap .uigate,
  .uiwrap .uibar-row,.uiwrap .uicrit>div,.uiwrap .uidoc .dr,.uiwrap .uidoc .dt,
  .uiwrap .uidoc .dsig>div,.uiwrap .uishot{opacity:1;transition:none}
}

/* ---------- the pricing page's header ----------
   The price, where the page's headline is, rather than a picture of the app
   two screens above the number the reader came for. It sits in the same slot
   the window would, so the header's shape is unchanged — but it is a panel,
   not a browser, so it takes none of the window chrome or the tilt. */
/* Every other header window holds a whole app screen, which is why that column
   is 810px wide. This one holds two prices and two lines, and at 810 it read as
   the biggest thing on the page — wider than the headline beside it — with the
   two cards floating in space. It gets a measure of its own.
   minmax(0,1fr) rather than a plain 1fr, which is minmax(auto,1fr) and would
   let the yearly card's longer line push past its share. The two cards do
   measure differently on screen — 266 against 277 — but that is the window
   being tilted in 3D and the far card projecting wider, not the grid: the
   columns themselves are 260 and 260. */
.priceArt{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:14px;
  max-width:580px;margin-left:auto;
  padding:22px;border-radius:18px;
  background:rgba(255,255,255,.045);border:1px solid rgba(255,255,255,.12);
  box-shadow:0 26px 64px -26px rgba(0,0,0,.6)}
.pcard{position:relative;padding:18px 16px 16px;border-radius:13px;
  background:rgba(255,255,255,.05);border:1px solid rgba(255,255,255,.12)}
.pcard.best{background:rgba(198,227,74,.12);border-color:rgba(198,227,74,.45)}
.pflag{position:absolute;top:-9px;right:12px;background:var(--lime);color:#12151a;
  font-size:10.5px;font-weight:800;letter-spacing:.04em;text-transform:uppercase;
  padding:3px 8px;border-radius:99px}
.pcard h4{margin:0;font-size:12px;font-weight:800;letter-spacing:.08em;
  text-transform:uppercase;color:rgba(255,255,255,.62)}
.pamt{font-size:38px;font-weight:800;letter-spacing:-.03em;line-height:1.05;
  margin-top:6px;color:#fff}
.pcard.best .pamt{color:var(--lime)}
.pper{font-size:13px;color:rgba(255,255,255,.66);margin-top:2px}
.pnote{font-size:12.5px;color:rgba(255,255,255,.5);margin-top:9px;
  padding-top:9px;border-top:1px solid rgba(255,255,255,.12)}
.pfoot{grid-column:1 / -1;display:flex;align-items:baseline;gap:10px;flex-wrap:wrap;
  padding-top:12px;border-top:1px solid rgba(255,255,255,.12)}
.pfoot b{font-size:15px;font-weight:800;color:#fff;letter-spacing:-.01em}
.pfoot span{font-size:13px;color:rgba(255,255,255,.62)}
.pfoot+.pfoot{padding-top:10px}
@media(max-width:620px){
  .priceArt{grid-template-columns:1fr;padding:18px;gap:12px}
  .pamt{font-size:32px}
}

/* ------------------------------------------------------------------ */
/* Templates — the free checklists and registers given away whole.     */
/* The table IS the page as far as a search engine is concerned, so it */
/* is real markup, not an image and not a download-only teaser.        */
/* ------------------------------------------------------------------ */
.tplScroll{overflow-x:auto;-webkit-overflow-scrolling:touch;margin:18px 0;
  border:1px solid var(--card-border);border-radius:14px;background:var(--card-bg)}
table.tpl{border-collapse:collapse;width:100%;min-width:700px;font-size:14px}
table.tpl caption{text-align:left;padding:14px 16px 0;color:var(--muted);font-size:13.5px}
table.tpl th{background:var(--ink,#12263a);color:#fff;text-align:left;font-weight:700;
  padding:10px 12px;font-size:12.5px;letter-spacing:.3px;text-transform:uppercase;
  white-space:nowrap}
table.tpl td{padding:10px 12px;border-top:1px solid var(--card-border);vertical-align:top;
  line-height:1.5;color:var(--text)}
table.tpl tbody tr:nth-child(even){background:rgba(127,127,127,.055)}
table.tpl td.num{width:48px;color:var(--muted);font-variant-numeric:tabular-nums}
table.tpl td.tag{white-space:nowrap;font-weight:700}
.tplNote{color:var(--muted);font-size:14px;margin:-6px 0 20px}

.dlRow{display:flex;flex-wrap:wrap;gap:12px;align-items:center;margin:22px 0 6px}
.dlBtn{display:inline-flex;align-items:center;gap:10px;padding:12px 18px;border-radius:12px;
  background:var(--lime);color:#12263a;font-weight:700;text-decoration:none;border:1px solid transparent}
.dlBtn:hover{filter:brightness(1.05)}
.dlBtn.alt{background:transparent;color:inherit;border-color:var(--card-border)}
.dlBtn svg{width:18px;height:18px;flex:none}
.dlMeta{color:var(--muted);font-size:13.5px}

.tplGrid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:18px}
@media(max-width:900px){.tplGrid{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media(max-width:620px){.tplGrid{grid-template-columns:1fr}}
@media print{.tplScroll{overflow:visible;border:0}table.tpl{min-width:0;font-size:10px}
  .dlRow,.nav,footer,.close{display:none!important}}
