/* ============================================================
   Flow Software, flowsoftware.ai
   The site's look: many streams meet and leave as one.
   One stylesheet, in layers:
     1. tokens          every colour, font family, spacing step and timing value
     2. fonts           self-hosted @font-face
     3. base            element defaults, focus, skip link
     4. layout          .container, sections
     5. components      header, hero, flow, cards, steps, pricing,
                        cta band, footer, buttons
     6. JS states       .js, .reveal, header states
     7. responsive      1024 / 768 / 640 / 480
     8. reduced motion
     9. print
   Colours are defined only in :root. Everything below refers to
   tokens, so a theme is a change of token values.
   ============================================================ */

/* ---------- 1. tokens ---------- */
:root{
  color-scheme:dark;

  /* ground and text: the family's ink-navy */
  --bg:#060913;
  --bg-alt:#0A0F1D;
  --surface:#0C1222;
  --surface-raised:#111A30;
  --line:rgba(148,178,255,.12);
  --line-strong:rgba(148,178,255,.24);
  --text:#F2F6FF;
  --muted:#8EA0C2;

  /* accent: warm gold, the colour the streams become */
  --accent:#F2CF86;
  --accent-ink:#060913;
  --accent-soft:rgba(242,207,134,.14);
  --accent-rail:rgba(242,207,134,.5);
  --accent-glow:rgba(242,207,134,.2);

  /* the API Flow and Call Flow colours: those two services' svc--
     modifiers only (card edges, list markers and product screens) */
  --stream-api:#4DA6FF;
  --stream-call:#34D9C4;

  /* the hero art's incoming streams: ink tones from the ground's own
     blue-grey family, never a service colour */
  --stream-ink-1:#AEBBD6;
  --stream-ink-2:#8A9CC0;
  --stream-ink-3:#6C7FA6;

  /* derived surfaces */
  --focus:var(--accent);
  --header-bg:rgba(6,9,19,.9);
  --selection:rgba(242,207,134,.32);
  --shadow:0 12px 32px rgba(2,4,10,.45);
  --shadow-hover:0 16px 40px rgba(2,4,10,.6);
  --mask-on:#000;
  --mask-off:transparent;

  /* type */
  --font-display:"Space Grotesk","Segoe UI Variable Display","Segoe UI",system-ui,sans-serif;
  --font-body:"Inter","Segoe UI Variable Text","Segoe UI",system-ui,sans-serif;
  --font-mono:"Space Mono",Consolas,"Liberation Mono",Menlo,monospace;

  /* shape */
  --radius:12px;
  --radius-lg:16px;

  /* spacing scale */
  --space-1:4px;
  --space-2:8px;
  --space-3:12px;
  --space-4:16px;
  --space-5:24px;
  --space-6:32px;
  --space-7:48px;
  --space-8:64px;
  --space-9:96px;
  --section-pad:clamp(72px,10vw,128px);

  /* layout */
  --container:1200px;
  --gutter:24px;
  --header-h:68px;
  --measure:38rem;  /* long-form reading width, about 72 characters */

  /* motion: UI settles fast on one curve; hovers resolve in 160ms */
  --ease:cubic-bezier(.2,.8,.2,1);
  --dur:420ms;
  --dur-fast:160ms;
  --rise:14px;
  --stagger:60ms;
}

/* ---------- 2. fonts ----------
   Inter and Space Grotesk ship as variable fonts, so each family is one
   file declared across its weight range. Space Mono is two static cuts. */
@font-face{font-family:"Space Grotesk";font-style:normal;font-weight:500 700;font-display:swap;src:url("../fonts/space-grotesk-500.woff2") format("woff2")}
@font-face{font-family:"Inter";font-style:normal;font-weight:400 600;font-display:swap;src:url("../fonts/inter-400.woff2") format("woff2")}
@font-face{font-family:"Space Mono";font-style:normal;font-weight:400;font-display:swap;src:url("../fonts/space-mono-400.woff2") format("woff2")}
@font-face{font-family:"Space Mono";font-style:normal;font-weight:700;font-display:swap;src:url("../fonts/space-mono-700.woff2") format("woff2")}

/* ---------- 3. base ---------- */
*,*::before,*::after{box-sizing:border-box}
[hidden]{display:none!important}
/* anchored and focused content scrolls to a stop below the sticky header */
html{-webkit-text-size-adjust:100%;text-size-adjust:100%;scroll-padding-top:calc(var(--header-h) + var(--space-4))}
body{
  margin:0;
  background:var(--bg);
  color:var(--text);
  font-family:var(--font-body);
  font-size:16px;
  line-height:1.65;
  -webkit-font-smoothing:antialiased;
  text-rendering:optimizeLegibility;
}
img,svg,canvas,video{display:block;max-width:100%}
a{color:var(--accent);text-decoration:none;text-underline-offset:3px}
a:hover{text-decoration:underline}
h1,h2,h3{
  font-family:var(--font-display);font-weight:700;line-height:1.1;
  letter-spacing:-.02em;margin:0 0 .5em;text-wrap:balance;
}
h1{font-size:clamp(38px,5.8vw,68px);letter-spacing:-.03em;line-height:1.04}
h2{font-size:clamp(30px,3.8vw,44px);letter-spacing:-.025em}
h3{font-size:clamp(18px,1.8vw,22px);line-height:1.2}
p{margin:0 0 1em}
ul,ol{margin:0;padding:0}
::selection{background:var(--selection);color:var(--text)}

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

.skip{
  position:absolute;left:var(--space-4);top:-100px;z-index:100;
  padding:var(--space-3) var(--space-4);border-radius:0 0 var(--radius) var(--radius);
  background:var(--accent);color:var(--accent-ink);
  font-family:var(--font-mono);font-size:13px;font-weight:700;text-decoration:none;
}
.skip:focus{top:0}

/* ---------- 4. layout ---------- */
.container{
  width:100%;max-width:var(--container);
  margin:0 auto;padding:0 var(--gutter);
}
.section{padding:var(--section-pad) 0;border-top:1px solid var(--line)}
.section--flow,.section--pricing{background:var(--bg-alt)}
.section__head{max-width:680px;margin-bottom:var(--space-8)}
.section__title{margin-bottom:var(--space-4)}
.section__lede{font-size:clamp(16.5px,1.6vw,18.5px);color:var(--muted);max-width:58ch;margin:0}
/* a closing link row under a section's content, such as "All services" */
.section__foot{margin-top:var(--space-6)}
/* an alternate-ground band on inner pages, such as a service's product screen */
.section--alt{background:var(--bg-alt)}

/* ---------- 5. components ---------- */

/* labels and small type: every eyebrow starts with a short gold rule */
.eyebrow{
  display:flex;align-items:center;gap:var(--space-3);
  font-family:var(--font-mono);font-size:12px;letter-spacing:.2em;text-transform:uppercase;
  color:var(--accent);margin:0 0 var(--space-4);
}
/* inside a service's svc-- scope (a service page's <main>) the rule takes
   that service's colour; everywhere else it stays gold */
.eyebrow::before{content:"";flex:none;width:24px;height:1px;background:var(--svc-accent,var(--accent))}
.tbd{
  font-family:var(--font-mono);font-size:.92em;color:var(--text);
  background:var(--accent-soft);border:1px dashed var(--accent);
  border-radius:4px;padding:0 .35em;white-space:nowrap;
}
/* a placeholder long enough to need more than one line: it wraps, and each
   line keeps the dashed frame */
.tbd--wrap{white-space:normal;-webkit-box-decoration-break:clone;box-decoration-break:clone}
.text-link{
  display:inline-flex;align-items:center;gap:var(--space-2);min-height:44px;
  font-family:var(--font-mono);font-size:13.5px;font-weight:700;color:var(--accent);
}
.text-link::after{content:"\2192";content:"\2192" / "";transition:transform var(--dur-fast) var(--ease)}
.text-link:hover::after{transform:translateX(3px)}

/* buttons: primary is a solid accent fill, secondary a bordered surface */
.actions{display:flex;flex-wrap:wrap;gap:var(--space-3);align-items:center}
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:var(--space-2);
  min-height:48px;padding:14px 26px;border-radius:var(--radius);border:1px solid transparent;
  font-family:var(--font-mono);font-size:13.5px;font-weight:700;letter-spacing:.01em;line-height:1.2;
  text-decoration:none;cursor:pointer;
  transition:background-color var(--dur-fast) var(--ease),border-color var(--dur-fast) var(--ease),
             box-shadow var(--dur-fast) var(--ease),transform var(--dur-fast) var(--ease);
}
.btn:hover{text-decoration:none}
.btn--primary{background:var(--accent);color:var(--accent-ink);box-shadow:var(--shadow)}
.btn--primary:hover{transform:translateY(-2px);box-shadow:var(--shadow-hover)}
.btn--secondary{background:var(--surface);color:var(--text);border-color:var(--line-strong)}
.btn--secondary:hover{border-color:var(--accent);background:var(--surface-raised)}

/* header */
.site-header{
  position:sticky;top:0;z-index:50;
  background:var(--header-bg);border-bottom:1px solid transparent;
  transition:border-color var(--dur-fast) var(--ease);
}
.site-header__inner{
  display:flex;align-items:center;justify-content:space-between;gap:var(--space-5);
  min-height:var(--header-h);
}
.brand{
  display:inline-flex;align-items:center;gap:var(--space-3);min-height:44px;
  color:var(--text);text-decoration:none;flex:none;
}
.brand:hover{text-decoration:none}
/* the logo mark, inlined from assets/brand/inline-mark.txt: ring and quiet
   stations take the text colour, the lit stretch and live station the accent */
.brand__mark{width:28px;height:28px;flex:none}
.brand__accent{color:var(--accent)}
.brand__name{font-family:var(--font-display);font-weight:700;font-size:19px;letter-spacing:-.02em;line-height:1}
.site-nav__list{display:flex;flex-wrap:wrap;align-items:center;gap:var(--space-1);list-style:none}
.site-nav__link{
  display:inline-flex;align-items:center;min-height:44px;padding:0 var(--space-3);border-radius:8px;
  font-family:var(--font-mono);font-size:13px;letter-spacing:.02em;color:var(--muted);text-decoration:none;
  transition:color var(--dur-fast) var(--ease);
}
.site-nav__link:hover,.site-nav__link[aria-current]{color:var(--text);text-decoration:none}

/* the menu button only appears on narrow screens once site.js is running */
.nav-toggle{
  display:none;align-items:center;gap:var(--space-2);min-height:44px;padding:0 var(--space-4);
  border:1px solid var(--line-strong);border-radius:var(--radius);background:var(--surface);
  color:var(--text);font-family:var(--font-mono);font-size:13px;cursor:pointer;
}
.nav-toggle__icon,.nav-toggle__icon::before,.nav-toggle__icon::after{
  display:block;width:16px;height:2px;border-radius:1px;background:currentColor;
  transition:transform var(--dur-fast) var(--ease),opacity var(--dur-fast) var(--ease);
}
.nav-toggle__icon{position:relative}
.nav-toggle__icon::before,.nav-toggle__icon::after{content:"";position:absolute;left:0}
.nav-toggle__icon::before{top:-5px}
.nav-toggle__icon::after{top:5px}

/* hero: copy on the left, the confluence on the right, a warm glow behind it */
.hero{position:relative;overflow:hidden;padding:clamp(64px,10vw,128px) 0 clamp(64px,9vw,112px)}
.hero::before{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:radial-gradient(52% 60% at 76% 50%,var(--accent-glow),transparent 72%);
}
.hero__inner{
  position:relative;
  display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);
  gap:var(--space-8);align-items:center;
}
.hero__copy{max-width:600px}
.hero__title{margin-bottom:var(--space-5)}
.hero__lede{font-size:clamp(17px,1.6vw,20px);color:var(--muted);max-width:54ch;margin-bottom:var(--space-6)}
/* the art slot: a borderless field the streams cross, a photographed
   ground underneath and the drawn streams on top */
.hero__art{
  position:relative;aspect-ratio:5 / 4;overflow:hidden;
  /* the field runs on to the right edge of the viewport: past the
     container's own gutter, then past the margin that centres it */
  margin-right:calc(-1 * (var(--gutter) + max(0px,(100vw - var(--container)) / 2)));
}
/* the photograph is screened onto the ground and fades out before its own
   edges, so only its light is seen, never its rectangle */
.hero__art .art-ground{
  position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:50% 50%;
  opacity:.85;mix-blend-mode:screen;
  -webkit-mask-image:radial-gradient(56% 56% at 50% 50%,var(--mask-on) 30%,var(--mask-off) 94%);
  mask-image:radial-gradient(56% 56% at 50% 50%,var(--mask-on) 30%,var(--mask-off) 94%);
}
/* the photographed ribbons that enter from the left are blue and teal, which
   would read as the two service colours. A colour-blend wash of
   the ground colour gives everything before the confluence the ground's own
   hue and low chroma, each pixel keeping its brightness: the ribbons turn to
   ink greys under the drawn blue-grey streams, and the navy ground, already
   that colour, is left as it is. It fades out at the confluence, so the gold
   ribbon keeps its colour, and beside the copy also towards the art's left,
   top and bottom edges, where the hero's warm glow crosses them, so it never
   shows as a box. It lies over the photograph and under the drawn streams
   (the canvas sits above it on z-index 1) */
.hero__art::after{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:var(--bg);mix-blend-mode:color;
  -webkit-mask-image:
    linear-gradient(90deg,var(--mask-off),var(--mask-on) 14%,var(--mask-on) 40%,var(--mask-off) 47%),
    linear-gradient(180deg,var(--mask-off),var(--mask-on) 18%,var(--mask-on) 82%,var(--mask-off));
  -webkit-mask-composite:source-in;
  mask-image:
    linear-gradient(90deg,var(--mask-off),var(--mask-on) 14%,var(--mask-on) 40%,var(--mask-off) 47%),
    linear-gradient(180deg,var(--mask-off),var(--mask-on) 18%,var(--mask-on) 82%,var(--mask-off));
  mask-composite:intersect;
}
/* beside the copy the field starts mid-page, so the drawn streams fade in
   from its left edge and the exit stream fades out before its right edge,
   the way the photograph beneath them does; strokes and packets alike */
.hero__art .art-canvas{
  position:absolute;inset:0;z-index:1;width:100%;height:100%;
  -webkit-mask-image:linear-gradient(90deg,var(--mask-off),var(--mask-on) 18%,var(--mask-on) 82%,var(--mask-off) 97%);
  mask-image:linear-gradient(90deg,var(--mask-off),var(--mask-on) 18%,var(--mask-on) 82%,var(--mask-off) 97%);
}

/* inner pages open with a page head instead of the hero: the eyebrow,
   the page's h1 and its lede under a quiet gold glow behind the title.
   Content that belongs to the h1 (the grid on the services hub) may
   follow inside it, so it closes with a full section's padding. The
   glow has a fixed size, so a tall head does not stretch it, and fades
   out before the top edge, so it never meets the header in a line */
.page-head{position:relative;overflow:hidden;isolation:isolate;padding:clamp(56px,8vw,104px) 0 var(--section-pad)}
.page-head::before{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:radial-gradient(640px 300px at 14% 240px,var(--accent-glow),transparent 72%);
}
.page-head > .container{position:relative}
.page-head .section__head{max-width:760px}
.page-head .section__head:last-child{margin-bottom:0}
.page-head .section__lede{font-size:clamp(17px,1.6vw,20px);max-width:60ch}
.page-head .actions{margin-top:var(--space-6)}
.page-head__title{margin-bottom:var(--space-5)}
/* a photograph behind an inner page head (the water channel on the pricing
   page), decorative and unlabelled. Beside the copy it fills the right of
   the head under the glow and fades out well before the text, so the copy
   keeps the plain ground behind it, and fades in from the top edge, so it
   never meets the header in a line; at 1024 and below it becomes a band
   under the copy that fades into the section's lower edge */
.page-head__backdrop{
  position:absolute;top:0;right:0;z-index:-1;width:min(50%,720px);height:100%;
  object-fit:cover;object-position:50% 50%;opacity:.8;pointer-events:none;
  -webkit-mask-image:
    radial-gradient(64% 58% at 62% 52%,var(--mask-on) 24%,var(--mask-off) 100%),
    linear-gradient(180deg,var(--mask-off),var(--mask-on) 22%);
  -webkit-mask-composite:source-in;
  mask-image:
    radial-gradient(64% 58% at 62% 52%,var(--mask-on) 24%,var(--mask-off) 100%),
    linear-gradient(180deg,var(--mask-off),var(--mask-on) 22%);
  mask-composite:intersect;
}

/* the flow: seven stages as nodes on one rail */
.flow{
  position:relative;list-style:none;
  display:grid;grid-template-columns:repeat(7,minmax(0,1fr));
  gap:var(--space-4);padding-top:var(--space-6);
}
.flow::before{
  content:"";position:absolute;left:0;right:0;top:0;height:1px;
  background:linear-gradient(90deg,var(--accent-rail),var(--accent-rail) 86%,var(--mask-off));
}
.flow__stage{position:relative;padding-right:var(--space-3)}
.flow__stage::before{
  content:"";position:absolute;left:0;top:calc(-1 * var(--space-6) - 4px);
  width:9px;height:9px;border-radius:50%;background:var(--accent);
  box-shadow:0 0 0 4px var(--accent-soft);
}
.flow__num{
  display:block;margin-bottom:var(--space-3);
  font-family:var(--font-mono);font-size:12px;letter-spacing:.12em;color:var(--accent);
}
.flow__name{font-size:20px;margin-bottom:var(--space-2)}
.flow__desc{font-size:14.5px;line-height:1.55;color:var(--muted);margin:0}

/* service cards: each service wears its own colour on the top edge and
   its markers, set by its svc-- modifier through --svc-accent; a card
   with no modifier falls back to the site gold */
.cards{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--space-5)}
.card{
  position:relative;display:flex;flex-direction:column;min-width:0;padding:var(--space-6);
  background:var(--surface);border:1px solid var(--line);border-radius:var(--radius-lg);overflow:hidden;
  transition:border-color var(--dur-fast) var(--ease),transform var(--dur-fast) var(--ease);
}
.card::before{content:"";position:absolute;left:0;right:0;top:0;height:2px;background:var(--svc-accent,var(--accent))}
/* only a card that holds a link lifts; a card with nothing to follow stays put */
.card:has(a):hover{border-color:var(--line-strong);transform:translateY(-2px)}
/* one modifier per service in content/services.json; a new service adds
   its colour token in :root and one line here. The stream tokens fall
   back to the accent so a variant without them still renders */
.svc--custom{--svc-accent:var(--accent)}
.svc--api-flow{--svc-accent:var(--stream-api,var(--accent))}
.svc--call-flow{--svc-accent:var(--stream-call,var(--accent))}
.card--engagement{
  border-color:var(--line-strong);
  background:linear-gradient(180deg,var(--accent-soft),var(--mask-off) 48%),var(--surface-raised);
}
.card__tag{
  font-family:var(--font-mono);font-size:11.5px;letter-spacing:.16em;text-transform:uppercase;
  color:var(--muted);margin:0 0 var(--space-3);
}
.card__title{font-size:clamp(22px,2vw,26px);margin-bottom:var(--space-3)}
.card__text{color:var(--muted);margin-bottom:var(--space-5)}
/* a card that ends on its text (the principles on the company page) keeps
   its bottom padding equal to its top */
.card__text:last-child{margin-bottom:0}
.card__list{list-style:none;display:grid;gap:var(--space-2);margin:0 0 var(--space-6)}
.card__list li{position:relative;padding-left:var(--space-5);font-size:15px;line-height:1.5}
.card__list li::before{
  content:"";position:absolute;left:0;top:.58em;width:7px;height:7px;border-radius:50%;background:var(--svc-accent,var(--accent));
}
/* the arrow is inline text joined to the last word by a no-break space,
   so a link that wraps keeps its arrow beside that word and never alone
   on a line; it nudges by relative offset, which inline boxes allow */
.card__link{
  margin-top:auto;align-self:flex-start;display:inline-block;min-height:44px;padding:11px 0;
  font-family:var(--font-mono);font-size:13.5px;font-weight:700;line-height:1.6;color:var(--accent);
}
.card__link::after{content:"\00a0\2192";content:"\00a0\2192" / "";position:relative;left:0;transition:left var(--dur-fast) var(--ease)}
.card__link:hover::after{left:3px}

/* engagement steps: a solid gold number on a rule with a gold lead-in */
.steps{list-style:none;display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--space-6)}
.step{position:relative;padding-top:var(--space-5);border-top:1px solid var(--line)}
.step::before{content:"";position:absolute;left:0;top:-1px;width:48px;height:1px;background:var(--accent)}
.step__num{
  display:inline-flex;align-items:center;justify-content:center;width:36px;height:36px;
  margin-bottom:var(--space-4);border-radius:50%;background:var(--accent);color:var(--accent-ink);
  font-family:var(--font-mono);font-size:13px;font-weight:700;
}
.step__title{margin-bottom:var(--space-3)}
.step__text{color:var(--muted);margin:0}

/* pricing promise: the three points sit on one panel, like a rate card */
.pricing{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.1fr);gap:var(--space-8);align-items:start}
.pricing .section__head{margin-bottom:0}
.pricing__body{
  padding:var(--space-2) var(--space-6) var(--space-5);
  background:var(--surface);border:1px solid var(--line);border-radius:var(--radius-lg);
}
.pricing__points{list-style:none;margin-bottom:var(--space-3)}
.pricing__points li{
  position:relative;padding:var(--space-4) 0 var(--space-4) var(--space-6);
  border-bottom:1px solid var(--line);
}
.pricing__points li:last-child{border-bottom:0}
.pricing__points li::before{
  content:"";position:absolute;left:0;top:calc(var(--space-4) + .55em);
  width:8px;height:8px;border-radius:50%;background:var(--svc-accent,var(--accent));
}

/* the contact details on the company page: one row per fact on the
   pricing panel, a small mono label beside its value; at 480 and below
   the label sits above the value */
.contact-list{margin:0 0 var(--space-3)}
.contact-list__item{
  display:grid;grid-template-columns:96px minmax(0,1fr);column-gap:var(--space-5);align-items:baseline;
  padding:var(--space-4) 0;border-bottom:1px solid var(--line);
}
.contact-list__item:last-child{border-bottom:0}
.contact-list__term{
  font-family:var(--font-mono);font-size:11.5px;letter-spacing:.16em;text-transform:uppercase;color:var(--muted);
}
.contact-list__detail{margin:0;min-width:0;color:var(--text);overflow-wrap:break-word}

/* a photograph in a quiet frame, such as the working-session room on the
   custom software page. Beside a section head it shares a .pricing grid,
   and a steps list after that grid keeps a section head's spacing */
.photo{margin:0;border:1px solid var(--line);border-radius:var(--radius-lg);overflow:hidden;background:var(--surface)}
.photo img{width:100%;height:auto}
.pricing + .steps{margin-top:var(--space-8)}

/* a product screen: an HTML panel on synthetic data, labelled "Sample data",
   in its service's colour through --svc-accent (the connections panel on
   services/api-flow.html). Each row is its own grid on the same columns as
   the header row; the header is aria-hidden, so every cell also carries a
   .screen__key, visually hidden on wide screens and shown as a small label
   when the rows stack at 768 and below */
.screen{margin:0}
.screen__panel{
  position:relative;overflow:hidden;
  background:var(--surface);border:1px solid var(--line);border-radius:var(--radius-lg);box-shadow:var(--shadow);
}
.screen__panel::before{content:"";position:absolute;left:0;right:0;top:0;height:2px;background:var(--svc-accent,var(--accent))}
.screen__bar{
  display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:var(--space-3);
  padding:var(--space-4) var(--space-5);background:var(--surface-raised);border-bottom:1px solid var(--line);
}
.screen__title{margin:0;font-family:var(--font-display);font-size:17px;font-weight:700;letter-spacing:-.01em;line-height:1.3}
.screen__label{
  margin:0;padding:2px var(--space-3);border:1px solid var(--svc-accent,var(--accent));border-radius:999px;
  font-family:var(--font-mono);font-size:11px;letter-spacing:.14em;text-transform:uppercase;line-height:1.6;
  color:var(--svc-accent,var(--accent));
}
.screen__head,.screen__row{
  display:grid;grid-template-columns:minmax(0,2.2fr) minmax(0,1.5fr) minmax(0,1fr) minmax(0,1fr);
  column-gap:var(--space-4);padding-left:var(--space-5);padding-right:var(--space-5);
}
.screen__head{
  padding-top:var(--space-3);padding-bottom:var(--space-3);border-bottom:1px solid var(--line);
  font-family:var(--font-mono);font-size:11px;letter-spacing:.12em;text-transform:uppercase;color:var(--muted);
}
.screen__rows{list-style:none}
.screen__row{
  position:relative;padding-top:var(--space-4);padding-bottom:var(--space-4);
  border-bottom:1px solid var(--line);font-size:15px;line-height:1.45;
}
.screen__row:last-child{border-bottom:0}
.screen__name{grid-column:1;grid-row:1;font-weight:600;color:var(--text)}
.screen__sub{grid-column:1;grid-row:2;margin-top:2px;font-size:13.5px;color:var(--muted)}
.screen__cell{grid-row:1 / span 2;align-self:center;color:var(--text)}
.screen__num{text-align:right;font-variant-numeric:tabular-nums}
.screen__status{display:flex;flex-wrap:wrap;align-items:center;column-gap:var(--space-3)}
.screen__dot{
  flex:none;width:8px;height:8px;border-radius:50%;background:var(--svc-accent,var(--accent));
  box-shadow:0 0 0 3px var(--line-strong);
  box-shadow:0 0 0 3px color-mix(in srgb,var(--svc-accent,var(--accent)) 26%,var(--mask-off));
}
.screen__note{
  flex-basis:100%;padding-left:calc(8px + var(--space-3));
  font-family:var(--font-mono);font-size:12.5px;line-height:1.6;color:var(--accent);
}
/* a row that needs attention takes the gold, apart from the service colour */
.screen__row--alert{background:var(--accent-soft)}
.screen__row--alert .screen__dot{background:var(--accent);box-shadow:0 0 0 3px var(--accent-glow)}
/* a dot with nothing to report yet ("None yet" on the call list): a ring
   in the service colour instead of a filled dot */
.screen__dot--empty{background:var(--mask-off);box-shadow:inset 0 0 0 1.5px var(--svc-accent,var(--accent))}
/* the row the user has open (services/call-flow.html): a tint of the
   service colour with that colour on its left edge, and a line of drawn
   outcome buttons under the row's values. The buttons are list items,
   not controls, since the screen is a picture on sample data */
.screen__row--open{
  background:var(--surface-raised);
  background:color-mix(in srgb,var(--svc-accent,var(--accent)) 7%,var(--surface));
  box-shadow:inset 3px 0 0 var(--svc-accent,var(--accent));
}
.screen__actions{
  grid-column:1 / -1;grid-row:3;
  display:flex;flex-wrap:wrap;align-items:center;gap:var(--space-2) var(--space-4);
  margin-top:var(--space-4);
}
.screen__actions ul{list-style:none;display:flex;flex-wrap:wrap;gap:var(--space-2)}
.screen__hint{
  font-family:var(--font-mono);font-size:11px;letter-spacing:.12em;text-transform:uppercase;
  line-height:1.6;color:var(--muted);
}
.screen__action{
  display:inline-flex;align-items:center;min-height:36px;padding:0 var(--space-4);
  background:var(--surface);border:1px solid var(--line-strong);border-radius:var(--radius);
  font-family:var(--font-mono);font-size:12.5px;font-weight:700;line-height:1.2;color:var(--text);
}
.screen__key{
  position:absolute;width:1px;height:1px;margin:-1px;padding:0;border:0;
  overflow:hidden;clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;
}
.screen__foot{
  margin:0;padding:var(--space-3) var(--space-5);background:var(--surface-raised);border-top:1px solid var(--line);
  font-family:var(--font-mono);font-size:12.5px;line-height:1.6;color:var(--muted);
}
.screen__caption{margin-top:var(--space-4);max-width:72ch;font-size:14.5px;line-height:1.6;color:var(--muted)}

/* the policy pages (legal/*.html, built by tools/legal_build.py from the
   drafts). A preview build opens on a dashed draft banner; the page head
   is shorter than other inner pages, since the document follows at once.
   Beside the text sits a sticky list of its sections; the text keeps a
   reading measure of about 72 characters. At 1024 and below the list
   becomes a panel above the text */
.draft-banner{background:var(--accent-soft);border-bottom:1px dashed var(--accent)}
.draft-banner__text{
  margin:0 auto;padding-top:var(--space-3);padding-bottom:var(--space-3);
  font-family:var(--font-mono);font-size:13px;line-height:1.6;color:var(--text);
}
.draft-banner__text strong{color:var(--accent)}
.page-head--compact{padding-bottom:var(--space-7)}
.page-head__meta{margin:0;font-family:var(--font-mono);font-size:13px;line-height:1.7;color:var(--muted)}
.legal{padding:var(--space-7) 0 var(--section-pad);border-top:1px solid var(--line)}
.legal__layout{
  display:grid;grid-template-columns:240px minmax(0,1fr);
  gap:var(--space-8);align-items:start;
}
.legal-toc{
  position:sticky;top:calc(var(--header-h) + var(--space-5));
  max-height:calc(100vh - var(--header-h) - var(--space-7));overflow-y:auto;
  scrollbar-width:thin;scrollbar-color:var(--line-strong) var(--mask-off);
}
.legal-toc__title{
  margin:0 0 var(--space-3);font-family:var(--font-mono);font-size:11.5px;font-weight:400;
  letter-spacing:.16em;line-height:1.6;text-transform:uppercase;color:var(--accent);
}
.legal-toc__list{list-style:none;border-left:1px solid var(--line)}
.legal-toc__list a{
  display:flex;gap:var(--space-2);margin-left:-1px;padding:5px 0 5px var(--space-4);
  border-left:1px solid var(--mask-off);font-size:14px;line-height:1.45;color:var(--muted);
  transition:color var(--dur-fast) var(--ease),border-color var(--dur-fast) var(--ease);
}
.legal-toc__list a:hover{color:var(--text);border-left-color:var(--accent);text-decoration:none}
/* the list scrolls on its own, which clips anything outside it: the focus
   ring is drawn just inside the link */
@media (min-width:1025px){.legal-toc__list a:focus-visible{outline-offset:-2px}}
.legal-toc__num{flex:none;min-width:2.3em;font-family:var(--font-mono);font-size:12px;line-height:1.7;color:var(--accent)}
.prose{
  min-width:0;max-width:var(--measure,38rem);
  font-size:17px;line-height:1.7;overflow-wrap:break-word;
}
/* the page's scroll padding already clears the header; this adds a little */
.prose h2,.prose h3{scroll-margin-top:var(--space-2)}
.prose h2{
  margin:var(--space-7) 0 var(--space-4);padding-top:var(--space-6);border-top:1px solid var(--line);
  font-size:clamp(22px,2.3vw,26px);line-height:1.25;letter-spacing:-.015em;
}
.prose > h2:first-child{margin-top:0;padding-top:0;border-top:0}
.prose h3{margin:var(--space-6) 0 var(--space-3);font-size:clamp(18px,1.7vw,20px);line-height:1.3;letter-spacing:-.01em}
.prose p,.prose ul,.prose ol{margin:0 0 1em}
.prose ul,.prose ol{padding-left:1.35em}
.prose ul{list-style:disc}
.prose ol{list-style:decimal}
.prose li{margin:.4em 0;padding-left:.25em}
.prose li::marker{color:var(--accent)}
.prose li > ul{margin:.4em 0 0;list-style:circle}
.prose strong{font-weight:600}
/* links in running text are underlined, since the gold alone sits too
   close to the text colour to mark them */
.prose a:not([class]){text-decoration:underline;text-decoration-color:var(--accent-rail);text-underline-offset:3px}
.prose a:not([class]):hover{text-decoration-color:var(--accent)}
/* an enumerated clause, "(a) ...": the letter hangs in the left margin */
.prose__clause{position:relative;padding-left:2.25em}
.prose__marker{position:absolute;left:0;top:0;color:var(--muted)}
.prose__foot{margin:var(--space-7) 0 0;padding-top:var(--space-5);border-top:1px solid var(--line)}
/* the policies index: four policy cards, two to a row */
.cards--two{grid-template-columns:repeat(2,minmax(0,1fr))}
.card__meta{margin:0 0 var(--space-5);font-family:var(--font-mono);font-size:12.5px;line-height:1.7;color:var(--muted)}

/* closing call to action: the gold stream arrives at the top of the band */
.cta-band{
  position:relative;overflow:hidden;
  padding:var(--section-pad) 0;border-top:1px solid var(--line);
  background:var(--bg-alt);text-align:center;
}
.cta-band::before{
  content:"";position:absolute;left:50%;top:0;width:min(760px,100%);height:100%;
  transform:translateX(-50%);pointer-events:none;
  background:radial-gradient(50% 58% at 50% 0%,var(--accent-glow),transparent 72%);
}
.cta-band::after{
  content:"";position:absolute;left:50%;top:-1px;width:160px;height:2px;
  transform:translateX(-50%);background:var(--accent);
}
.cta-band__inner{position:relative;display:flex;flex-direction:column;align-items:center}
.cta-band__title{max-width:22ch;margin-bottom:var(--space-4)}
.cta-band__text{color:var(--muted);max-width:52ch;margin-bottom:var(--space-6)}
.cta-band .actions{justify-content:center}
.cta-band__contact{
  margin:var(--space-5) 0 0;font-family:var(--font-mono);font-size:13px;color:var(--muted);
}

/* footer */
.site-footer{padding:var(--space-8) 0 var(--space-6);border-top:1px solid var(--line);background:var(--bg)}
.site-footer__grid{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,2.5fr);gap:var(--space-7)}
.site-footer__about{margin:var(--space-3) 0 0;max-width:34ch;font-size:14.5px;color:var(--muted)}
/* the link groups (Services, Applications, Company, Legal) share one row,
   one column each, however many groups the build script writes. Beside
   the brand the columns are as equal as the longest link in each allows,
   so no link wraps; under it (1024 and below) they are equal, and at 640
   and below they sit two by two */
.site-footer__nav{display:grid;grid-auto-flow:column;grid-auto-columns:minmax(max-content,1fr);gap:var(--space-5)}
.footer-group__title{
  font-family:var(--font-mono);font-size:11.5px;font-weight:400;letter-spacing:.16em;
  text-transform:uppercase;color:var(--accent);margin:0 0 var(--space-3);
}
.footer-group__list{list-style:none;display:grid;gap:var(--space-1)}
.footer-group__list a{
  display:inline-flex;align-items:center;min-height:36px;
  font-size:14.5px;color:var(--text);
}
/* the base lines stack: entity, location and contact, then the notices */
.site-footer__bottom{
  display:grid;gap:var(--space-2);
  margin-top:var(--space-7);padding-top:var(--space-5);border-top:1px solid var(--line);
}
.site-footer__legal{margin:0;font-family:var(--font-mono);font-size:12.5px;line-height:1.7;color:var(--muted)}

/* ---------- 6. JS states ----------
   site.js adds .js to <html>. Hidden starting states apply only then, so
   the page reads in full without scripts. */
.js .reveal{opacity:0}
.js .reveal.in{
  opacity:1;
  animation:reveal-rise var(--dur) var(--ease) var(--reveal-delay,0ms) backwards;
}
/* no end frame: once the rise finishes the element's own styles apply,
   so hover transitions on revealed cards keep working */
@keyframes reveal-rise{from{opacity:0;transform:translateY(var(--rise))}}

.site-header.is-scrolled{border-bottom-color:var(--line)}
.site-header.is-open .nav-toggle__icon{background:transparent}
.site-header.is-open .nav-toggle__icon::before{transform:translateY(5px) rotate(45deg)}
.site-header.is-open .nav-toggle__icon::after{transform:translateY(-5px) rotate(-45deg)}

/* ---------- 7. responsive ---------- */
@media (max-width:1024px){
  .hero{padding-bottom:0}
  .hero::before{background:radial-gradient(70% 40% at 50% 100%,var(--accent-glow),transparent 72%)}
  .hero__inner{grid-template-columns:minmax(0,1fr);gap:var(--space-7)}
  .hero__copy{max-width:640px}
  /* the art becomes a wide band under the copy, bleeding to both edges */
  .hero__art{
    aspect-ratio:21 / 9;
    margin:0 calc(-1 * var(--gutter));
  }
  .hero__art .art-ground{
    -webkit-mask-image:linear-gradient(180deg,var(--mask-off),var(--mask-on) 18%,var(--mask-on) 82%,var(--mask-off));
    mask-image:linear-gradient(180deg,var(--mask-off),var(--mask-on) 18%,var(--mask-on) 82%,var(--mask-off));
  }
  /* edge to edge, the streams enter and leave at the viewport's own edges */
  .hero__art .art-canvas{-webkit-mask-image:none;mask-image:none}
  /* and the photographed ribbons enter at full strength there, so the wash
     runs to the left edge. The warm glow rises from the band's foot, so the
     wash also fades out around the middle of the foot, below the ribbons,
     and never greys the glow into a seam */
  .hero__art::after{
    -webkit-mask-image:
      linear-gradient(90deg,var(--mask-on) 40%,var(--mask-off) 47%),
      radial-gradient(30% 45% at 50% 100%,var(--mask-off) 25%,var(--mask-on));
    -webkit-mask-composite:source-in;
    mask-image:
      linear-gradient(90deg,var(--mask-on) 40%,var(--mask-off) 47%),
      radial-gradient(30% 45% at 50% 100%,var(--mask-off) 25%,var(--mask-on));
    mask-composite:intersect;
  }

  /* the flow becomes a vertical rail with a node per stage */
  .flow{grid-template-columns:minmax(0,1fr);gap:var(--space-5);padding:0 0 0 var(--space-6);max-width:640px}
  .flow::before{
    left:4px;right:auto;top:6px;bottom:6px;width:1px;height:auto;
    background:linear-gradient(180deg,var(--accent-rail),var(--accent-rail) 86%,var(--mask-off));
  }
  .flow__stage{
    display:grid;grid-template-columns:auto minmax(0,1fr);column-gap:var(--space-4);
    align-items:baseline;padding:0;
  }
  .flow__stage::before{left:calc(-1 * var(--space-6));top:6px}
  .flow__num{grid-row:span 2;margin:0}
  .flow__name{margin-bottom:var(--space-1)}

  .cards{grid-template-columns:repeat(2,minmax(0,1fr))}
  .card--engagement{grid-column:1 / -1}
  /* an odd number of cards: the first runs full width and the rest pair up */
  .cards > .card:first-child:nth-last-child(odd){grid-column:1 / -1}

  .pricing{grid-template-columns:minmax(0,1fr);gap:var(--space-6)}
  /* the page-head photograph drops under the copy as a full-width band */
  .page-head__backdrop{
    position:relative;z-index:auto;width:100%;height:auto;aspect-ratio:2 / 1;max-height:360px;
    margin:var(--space-7) 0 calc(-1 * var(--section-pad));opacity:.85;
    -webkit-mask-image:linear-gradient(180deg,var(--mask-off),var(--mask-on) 26%,var(--mask-on) 62%,var(--mask-off));
    mask-image:linear-gradient(180deg,var(--mask-off),var(--mask-on) 26%,var(--mask-on) 62%,var(--mask-off));
  }
  /* stacked under its heading, a photograph runs full width in a wider crop */
  .photo img{aspect-ratio:16 / 9;object-fit:cover;object-position:50% 40%}
  /* a policy page runs in one column: its section list becomes a panel
     above the text, as wide as the text, in two columns */
  .legal__layout{grid-template-columns:minmax(0,1fr);gap:var(--space-7)}
  .legal-toc{
    position:static;max-height:none;overflow:visible;max-width:var(--measure,38rem);
    padding:var(--space-5);background:var(--surface);border:1px solid var(--line);border-radius:var(--radius-lg);
  }
  .legal-toc__list{columns:2;column-gap:var(--space-5);border-left:0}
  .legal-toc__list li{break-inside:avoid}
  .legal-toc__list a{margin-left:0;padding-left:0;border-left:0}
  .site-footer__grid{grid-template-columns:minmax(0,1fr);gap:var(--space-6)}
  .site-footer__nav{grid-auto-columns:minmax(0,1fr)}
}

@media (max-width:768px){
  :root{--header-h:60px}

  /* narrow header: brand plus menu button; the nav drops below as a panel */
  .js .nav-toggle{display:inline-flex}
  .js .site-nav{
    display:none;position:absolute;top:100%;left:0;right:0;
    background:var(--bg-alt);border-bottom:1px solid var(--line);
  }
  .js .site-header.is-open .site-nav{display:block}
  .js .site-nav__list{
    flex-direction:column;align-items:stretch;gap:0;
    max-width:var(--container);margin:0 auto;padding:var(--space-2) var(--gutter) var(--space-4);
  }
  /* each link fills its row, so the tap target, the focus ring and the
     divider all run the panel's full width */
  .js .site-nav__link{display:flex;min-height:48px;padding:0;font-size:14px;border-bottom:1px solid var(--line);border-radius:0}
  .js .site-nav__list li:last-child .site-nav__link{border-bottom:0}
  /* without scripts the links wrap under the brand instead, and the taller
     header scrolls away, so an anchor's heading never lands under it and
     needs no scroll padding */
  .site-header__inner{flex-wrap:wrap;row-gap:0}
  html:not(.js) .site-header{position:static}
  html:not(.js){scroll-padding-top:0}

  .hero__art{aspect-ratio:16 / 9}

  .cards{grid-template-columns:minmax(0,1fr)}
  /* steps read as a numbered list: the badge on the left, the text beside it */
  .steps{grid-template-columns:minmax(0,1fr);gap:var(--space-5)}
  .step{
    display:grid;grid-template-columns:36px minmax(0,1fr);column-gap:var(--space-4);
    align-items:start;
  }
  .step__num{grid-row:span 2;margin:0}
  .section__head{margin-bottom:var(--space-7)}
  .pricing + .steps{margin-top:var(--space-7)}

  /* a product screen's rows stack: name and status, the latest record,
     then each value under its own small label */
  .screen__head{display:none}
  .screen__row{grid-template-columns:minmax(0,1fr) minmax(0,1fr);row-gap:var(--space-1)}
  .screen__sub{grid-column:1 / -1;grid-row:2}
  .screen__cell{grid-column:1;grid-row:3;align-self:start;margin-top:var(--space-2)}
  .screen__num{grid-column:2}
  .screen__status{grid-column:2;grid-row:1;margin-top:0;justify-content:flex-end;text-align:right}
  .screen__note{padding-left:0}
  .screen__actions{grid-row:4;margin-top:var(--space-3)}
  .screen__key{
    position:static;display:block;width:auto;height:auto;margin:0;overflow:visible;
    clip:auto;clip-path:none;
    font-family:var(--font-mono);font-size:11px;letter-spacing:.12em;text-transform:uppercase;color:var(--muted);
  }
  /* the status label sits on its own line above the dot and word */
  .screen__status .screen__key{flex-basis:100%;text-align:right}
}

/* four link groups no longer fit one row: they sit two by two */
@media (max-width:640px){
  .site-footer__nav{grid-auto-flow:row;grid-template-columns:repeat(2,minmax(0,1fr))}
}

@media (max-width:480px){
  :root{--gutter:16px}
  .hero{padding-top:var(--space-8)}
  .hero__art{aspect-ratio:16 / 10}
  .card{padding:var(--space-5)}
  .pricing__body{padding:0 var(--space-5) var(--space-4)}
  .contact-list__item{grid-template-columns:minmax(0,1fr);row-gap:var(--space-1)}
  .screen__bar,.screen__row,.screen__foot{padding-left:var(--space-4);padding-right:var(--space-4)}
  .legal-toc{padding:var(--space-4) var(--space-5)}
  .legal-toc__list{columns:1}
  .prose{font-size:16px}
  .draft-banner__text{font-size:12.5px}
  .actions .btn{flex:1 1 auto}
  /* four buttons (the 404's ways back) sit two by two, so none is left
     alone on a row */
  .actions--grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr))}
  .brand__name{font-size:18px}
}

/* ---------- 8. reduced motion ----------
   No movement at all: reveals show in place, hovers change colour only.
   The hero art draws one still frame (see hero.js) and never runs. */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{
    animation-duration:.001ms!important;animation-iteration-count:1!important;
    animation-delay:0ms!important;transition-duration:.001ms!important;
    transition-delay:0ms!important;scroll-behavior:auto!important;
  }
  .js .reveal,.js .reveal.in{opacity:1;animation:none}
  .btn--primary:hover,.card:has(a):hover,.text-link:hover::after{transform:none}
  .card__link:hover::after{left:0}
}
@media (prefers-reduced-motion:no-preference){
  html{scroll-behavior:smooth}
}

/* ---------- 9. print ----------
   A printed or saved page (a policy, most often) comes out dark on white:
   the tokens turn light, and the header, menu, banner, contents list, call
   to action, art and buttons are left off the paper. */
@media print{
  :root{--bg:#fff;--bg-alt:#fff;--surface:#fff;--surface-raised:#fff;--text:#000;--muted:#333;--accent:#000;--accent-ink:#fff;--line:#bbb;--line-strong:#888;color-scheme:light}
  .skip,.site-header,.nav-toggle,.draft-banner,.legal-toc,.cta-band,.hero__art,.page-head__backdrop,.actions{display:none!important}
  .legal__layout{grid-template-columns:minmax(0,1fr)}
  .prose{max-width:none}
  .js .reveal{opacity:1;animation:none}
}
