/* ==========================================================================
   GoWise — go-wise.ai
   Visual authority: GoWise-presentation-design-system-v1.png; the hero follows
   the approved gradient-field concept, which supersedes A01-V03-HERO-BRIEF.md
   Copy authority:   planning/landing-page-rebuild/01-CONTENT-SPEC.md

   Two rules govern everything below.

   THE FIELD RULE.  Navy is where the system diagrams live — the thin strokes
   and the cyan/periwinkle/violet sequence only read on it. Reading sections
   are light. A diagram on paper, or a wall of body copy on navy, breaks both.

   THE TWO-RAMP RULE.  Brand hues do atmosphere and strokes on navy. Anything
   carrying text on a light ground uses a darkened derivative. Raw periwinkle
   under white text measures 3.4:1 and fails; --brand-ink measures 8.9:1.
   ========================================================================== */

@import url('https://fonts.googleapis.com/css2?family=Outfit:wght@400;500;600&display=swap');

/* --------------------------------------------------------------- tokens -- */

:root{
  /* frozen brand ---------------------------------------------------------- */
  --navy:#151342;
  --navy-2:#24205F;
  --navy-deep:#0E0C2B;
  --cy:#55C8F3;
  --pw:#7E82F4;
  --vi:#A97AF6;
  --vi-t:#C4A3FF;   /* violet lifted for text on a plate — 5.7:1 */
  --pw-t:#A6A9FA;   /* periwinkle lifted for text on a plate — 5.9:1 */
  --warm:#F7F6F2;
  --ice:#EEF4FF;

  /* grounds */
  --field:#FFFFFF;
  --field-2:#FAFAFB;

  /* ink on light — measured against #FFFFFF */
  --ink:#151342;      /* 16.4:1 */
  --ink-2:#4B4977;    /*  8.3:1 — body */
  --ink-3:#5E5C85;    /*  6.3:1 on white, 5.4:1 under the strong wash */
  --brand-ink:#3D39A8;/*  8.9:1 — eyebrows, links, numerals */

  /* ink on navy — measured against #151342 */
  --on-navy:#FFFFFF;   /* 17.7:1 */
  --on-navy-2:#C3C7EA; /* 10.7:1 */
  --on-navy-3:#A8ACD4; /*  8.0:1 on navy, 5.4:1 on the figure plate */

  /* rules */
  --rule:rgba(21,19,66,.10);
  --rule-2:rgba(21,19,66,.17);
  --rule-i:rgba(174,180,235,.17);
  --rule-i2:rgba(174,180,235,.32);

  /* Status ramp, two ramps like the ink. The context comparison is light, so
     its red and green labels take the paper-safe ramp, not the plate one. */
  --go:#1F7A55;   --care:#8A5A06;   --stop:#A62A21;    /* on paper */
  --go-i:#3FD69A; --care-i:#F0B840; --stop-i:#F2707A;  /* on a plate */

  /* the action gradient — lightest stop holds 4.8:1 with white text */
  --btn:linear-gradient(135deg,#6461E4 0%,#5450D6 52%,#443FBE 100%);
  --btn-shadow:0 10px 26px rgba(68,63,190,.26);
  --btn-shadow-lift:0 14px 32px rgba(68,63,190,.34);

  /* type ramp */
  --t-h1:clamp(2.4rem,5vw,3.3rem);
  --t-h2:clamp(1.85rem,3.3vw,2.6rem);
  --t-h3:1.3rem;
  --t-lead:clamp(1.06rem,1.5vw,1.19rem);
  --t-body:1.0625rem;
  --t-sm:.9375rem;
  --t-xs:.8125rem;

  /* motion — Corporate: no overshoot, ever */
  --quick:140ms;
  --std:260ms;
  --slow:420ms;
  --ease:cubic-bezier(.2,0,0,1);

  --shell:1200px;
  --gutter:clamp(20px,5vw,40px);
}

/* ---------------------------------------------------------------- reset -- */

*,*::before,*::after{ box-sizing:border-box; }

html{ -webkit-text-size-adjust:100%; scroll-behavior:smooth; }
@media (prefers-reduced-motion:reduce){ html{ scroll-behavior:auto; } }

body{
  margin:0;
  background:var(--field);
  color:var(--ink-2);
  font-family:"Outfit","Segoe UI",system-ui,-apple-system,sans-serif;
  font-size:var(--t-body);
  line-height:1.62;
  font-weight:400;
  -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
}

img,svg{ max-width:100%; }
img{ height:auto; display:block; }

h1,h2,h3,h4{
  margin:0;
  color:var(--ink);
  font-weight:600;
  line-height:1.14;
  letter-spacing:-.018em;
  text-wrap:balance;
}
h1{ font-size:var(--t-h1); line-height:1.06; letter-spacing:-.03em; }
h2{ font-size:var(--t-h2); }
h3{ font-size:var(--t-h3); letter-spacing:-.012em; line-height:1.3; }

p{ margin:0 0 1.05em; }
p:last-child{ margin-bottom:0; }

a{ color:var(--brand-ink); text-decoration-thickness:1px; text-underline-offset:3px; }

ul{ margin:0; padding:0; list-style:none; }

/* An optional break. Three sentences on the page used to start in the last
   few characters of a line, which reads as a stray word; these put them on a
   line of their own where there is room, and vanish where the column is
   narrow enough to reflow them anyway. Added 2026-09-24. */
.brk{ display:inline; }
/* ~~display:none below 1000px~~ since 2026-09-25, at the user's request, the
   break applies at every width: a new sentence inside a paragraph starts on a
   line of its own, so none begins in the last few characters of a line. */

.sr{
  position:absolute; width:1px; height:1px; padding:0; margin:-1px;
  overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; border:0;
}

:focus-visible{
  outline:2px solid var(--brand-ink);
  outline-offset:3px;
  border-radius:4px;
}
.plate :focus-visible{ outline-color:var(--cy); }

/* --------------------------------------------------------------- layout -- */

.wrap{
  width:100%;
  max-width:var(--shell);
  margin-inline:auto;
  padding-inline:var(--gutter);
}

section{ position:relative; }

/* A light reading section. One faint wash, assigned hue, nothing stacked.
   Cap is 0.13 alpha at 460px+ radius — above that it stops reading as tinted
   paper and starts reading as a glow orb, which is the failure this avoids. */
.light{
  background:var(--field);
  padding-block:clamp(72px,9vw,124px);
  isolation:isolate;
}
.light > *{ position:relative; z-index:1; }

.light::before{
  content:"";
  position:absolute; inset:0;
  pointer-events:none; z-index:0;
  background:
    radial-gradient(58% 70% at 84% 8%,  var(--wash-a), transparent 68%),
    radial-gradient(52% 64% at 10% 88%, var(--wash-b), transparent 70%);
}
[data-hue="cy"]{ --wash-a:rgba(85,200,243,.13);  --wash-b:rgba(126,130,244,.08); --hue:85,200,243; }
[data-hue="pw"]{ --wash-a:rgba(126,130,244,.13); --wash-b:rgba(169,122,246,.08); --hue:126,130,244; }
[data-hue="vi"]{ --wash-a:rgba(169,122,246,.12); --wash-b:rgba(85,200,243,.08);  --hue:169,122,246; }
/* ~~[data-hue="warm"] — a cream wash at .55, four times the alpha of every
   other hue.~~ **Removed 2026-09-24 at the user's request:** it read as gold
   across the whole top of Why GoWise. That section now takes `pw` like the
   rest, and no section carries a warm wash. */

/* A navy plate. Its own field — diagrams and the hero live here. */
.plate{
  background:var(--navy);
  color:var(--on-navy-2);
  padding-block:clamp(72px,9vw,124px);
  isolation:isolate;
  --hue:85,200,243;
}
.plate > *{ position:relative; z-index:1; }
.plate h1,.plate h2,.plate h3{ color:var(--on-navy); }
.plate::before{
  content:"";
  position:absolute; inset:0;
  pointer-events:none; z-index:0;
  background:
    radial-gradient(64% 74% at 78% 6%,  rgba(85,200,243,.13), transparent 68%),
    radial-gradient(58% 66% at 6% 92%,  rgba(126,130,244,.16), transparent 70%);
}

/* ---------------------------------------------------- the pointer wash ----

   One soft field that follows the pointer and, crucially, LAGS it — the JS
   lerps toward the cursor at ~0.1/frame so the light trails and settles.
   Locked to the pointer it reads as a template component; trailing, it reads
   as material. Hover-capable pointers only; never on touch.                */

.glow{
  position:absolute; inset:0;
  pointer-events:none; z-index:0;
  opacity:0;
  transition:opacity var(--slow) var(--ease);
  /* two stops: a small core gives the light a centre, the wide field gives it
     reach. One radial alone reads either flat or blobby. */
  background:
    radial-gradient(230px circle at var(--px,50%) var(--py,50%),
      rgba(var(--hue),var(--glow-core,.05)), transparent 72%),
    radial-gradient(480px circle at var(--px,50%) var(--py,50%),
      rgba(var(--hue),var(--glow-a,.10)), transparent 68%);
}
.plate .glow{ --glow-a:.15; --glow-core:.08; }


@media (hover:hover) and (pointer:fine){
  .is-lit > .glow{ opacity:1; }
}
@media (prefers-reduced-motion:reduce){
  .glow{ display:none; }
}

/* ----------------------------------------------------------- primitives -- */

/* Eyebrow — flanked rule, never a floating chip. Enlarged 2026-09-15 at the
   user's request (13px read as a caption): 15px on phones rising to 17px on
   desktop, with the tracking eased a touch so the longer ones stay compact. */
.eyebrow{
  display:flex; align-items:center; gap:16px;
  margin:0 0 20px;
  /* 15–17px until 2026-09-24, when the user asked every eyebrow up a size. */
  font-size:clamp(1.0625rem, .84rem + .5vw, 1.1875rem);
  font-weight:600;
  letter-spacing:.18em;
  text-wrap:balance;          /* a two-line eyebrow splits evenly, no orphan */
  text-transform:uppercase;
  color:var(--brand-ink);
}
.eyebrow::after{
  content:""; flex:1 1 auto; max-width:92px; height:2px; border-radius:2px;
  background:linear-gradient(90deg,currentColor,transparent);
  opacity:.5;
}
.plate .eyebrow{ color:var(--cy); }
/* Lifted cyan for the hero only. Raw --cy measures 6.2:1 on flat navy, but the
   bloom lifts the ground beneath this line and it fell to 3.13:1 — measured,
   not assumed. Same reasoning that produced --pw-t and --vi-t. */
.hero .eyebrow{
  color:#8FDCFA;
  /* Larger than the section eyebrows below: this one opens the page. Raised
     with them 2026-09-15 (16px → 19px, was 14–15.5px) so it stays a step
     above; the phone tracking below keeps it on one line at 360. */
  font-size:clamp(1rem, .8rem + .5vw, 1.1875rem);
}
.eyebrow--mid{ justify-content:center; }
.eyebrow--mid::before{
  content:""; flex:1 1 auto; max-width:92px; height:2px; border-radius:2px;
  background:linear-gradient(90deg,transparent,currentColor);
  opacity:.5;
}

/* Action */
.btn{
  display:inline-flex; align-items:center; justify-content:center; gap:10px;
  min-height:52px; padding:0 34px;
  border:0; border-radius:999px;
  background-image:var(--btn);
  color:#fff;
  font:inherit; font-size:1.0625rem; font-weight:500;
  letter-spacing:-.005em;
  text-decoration:none; cursor:pointer;
  box-shadow:var(--btn-shadow);
  transition:transform var(--std) var(--ease), box-shadow var(--std) var(--ease);
}
.btn:hover{ transform:translateY(-1px); box-shadow:var(--btn-shadow-lift); }
.btn:active{ transform:translateY(0); }
.btn svg{ width:17px; height:17px; flex:none; transition:transform var(--std) var(--ease); }
.btn:hover svg{ transform:translateX(3px); }
.btn--sm{ min-height:44px; padding:0 24px; font-size:var(--t-sm); }
.nav .btn{ flex:none; }

/* Ghost — an underlined text action, per the hero concept */
.ghost{
  display:inline-flex; align-items:center; gap:8px;
  min-height:44px; padding:6px 2px;
  color:var(--ink);
  font-weight:500; font-size:1.0625rem;
  text-decoration:none;
  border-bottom:1px solid var(--rule-2);
  transition:border-color var(--std) var(--ease), color var(--std) var(--ease);
}
.ghost:hover{ border-color:var(--brand-ink); color:var(--brand-ink); }
.ghost svg{ width:14px; height:14px; transition:transform var(--std) var(--ease); }
.ghost:hover svg{ transform:translateX(3px); }
.plate .ghost{ color:var(--on-navy); border-color:var(--rule-i2); }
.plate .ghost:hover{ color:var(--cy); border-color:var(--cy); }

/* Section head */
.head{ max-width:56ch; margin-bottom:clamp(38px,4.5vw,60px); }
.head--mid{ margin-inline:auto; text-align:center; }
.head--mid .eyebrow{ justify-content:center; }
.head--mid .eyebrow::before{
  content:""; flex:1 1 auto; max-width:92px; height:2px; border-radius:2px;
  background:linear-gradient(90deg,transparent,currentColor); opacity:.5;
}
.lede{
  margin-top:18px;
  font-size:var(--t-lead);
  color:var(--ink-2);
  max-width:60ch;
}
.plate .lede{ color:var(--on-navy-2); }

/* ------------------------------------------------------------------ nav -- */

.nav{
  position:sticky; top:0; z-index:60;
  background:rgba(21,19,66,.86);
  backdrop-filter:blur(14px) saturate(140%);
  -webkit-backdrop-filter:blur(14px) saturate(140%);
  border-bottom:1px solid transparent;
  transition:border-color var(--std) var(--ease), background var(--std) var(--ease);
}
.nav.is-stuck{ border-bottom-color:var(--rule-i); background:rgba(21,19,66,.94); }
.nav__in{
  display:flex; align-items:center; gap:24px;
  min-height:72px;
}
.mark{
  display:block; flex:none;
  width:132px; height:29px;
  /* Twice the mark's width and symmetrical, so sliding it end to end runs the
     colours through the letterforms and back without a seam. At rest the left
     half is showing: violet on "Go", cyan on "ise", as the logo file reads. */
  background-image:linear-gradient(102deg,
    var(--vi) 0%, var(--pw) 25%, var(--cy) 50%, var(--pw) 75%, var(--vi) 100%);
  background-size:200% 100%;
  background-position:0% 50%;
  -webkit-mask:url(../img/wordmark-trim.png) no-repeat center/contain;
  mask:url(../img/wordmark-trim.png) no-repeat center/contain;
}
a.mark{
  text-decoration:none;
  height:44px;                          /* hit area, not glyph height */
  -webkit-mask-size:132px 29px; mask-size:132px 29px;
  transition:background-position 640ms var(--ease);
}
/* The colours travel through the wordmark and settle mirrored. No overlay, no
   flash — the gradient itself moves. An earlier white sheen swept across the
   glyphs instead and read as a hard glint; this is the quieter thing. */
a.mark:hover,
a.mark:focus-visible{ background-position:100% 50%; }

.nav__links{
  display:flex; align-items:center; gap:30px;
  margin-left:auto;
}
.nav__links a:not(.btn){
  color:var(--on-navy-2);
  font-size:var(--t-sm); font-weight:500;
  text-decoration:none;
  padding:6px 0;
  position:relative;
  transition:color var(--std) var(--ease);
}
.nav__links a:not(.btn)::after{
  content:""; position:absolute; left:0; right:0; bottom:0;
  height:1px; background:var(--cy);
  transform:scaleX(0); transform-origin:left;
  transition:transform var(--std) var(--ease);
}
.nav__links a:not(.btn):hover{ color:var(--on-navy); }
.nav__links a:not(.btn):hover::after{ transform:scaleX(1); }
/* the page you are on (the Selected work page): full ink, underline held */
.nav__links a[aria-current="page"]:not(.btn){ color:var(--on-navy); }
.nav__links a[aria-current="page"]:not(.btn)::after{ transform:scaleX(1); }

.burger{
  display:none;
  margin-left:auto;
  width:44px; height:44px;
  padding:0; border:1px solid var(--rule-i2); border-radius:10px;
  background:transparent; color:var(--on-navy);
  cursor:pointer;
  align-items:center; justify-content:center;
}
.burger svg{ width:20px; height:20px; }
.burger .x{ display:none; }
.burger[aria-expanded="true"] .m{ display:none; }
.burger[aria-expanded="true"] .x{ display:block; }

/* ----------------------------------------------------------------- hero -- */

/* Centred, full-bleed, ambient. The earlier split layout spent its right half
   trying to fill a column that did not need to exist; centring deletes the
   problem instead of decorating around it, and a centred stack shrinks under
   breakpoints where a split layout has to be recomposed at each one. */
.plate.hero{
  background:
    radial-gradient(120% 92% at 50% 38%, #17153F 0%, #100E2F 62%, #0C0A24 100%);
}
.hero{
  position:relative;
  overflow:hidden;                    /* the field is full-bleed; clip it */
  display:flex; flex-direction:column;
  padding-block:clamp(44px,5vw,72px) clamp(26px,3vw,40px);
  text-align:center;
}
.hero__in{
  flex:1 1 auto;
  display:grid;
  grid-template-rows:1fr auto auto;   /* copy floats in the free space */
}

@media (min-width:1001px){
  /* svh, not vh: a mobile browser's dynamic toolbar makes vh overshoot.
     Capped so a very tall monitor cannot strand the anchors off-screen. */
  .hero{ min-height:min(900px, calc(100svh - 72px)); }
}

.hero__copy{ align-self:center; max-width:900px; margin-inline:auto; position:relative; }
.hero h1{
  margin-bottom:22px;
  font-size:clamp(2.45rem,4.9vw,4.4rem);
}
.hero .lede{ margin-top:0; margin-inline:auto; max-width:54ch; }
.acts{
  display:flex; flex-wrap:wrap; align-items:center; justify-content:center;
  gap:14px 26px; margin-top:36px;
}

/* The two-line composition, without a hard break. Block-level AND
   non-wrapping above 1180px: nowrap alone would still let both clauses share
   a line on a very wide viewport, and display:block alone would still allow
   the second clause to wrap internally. Together they guarantee exactly two
   lines. Below the breakpoint both properties are handed back. */
.hero h1 .hl{ display:inline; white-space:normal; }
/* 1001, not 1180: between the two the headline had room to run as a single
   forty-character line, which is the same failure the tablet cap fixes lower
   down. Aligning the breakpoint with the desktop layout closes the gap, and
   the longer clause still only needs ~590px at this size, so nowrap is safe. */
@media (min-width:1001px){
  .hero h1 .hl{ display:block; white-space:nowrap; }
}

/* -------------------------------------------------------- hero field ----

   `.plate > *` sets position:relative/z-index:1 on every child, so the rules
   below are written at (0,2,0) to outrank it rather than relying on source
   order — the same specificity trap recorded in DESIGN.md.
   ---------------------------------------------------------------------- */

.hero .glow{ z-index:1; }
.hero .hf{
  position:absolute; inset:0; z-index:0;
  pointer-events:none;                /* never captures or blocks a click */
  overflow:hidden;
  --hx:0; --hy:0;                     /* eased pointer, -1..1, written by JS */
}

/* The shared .plate wash is tuned for a plate carrying a diagram. The hero
   ground wants to be deeper so the bloom reads as the light source. Scoped to
   .hero — #contact keeps the plate wash unchanged. */
.hero::before{ background:none; }   /* the bloom is the only light source */

/* ---- the bloom ----------------------------------------------------------

   Radial gradients, not blurred circles. A radial gradient is already soft,
   so there is no filter to re-rasterise on every frame and each blob animates
   on transform alone. Blurring solid circles — which is how this pattern is
   usually built — is precisely what makes it expensive.

   Cycle lengths are co-prime (23/29/31/37/41s) so the five never resync and
   the field has no visible loop.                                          */

.hf__bloom{ position:absolute; inset:0; }
.hf__b{
  position:absolute;
  border-radius:50%;
  mix-blend-mode:plus-lighter;
  will-change:transform;
}
.hf__b--1{
  width:40vw; height:40vw; left:24%; top:58%; margin:-20vw 0 0 -20vw;
  background:radial-gradient(circle, rgba(85,200,243,.26) 0%, rgba(85,200,243,0) 62%);
  animation:hf-d1 23s ease-in-out infinite;
}
.hf__b--2{                            /* the main bloom, behind the headline */
  width:52vw; height:52vw; left:52%; top:40%; margin:-26vw 0 0 -26vw;
  background:radial-gradient(circle, rgba(126,130,244,.30) 0%, rgba(126,130,244,0) 62%);
  animation:hf-d2 29s ease-in-out infinite;
}
.hf__b--3{
  width:44vw; height:44vw; left:68%; top:56%; margin:-22vw 0 0 -22vw;
  background:radial-gradient(circle, rgba(169,122,246,.28) 0%, rgba(169,122,246,0) 62%);
  animation:hf-d3 31s ease-in-out infinite;
}
.hf__b--4{
  width:30vw; height:30vw; left:82%; top:22%; margin:-15vw 0 0 -15vw;
  background:radial-gradient(circle, rgba(196,163,255,.16) 0%, rgba(196,163,255,0) 64%);
  animation:hf-d4 37s ease-in-out infinite;
}
.hf__b--5{
  width:34vw; height:34vw; left:16%; top:72%; margin:-17vw 0 0 -17vw;
  background:radial-gradient(circle, rgba(85,200,243,.14) 0%, rgba(85,200,243,0) 64%);
  animation:hf-d5 41s ease-in-out infinite;
}
/* the sixth follows the pointer, lagging — JS writes --bx/--by */
.hf__b--ptr{
  width:32vw; height:32vw; left:0; top:0; margin:-16vw 0 0 -16vw;
  background:radial-gradient(circle, rgba(126,130,244,.20) 0%, rgba(85,200,243,.09) 40%, rgba(85,200,243,0) 66%);
  transform:translate3d(var(--bx,50vw), var(--by,45vh), 0);
  opacity:0; transition:opacity var(--slow) var(--ease);
}
.hf.is-near .hf__b--ptr{ opacity:1; }

@keyframes hf-d1{ 0%,100%{transform:translate3d(0,0,0)} 33%{transform:translate3d(7vw,5vh,0)} 66%{transform:translate3d(-4vw,-3vh,0)} }
@keyframes hf-d2{ 0%,100%{transform:translate3d(0,0,0)} 30%{transform:translate3d(-6vw,4vh,0)} 70%{transform:translate3d(5vw,-5vh,0)} }
@keyframes hf-d3{ 0%,100%{transform:translate3d(0,0,0)} 40%{transform:translate3d(6vw,-6vh,0)} 75%{transform:translate3d(-5vw,3vh,0)} }
@keyframes hf-d4{ 0%,100%{transform:translate3d(0,0,0)} 45%{transform:translate3d(-8vw,-4vh,0)} 80%{transform:translate3d(4vw,6vh,0)} }
@keyframes hf-d5{ 0%,100%{transform:translate3d(0,0,0)} 35%{transform:translate3d(5vw,-5vh,0)} 72%{transform:translate3d(-6vw,4vh,0)} }

/* ---- the particle field -------------------------------------------------
   Brand ramp only. The container carries one very slow drift; individual
   stars twinkle on opacity (which cannot fight the transform) and take their
   pointer offset from JS. Delete .hf__stars from the markup to remove them —
   nothing else depends on it.                                             */

.hf__stars{
  position:absolute; inset:0;
  animation:hf-stars 90s ease-in-out infinite;
}
@keyframes hf-stars{ 0%,100%{transform:translate3d(0,0,0)} 50%{transform:translate3d(-2.5vw,1.6vh,0)} }

.hf__s{
  position:absolute; left:var(--x); top:var(--y);
  /* Diameter halved 2026-09-12 at the user's request, then raised 20% the same
     day (x.6 of the original): finer points, same field. */
  width:calc(var(--s) * .6); height:calc(var(--s) * .6);
  border-radius:50%;
  /* Brightened 2026-09-12 at the user's request: each hue lifted toward
     white, opacity raised by about a third, and a faint halo sized to the
     star, so the field reads on the navy rather than hiding in it. */
  --oo:min(1, calc(var(--o) * 1.3 + .1));
  background:var(--c);
  background:color-mix(in srgb, var(--c) 72%, #fff);
  box-shadow:0 0 calc(var(--s) * .96) color-mix(in srgb, var(--c) 55%, transparent);
  opacity:var(--oo);
  transform:translate3d(var(--sx,0px), var(--sy,0px), 0);
  animation:hf-tw var(--t) ease-in-out var(--dl) infinite;
}
/* Rests at full opacity, dips in the middle. The global reduced-motion rule
   collapses every animation to its final keyframe, so 100% has to be the
   state we actually want to see — the inverse landed on the dim end. */
@keyframes hf-tw{ 0%,100%{ opacity:var(--oo); } 50%{ opacity:calc(var(--oo) * .42); } }

/* ---- the pointer layer --------------------------------------------------
   Two parts, at different lags: a small gradient dot that leads and stays
   close to the cursor, and a soft glow that trails behind it. The native
   cursor is never hidden — replacing it breaks affordances on links and form
   fields for the sake of a flourish.                                      */

.hf__spark{
  position:absolute; top:0; left:0;
  width:540px; height:540px; margin:-270px 0 0 -270px;
  border-radius:50%;
  /* Halved three times from .30/.18/.09. At this level the wash is at the
     edge of what a display can resolve over the bloom — see the measured
     contribution in the handoff. The dot carries the pointer now. */
  background:radial-gradient(circle,
    rgba(200,225,255,.037) 0%, rgba(150,150,255,.022) 26%,
    rgba(126,130,244,.011) 48%, rgba(85,200,243,0) 70%);
  mix-blend-mode:plus-lighter;
  opacity:0; transition:opacity var(--slow) var(--ease);
  will-change:transform;
}
.hf.is-near .hf__spark{ opacity:1; }

/* ------------------------------------------------------ the cursor dot --

   Page-wide, not hero-scoped. Fixed positioning means it reads viewport
   coordinates straight from the pointer event with no scroll compensation,
   and it sits above the sticky nav, because a cursor ornament that slides
   under the header reads as a bug.

   It carries the brand ramp, so it stays legible on the navy plates and on
   the light reading sections alike. Never captures a click.               */

.cursor-dot{
  position:fixed; top:0; left:0; z-index:9999;
  width:11px; height:11px; margin:-5.5px 0 0 -5.5px;
  border-radius:50%;
  background:linear-gradient(140deg, var(--cy), var(--pw) 52%, var(--vi));
  box-shadow:0 0 12px 3px rgba(126,130,244,.38);
  pointer-events:none;
  opacity:0; transition:opacity var(--std) var(--ease);
  will-change:transform;
}
.cursor-dot.is-on{ opacity:1; }
@media (hover:none),(pointer:coarse){ .cursor-dot{ display:none; } }
@media (prefers-reduced-motion:reduce){ .cursor-dot{ display:none; } }

/* The copy's ground. A soft radial lift under the text block and a firm foot
   under the anchors, so neither ever sits on a bloom peak. */
.hf__scrim{
  position:absolute; inset:0;
  background:
    linear-gradient(180deg, rgba(12,10,36,.74) 0%, rgba(12,10,36,0) 30%),
    radial-gradient(58% 42% at 50% 42%, rgba(12,10,36,.56) 0%, rgba(12,10,36,0) 74%),
    radial-gradient(120% 100% at 50% 45%, rgba(12,10,36,0) 44%, rgba(12,10,36,.72) 100%),
    linear-gradient(0deg, #0C0A24 0%, #0C0A24 5%, rgba(12,10,36,.85) 15%, rgba(12,10,36,0) 34%);
}

/* --------------------------------------------------- capability anchors --

   A plain ordered list. Non-interactive by decision: no pointer cursor, no
   lift, no hover state — nothing may suggest these are clickable. Numerals
   are large enough for the 3:1 large-text floor, and every gradient stop uses
   a lifted derivative (--pw-t, --vi-t) rather than raw brand hex, per the
   two-ramp rule.
   -------------------------------------------------------------------- */

.caps{
  display:grid;
  /* The middle label is the longest, so its column takes a little more room
     (2026-09-15, user request) and fits on one line from about 940px. The
     outer anchors each give up ~28px, so they sit slightly further out. */
  grid-template-columns:minmax(0,1fr) minmax(0,1.25fr) minmax(0,1fr);
  gap:0;
  margin:0; padding:clamp(26px,3.4vw,44px) 0 0;
  border-top:1px solid var(--rule-i);
  list-style:none;
}
.caps__i{
  display:flex; align-items:center; justify-content:center;
  gap:clamp(10px,1.1vw,16px);
  padding:clamp(4px,1vw,12px) clamp(12px,1.6vw,24px);
  text-align:left;
}
.caps__i + .caps__i{ border-left:1px solid var(--rule-i); }

.caps__n{
  flex:none;
  font-size:clamp(2.1rem,3.4vw,3.1rem);
  font-weight:600; line-height:1; letter-spacing:-.03em;
  background-image:linear-gradient(150deg,var(--cy),var(--pw-t));
  -webkit-background-clip:text; background-clip:text;
  color:transparent;
}
.caps__i:nth-child(2) .caps__n{ background-image:linear-gradient(150deg,#6FA2F6,var(--pw-t)); }
.caps__i:nth-child(3) .caps__n{ background-image:linear-gradient(150deg,var(--pw-t),var(--vi-t)); }

.caps__r{
  flex:none; width:clamp(14px,1.6vw,30px); height:1px;
  background:linear-gradient(90deg,var(--rule-i2),rgba(174,180,235,.10));
}
.caps__t{
  font-size:clamp(11.5px,.86vw,12.5px);
  font-weight:500; line-height:1.35;
  letter-spacing:.11em; text-transform:uppercase;
  color:var(--on-navy-2);
}

/* Scroll indicator — decorative, so it is aria-hidden in the markup and never
   takes focus. The bob is CSS-only and needs no script. */
.hero__down{
  justify-self:center;
  margin-top:clamp(14px,2vw,26px);
  color:var(--on-navy-3);
  opacity:.62;
}
.hero__down svg{ display:block; width:26px; height:26px; }
@media (prefers-reduced-motion:no-preference){
  .hero__down svg{ animation:hf-bob 2.8s var(--ease) infinite; }
}
@keyframes hf-bob{ 0%,68%,100%{ transform:none; } 84%{ transform:translateY(4px); } }

/* Off-screen or hidden tab: stop burning frames on a hero nobody is looking
   at. JS adds .hero--rest; without JS everything simply keeps running. */
.hero--rest .hf__b,
.hero--rest .hf__stars,
.hero--rest .hf__s,
.hero--rest .hero__down svg{ animation-play-state:paused; }

/* ================================================= context comparison ====

   Replaced the A02 before/after slider 2026-09-15, to the user's concept
   image and locked copy. One shared task, asked once, branches into two ways
   of working: AI used as a chatbot, where the context is typed every
   session, and AI with working context, where it is already in place. HTML
   and CSS only, no script; the concept image is a reference, never an asset.

   Stacking follows the section's real width. .ctx is a size container: the
   pair sits side by side only from 990px of content (about 1070px of
   viewport), where each panel keeps ~480px — a comfortable prompt measure,
   the chips and their label on one row, a 2×2 tile group. Narrower, the task
   and both panels stack in a centred 780px column, chatbot first. Each
   panel is its own container for the phone adjustments.
   ========================================================================= */

.ctx{
  --ctx-g:clamp(20px,2.2vw,32px);
  container:ctx / inline-size;
}
.ctx svg{
  fill:none; stroke:currentColor; stroke-width:1.6;
  stroke-linecap:round; stroke-linejoin:round;
}
/* 32–40px from the headline to the task (the supporting line under the
   headline was removed 2026-09-15 at the user's request) */
.ctx__head{ max-width:none; margin-bottom:clamp(32px,3vw,40px); }
.ctx__head h2{ max-width:24em; margin-inline:auto; text-wrap:balance; }

/* the small uppercase labels: TASK, the prompt's three headings, AI RESPONSE */
.ctx__k{
  display:block;
  margin:0 0 4px;
  font-size:12px; font-weight:600; line-height:1.3;
  letter-spacing:.14em; text-transform:uppercase;
  color:var(--ink-3);
}

/* ------ the shared task: the request, once */
.ctx__task,
.ctx__pair{ max-width:780px; margin-inline:auto; }
.ctx__task{
  display:flex; align-items:center; gap:16px;
  padding:14px 22px 14px 14px;
  border:1px solid rgba(61,57,168,.22);
  border-radius:16px;
  background:rgba(255,255,255,.92);
  box-shadow:0 14px 32px -24px rgba(61,57,168,.5);
  transition:translate var(--std) var(--ease), border-color var(--std) var(--ease), box-shadow var(--std) var(--ease);
}
.ctx__task-ic{
  flex:none; display:grid; place-items:center;
  width:46px; height:46px; border-radius:12px;
  background:#F4F5FF; box-shadow:inset 0 0 0 1px rgba(61,57,168,.12);
  color:var(--ink);
  transition:background-color var(--std) var(--ease), color var(--std) var(--ease), box-shadow var(--std) var(--ease);
}
.ctx__task-ic svg{ width:24px; height:24px; }
.ctx__task p{
  margin:0;
  font-size:clamp(1.0625rem,1.4vw,1.25rem); font-weight:500; line-height:1.35;
  color:var(--ink);
}
.ctx__task .ctx__k{ margin-bottom:2px; }

/* ------ the connector. Stacked: one short stem from the task into the
   first panel. Side by side (below): the stem forks, red down to the chatbot
   panel and violet down to the working-context one, each ending in a dot on
   its panel's top edge. Decoration only. */
.ctx__fork{ position:relative; height:22px; }
.ctx__fork::before{
  content:""; position:absolute; left:50%; top:0; bottom:0;
  width:2px; margin-left:-1px; border-radius:2px;
  background:linear-gradient(rgba(61,57,168,.3),rgba(166,42,33,.4));
  transition:top var(--std) var(--ease);   /* follows the task when it lifts */
}
.ctx__br{ display:none; }

/* ------ the two panels */
.ctx__pair{ display:grid; gap:18px; }
.ctx__p{
  --pb:rgba(166,42,33,.2); --pbh:rgba(166,42,33,.36); --psh:rgba(166,42,33,.34);
  container:ctxp / inline-size;
  position:relative;
  display:flex; flex-direction:column;
  padding:clamp(20px,2.4vw,30px);
  border:1px solid var(--pb);
  border-radius:20px;
  background:linear-gradient(180deg,#FFF4F2 0%,#FFF9F7 45%,#FFFCFB 100%);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.9), 0 18px 40px -32px var(--psh);
  transition:translate var(--std) var(--ease), border-color var(--std) var(--ease), box-shadow var(--std) var(--ease);
}
.ctx__p--ctx{
  --pb:rgba(61,57,168,.2); --pbh:rgba(61,57,168,.36); --psh:rgba(61,57,168,.4);
  background:linear-gradient(180deg,#F1F4FF 0%,#F7F8FF 45%,#FBFCFF 100%);
}
.ctx__tag{
  align-self:flex-start;
  max-width:100%;
  margin:0 0 14px; padding:6px 14px;
  border-radius:14px;              /* a pill on one line, a soft box if it wraps */
  text-wrap:balance;
  font-size:12px; font-weight:600; line-height:1.3;
  letter-spacing:.14em; text-transform:uppercase;
  color:var(--stop);
  background:rgba(166,42,33,.08); box-shadow:inset 0 0 0 1px rgba(166,42,33,.16);
}
.ctx__p--ctx .ctx__tag{
  color:var(--brand-ink);
  background:rgba(126,130,244,.13); box-shadow:inset 0 0 0 1px rgba(61,57,168,.14);
}
.ctx__p h3{
  margin:0 0 18px;
  font-size:clamp(1.3rem,1.9vw,1.6rem); line-height:1.2; letter-spacing:-.015em;
  color:var(--ink);
}

/* the prompt, typed out again by hand */
.ctx__prompt{
  position:relative;               /* anchors the red label on wider panels */
  padding:18px 20px 16px;
  border-radius:14px;
  background:rgba(255,255,255,.85);
  box-shadow:inset 0 0 0 1px rgba(166,42,33,.12), 0 10px 24px -22px rgba(166,42,33,.45);
}
/* direct children only: the tilted label is a <p> further down and keeps
   its own size and margins */
.ctx__prompt > p{ margin:0 0 14px; font-size:15.5px; line-height:1.55; color:var(--ink-2); }
.ctx__prompt .ctx__k{ margin:0 0 3px; font-size:12px; line-height:1.3; }
/* A hand-drawn loop around a detail that has to be typed again. The phrase
   never wraps and the instructions break one sentence per line (2026-09-15,
   user request), so every detail gets exactly one loop. The loop runs just
   outside the text on every side and its overshoot trails under the
   baseline — an earlier draw closed across the first letters and read as a
   strike-through. The text never moves. */
.ctx__ring{
  padding:.18em .42em; margin:0 -.42em;
  white-space:nowrap;
  background:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 40' preserveAspectRatio='none'%3E%3Cpath d='M46 36C18 37 3 31 4 21 5 9 48 2 104 3c56 1 93 7 92 18-1 11-40 17-97 16-27-1-49-2-71-5' fill='none' stroke='%23A62A21' stroke-width='1.5' stroke-opacity='.72' stroke-linecap='round' vector-effect='non-scaling-stroke'/%3E%3C/svg%3E") center / 100% 100% no-repeat;
  transition:background-image var(--std) var(--ease);
}
/* A hand-drawn underline under the attachment list the prompt retypes
   (2026-09-15, user sketch). Unlike the loops it wraps with the text: the
   background is cloned per line fragment, so each line gets its own stroke. */
.ctx__under{
  padding-bottom:.16em;
  -webkit-box-decoration-break:clone; box-decoration-break:clone;
  background:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 8' preserveAspectRatio='none'%3E%3Cpath d='M2 5.5C38 3 82 6.5 124 4.5S182 3.5 198 5' fill='none' stroke='%23A62A21' stroke-width='1.6' stroke-opacity='.72' stroke-linecap='round' vector-effect='non-scaling-stroke'/%3E%3C/svg%3E") left bottom / 100% .42em no-repeat;
  transition:background-image var(--std) var(--ease);
}
.ctx__attach{
  display:flex; flex-wrap:wrap; align-items:center; gap:10px 12px;
  margin-top:2px;
}
.ctx__files{ display:flex; flex-wrap:wrap; gap:8px; margin:0; padding:0; list-style:none; }
.ctx__files li{
  display:inline-flex; align-items:center; gap:7px;
  padding:7px 11px;
  border-radius:10px;
  background:#fff; box-shadow:inset 0 0 0 1px rgba(21,19,66,.1);
  font-size:13px; font-weight:500; line-height:1.2; color:var(--ink);
  white-space:nowrap;
}
.ctx__files svg{ flex:none; width:16px; height:16px; color:var(--ink-3); }
.ctx__files .is-sheet svg{ color:var(--go); }

/* The tilted labels: a fine outline, a warm-white fill, a slight turn and a
   small offset shadow in the label's own colour (the brief asks for the
   offset). Each sits in its own space — the chip row, the row under the
   tiles — and the vertical margin covers the corners the turn lifts, so it
   never covers text. */
.ctx__stk{
  --c:166,42,33; --rot:-5deg;
  display:inline-flex; align-items:center; gap:7px;
  width:max-content; max-width:100%;
  margin:8px 2px 8px auto;
  padding:8px 16px 8px 12px;
  border:1.5px solid rgb(var(--c)); border-radius:11px;
  background:#FFFDF9;
  color:rgb(var(--c));
  font-size:15px; font-weight:600; line-height:1.2;
  rotate:var(--rot);
  box-shadow:3px 4px 0 -1px rgba(var(--c),.22), 0 10px 18px -12px rgba(var(--c),.45);
  transition:rotate var(--std) var(--ease), box-shadow var(--std) var(--ease);
}
.ctx__stk svg{ flex:none; width:14px; height:14px; stroke-width:2.4; }
.ctx__stk--ok{ --c:31,122,85; margin:-2px 6px 6px auto; }
/* On panels wide enough, the red label straddles the prompt box's lower-right
   edge instead of taking a row of its own (2026-09-15, user sketch). The extra
   bottom padding keeps it clear of the chips; below the box it sits right of
   "AI response", never over it. Narrower, it stays in the chip row. */
@container ctxp (min-width:470px){
  .ctx__prompt{ padding-bottom:28px; }
  .ctx__prompt .ctx__stk--no{ position:absolute; right:18px; bottom:-20px; margin:0; }
}

/* the four kinds of context: categories, never numbered */
.ctx__tiles{
  display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:10px;
  margin:0; padding:10px 10px 14px; list-style:none;
  border-radius:16px;
  background:rgba(255,255,255,.55); box-shadow:inset 0 0 0 1px rgba(61,57,168,.1);
}
.ctx__tiles li{
  display:flex; align-items:center; gap:12px;
  min-height:56px; padding:12px 14px;
  border-radius:12px;
  background:#fff;
  box-shadow:inset 0 0 0 1px rgba(21,19,66,.08), 0 6px 16px -14px rgba(61,57,168,.5);
  font-size:15px; font-weight:500; line-height:1.25; color:var(--ink);
  transition:translate var(--std) var(--ease), background-color var(--std) var(--ease), box-shadow var(--std) var(--ease);
}
.ctx__tiles svg{
  flex:none; width:22px; height:22px; color:var(--brand-ink);
  transition:scale var(--std) var(--ease), color var(--std) var(--ease);
}

/* the response */
.ctx__p > .ctx__k{ margin:22px 0 6px; }
.ctx__resp{ margin:0; font-size:15.5px; line-height:1.5; color:var(--ink-2); }
.ctx__resp strong{ display:block; margin-bottom:2px; font-size:1.125rem; font-weight:600; color:var(--ink); }
.ctx__resp--done{ font-size:1.0625rem; color:var(--ink); }
.ctx__resp--done strong{ display:inline; margin:0; font-size:inherit; }
.ctx__p--chat .ctx__resp{ margin-bottom:22px; }
/* the verdict sits at the foot of the panel, whatever its height */
.ctx__verdict{
  margin:auto 0 0; padding-top:18px;
  border-top:1.5px solid rgba(166,42,33,.4);
  font-size:clamp(1.15rem,1.55vw,1.35rem); font-weight:600; line-height:1.3; letter-spacing:-.01em;
  color:var(--stop);
}

/* the finished file — an illustration, not a control */
.ctx__file{
  display:flex; align-items:center; gap:18px;
  margin-top:12px; padding:14px 16px;
  border-radius:14px; background:#fff;
  box-shadow:inset 0 0 0 1px rgba(21,19,66,.08), 0 10px 24px -20px rgba(61,57,168,.55);
}
.ctx__cover{
  position:relative; flex:none; overflow:hidden;
  width:64px; aspect-ratio:3 / 4;
  border-radius:6px;
  background:#fff;
  box-shadow:0 0 0 1px rgba(21,19,66,.1), 0 6px 14px -8px rgba(21,19,66,.35);
}
.ctx__cover i{ position:absolute; left:14%; height:2px; border-radius:2px; background:rgba(21,19,66,.16); }
.ctx__cover i:nth-child(1){ top:15%; width:46%; height:3px; background:rgba(21,19,66,.5); }
.ctx__cover i:nth-child(2){ top:28%; width:64%; }
.ctx__cover i:nth-child(3){ top:36%; width:52%; }
.ctx__cover::after{
  content:""; position:absolute; left:0; right:0; bottom:0; height:40%;
  background:linear-gradient(120deg,var(--cy),var(--pw) 55%,var(--vi));
  clip-path:ellipse(95% 72% at 72% 100%);
}
.ctx__meta p{ margin:0; }
.ctx__meta .ctx__file-t{ font-size:15.5px; font-weight:600; line-height:1.3; color:var(--ink); }
.ctx__meta .ctx__file-s{ margin-top:3px; font-size:13.5px; line-height:1.35; color:var(--ink-3); }
/* quiet metadata: no arrow, underline, link colour, cursor or hover */
.ctx__meta .ctx__open{ margin-top:5px; font-size:13.5px; font-weight:500; line-height:1.35; color:var(--ink-3); }

/* More air above the checks and between them, a step up in size
   (2026-09-15), and a check with a little depth: a soft top-lit green, a fine
   highlight on the rim, a small shadow and a crisp tick. */
/* at least 28px above the list; side by side, the list sits at the foot of
   its panel, level with the red verdict, so both panels end together */
.ctx__checks{ display:grid; gap:14px; margin:auto 0 0; padding:28px 0 0; list-style:none; }
.ctx__checks li{ position:relative; padding-left:38px; font-size:16.5px; line-height:1.45; color:var(--ink-2); }
.ctx__checks li::before{
  content:""; position:absolute; left:0; top:0;
  width:24px; height:24px; border-radius:50%;
  background:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M4.3 8.3l2.5 2.5 4.9-5.4' fill='none' stroke='%23fff' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") center / 15px no-repeat,
    linear-gradient(160deg,#2EBF7E 0%,#1D9A61 55%,#168552 100%);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.4), 0 3px 8px -3px rgba(23,144,90,.55);
  transition:filter var(--std) var(--ease), box-shadow var(--std) var(--ease);
}

.ctx__close{
  margin:clamp(40px,3.3vw,48px) auto 0;     /* 40–48px before the closing line */
  text-align:center;
  font-size:clamp(1.45rem,2.8vw,2.25rem);
  font-weight:600; line-height:1.2; letter-spacing:-.022em;
  color:var(--ink);
  text-wrap:balance;
}
/* the site's cyan → violet, darkened to hold on white (as .how__em) */
.ctx__em{
  background-image:linear-gradient(90deg,#1A7FBF,#4E53D6 52%,#7A45DA);
  -webkit-background-clip:text; background-clip:text;
  color:transparent;
  -webkit-box-decoration-break:clone; box-decoration-break:clone;
}
@media (forced-colors:active){ .ctx__em{ background:none; color:inherit; } }

/* ------ side by side, from 990px of content */
@container ctx (min-width:990px){
  .ctx__task{ max-width:860px; }
  .ctx__pair{ max-width:none; grid-template-columns:repeat(2,minmax(0,1fr)); gap:var(--ctx-g); }
  .ctx__fork{
    display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); column-gap:var(--ctx-g);
    height:40px;
  }
  .ctx__fork::before{ bottom:auto; height:14px; background:rgba(61,57,168,.3); }
  .ctx__br{ --c:166,42,33; --a:.6; display:block; position:relative; }
  .ctx__br--ctx{ --c:84,80,222; }
  /* each branch: from the centre of the gap along the top, then down into
     its panel's centre; the two meet under the stem */
  .ctx__br::before{
    content:""; position:absolute; top:12px; bottom:4px;
    left:50%; right:calc(var(--ctx-g) / -2 - 1px);
    border:0 solid rgba(var(--c),var(--a));
    border-top-width:2px; border-left-width:2px;
    border-top-left-radius:14px;
    transition:border-color var(--std) var(--ease);
  }
  .ctx__br--ctx::before{
    left:calc(var(--ctx-g) / -2 - 1px); right:50%;
    border-left-width:0; border-right-width:2px;
    border-top-left-radius:0; border-top-right-radius:14px;
  }
  .ctx__br::after{
    content:""; position:absolute; bottom:-4px; left:50%;
    width:8px; height:8px; margin-left:-3px; border-radius:50%;
    background:rgba(var(--c),calc(var(--a) + .3));
    transition:background-color var(--std) var(--ease);
  }
  .ctx__br--ctx::after{ margin-left:-5px; }
}

/* ------ phones */
@container ctx (max-width:520px){
  .ctx__p{ padding:18px; border-radius:18px; }
  .ctx__task{ gap:12px; padding:12px 16px 12px 12px; }
  .ctx__task-ic{ width:40px; height:40px; }
}
@container ctxp (max-width:419px){
  .ctx__prompt{ padding:14px 14px 12px; }
  .ctx__prompt > p{ font-size:15px; line-height:1.6; }
  .ctx__stk{ --rot:-4deg; }
  .ctx__tiles{ grid-template-columns:1fr; }
  .ctx__file{ gap:14px; padding:12px 14px; }
  .ctx__cover{ width:56px; }
}

/* ------ hover: fine pointers only, and never the only way to see anything */
@media (hover:hover) and (pointer:fine){
  .ctx__p:hover{
    translate:0 -3px;
    border-color:var(--pbh);
    box-shadow:inset 0 1px 0 rgba(255,255,255,.9), 0 28px 52px -32px var(--psh);
  }
  .ctx__p--chat:hover .ctx__ring{
    background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 40' preserveAspectRatio='none'%3E%3Cpath d='M46 36C18 37 3 31 4 21 5 9 48 2 104 3c56 1 93 7 92 18-1 11-40 17-97 16-27-1-49-2-71-5' fill='none' stroke='%23A62A21' stroke-width='1.9' stroke-linecap='round' vector-effect='non-scaling-stroke'/%3E%3C/svg%3E");
  }
  .ctx__p--chat:hover .ctx__under{
    background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 8' preserveAspectRatio='none'%3E%3Cpath d='M2 5.5C38 3 82 6.5 124 4.5S182 3.5 198 5' fill='none' stroke='%23A62A21' stroke-width='2' stroke-linecap='round' vector-effect='non-scaling-stroke'/%3E%3C/svg%3E");
  }
  .ctx__p:hover .ctx__stk{
    rotate:calc(var(--rot) + 2deg);
    box-shadow:4px 5px 0 -1px rgba(var(--c),.32), 0 14px 22px -12px rgba(var(--c),.5);
  }
  .ctx__p--ctx:hover .ctx__tiles li{ box-shadow:inset 0 0 0 1px rgba(61,57,168,.2), 0 8px 18px -14px rgba(61,57,168,.6); }
  /* a single tile: a small lift, a brand hairline, the icon comes forward.
     Scoped under .ctx__p--ctx so it outranks the panel-hover rule above, which
     is also true whenever a tile is hovered. */
  .ctx__p--ctx .ctx__tiles li:hover{
    translate:0 -2px;
    background-color:#FCFCFF;
    box-shadow:inset 0 0 0 1.5px rgba(61,57,168,.42), 0 12px 22px -14px rgba(61,57,168,.6);
  }
  .ctx__p--ctx .ctx__tiles li:hover svg{ scale:1.1; color:#2F2B96; }
  .ctx__p--ctx:hover .ctx__checks li::before{
    filter:saturate(1.12) brightness(.96);
    box-shadow:inset 0 1px 0 rgba(255,255,255,.4), 0 4px 10px -3px rgba(23,144,90,.6), 0 0 0 4px rgba(31,157,99,.13);
  }
  /* the task (2026-09-15, user request): a light lift, a firmer hairline, the
     icon tile tints, and both branches brighten — it feeds both panels. The
     stem stretches up with it, so no gap opens under the lifted bar. */
  .ctx__task:hover{
    translate:0 -2px;
    border-color:rgba(61,57,168,.36);
    box-shadow:0 20px 38px -26px rgba(61,57,168,.6);
  }
  .ctx__task:hover .ctx__task-ic{
    background-color:#ECEEFF; color:var(--brand-ink);
    box-shadow:inset 0 0 0 1px rgba(61,57,168,.22);
  }
  .ctx:has(.ctx__task:hover) .ctx__fork::before{ top:-2px; }
  .ctx:has(.ctx__task:hover) .ctx__br{ --a:.95; }
  /* the connector brightens toward the hovered panel */
  .ctx:has(.ctx__p:hover) .ctx__br{ --a:.28; }
  .ctx:has(.ctx__p--chat:hover) .ctx__br--chat,
  .ctx:has(.ctx__p--ctx:hover) .ctx__br--ctx{ --a:1; }
}
@media (prefers-reduced-motion:reduce){
  .ctx__p:hover{ translate:none; }
  .ctx__p:hover .ctx__stk{ rotate:var(--rot); }
  .ctx__p--ctx .ctx__tiles li:hover{ translate:none; }
  .ctx__p--ctx .ctx__tiles li:hover svg{ scale:none; }
  .ctx__task:hover{ translate:none; }
  .ctx:has(.ctx__task:hover) .ctx__fork::before{ top:0; }
}

/* ~~What we do (.svc)~~ removed 2026-09-25 at the user's request: the three
   capabilities now live as service labels on How we work. */

/* ------------------------------------------------------- selected work --

   The two examples moved to their own page (/work/) on 2026-09-25. The
   shared vocabulary below (label, numeral, outcome, evidence tags, points)
   and the three figures (.ml, .tt, .vp) are unchanged; the page layout that
   holds them is at the end of this section, under "the Selected work page".
   Built in HTML and CSS rather than inline SVG: every label is set in px
   (or in container units with a px floor) and renders at that size at any
   width. `.rv` goes on a wrapper, never on an artefact: it animates
   transform, which would replace an artefact's own.                      */

/* ~~The numbered label (.work__lab, .work__n)~~ removed 2026-09-25: on the
   Selected work page each example opens on the section eyebrow, as Why GoWise
   does. */
/* The outcome is the row's claim: a statement under a short rule, in the
   eyebrow vocabulary of this page. A side stripe here read as a stock card
   accent, and the detector flagged it as exactly that. */
.work__out{
  position:relative;
  margin-top:20px; padding-top:14px;
  font-weight:600; color:var(--ink);
  text-wrap:pretty;
}
.work__out::before{
  content:""; position:absolute; left:0; top:0;
  width:36px; height:2px; border-radius:2px;
  background:linear-gradient(90deg,var(--cy),var(--pw),var(--vi));
}
.work__ev{
  display:flex; flex-wrap:wrap; gap:8px;
  margin:22px 0 0; padding:0; list-style:none;
}
/* Evidence, not controls: hairline and an 8px radius so it never reads as a
   pill button. ~~No hover state~~ — superseded 2026-09-10 at the user's
   request: on hover a light line crowns the tag, a sheen crosses it and its
   edge takes the brand hue. Still no pointer cursor and no press state,
   nothing that promises an action. */
.work__ev li{
  position:relative; overflow:hidden;
  padding:6px 12px;
  border:1px solid var(--rule-2); border-radius:8px;
  background:rgba(255,255,255,.55);
  font-size:var(--t-xs); font-weight:500;
  color:var(--ink-2);
  transition:
    border-color var(--std) var(--ease), background-color var(--std) var(--ease),
    color var(--std) var(--ease), box-shadow var(--slow) var(--ease),
    translate var(--std) var(--ease);
}
.work__ev li::before{
  content:""; position:absolute; left:8%; right:8%; top:0; height:1px;
  background:linear-gradient(90deg, transparent, var(--cy), var(--pw), var(--vi), transparent);
  opacity:0;
  transition:opacity var(--std) var(--ease);
}
.work__ev li::after{
  content:""; position:absolute; inset:0;
  background:linear-gradient(110deg, transparent 30%, rgba(255,255,255,.95) 47%, rgba(169,122,246,.16) 55%, transparent 70%);
  translate:-110% 0;
  pointer-events:none;
}
@media (hover:hover) and (pointer:fine){
  .work__ev li:hover{
    border-color:rgba(126,130,244,.5);
    background-color:#fff;
    color:var(--ink);
    translate:0 -1px;
    box-shadow:
      0 0 0 3px rgba(126,130,244,.09),
      0 -4px 14px -6px rgba(85,200,243,.45),
      0 8px 20px -8px rgba(99,91,240,.4),
      inset 0 1px 0 #fff;
  }
  .work__ev li:hover::before{ opacity:1; }
  .work__ev li:hover::after{ translate:110% 0; transition:translate .8s var(--ease); }
}
@media (prefers-reduced-motion:reduce){
  .work__ev li:hover{ translate:none; }
  .work__ev li::after{ display:none; }
}

/* ------------------------------------------------ 01 · meeting intelligence

   Simplified 2026-09-10 to the user's second reference: six glass nodes on
   one continuous line — meeting, decisions, actions and owners, task
   tracker, project history, next meeting — and a return arc that closes the
   loop. No box: the field melts into the section, a recorded exception to
   the field rule (see DESIGN.md).

   Geometry lives in one coordinate space. The stage keeps the SVG's aspect
   ratio (1000 × 344) and is the query container, so 1 unit = .1cqw: every
   node is placed and sized in the same units the connectors are drawn in,
   and they meet at any width with no measuring script. Labels are set in
   px (11px floor), so text never scales with the drawing. Below 680px the
   line gives way to a vertical list with its own loop.                   */

.work__intro{ margin-bottom:10px; }
.work__pts{
  display:grid; gap:9px;
  margin:0; padding:0; list-style:none;
  line-height:1.5;
}
.work__pts li{ position:relative; padding-left:22px; }
/* a drawn dot on the first line, in the eyebrow's cyan → violet */
.work__pts li::before{
  content:""; position:absolute; left:3px; top:.62em;
  width:7px; height:7px; border-radius:50%;
  background:linear-gradient(135deg,var(--cy),var(--vi));
}

.ml{
  position:relative; isolation:isolate;
  margin:0;
  container:ml / inline-size;
}

/* the field: lavender and blue haze, no edge, masked to nothing before
   the figure's own bounds end. No white bloom and no disc (removed
   2026-09-11 at the user's request). */
.ml__field{
  position:absolute; inset:-16% -4% -18% -9%; z-index:-1;
  pointer-events:none;
  background:
    radial-gradient(30% 38% at 20% 66%, rgba(126,130,244,.15), transparent 70%),
    radial-gradient(28% 40% at 86% 26%, rgba(169,122,246,.15), transparent 70%),
    radial-gradient(42% 44% at 62% 92%, rgba(85,200,243,.09), transparent 72%),
    radial-gradient(60% 60% at 50% 50%, rgba(238,236,255,.75), transparent 78%);
  -webkit-mask-image:radial-gradient(closest-side, #000 58%, transparent);
          mask-image:radial-gradient(closest-side, #000 58%, transparent);
}

.ml__stage{ position:relative; aspect-ratio:1000 / 344; }

.ml__wires{
  position:absolute; inset:0; z-index:0;
  width:100%; height:100%; overflow:visible;
}
.ml__w  { fill:none; stroke-width:3; stroke-linecap:round; transition:opacity var(--slow) var(--ease); }
/* one gradient across the whole thread, so the segments read as one line */
.ml__w--a,.ml__w--b,.ml__w--c,.ml__w--d,.ml__w--e{ stroke:url(#mlW); }
.ml__tip{ fill:none; stroke-width:3; stroke-linecap:round; stroke-linejoin:round; }
.ml__tip--e{ stroke:#A24FE6; }
.ml__dot{ stroke:#fff; stroke-width:2.5; transform-box:fill-box; transform-origin:center; }
/* a light that runs along a connector on hover; pathLength 1, one dash */
.ml__comet{
  fill:none; stroke:#fff; stroke-width:5; stroke-linecap:round;
  stroke-dasharray:.07 1.3; stroke-dashoffset:.07;
  opacity:0; pointer-events:none;
}

/* ------ the nodes */

.ml__steps{
  position:absolute; inset:0; z-index:1;
  margin:0; padding:0; list-style:none;
}
.ml__step{
  --r:56;
  position:absolute;
  left:calc(var(--cx) * .1cqw);
  top:calc((var(--cy) - var(--r)) * .1cqw);
  width:calc(var(--r) * .2cqw);
  translate:-50% 0;
  display:flex; flex-direction:column; align-items:center;
  text-align:center;
}
.ml__step--1{ --cx:70;  --cy:122; --t1:#F5FAFF; --t2:#DCEAFF; --lit:64,150,255; }
.ml__step--2{ --cx:242; --cy:96; --t1:#F4F8FF; --t2:#DAE6FF; --lit:78,132,252; }
.ml__step--3{ --cx:414; --cy:148; --t1:#F6F6FF; --t2:#E1E0FF; --lit:104,108,248; }
.ml__step--4{ --cx:586; --cy:96; --t1:#F7F4FF; --t2:#E4DDFF; --lit:122,96,245; }
.ml__step--5{ --cx:758; --cy:148; --t1:#F8F3FF; --t2:#E8DBFF; --lit:139,90,242; }
.ml__step--6{ --cx:930; --cy:122; --t1:#FAF3FF; --t2:#ECDAFF; --lit:160,84,238; }
/* Where the thread passes under a node, the node drops and its label goes
   above it: every label sits on the side away from its curve, and the
   drawing mirrors about the baseline. The orb stays at --cy by pinning the
   item's bottom edge (the orb's bottom) to the stage instead of its top;
   344 is the stage height in units. */
.ml__step--3,.ml__step--5{
  top:auto;
  bottom:calc((344 - var(--cy) - var(--r)) * .1cqw);
  flex-direction:column-reverse;
}
.ml__step--3 .ml__lab,
.ml__step--5 .ml__lab{ margin-top:0; margin-bottom:clamp(10px,1.5cqw,16px); }
.ml__step--3::before,
.ml__step--5::before{ top:auto; bottom:calc(var(--r) * -.07cqw); }

/* the bloom that rises behind a node on hover */
.ml__step::before{
  content:""; position:absolute; z-index:-1;
  left:50%; top:calc(var(--r) * -.07cqw); width:170%; aspect-ratio:1;
  translate:-50% 0; scale:.7;
  border-radius:50%;
  background:radial-gradient(closest-side, rgba(var(--lit),.30), rgba(var(--lit),.10) 55%, transparent);
  opacity:0;
  transition:opacity var(--slow) var(--ease), scale .6s var(--ease);
  pointer-events:none;
}

.ml__orb{
  --ring:max(4px,.7cqw);
  position:relative;
  display:grid; place-items:center;
  width:100%; aspect-ratio:1;
  border-radius:50%;
  background:
    radial-gradient(110% 80% at 50% -6%, rgba(255,255,255,.95), rgba(255,255,255,0) 58%),
    radial-gradient(circle at 50% 62%, var(--t1) 0%, var(--t2) 100%);
  box-shadow:
    0 0 0 var(--ring) rgba(255,255,255,.74),
    0 0 0 calc(var(--ring) + 1px) rgba(126,130,244,.10),
    0 1.9cqw 4.4cqw -1.6cqw rgba(70,62,190,.34),
    inset 0 -1.1cqw 2.2cqw rgba(116,100,232,.13),
    inset 0 1px 1px #fff;
  transition:
    translate .5s var(--ease), scale .5s var(--ease),
    box-shadow .5s var(--ease), opacity var(--std) var(--ease);
}
/* the gradient ring that lights on hover */
.ml__orb::before{
  content:""; position:absolute;
  inset:calc(var(--ring) * -1 - 1px);
  padding:2px; border-radius:50%;
  background:conic-gradient(from 200deg, #55C8F3, #7E82F4, #A97AF6, #55C8F3);
  -webkit-mask:linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite:xor;
          mask:linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0);
  opacity:0;
  transition:opacity var(--slow) var(--ease);
}
/* light from above, brightening the crown of the glass on hover */
.ml__orb::after{
  content:""; position:absolute; inset:0; z-index:1;
  border-radius:50%;
  background:radial-gradient(72% 52% at 50% 0%, #fff, rgba(255,255,255,0) 72%);
  opacity:0;
  transition:opacity var(--slow) var(--ease);
}
/* a specular sweep across the glass, clipped to the circle */
.ml__sheen{
  position:absolute; inset:0; z-index:1;
  border-radius:50%; overflow:hidden;
  pointer-events:none;
}
.ml__sheen::before{
  content:""; position:absolute; inset:-25%;
  background:linear-gradient(115deg, transparent 38%, rgba(255,255,255,.85) 50%, transparent 62%);
  translate:-105% 0;
}
.ml__ic{
  position:relative; z-index:2;
  width:45%; height:45%;
  overflow:visible;
  filter:drop-shadow(0 2px 4px rgba(70,62,190,.16));
  transition:translate .5s var(--ease), scale .5s var(--ease);
}

.ml__lab{
  width:max-content;
  margin-top:clamp(10px,1.5cqw,16px);
  /* 11–13px until 2026-09-24. Raised with .ml__sub so the pair keeps its
     relationship: the quiet line under a label was asked to grow, and a
     label smaller than its own subtitle inverts the hierarchy. */
  font-size:clamp(12.5px,1.55cqw,14.5px); font-weight:600;
  line-height:1.3; letter-spacing:.075em; text-transform:uppercase;
  color:var(--ink);
  transition:color var(--std) var(--ease);
}
.ml__sub{
  display:block; margin-top:4px;
  /* 11–12.5px, then 13–14px on 2026-09-15, then this on 2026-09-24 — both at the
     user's request. With the return arc gone, this line is what closes the
     sequence, so it earns the size. */
  font-size:clamp(15px,1.9cqw,17px); font-weight:400;
  line-height:1.35; letter-spacing:0; text-transform:none;
  color:var(--ink-3);
}

/* ------ hover: lift, ring, crown light, bloom, sweep — and the node's
   a light runs once along its outgoing connector. The other nodes and
   connectors step back a little so the one under the pointer leads. */
@media (hover:hover) and (pointer:fine){
  .ml__step:hover .ml__orb{
    translate:0 -6px; scale:1.05;
    box-shadow:
      0 0 0 var(--ring) rgba(255,255,255,.92),
      0 0 0 calc(var(--ring) + 1px) rgba(var(--lit),.20),
      0 0 4.4cqw 1cqw rgba(var(--lit),.26),
      0 2.8cqw 5.2cqw -1.6cqw rgba(var(--lit),.42),
      inset 0 -1.1cqw 2.2cqw rgba(var(--lit),.14),
      inset 0 1px 1px #fff;
  }
  .ml__step:hover::before{ opacity:1; scale:1; }
  .ml__step:hover .ml__orb::before,
  .ml__step:hover .ml__orb::after{ opacity:1; }
  .ml__step:hover .ml__sheen::before{ translate:105% 0; transition:translate .9s var(--ease); }
  .ml__step:hover .ml__ic{ translate:0 -1px; scale:1.08; }
  .ml__step:hover .ml__lab{ color:var(--brand-ink); }
  .ml__steps:has(.ml__step:hover) .ml__step:not(:hover) .ml__orb{ opacity:.66; }

  /* the connectors step back too, all but the segment that wraps the
     hovered node (Meeting takes the first, Next meeting the last) */
  .ml:has(.ml__step:hover) .ml__w{ opacity:.4; }
  .ml:has(.ml__step--1:hover, .ml__step--2:hover) .ml__w--a,
  .ml:has(.ml__step--3:hover) .ml__w--b,
  .ml:has(.ml__step--4:hover) .ml__w--c,
  .ml:has(.ml__step--5:hover) .ml__w--d,
  .ml:has(.ml__step--6:hover) .ml__w--e{ opacity:1; }
  .ml:has(.ml__step--1:hover, .ml__step--2:hover) .ml__comet--a,
  .ml:has(.ml__step--3:hover) .ml__comet--b,
  .ml:has(.ml__step--4:hover) .ml__comet--c,
  .ml:has(.ml__step--5:hover) .ml__comet--d,
  .ml:has(.ml__step--6:hover) .ml__comet--e{ animation:mlComet 1.15s var(--ease) both; }
}

/* ------ the sequence: the line draws left to right and each node lands as
   it arrives and the next meeting lands. ~~A return arc then closed the loop
   back to the start; removed 2026-09-24 at the user's request.~~ Once. No script
   means no .anim, so the resting CSS
   above IS the final frame. Held until main.js adds .is-run (on screen, tab
   visible); a paused animation freezes its pending delay too, so scrolling
   away and back resumes.
   Sped up 2026-09-14 at the user's request — the reader should never wait.
   Every delay and duration is the original choreography × --pace: at .4 the
   first node lands at .1s and the loop rests at about 1.75s (was 4.4s), in
   the same order with the same overlaps. One number to retune. */
.ml{ --pace:.4; }
.anim .ml__cel{
  animation-duration:calc(var(--pace) * .6s); animation-timing-function:var(--ease);
  animation-fill-mode:both; animation-play-state:paused;
}
.anim .ml.is-run .ml__cel{ animation-play-state:running; }
.anim .ml__step{ animation-name:mlIn; }
.anim .ml__w   { stroke-dasharray:1 1; animation-name:mlDraw; }
.anim .ml__dot { animation-name:mlPop; animation-duration:calc(var(--pace) * .34s); }
.anim .ml__tip { animation-name:mlFade; animation-duration:calc(var(--pace) * .24s); }

.ml__step--1{ animation-delay:calc(var(--pace) * .25s); }
.ml__w--a{ animation-delay:calc(var(--pace) * .55s); }   .ml__dot--1{ animation-delay:calc(var(--pace) * .72s); }
.ml__step--2{ animation-delay:calc(var(--pace) * .8s); } .ml__dot--2{ animation-delay:calc(var(--pace) * 1.22s); }
.ml__w--b{ animation-delay:calc(var(--pace) * 1.25s); }  .ml__step--3{ animation-delay:calc(var(--pace) * 1.4s); }  .ml__dot--3{ animation-delay:calc(var(--pace) * 1.68s); }
.ml__w--c{ animation-delay:calc(var(--pace) * 1.7s); }   .ml__step--4{ animation-delay:calc(var(--pace) * 1.85s); } .ml__dot--4{ animation-delay:calc(var(--pace) * 2.13s); }
.ml__w--d{ animation-delay:calc(var(--pace) * 2.15s); }  .ml__step--5{ animation-delay:calc(var(--pace) * 2.3s); }  .ml__dot--5{ animation-delay:calc(var(--pace) * 2.58s); }
.ml__w--e{ animation-delay:calc(var(--pace) * 2.6s); }   .ml__step--6{ animation-delay:calc(var(--pace) * 2.72s); } .ml__tip--e{ animation-delay:calc(var(--pace) * 2.84s); }
/* durations need the .anim weight, or .anim .ml__cel wins */
.anim .ml__w--a{ animation-duration:calc(var(--pace) * .72s); }
.anim .ml__w--b,.anim .ml__w--c,.anim .ml__w--d{ animation-duration:calc(var(--pace) * .46s); }
.anim .ml__w--e{ animation-duration:calc(var(--pace) * .26s); }

@keyframes mlIn   { from{ opacity:0; transform:translateY(10px) scale(.9); } to{ opacity:1; transform:none; } }
@keyframes mlDraw { from{ stroke-dashoffset:1; } to{ stroke-dashoffset:0; } }
@keyframes mlPop  { from{ opacity:0; transform:scale(.3); } to{ opacity:1; transform:none; } }
@keyframes mlFade { from{ opacity:0; } to{ opacity:1; } }
@keyframes mlComet{
  0%  { stroke-dashoffset:.07; opacity:0; }
  12% { opacity:1; }
  82% { opacity:1; }
  100%{ stroke-dashoffset:-1; opacity:0; }
}

/* ------ narrow: a vertical list. The line runs down through the node
   centres. ~~A return arc on the left brought the last node back to the first;
   removed 2026-09-24 with the desktop arc, so the diagram reads the same way at
   every width.~~ Rows are fixed at the node's height so the line stays exact. */
@container ml (max-width:679px){
  .ml__stage{ aspect-ratio:auto; }
  .ml__wires{ display:none; }
  .ml__steps{
    position:relative; inset:auto;
    display:grid; gap:18px;
    padding:0 0 0 30px;
  }
  .ml__step{
    position:relative; left:auto; top:auto; bottom:auto; translate:none;
    width:auto; min-height:60px;
    flex-direction:row; gap:16px;
    text-align:left;
  }
  .ml__step::before,
  .ml__step--3::before,
  .ml__step--5::before{ left:30px; top:-25px; bottom:auto; width:110px; }
  .ml__step--3 .ml__lab,
  .ml__step--5 .ml__lab{ margin:0; }
  .ml__orb{ --ring:4px; flex:none; width:60px; }
  .ml__orb{
    box-shadow:
      0 0 0 4px rgba(255,255,255,.74),
      0 0 0 5px rgba(126,130,244,.12),
      0 10px 22px -10px rgba(70,62,190,.36),
      inset 0 -6px 12px rgba(116,100,232,.13),
      inset 0 1px 1px #fff;
  }
  .ml__lab{ width:auto; margin:0; font-size:13.5px; }
  .ml__lab br{ display:none; }
  .ml__sub{ font-size:15px; }
  /* the forward line, through the node centres */
  .ml__steps::before{
    content:""; position:absolute; left:59px; top:30px; bottom:30px; width:2px;
    background:linear-gradient(#3F9BF3,#7E82F4 50%,#A24FE6);
  }
}

@media (prefers-reduced-motion:reduce){
  .anim .ml__cel{ animation:none !important; }
  .ml__orb,.ml__ic,.ml__step::before{ transition:opacity var(--std) var(--ease), box-shadow var(--std) var(--ease); }
  .ml__step:hover .ml__orb,
  .ml__step:hover .ml__ic{ translate:none; scale:none; }
  .ml__sheen,.ml__comet{ display:none; }
}

/* ------------------------------------------------ the task tracker (.tt) --

   Added 2026-09-24. The artefact the meeting loop produces, sitting full
   width under the loop that describes it — the same shape the video row
   already had (header pair, then one full-width visual). Until now Operations
   was the only case with no artefact: the reel proves video production, and a
   flowchart was proving Operations, which is to say nothing was.

   Ported from planning/…/A09-meeting-dashboard-proof/dashboard-proof.html.
   That source is built for three fixed canvases and sizes everything in
   absolute px against them; none of that survives here. Sizes are set for the
   width the label will actually render at, and the three layouts are container
   queries on the figure, not viewport media queries, so the tracker reflows
   with its own column.

   Nothing here is interactive, by design: it is a product shot, not a toy.
   Default cursor, no hover, no focus stop. The chrome deliberately still
   LOOKS operational — a status that reads as mutable is the whole argument
   that this is a working surface rather than a report.

   Its palette is local. The page has no department colours, and these five
   were already contrast-checked in the source; only the blue moved, to the
   page's proven #156EA8 (5.5:1).                                          */

.tt{
  --tt-navy:#151342; --tt-ink:#28265c; --tt-ink2:#4b4977; --tt-ink3:#66648b;
  --tt-rule:#e3e5ef; --tt-rule2:#d5d8e7;
  --tt-brand:#5f5bdc; --tt-brand-ink:#3d39a8;
  --tt-canvas:#F3F6FF; --tt-paper:#fff;
  margin:0;
  /* The container moved to .tt__app on 2026-09-24: collapsed, that element is
     pinned to the full-width layout and scaled down, so the queries have to
     read the layout width it is composed at, not the box it is squeezed into. */
}
.tt__lab{
  display:flex; align-items:center; gap:14px;
  margin:0 0 16px;
  font-size:var(--t-xs); font-weight:600;
  letter-spacing:.2em; text-transform:uppercase;
  color:var(--ink-3);
}
.tt__lab::before{
  content:""; flex:none; width:36px; height:2px; border-radius:2px;
  background:linear-gradient(90deg,var(--cy),var(--vi));
}
.tt__frame{
  position:relative;
  border-radius:18px; overflow:hidden;
  background:#fff;
  box-shadow:0 0 0 1px rgba(21,19,66,.07), 0 34px 70px -40px rgba(21,19,66,.45);
  transition:box-shadow var(--slow) var(--ease);
}
/* Above the frame since 2026-09-24, at the user's request — under it, below
   the fold of a clipped preview and under the button, nobody read it. It is
   the line that keeps the figure honest, so it sits where the eye lands. */
/* 15px on phones to 17px on desktop since 2026-09-25: on the Selected work
   page the captions carry the honesty of each proof and were reading small */
.tt__cap{ margin:0 0 16px; max-width:76ch; font-size:clamp(.9375rem,.85rem + .3vw,1.0625rem); color:var(--ink-3); }

/* ~~The clipped preview, its "Open the tracker" control and the scaled
   mini layout~~ removed 2026-09-25: on the Selected work page the tracker is
   shown in full at every width, and .tt__app reads its own width. */
.tt__app{ cursor:default; container:tt / inline-size; }

/* ---- workspace bar */
.tt__bar{
  display:flex; align-items:center;
  height:56px; padding:0 20px;
  border-bottom:1px solid var(--tt-rule);
}
.tt__mark{ width:84px; height:19px; }
.tt__bar-name{
  margin-left:12px; padding-left:12px;
  border-left:1px solid var(--tt-rule);
  font-size:13px; color:var(--tt-ink3);
}
.tt__project{
  margin-left:28px; padding-left:18px;
  border-left:1px solid var(--tt-rule);
  display:flex; align-items:center; gap:6px;
  font-size:14px; font-weight:500; color:var(--tt-ink2);
}
.tt__project svg{ width:14px; height:14px; fill:none; stroke:currentColor; stroke-width:1.8; }
.tt__search{
  margin-left:auto;
  display:flex; align-items:center; gap:8px;
  width:210px; height:36px; padding:0 12px;
  border:1px solid var(--tt-rule2); border-radius:9px;
  font-size:13px; color:var(--tt-ink3);
}
.tt__search svg{ width:16px; height:16px; flex:none; fill:none; stroke:currentColor; stroke-width:1.8; }
.tt__live{ margin-left:14px; display:flex; align-items:center; gap:8px; font-size:12.5px; color:var(--tt-ink3); }
.tt__live i{ width:8px; height:8px; border-radius:50%; background:#31b97a; box-shadow:0 0 0 4px rgba(49,185,122,.1); }

/* ---- page head */
/* Tinted canvas, white cards — 2026-09-24, at the user's request, and the same
   move the context comparison already makes: a pale blue ground so the task
   cards read as objects on a surface rather than white on white. Flat, not a
   gradient: the preview is clipped at an arbitrary height, and the fade below
   has to end on exactly this colour whatever that height turns out to be.
   Checked on the tint: --tt-ink3 holds 5.1:1 and --tt-ink2 7.7:1. */
.tt__main{ padding:18px 20px 20px; background:var(--tt-canvas); }
.tt__bar{ background:#fff; }
.tt__head{ display:flex; align-items:flex-start; justify-content:space-between; gap:20px; }
.tt__h1{ margin:0; font-size:25px; line-height:1.1; letter-spacing:-.03em; font-weight:600; color:var(--tt-navy); }
.tt__sub{ margin:5px 0 0; font-size:14px; color:var(--tt-ink3); }
.tt__new{
  flex:none; height:38px; padding:0 17px; border-radius:9px;
  display:inline-flex; align-items:center;
  color:#fff; background:linear-gradient(135deg,#6461e4,#4c47c9);
  font-size:13.5px; font-weight:600;
  box-shadow:0 10px 24px -15px rgba(68,63,190,.72);
}

/* ---- filters. The two rows are the argument that responsibility is
   visible: who owns it, and which part of the business it belongs to. */
.tt__filters{
  margin-top:14px; padding:10px 2px;
  border-top:1px solid var(--tt-rule); border-bottom:1px solid var(--tt-rule);
  display:grid; gap:8px;
}
.tt__row{ display:flex; align-items:center; gap:7px; flex-wrap:wrap; }
.tt__flab{
  width:92px; flex:none;
  font-size:11px; font-weight:600; letter-spacing:.08em; text-transform:uppercase;
  color:var(--tt-ink3);
}
.tt__chip{
  height:30px; padding:0 11px;
  border:1px solid var(--tt-rule); border-radius:8px; background:#fff;
  display:inline-flex; align-items:center; gap:7px;
  font-size:13px; font-weight:500; color:var(--tt-ink2);
}
.tt__chip.is-on{ color:var(--tt-brand-ink); border-color:rgba(61,57,168,.17); background:#eff0ff; }
.tt__av{
  width:18px; height:18px; border-radius:50%;
  display:grid; place-items:center;
  font-style:normal; font-size:10px; font-weight:600; color:#fff;   /* a decorative initial, not information: the name is beside it */
}
.tt__av--1{ background:#5e5ad8; } .tt__av--2{ background:#2d7da8; } .tt__av--3{ background:#9b5aad; }
.tt__av--4{ background:#2d8b71; } .tt__av--5{ background:#b66742; }

/* one colour per department, carried by both the filter chip and the tag on
   a task, so the two always agree */
.tt__chip--mk,.tt__tag--mk{ --c:#704ac8; --bg:#f2edff; --bd:#ded2fa; }
.tt__chip--hr,.tt__tag--hr{ --c:#a94750; --bg:#fff0f1; --bd:#f1d3d6; }
.tt__chip--fi,.tt__tag--fi{ --c:#8a5a06; --bg:#fff6df; --bd:#ecdba9; }
.tt__chip--op,.tt__tag--op{ --c:#156EA8; --bg:#eaf5fc; --bd:#cee5f2; }
.tt__chip--de,.tt__tag--de{ --c:#1f7a55; --bg:#e8f6ef; --bd:#cae7d9; }
.tt__chip--mk,.tt__chip--hr,.tt__chip--fi,.tt__chip--op,.tt__chip--de{
  color:var(--c); background:var(--bg); border-color:var(--bd);
}
.tt__count{ margin-left:auto; display:flex; gap:16px; font-size:13px; color:var(--tt-ink3); }
.tt__count > span{ display:flex; align-items:baseline; gap:5px; }
.tt__count b{ font-size:16px; font-weight:600; color:var(--tt-navy); font-variant-numeric:tabular-nums; }
.tt__count--go b{ color:var(--tt-brand-ink); }
.tt__status{
  margin-left:8px; padding-left:15px;
  border-left:1px solid var(--tt-rule);
  display:inline-flex; align-items:center; gap:7px;
  font-size:13px; color:var(--tt-ink2);
}
.tt__status svg{ width:13px; height:13px; fill:none; stroke:currentColor; stroke-width:2; }

/* ---- the task list */
.tt__list{ margin-top:12px; display:grid; gap:8px; }
.tt__task{ border:1px solid var(--tt-rule); border-radius:13px; background:#fff; }
/* The open task leads on border, ring and shadow only. The source drew a 3px
   cyan to violet stripe across its top edge; it went on 2026-09-24, for the
   same reason the outcome rule replaced a side stripe elsewhere on this page —
   a coloured bar on one edge of a card reads as a stock accent, and the
   detector names it the most recognisable tell of a generated UI. This card is
   already the only one with a body; it does not need a flag as well. */
.tt__task--open{
  position:relative; overflow:hidden;
  border-color:#cfd2f6;
  box-shadow:0 0 0 1px rgba(95,91,220,.10), 0 16px 38px -28px rgba(61,57,168,.55);
}
.tt__task-head{
  padding:15px 18px 12px;
  display:grid; grid-template-columns:minmax(0,1fr) auto; gap:9px 18px;
}
.tt__title{ margin:0; font-size:18px; line-height:1.3; font-weight:600; letter-spacing:-.01em; color:var(--tt-navy); }
.tt__side{ display:flex; align-items:center; gap:9px; }
.tt__due{
  display:grid; align-content:center;
  min-width:90px; padding:5px 12px; border-radius:9px;
  background:#fff6df; color:#8a5a06;
}
.tt__due i{ font-style:normal; font-size:11px; line-height:1; letter-spacing:.1em; text-transform:uppercase; font-weight:600; }
.tt__due b{ margin-top:3px; font-size:18px; line-height:1; font-weight:600; font-variant-numeric:tabular-nums; }
.tt__state,.tt__toggle{
  height:28px; padding:0 10px; border-radius:8px;
  display:inline-flex; align-items:center; gap:7px;
  white-space:nowrap;
}
.tt__state{ background:#eeedff; color:var(--tt-brand-ink); font-size:12px; font-weight:600; letter-spacing:.04em; text-transform:uppercase; }
.tt__toggle{ background:#f5f6fa; color:var(--tt-ink2); font-size:12px; font-weight:500; }
.tt__state svg,.tt__toggle svg{ width:13px; height:13px; fill:none; stroke:currentColor; stroke-width:2; }
.tt__meta{ grid-column:1 / -1; display:flex; align-items:center; gap:7px; flex-wrap:wrap; }
.tt__tag{
  height:25px; padding:0 9px; border-radius:7px;
  display:inline-flex; align-items:center;
  font-size:12px; font-weight:500;
  background:#f3f4f8; color:var(--tt-ink2);
}
.tt__tag--who{ background:#f0efff; color:var(--tt-brand-ink); }
.tt__tag--mk,.tt__tag--hr,.tt__tag--fi,.tt__tag--op,.tt__tag--de{ background:var(--bg); color:var(--c); }

/* ---- the open task */
.tt__body{
  padding:15px 18px 17px;
  border-top:1px solid var(--tt-rule); background:#F7FAFF;
  display:grid; grid-template-columns:minmax(0,1.5fr) minmax(0,.82fr); gap:24px;
}
.tt__h2{ margin:0 0 9px; font-size:13px; font-weight:600; color:var(--tt-ink2); }
.tt__decision{
  margin-bottom:13px; padding:11px 13px; border-radius:10px;
  background:#f0f1ff;
  display:flex; align-items:flex-start; gap:10px;
}
.tt__decision svg{ width:17px; height:17px; flex:none; margin-top:1px; fill:none; stroke:var(--tt-brand); stroke-width:1.9; }
.tt__decision b{ display:block; font-size:13px; color:var(--tt-brand-ink); }
.tt__decision p{ margin:3px 0 0; font-size:14px; line-height:1.35; color:var(--tt-ink); }
.tt__updates{ display:grid; gap:11px; }
.tt__u{ position:relative; padding-left:18px; display:grid; grid-template-columns:58px minmax(0,1fr); gap:12px; }
/* the dated spine: the newest update is the lit one */
.tt__u::before{
  content:""; position:absolute; left:0; top:6px;
  width:8px; height:8px; border-radius:50%;
  background:#fff; box-shadow:0 0 0 1px #bfc2da;
}
.tt__u:first-child::before{ background:var(--tt-brand); box-shadow:0 0 0 4px rgba(95,91,220,.11); }
.tt__when{ font-size:12px; color:var(--tt-ink3); font-variant-numeric:tabular-nums; }
.tt__u p{ margin:0; font-size:13.5px; line-height:1.42; color:var(--tt-ink2); }
.tt__u b{ color:var(--tt-navy); font-weight:600; }
.tt__right{ padding-left:22px; border-left:1px solid var(--tt-rule); }
.tt__docs{ display:grid; gap:7px; }
.tt__doc{
  min-height:36px; padding:0 10px;
  border:1px solid var(--tt-rule2); border-radius:9px; background:#fff;
  display:flex; align-items:center; gap:8px;
  font-size:13px; font-weight:500; color:var(--tt-brand-ink);
}
.tt__doc > span{ overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.tt__doc svg{ width:14px; height:14px; flex:none; fill:none; stroke:currentColor; stroke-width:1.8; }
.tt__out{ margin-left:auto; color:var(--tt-ink3); }
.tt__review{ margin:11px 0 0; display:flex; align-items:center; gap:8px; font-size:13.5px; font-weight:600; color:var(--tt-ink2); }
.tt__review svg{ width:16px; height:16px; flex:none; fill:none; stroke:var(--tt-brand); stroke-width:1.8; }
.tt__comment{ margin-top:11px; display:flex; gap:7px; }
.tt__input{
  flex:1; min-width:0; height:38px; padding:0 12px;
  border:1px solid var(--tt-rule2); border-radius:9px; background:#fff;
  display:flex; align-items:center;
  font-size:13px; color:var(--tt-ink3);
}
.tt__send{ width:40px; height:38px; flex:none; border-radius:9px; background:var(--navy-deep); display:grid; place-items:center; color:#fff; }
.tt__send svg{ width:16px; height:16px; fill:none; stroke:currentColor; stroke-width:1.8; }

/* ---- the two closed tasks. They are what makes this a list of work rather
   than one card, so they stay at every width. */
.tt__task--shut{ min-height:52px; padding:0 16px; display:flex; align-items:center; gap:12px; }
.tt__title--shut{ margin:0; min-width:0; font-size:14px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.tt__task--shut .tt__meta{ grid-column:auto; flex:none; }
.tt__task--shut .tt__tag{ height:23px; }
/* the collapsed rows carry their deadline too (2026-09-25, user request):
   the same amber, compact, label and date on one line, pushed right */
.tt__due--sm{
  margin-left:auto; flex:none;
  display:inline-flex; align-items:center; gap:6px;
  min-width:112px; justify-content:space-between;   /* the rows' chips line up */
  height:24px; padding:0 9px; border-radius:7px;
}
.tt__due--sm i{ font-size:10px; }
.tt__due--sm b{ margin:0; font-size:13px; }
.tt__open{
  flex:none;
  height:24px; padding:0 10px; border-radius:999px;
  background:#eaf5fc; color:#156EA8;
  display:inline-flex; align-items:center;
  font-size:11px; font-weight:600; letter-spacing:.05em; text-transform:uppercase;
}
.tt__toggle--shut{ flex:none; border:1px solid var(--tt-rule); background:transparent; }

/* ---- medium: the workspace chrome thins out and the open task goes
   vertical, documents running as a row under the updates rather than in a
   column beside them. */
/* 939, not 999: at a 1024 viewport the open tracker is 944px wide, and the
   full layout still fits there. Cutting at 999 meant opening it showed LESS
   than the scaled preview did, which reads as the control taking something
   away. Retuned 2026-09-24. */
@container tt (max-width:939px){
  .tt__bar-name,.tt__project,.tt__live{ display:none; }
  .tt__search{ margin-left:auto; }
  .tt__count{ display:none; }
  .tt__chip--5{ display:none; }
  .tt__body{ grid-template-columns:minmax(0,1fr); gap:0; }
  .tt__right{ margin-top:15px; padding:14px 0 0; border-left:0; border-top:1px solid var(--tt-rule); }
  .tt__docs{ grid-template-columns:1fr 1fr; }
  .tt__doc--3{ grid-column:1 / -1; }
}

/* ---- phone. Not a shrunken desktop: the search, the status filter and the
   later chips go, the task head stacks, the third update and third document
   go, and the filter label takes its own line so the chips never squeeze.
   The comment box stays — it is what says the tracker is worked in. */
@container tt (max-width:700px){
  .tt__frame{ border-radius:14px; }
  .tt__bar{ height:50px; padding:0 14px; }
  .tt__mark{ width:72px; height:16px; }
  .tt__search{ display:none; }
  .tt__main{ padding:14px 13px 16px; }
  .tt__h1{ font-size:22px; }
  .tt__sub{ font-size:13px; }
  .tt__new{ height:34px; padding:0 13px; font-size:13px; }
  .tt__filters{ padding:9px 0; }
  .tt__flab{ width:100%; }
  .tt__chip--4,.tt__chip--5{ display:none; }
  .tt__status{ display:none; }
  .tt__task-head{ padding:13px 13px 11px; grid-template-columns:minmax(0,1fr); }
  .tt__title{ font-size:16.5px; }
  .tt__side{ flex-wrap:wrap; }
  .tt__body{ padding:13px 13px 15px; }
  .tt__decision p{ font-size:13.5px; }
  .tt__u{ grid-template-columns:minmax(0,1fr); gap:3px; }
  .tt__u--3{ display:none; }
  .tt__doc--3{ display:none; }
  .tt__docs{ grid-template-columns:1fr; }
  .tt__task--shut{ min-height:0; padding:11px 13px; flex-wrap:wrap; }
  .tt__title--shut{ flex:1 1 100%; white-space:normal; }
  /* every deadline sits top right beside its title on phones (2026-09-25,
     user request), so the date is read with the task, not wrapped under it */
  .tt__task-head,.tt__task--shut{ position:relative; }
  .tt__task-head .tt__title{ padding-right:100px; }
  .tt__title--shut{ padding-right:96px; }
  .tt__side .tt__due{ position:absolute; top:13px; right:13px; min-width:0; }
  /* stacked like the open task's, which also keeps it narrow enough to sit
     beside the title */
  .tt__task--shut .tt__due--sm{
    position:absolute; top:10px; right:13px; margin:0;
    display:grid; gap:2px; min-width:0; height:auto; padding:5px 9px;
  }
  .tt__task--shut .tt__due--sm b{ font-size:14px; line-height:1; }
  /* the closed rows keep their state but lose the toggle: with the title on
     its own line there is not room for four things, and one row wrapped
     while the other did not */
  .tt__toggle--shut{ display:none; }
}

/* -------------------------------------------------- 02 · video production

   Rebuilt 2026-09-11 to the user's brief, then simplified the same day to
   the user's reference. Desktop: the text and the video side by side, the
   production workflow full width beneath. The workflow is six stages on one
   straight production line; one automated loop above it (AI review back to
   AI generation), one human loop below it (between AI generation and Human
   approval, a head at each end). ~~The memory line beneath~~ removed
   2026-09-11: the bold statement in the text already says it.

   Real HTML nodes and labels over a decorative SVG in the same 1000 × 410
   space; the figure is the query container, so one unit is .1cqw and node,
   line and label meet at any width with no script. Labels are px with an
   11px floor. Every arrowhead sits on its curve's exact end tangent, and
   each stroke ends inside its head. Below an 860px figure the workflow
   becomes a vertical list with the two loops as brackets.                 */

.vp{
  position:relative; isolation:isolate;
  margin:clamp(48px,6vw,88px) 0 0;
  container:vp / inline-size;
}
/* soft cyan and lilac haze at the ends, masked to nothing at the edges */
.vp__field{
  position:absolute; inset:-12% -3% -8%; z-index:-1;
  pointer-events:none;
  background:
    radial-gradient(22% 44% at 10% 42%, rgba(85,200,243,.12), transparent 70%),
    radial-gradient(26% 48% at 90% 38%, rgba(169,122,246,.12), transparent 70%),
    radial-gradient(34% 40% at 50% 92%, rgba(126,130,244,.07), transparent 72%);
  -webkit-mask-image:radial-gradient(closest-side, #000 62%, transparent);
          mask-image:radial-gradient(closest-side, #000 62%, transparent);
}

.vp__stage{ position:relative; aspect-ratio:1000 / 410; }
.vp__wires{
  position:absolute; inset:0; z-index:0;
  width:100%; height:100%; overflow:visible;
}
.vp__g   { fill:none; stroke:url(#vpM); stroke-width:4.5; stroke-linecap:round; }
.vp__auto{ fill:none; stroke:#1BA3D9; stroke-width:2.4; stroke-linecap:round; }
.vp__hum { fill:none; stroke:#8A55EE; stroke-width:2.4; stroke-linecap:round; }
.vp__g,.vp__auto,.vp__hum{ transition:opacity var(--slow) var(--ease); }
/* a light that runs along a line on hover, as on the meeting loop;
   pathLength 1, one dash — a longer one on the short straight segments */
.vp__comet{
  fill:none; stroke:#fff; stroke-width:6; stroke-linecap:round;
  stroke-dasharray:.16 1.3; stroke-dashoffset:.16;
  opacity:0; pointer-events:none;
}
.vp__comet--auto,.vp__comet--hum{ stroke-width:5; stroke-dasharray:.07 1.3; stroke-dashoffset:.07; }
.vp__tip { stroke:none; }
.vp__tip--auto{ fill:#1BA3D9; }
.vp__tip--hum { fill:#8A55EE; }

/* ------ labels on the lines */

.vp__tag{
  position:absolute; z-index:2; margin:0;
  left:calc(var(--x) * .1cqw); top:calc(var(--y) * .1cqw);
  translate:-50% -50%;
  display:inline-flex; align-items:center; gap:8px;
  white-space:nowrap;
  font-size:clamp(12px,1.2cqw,13.5px); line-height:1.2;
}
.vp__ti{ flex:none; width:1.2em; height:1.2em; }
.vp__tag--brand{
  --x:488; --y:30;
  gap:10px;
  padding:10px 22px 10px 16px;
  border:1px solid rgba(126,130,244,.24); border-radius:999px;
  background:rgba(255,255,255,.9);
  box-shadow:0 8px 22px -12px rgba(70,62,190,.35), inset 0 1px 0 #fff;
  color:var(--brand-ink); font-weight:500;
  /* larger than the loop labels since 2026-09-17 (user request): it names
     the rule over the whole line, not one loop */
  font-size:clamp(14px,1.65cqw,17px);
}
.vp__tag--auto { --x:505; --y:72;  color:#0B6F99; font-weight:600; letter-spacing:.01em; }
.vp__tag--human{ --x:567; --y:390; color:#6A3DC4; font-weight:600; letter-spacing:.01em; }

/* ------ the six stages */

.vp__vw{ display:none; }
.vp__steps{
  position:absolute; inset:0; z-index:1;
  margin:0; padding:0; list-style:none;
}
.vp__step{
  position:absolute;
  left:calc(var(--cx) * .1cqw);
  top:14.6cqw;                     /* (190 − 44) × .1: the orb's top edge */
  width:8.8cqw;                    /* 2 × 44 × .1 */
  translate:-50% 0;
  display:flex; flex-direction:column; align-items:center;
  text-align:center;
}
.vp__step--1{ --cx:96;  --t1:#FFFFFF; --t2:#F1F6FF; --lit:60,150,245; }
.vp__step--2{ --cx:253; --t1:#FFFFFF; --t2:#F0F3FF; --lit:70,130,245; }
.vp__step--3{ --cx:410; --t1:#FBFAFF; --t2:#EAE7FF; --lit:100,105,242; }
.vp__step--4{ --cx:567; --t1:#FBF9FF; --t2:#E9E3FF; --lit:122,96,240; }
.vp__step--5{ --cx:724; --t1:#FBF8FF; --t2:#EAE2FF; --lit:138,90,238; }
.vp__step--6{ --cx:881; --t1:#FFFFFF; --t2:#F4F0FF; --lit:150,98,236; }
/* the bloom that rises behind a stage on hover, centred on the orb */
.vp__step::before{
  content:""; position:absolute; z-index:-1;
  left:50%; top:calc(44 * -.07cqw); width:170%; aspect-ratio:1;
  translate:-50% 0; scale:.7;
  border-radius:50%;
  background:radial-gradient(closest-side, rgba(var(--lit),.30), rgba(var(--lit),.10) 55%, transparent);
  opacity:0;
  transition:opacity var(--slow) var(--ease), scale .6s var(--ease);
  pointer-events:none;
}

.vp__orb{
  --ring:max(3px,.45cqw);
  position:relative;
  display:grid; place-items:center;
  width:100%; aspect-ratio:1;
  border-radius:50%;
  background:radial-gradient(circle at 50% 32%, #fff 0%, var(--t1) 45%, var(--t2) 100%);
  box-shadow:
    0 0 0 1.5px rgba(var(--lit),.34),
    0 0 0 calc(var(--ring) + 1.5px) rgba(255,255,255,.75),
    0 0 0 calc(var(--ring) + 2.5px) rgba(var(--lit),.10),
    0 1.4cqw 3.4cqw -1.2cqw rgba(70,62,190,.26),
    inset 0 -.8cqw 1.8cqw rgba(var(--lit),.10);
  transition:
    translate .5s var(--ease), scale .5s var(--ease),
    box-shadow .5s var(--ease), opacity var(--std) var(--ease);
}
/* the meeting loop's hover pieces: a gradient ring on the outer edge, light
   on the crown of the glass, and a specular sweep clipped to the circle */
.vp__orb::before{
  content:""; position:absolute;
  inset:calc(var(--ring) * -1 - 2.5px);
  padding:2px; border-radius:50%;
  background:conic-gradient(from 200deg, #55C8F3, #7E82F4, #A97AF6, #55C8F3);
  -webkit-mask:linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite:xor;
          mask:linear-gradient(#000 0 0) content-box exclude, linear-gradient(#000 0 0);
  opacity:0;
  transition:opacity var(--slow) var(--ease);
}
.vp__orb::after{
  content:""; position:absolute; inset:0; z-index:1;
  border-radius:50%;
  background:radial-gradient(72% 52% at 50% 0%, #fff, rgba(255,255,255,0) 72%);
  opacity:0;
  transition:opacity var(--slow) var(--ease);
}
.vp__sheen{
  position:absolute; inset:0; z-index:1;
  border-radius:50%; overflow:hidden;
  pointer-events:none;
}
.vp__sheen::before{
  content:""; position:absolute; inset:-25%;
  background:linear-gradient(115deg, transparent 38%, rgba(255,255,255,.85) 50%, transparent 62%);
  translate:-105% 0;
}
.vp__ic{
  position:relative; z-index:2;
  width:46%; height:46%; overflow:visible;
  filter:drop-shadow(0 2px 4px rgba(70,62,190,.16));
  transition:translate .5s var(--ease), scale .5s var(--ease);
}
.vp__lab{
  width:max-content;
  margin-top:clamp(10px,1.3cqw,15px);
  font-size:clamp(11.5px,1.2cqw,13px); font-weight:600;
  line-height:1.3; letter-spacing:.06em; text-transform:uppercase;
  color:var(--ink);
  transition:color var(--std) var(--ease);
}
.vp__desc{
  display:block; margin-top:4px;
  font-size:clamp(13px,1.4cqw,14px); font-weight:400;   /* was 11.5–12.5px; enlarged 2026-09-15 */
  letter-spacing:.01em; text-transform:none;
  color:var(--ink-3);
}
.vp__sub{ display:none; }

/* a ring that flashes on AI generation when work is sent back to it */
.vp__pulse{
  position:absolute; inset:calc(var(--ring) * -1 - 4px);
  border:2px solid #1BA3D9; border-radius:50%;
  opacity:0; pointer-events:none;
}
/* the approval mark on the human gate */
.vp__ok{
  position:absolute; z-index:2; right:-4%; top:-4%;
  display:grid; place-items:center;
  width:max(20px,2.5cqw); aspect-ratio:1;
  border-radius:50%;
  background:#1F9D63;
  box-shadow:0 0 0 2px #fff, 0 4px 10px -3px rgba(31,122,85,.55);
}
.vp__ok svg{
  width:64%; height:64%;
  fill:none; stroke:#fff; stroke-width:2; stroke-linecap:round; stroke-linejoin:round;
}

/* ------ hover: the meeting loop's, brought across 2026-09-14 at the user's
   request so both diagrams answer the pointer the same way — lift, ring,
   crown light, bloom, sweep, the icon rises and the label takes the brand
   ink. The other stages and lines step back, and a light runs once along
   the hovered stage's line (and along its loop, at the two review stages). */
@media (hover:hover) and (pointer:fine){
  .vp__step:hover .vp__orb{
    translate:0 -6px; scale:1.05;
    box-shadow:
      0 0 0 1.5px rgba(var(--lit),.55),
      0 0 0 calc(var(--ring) + 1.5px) rgba(255,255,255,.92),
      0 0 0 calc(var(--ring) + 2.5px) rgba(var(--lit),.20),
      0 0 3.4cqw .8cqw rgba(var(--lit),.26),
      0 2.2cqw 4cqw -1.2cqw rgba(var(--lit),.42),
      inset 0 -.8cqw 1.8cqw rgba(var(--lit),.14);
  }
  .vp__step:hover::before{ opacity:1; scale:1; }
  .vp__step:hover .vp__orb::before,
  .vp__step:hover .vp__orb::after{ opacity:1; }
  .vp__step:hover .vp__sheen::before{ translate:105% 0; transition:translate .9s var(--ease); }
  .vp__step:hover .vp__ic{ translate:0 -1px; scale:1.08; }
  .vp__step:hover .vp__lab{ color:var(--brand-ink); }
  .vp__steps:has(.vp__step:hover) .vp__step:not(:hover) .vp__orb{ opacity:.66; }

  /* the lines step back too, all but the hovered stage's own: its outgoing
     segment, plus the automated loop at AI review and the human loop at
     approval; Final production keeps the segment that feeds it */
  .vp:has(.vp__step:hover) :is(.vp__g,.vp__auto,.vp__hum){ opacity:.4; }
  .vp:has(.vp__step--1:hover) .vp__g--1,
  .vp:has(.vp__step--2:hover) .vp__g--2,
  .vp:has(.vp__step--3:hover) .vp__g--3,
  .vp:has(.vp__step--4:hover) :is(.vp__g--4,.vp__auto),
  .vp:has(.vp__step--5:hover) :is(.vp__g--5,.vp__hum),
  .vp:has(.vp__step--6:hover) .vp__g--5{ opacity:1; }
  .vp:has(.vp__step--1:hover) .vp__comet--1,
  .vp:has(.vp__step--2:hover) .vp__comet--2,
  .vp:has(.vp__step--3:hover) .vp__comet--3,
  .vp:has(.vp__step--4:hover) .vp__comet--4,
  .vp:has(.vp__step--5:hover) .vp__comet--5,
  .vp:has(.vp__step--6:hover) .vp__comet--5{ animation:mlComet .8s var(--ease) both; }
  .vp:has(.vp__step--4:hover) .vp__comet--auto,
  .vp:has(.vp__step--5:hover) .vp__comet--hum{ animation:mlComet 1.15s var(--ease) both; }
}

/* ------ the sequence, once: the line draws stage to stage; at AI review
   the cyan loop sends work back to generation; at the human gate the violet
   loop goes back and forth and the approval mark lands; the line finishes.
   No script means no .anim, so the resting CSS above IS the final frame.
   Held until main.js adds .is-run (on screen, tab visible).
   Sped up 2026-09-14 with the meeting loop: every delay and duration is the
   original choreography × --pace; at .4 the first stage lights at .06s and
   the sequence rests at about 1.7s (was 4.3s). The two pulse flashes still
   land on the two loops' arrowheads, since both scale together. */
.vp{ --pace:.4; }
.anim .vp__cel{
  animation-duration:calc(var(--pace) * .35s); animation-timing-function:var(--ease);
  animation-fill-mode:both; animation-play-state:paused;
}
.anim .vp.is-run .vp__cel{ animation-play-state:running; }
.anim .vp__step{ animation-name:vpOn; animation-duration:calc(var(--pace) * .24s); }
.anim .vp__g,
.anim .vp__auto,
.anim .vp__hum { stroke-dasharray:1 1; animation-name:vpDraw; }
.anim .vp__tip,
.anim .vp__tag { animation-name:vpFade; animation-duration:calc(var(--pace) * .3s); }
.anim .vp__ok  { animation-name:vpPop; animation-duration:calc(var(--pace) * .26s); }
.anim .vp__pulse{ animation-name:vpPulseTwice; animation-duration:calc(var(--pace) * 1.5s); animation-timing-function:linear; }
.anim .vp__auto{ animation-duration:calc(var(--pace) * .5s); }
.anim .vp__hum { animation-duration:calc(var(--pace) * .55s); }

.vp__tag--brand{ animation-delay:calc(var(--pace) * .2s); }
.vp__step--1{ animation-delay:calc(var(--pace) * .15s); }
.vp__g--1{ animation-delay:calc(var(--pace) * .3s); }   .vp__step--2{ animation-delay:calc(var(--pace) * .6s); }
.vp__g--2{ animation-delay:calc(var(--pace) * .72s); }  .vp__step--3{ animation-delay:calc(var(--pace) * 1.02s); }
.vp__g--3{ animation-delay:calc(var(--pace) * 1.14s); } .vp__step--4{ animation-delay:calc(var(--pace) * 1.44s); }
.vp__auto{ animation-delay:calc(var(--pace) * 1.6s); }  .vp__tag--auto{ animation-delay:calc(var(--pace) * 1.75s); } .vp__tip--auto{ animation-delay:calc(var(--pace) * 2.08s); }
.vp__pulse{ animation-delay:calc(var(--pace) * 2.08s); }
.vp__g--4{ animation-delay:calc(var(--pace) * 2.3s); }  .vp__step--5{ animation-delay:calc(var(--pace) * 2.6s); }
.vp__hum{ animation-delay:calc(var(--pace) * 2.75s); }  .vp__tag--human{ animation-delay:calc(var(--pace) * 2.9s); } .vp__tip--hum{ animation-delay:calc(var(--pace) * 3.28s); }
.vp__ok{ animation-delay:calc(var(--pace) * 3.55s); }
.vp__g--5{ animation-delay:calc(var(--pace) * 3.75s); } .vp__step--6{ animation-delay:calc(var(--pace) * 4.05s); }

@keyframes vpOn  { from{ opacity:.22; transform:scale(.9); } to{ opacity:1; transform:none; } }
@keyframes vpDraw{ from{ stroke-dashoffset:1; } to{ stroke-dashoffset:0; } }
@keyframes vpPop { from{ opacity:0; transform:scale(.3); } to{ opacity:1; transform:none; } }
@keyframes vpFade{ from{ opacity:0; } to{ opacity:1; } }
/* two flashes on AI generation: sent back by automated review (cyan) at
   about 2.1s, then by the human gate (violet) at about 3.3s */
@keyframes vpPulseTwice{
  0%    { opacity:0; transform:scale(.92); border-color:#1BA3D9; }
  3%    { opacity:1; }
  13%   { opacity:0; transform:scale(1.3); }
  13.1% { transform:scale(.92); }
  78%   { opacity:0; transform:scale(.92); border-color:#8A55EE; }
  81%   { opacity:1; border-color:#8A55EE; }
  93%   { opacity:0; transform:scale(1.3); border-color:#8A55EE; }
  100%  { opacity:0; border-color:#8A55EE; }
}

/* ------ narrow: a vertical sequence. The production line runs down the
   node centres; the automated loop and the human loop become brackets on
   the left (cyan AI review → AI generation, violet between Human approval
   and AI generation, a head at each end); the loop names sit under their
   stage labels; the brand statement opens the list. Rows are fixed at 56px so the px brackets hold. */
@container vp (max-width:859px){
  .vp__stage{
    aspect-ratio:auto;
    display:flex; flex-direction:column; align-items:flex-start; gap:20px;
  }
  .vp__wires,
  .vp__tag--auto,
  .vp__tag--human{ display:none; }
  .vp__tag{ position:static; translate:none; white-space:normal; }
  .vp__list{ order:1; position:relative; width:100%; padding-left:64px; }
  .vp__vw{
    display:block; position:absolute; left:0; top:0;
    width:64px; height:406px; overflow:visible;
  }
  .vp__steps{ position:relative; inset:auto; display:grid; gap:14px; }
  .vp__steps::before{
    content:""; position:absolute; left:22px; top:28px; bottom:28px; width:4px; border-radius:2px;
    background:linear-gradient(#5DB6F5,#7C7EF2 50%,#B091F4);
  }
  .vp__step{
    position:relative; left:auto; top:auto; translate:none;
    width:auto; height:56px;
    flex-direction:row; gap:14px;
    text-align:left;
  }
  .vp__orb{
    --ring:3px; flex:none; width:48px;
    box-shadow:
      0 0 0 1.5px rgba(var(--lit),.34),
      0 0 0 4.5px rgba(255,255,255,.8),
      0 8px 18px -8px rgba(70,62,190,.32),
      inset 0 -5px 10px rgba(var(--lit),.10);
  }
  .vp__step::before{ left:24px; top:-31px; width:118px; }   /* on the 48px orb */
  .vp__ok{ width:18px; right:-5px; top:-5px; }
  .vp__lab{ width:auto; margin:0; font-size:12.5px; }
  .vp__lab br{ display:none; }
  .vp__desc{ margin-top:2px; font-size:14px; }
  .vp__sub{
    display:block; margin-top:2px;
    font-size:13.5px; font-weight:600; letter-spacing:.01em; text-transform:none;
  }
  .vp__sub--auto { color:#0B6F99; }
  .vp__sub--human{ color:#6A3DC4; }
}
.vp__vw-auto{ fill:none; stroke:#1BA3D9; stroke-width:2; }
.vp__vw-halo{ fill:none; stroke:#fff; stroke-width:6; }
.vp__vw-hum { fill:none; stroke:#8A55EE; stroke-width:2; }
.vp__vw-tip--auto{ fill:#1BA3D9; }
.vp__vw-tip--hum { fill:#8A55EE; }

/* ------ the proof: one real reel, presented as evidence */

.vproof{ margin:0; }
.vproof__lab{
  display:flex; align-items:center; gap:14px;
  margin:0 0 16px;
  font-size:var(--t-xs); font-weight:600;
  letter-spacing:.2em; text-transform:uppercase;
  color:var(--ink-3);
}
.vproof__lab::before{
  content:""; flex:none; width:36px; height:2px; border-radius:2px;
  background:linear-gradient(90deg,var(--cy),var(--pw),var(--vi));
}
.vproof__fig{ margin:0; }
.vproof__frame{
  position:relative;
  aspect-ratio:16 / 9;
  border-radius:14px; overflow:hidden;
  background:var(--navy-deep);
  box-shadow:0 0 0 1px rgba(21,19,66,.08), 0 30px 60px -34px rgba(21,19,66,.6);
}
.vproof__v{ display:block; width:100%; height:100%; object-fit:cover; }
/* always visible, never hover-revealed: the pause control WCAG 2.2.2
   requires for a loop that runs past five seconds */
.vproof__pp{
  position:absolute; left:16px; bottom:18px; z-index:1;
  display:grid; place-items:center;
  width:44px; height:44px; padding:0;
  border:1px solid var(--rule-i2); border-radius:50%;
  background:rgba(14,12,43,.72);
  -webkit-backdrop-filter:blur(6px); backdrop-filter:blur(6px);
  color:#fff; cursor:pointer;
  transition:background var(--std) var(--ease);
}
.vproof__pp:hover{ background:rgba(14,12,43,.9); }
.vproof__pp:focus-visible{ outline:2px solid var(--cy); outline-offset:3px; }
.vproof__pp[hidden],
.vproof__prog[hidden]{ display:none; }
.vproof__ic{ grid-area:1 / 1; width:16px; height:16px; fill:currentColor; }
.vproof__ic--pause,
.vproof__pp.is-playing .vproof__ic--play{ display:none; }
.vproof__pp.is-playing .vproof__ic--pause{ display:block; }
.vproof__prog{
  position:absolute; left:0; right:0; bottom:0; height:3px;
  background:rgba(255,255,255,.14);
  cursor:pointer; touch-action:none;
}
/* The hairline doubles as a scrubber (2026-09-17, user request) and looks
   exactly as before: a transparent 16px hit area sits over it, clear of the
   play button, and focus shows only for the keyboard. */
.vproof__prog::before{ content:""; position:absolute; left:0; right:0; bottom:0; height:16px; }
.vproof__prog:focus{ outline:none; }
.vproof__prog:focus-visible{ box-shadow:0 -2px 0 var(--cy); }
.vproof__prog i{
  display:block; width:100%; height:100%;
  transform-origin:left; transform:scaleX(var(--p,0));
  background:linear-gradient(90deg,var(--cy),var(--pw),var(--vi));
}
.vproof__cap{ margin:12px 0 0; font-size:clamp(.9375rem,.85rem + .3vw,1.0625rem); color:var(--ink-3); }

/* ------ the expand control and the expanded player, 2026-09-25

   The control mirrors the play button in the opposite corner: the same 44px
   glass disc, always visible (never hover-revealed, so it works on touch).
   The player is a native <dialog>, so focus is trapped, Esc closes it and the
   page behind is inert. main.js moves the one <video> into it and back, so
   playback carries over and nothing loads twice. Its scrubber is the inline
   hairline grown up: a 6px track, a thumb, and a 32px hit area, with the
   elapsed and total time either side. */
.vproof__x{
  position:absolute; right:16px; top:16px; z-index:1;
  display:grid; place-items:center;
  width:44px; height:44px; padding:0;
  border:1px solid var(--rule-i2); border-radius:50%;
  background:rgba(14,12,43,.72);
  -webkit-backdrop-filter:blur(6px); backdrop-filter:blur(6px);
  color:#fff; cursor:pointer;
  transition:background var(--std) var(--ease), transform var(--std) var(--ease);
}
.vproof__x svg{ width:17px; height:17px; fill:none; stroke:currentColor; stroke-width:1.9; stroke-linecap:round; stroke-linejoin:round; }
.vproof__x:hover{ background:rgba(14,12,43,.9); }
.vproof__x:focus-visible{ outline:2px solid var(--cy); outline-offset:3px; }
.vproof__x[hidden]{ display:none; }
@media (hover:hover) and (pointer:fine){ .vproof__x:hover{ transform:scale(1.06); } }

html:has(.vx[open]){ overflow:hidden; }
.vx{
  width:min(1240px, 100vw - 32px); max-width:none;
  max-height:calc(100dvh - 32px);
  margin:auto; padding:0;
  border:0; border-radius:18px;
  background:var(--navy-deep);
  color:var(--on-navy);
  box-shadow:0 0 0 1px var(--rule-i2), 0 40px 90px -30px rgba(0,0,0,.7);
  overflow:hidden;
}
.vx::backdrop{
  background:rgba(8,7,26,.82);
  -webkit-backdrop-filter:blur(6px); backdrop-filter:blur(6px);
}
.vx__in{ display:grid; }
.vx__head{
  display:flex; align-items:center; gap:16px;
  padding:10px 10px 10px 22px;
}
.vx__t{
  margin:0; flex:1 1 auto;
  font-size:var(--t-xs); font-weight:600;
  letter-spacing:.2em; text-transform:uppercase;
  color:var(--on-navy-3);
}
.vx__close,.vx__pp{
  display:grid; place-items:center; flex:none;
  width:44px; height:44px; padding:0;
  border:1px solid var(--rule-i2); border-radius:50%;
  background:transparent; color:#fff; cursor:pointer;
  transition:background var(--std) var(--ease), border-color var(--std) var(--ease);
}
.vx__close:hover,.vx__pp:hover{ background:rgba(255,255,255,.08); border-color:var(--on-navy-3); }
.vx__close:focus-visible,.vx__pp:focus-visible,.vx__scrub:focus-visible{ outline:2px solid var(--cy); outline-offset:3px; }
.vx__close svg{ width:18px; height:18px; fill:none; stroke:currentColor; stroke-width:1.8; stroke-linecap:round; }
.vx__stage{ background:#000; }
/* the video keeps 16:9 and never pushes the controls off a short screen */
.vx__stage .vproof__v{
  display:block; width:100%; height:auto;
  max-height:calc(100dvh - 32px - 64px - 76px);
  aspect-ratio:16 / 9; object-fit:contain;
}
.vx__bar{
  display:flex; align-items:center; gap:14px;
  padding:16px 22px 18px;
}
.vx__ic{ width:16px; height:16px; fill:currentColor; }
.vx__ic--pause,
.vx__pp.is-playing .vx__ic--play{ display:none; }
.vx__pp.is-playing .vx__ic--pause{ display:block; }
.vx__time{
  flex:none; min-width:3.2em;
  font-size:var(--t-sm); font-variant-numeric:tabular-nums;
  color:var(--on-navy-2);
}
.vx__time--end{ text-align:right; }
.vx__scrub{
  position:relative; flex:1 1 auto;
  height:32px;                          /* the hit area; the track is 6px */
  display:flex; align-items:center;
  cursor:pointer; touch-action:none;
  --p:0;
}
.vx__track{
  position:relative; width:100%; height:6px; border-radius:6px;
  background:rgba(255,255,255,.16); overflow:hidden;
}
.vx__fill{
  position:absolute; inset:0;
  transform-origin:left; transform:scaleX(var(--p));
  background:linear-gradient(90deg,var(--cy),var(--pw),var(--vi));
}
.vx__thumb{
  position:absolute; top:50%; left:calc(var(--p) * 100%);
  width:16px; height:16px; margin:-8px 0 0 -8px; border-radius:50%;
  background:#fff;
  box-shadow:0 0 0 4px rgba(126,130,244,.35), 0 2px 8px rgba(0,0,0,.4);
  transition:scale var(--quick) var(--ease);
}
.vx__scrub:hover .vx__thumb,
.vx__scrub.is-drag .vx__thumb{ scale:1.2; }
@media (max-width:560px){
  .vx{ width:calc(100vw - 16px); border-radius:14px; }
  .vx__bar{ gap:10px; padding:12px 14px 14px; }
  .vx__head{ padding-left:16px; }
}
@media (prefers-reduced-motion:reduce){
  .vproof__x:hover{ transform:none; }
  .vx__thumb{ transition:none; }
}

@media (prefers-reduced-motion:reduce){
  .anim .vp__cel{ animation:none !important; }
  .vp__orb,.vp__ic,.vp__step::before{ transition:opacity var(--std) var(--ease), box-shadow var(--std) var(--ease); }
  .vp__step:hover .vp__orb,
  .vp__step:hover .vp__ic{ translate:none; scale:none; }
  .vp__sheen,.vp__comet{ display:none; }
}

/* ------------------------------------------------ the Selected work page --

   /work/, created 2026-09-25 when both examples left the homepage. Each
   example has one anatomy: what it is (a two-column head), how it runs (its
   diagram, full width), then the proof. On the homepage each sat as copy
   beside a visual, and the copy outran the visual by 190px (video) or needed
   the clipped tracker to fill the gap (operations); stacking the beats
   removes both dead bands.

   The masthead is a short navy plate with no particle field: the hero's
   field is the homepage's opening, not a page-header style.               */

.wk-mast{ padding-block:clamp(56px,7vw,96px) clamp(52px,6vw,88px); }
.wk-mast h1{ max-width:15em; }
.wk-mast .lede{ max-width:58ch; }
.wk-mast__jump{
  display:flex; flex-wrap:wrap; gap:6px 34px;
  margin-top:clamp(26px,3vw,36px);
}
.wk-mast__n{
  margin-right:10px;
  color:var(--cy); font-weight:600;
  font-variant-numeric:tabular-nums;
}

.wk__head{ display:grid; row-gap:18px; }
.wk__head .eyebrow{ margin:0; }
.wk__h{
  max-width:17em;
  font-size:clamp(1.625rem,1.1rem + 1.6vw,2.25rem);
  line-height:1.12; letter-spacing:-.022em;
}
.wk__intro,
.wk__proof-txt{ max-width:62ch; }
.wk__intro p,
.wk__proof-txt p{ font-size:clamp(1.0625rem,1rem + .2vw,1.125rem); }
.wk__intro .work__intro{ margin-bottom:12px; }

/* From 1000px: label over headline on the left, introduction on the right,
   its first line level with the headline's. The title wrapper dissolves so
   label, headline and introduction share one grid. */
@media (min-width:1000px){
  .wk__head{
    grid-template-columns:minmax(0,1fr) minmax(0,1.08fr);
    column-gap:clamp(48px,6vw,96px);
    align-items:start;
  }
  .wk__title{ display:contents; }
  .wk__head .eyebrow{ grid-column:1; grid-row:1; }
  .wk__h{ grid-column:1; grid-row:2; }
  .wk__intro{ grid-column:2; grid-row:2; padding-top:.35em; }
}

/* 01 · the reel beside how a team uses the pipeline */
.wk__proof{
  display:grid; gap:28px;
  margin-top:clamp(56px,6vw,88px);
}
@media (min-width:1000px){
  .wk__proof{
    grid-template-columns:minmax(0,1.35fr) minmax(0,1fr);
    column-gap:clamp(40px,5vw,72px);
    align-items:center;
  }
}

/* 02 · the loop full width, then the tracker whole, then the claim */
.wk .ml{ width:100%; max-width:980px; margin:clamp(44px,5vw,72px) auto 0; }
/* The tracker follows the loop directly as its concrete proof. ~~The claim
   line and evidence tags between them~~ were removed 2026-09-25 at the user's
   request (they repeated the headline and the last node), and the gap
   tightened with them. */
.wk__tracker{ margin-top:clamp(28px,3.4vw,48px); }
/* the wide loop keeps empty drawing space under its labels (its box is the
   1000 x 344 wire space), so from 800px the tracker tucks up to it */
@media (min-width:800px){ .wk__tracker{ margin-top:12px; } }

/* ------ the video example on phones, 2026-09-25: proof before process.
   Below 1000px the reel comes straight after the headline and first
   paragraph, then the paragraph on how a team uses the pipeline, then the
   workflow it describes, then the carry-forward outcome. The wrappers
   dissolve (display:contents) so their children can be ordered in one
   column; from 1000px nothing here applies and the desktop layout stands. */
@media (max-width:999px){
  .wk--video .wrap{ display:flex; flex-direction:column; }
  .wk--video :is(.wk__head,.wk__title,.wk__intro,.wk__proof,.wk__proof-txt){ display:contents; }
  .wk--video .wk__head .eyebrow{ order:1; }
  .wk--video .wk__h{ order:2; margin-top:18px; }
  .wk--video .wk__intro p{ order:3; margin:18px 0 0; max-width:62ch; }
  .wk--video .vproof{ order:4; margin-top:clamp(28px,5vw,40px); }
  .wk--video .wk__use{ order:5; margin:clamp(28px,5vw,40px) 0 0; max-width:62ch; }
  .wk--video .vp{ order:6; }
  .wk--video .work__out{ order:7; max-width:62ch; }
  .wk--video .wk__proof-txt p,
  .wk--video .wk__intro p{ font-size:clamp(1.0625rem,1rem + .2vw,1.125rem); }
}

/* the close: back to the one contact form, on the homepage */
.wk-end{ padding-block:clamp(64px,8vw,104px); }
.wk-end__in{ text-align:center; }
.wk-end__in h2{ max-width:18em; margin-inline:auto; }
.wk-end__in .acts{ margin-top:30px; }


/* --------------------------------------------------------- how we work --

   Third pass 2026-09-12, to the user's concept image and copy. The
   distilled logic stays — each stage is an action and a labelled outcome —
   and the look follows the concept: headline and one introduction; four
   stages on one line, each node inset over its column with a short tick
   down to its title; the four outcomes on one tinted panel split by
   hairlines; the closing line centred beneath. The "Outcome" labels stay,
   so the panel never reads as a row of bullets.

   Hover (fine pointers, desktop): the stage comes forward — its node rises
   and fills, its tick extends, its title takes the brand ink and its outcome
   cell turns to paper — while the other three step back.

   Mobile first: a vertical path. From 1000px the stages sit side by side on
   a subgrid, so titles and outcomes each line up across all four.        */

#how{
  --how-h:clamp(1.95rem,4.1vw,3.25rem);
  --how-nd:44px;
  --how-in:30px;                       /* node inset over its column, desktop */
}
.how__head h2{
  max-width:18.5em;
  font-size:var(--how-h);
  line-height:1.06;
  letter-spacing:-.03em;
}
/* Enlarged 2026-09-24 at the user's request: this intro carries the section on
   its own, so it sets a step above the shared --t-lead. */
.how__intro{
  max-width:1040px;
  margin:22px 0 0;
  font-size:clamp(1.1875rem, 1.65vw, 1.3125rem);
  line-height:1.6;
  color:var(--ink-2);
  text-wrap:pretty;
}

.how__path{
  position:relative;
  display:grid; gap:34px;
  max-width:760px;
  margin:clamp(48px,6vw,76px) 0 0; padding:0;
  list-style:none;
}
/* the line: down the node centres here, across them on desktop. Revealed,
   not stretched, so each stretch keeps its own hue as it draws. */
.how__path::after{
  content:"";
  position:absolute;
  left:calc(var(--how-nd) / 2 - .75px); top:calc(var(--how-nd) / 2); bottom:0;
  width:1.5px;
  background:linear-gradient(180deg,var(--cy),#6A9CF5 30%,var(--pw) 58%,var(--vi) 84%,rgba(169,122,246,0));
  clip-path:inset(0);
  transition:clip-path 1s var(--ease) .1s;
  display:none;                         /* desktop only; phones use the segments below */
}
/* phones: one segment per gap, from just under each node to just above the
   next, in the two hues it joins — the line never touches a ring */
.how__stage:not(:last-child)::after{
  content:"";
  position:absolute;
  left:calc(var(--how-nd) / 2 - .75px); width:1.5px;
  top:calc(var(--how-nd) + 7px);
  bottom:calc(7px - 34px);              /* 34px is the path's gap between stages */
  border-radius:2px;
  background:linear-gradient(180deg,rgba(var(--rgb),.85),rgba(var(--rgb2),.85));
  clip-path:inset(0);
  transition:clip-path .6s var(--ease);
}

.how__stage{
  --i:0; --rgb:85,200,243; --rgb2:106,156,245; --tint:#EAF7FD; --tint2:#D6F0FB;
  --svc-a:#156EA8; --svc-b:#2A62C4;
  position:relative;
  display:grid;
  grid-template-columns:var(--how-nd) minmax(0,1fr);
  column-gap:20px;
  align-items:start;
}
.how__stage--2{ --i:1; --rgb:106,156,245; --rgb2:126,130,244; --tint:#EDF3FE; --tint2:#DAE6FD; --svc-a:#2A62C4; --svc-b:#4E53D6; }
.how__stage--3{ --i:2; --rgb:126,130,244; --rgb2:169,122,246; --tint:#EFF0FE; --tint2:#DFE0FD; --svc-a:#4E53D6; --svc-b:#6A4AD8; }
.how__stage--4{ --i:3; --rgb:169,122,246; --tint:#F4EFFE; --tint2:#E8DCFD; --svc-a:#6A4AD8; --svc-b:#7A45DA; }

/* the numeral is the marker; opaque, so the line passes behind it. It spans
   title, service label and outcome (three rows since 2026-09-25). */
.how__n{
  position:relative; z-index:1;
  grid-row:1 / span 3;
  width:var(--how-nd); height:var(--how-nd);
  display:grid; place-items:center;
  border-radius:50%;
  border:1.5px solid rgba(var(--rgb),.95);
  background-color:var(--tint);
  outline:1px solid rgba(var(--rgb),0); outline-offset:0;
  color:var(--brand-ink);
  font-size:15px; font-weight:600; line-height:1;
  letter-spacing:.02em;
  font-variant-numeric:tabular-nums;
  transition:
    background-color var(--slow) var(--ease), border-color var(--slow) var(--ease),
    translate var(--std) var(--ease), box-shadow var(--std) var(--ease),
    outline-color var(--std) var(--ease), outline-offset var(--std) var(--ease),
    opacity var(--std) var(--ease);
}
.how__stage h3{
  margin:0;
  padding-top:calc((var(--how-nd) - 1.25em) / 2);  /* first line on the node's centre */
  font-size:clamp(1.25rem,1.7vw,1.5rem);
  line-height:1.25; letter-spacing:-.015em;
  text-wrap:balance;
  transition:opacity var(--slow) var(--ease), translate var(--slow) var(--ease), color var(--std) var(--ease);
}
/* The service label, added 2026-09-25 at the user's request: one per stage,
   between the title and the outcome. Static gradient text, each label running
   from its stage's hue into the next, so the four read as one cyan → violet
   ribbon in segments, the move the phone timeline segments already make.
   Every stop is a darkened derivative: 5.5–6.0:1 on white, 4.83:1 at worst on
   the wash. Sentence case in the markup, uppercased here, as .eyebrow is.
   13.5px at .12em keeps "Workflows & automation" on one line in the 235px
   desktop column from 1180px; below that it balances onto two, and the
   subgrid keeps the four rows level. */
.how__svc{
  justify-self:start;
  margin:8px 0 0;
  font-size:.84375rem; font-weight:600; line-height:1.25;
  letter-spacing:.12em; text-transform:uppercase;
  text-wrap:balance;
  background-image:linear-gradient(90deg,var(--svc-a),var(--svc-b));
  -webkit-background-clip:text; background-clip:text;
  color:transparent;
  -webkit-box-decoration-break:clone; box-decoration-break:clone;
  transition:opacity var(--slow) var(--ease), translate var(--slow) var(--ease);
}
@media (forced-colors:active){ .how__svc{ background:none; color:inherit; } }

.how__out{
  position:relative; z-index:0;
  margin:12px 0 0;
  padding:16px 18px 18px;
  border-radius:14px;
  background:linear-gradient(135deg,rgba(85,200,243,.08),rgba(169,122,246,.09));
  font-size:1.0625rem; line-height:1.5;
  color:var(--ink);
  text-wrap:pretty;
  transition:opacity var(--slow) var(--ease), translate var(--slow) var(--ease);
}
.how__tag{
  display:flex; align-items:center; gap:7px;
  margin-bottom:7px;
  font-size:12px; font-weight:600; line-height:1.2;
  letter-spacing:.14em; text-transform:uppercase;
  color:var(--brand-ink);
}
.how__tag svg{ width:15px; height:15px; flex:none; }
.how__tag circle{ fill:none; stroke:currentColor; stroke-width:1.3; opacity:.5; }
.how__tag path{ fill:none; stroke:currentColor; stroke-width:1.7; stroke-linecap:round; stroke-linejoin:round; }

.how__close{
  margin:clamp(48px,5.5vw,72px) 0 0;
  font-size:clamp(1.5rem,2.8vw,2.25rem);
  font-weight:600; line-height:1.2; letter-spacing:-.022em;
  color:var(--ink);
  text-wrap:balance;
}
/* the site's cyan → violet, darkened to hold on white: 4.4 / 6.0 / 5.7:1 */
.how__em{
  font-style:normal;
  background-image:linear-gradient(90deg,#1A7FBF,#4E53D6 52%,#7A45DA);
  -webkit-background-clip:text; background-clip:text;
  color:transparent;
  -webkit-box-decoration-break:clone; box-decoration-break:clone;
}
@media (forced-colors:active){ .how__em{ background:none; color:inherit; } }

/* ------ the route to the Selected work page, 2026-09-25

   One link, the whole card, beneath the closing line. The arrow disc carries
   the action gradient so the card reads as a destination at a glance, but it
   is not a second gradient pill competing with Contact us. The two orbs reuse
   the diagrams' own marks and say what is behind the link. Hover and focus
   share one state: the card lifts 2px, its edge firms, the disc steps right. */
.how__work{
  position:relative;
  display:grid;
  grid-template-columns:auto minmax(0,1fr) auto;
  align-items:center; column-gap:22px;
  max-width:600px;              /* 760 until the supporting line went, 2026-09-25 */
  margin:clamp(30px,3.4vw,40px) 0 0;
  padding:20px 22px 20px 20px;
  border-radius:20px;
  background:rgba(255,255,255,.92);
  box-shadow:inset 0 0 0 1px rgba(126,130,244,.26), 0 18px 40px -28px rgba(61,57,168,.45);
  color:var(--ink);
  text-decoration:none;
  transition:translate var(--std) var(--ease), box-shadow var(--std) var(--ease);
}
/* a hairline crown in the page's cyan → violet */
.how__work::before{
  content:""; position:absolute; top:0; left:28px; right:28px; height:1px;
  background:linear-gradient(90deg,transparent,var(--cy) 18%,var(--pw) 50%,var(--vi) 82%,transparent);
  opacity:.75;
}
.how__work:focus-visible{ border-radius:20px; outline-offset:4px; }
.how__work-ic{ display:flex; }
.how__work-orb{
  display:grid; place-items:center;
  width:46px; height:46px; border-radius:50%;
  background:radial-gradient(circle at 32% 26%,#fff 0%,#F1F2FF 62%,#E6E8FD 100%);
  box-shadow:inset 0 0 0 1px rgba(126,130,244,.28), 0 8px 18px -10px rgba(61,57,168,.45);
  transition:translate var(--std) var(--ease);
}
.how__work-orb + .how__work-orb{ margin-left:-12px; transition-delay:40ms; }
.how__work-orb svg{ width:24px; height:24px; }
.how__work-txt{ display:grid; gap:3px; min-width:0; }
.how__work-k{
  font-size:.8125rem; font-weight:600; line-height:1.3;
  letter-spacing:.16em; text-transform:uppercase;
  color:var(--brand-ink);
}
.how__work-t{
  font-size:clamp(1.1875rem,1rem + .5vw,1.375rem); font-weight:600;
  line-height:1.25; letter-spacing:-.012em;
  color:var(--ink);
  text-wrap:balance;           /* no lone "built" on phones */
}
.how__work-s{ font-size:1rem; line-height:1.5; color:var(--ink-2); text-wrap:pretty; }
.how__work-go{
  display:grid; place-items:center;
  width:48px; height:48px; border-radius:50%;
  background-image:var(--btn);
  color:#fff;
  box-shadow:var(--btn-shadow);
  transition:translate var(--std) var(--ease), box-shadow var(--std) var(--ease);
}
.how__work-go svg{ width:18px; height:18px; }
.how__work:focus-visible{
  translate:0 -2px;
  box-shadow:inset 0 0 0 1px rgba(126,130,244,.5), 0 24px 48px -28px rgba(61,57,168,.55);
}
.how__work:focus-visible .how__work-go{ translate:3px 0; box-shadow:var(--btn-shadow-lift); }
.how__work:focus-visible .how__work-orb{ translate:0 -2px; }
/* hover on fine pointers only, so a tap never leaves the card lifted */
@media (hover:hover) and (pointer:fine){
  .how__work:hover{
    translate:0 -2px;
    box-shadow:inset 0 0 0 1px rgba(126,130,244,.5), 0 24px 48px -28px rgba(61,57,168,.55);
  }
  .how__work:hover .how__work-go{ translate:3px 0; box-shadow:var(--btn-shadow-lift); }
  .how__work:hover .how__work-orb{ translate:0 -2px; }
}
.how__work:active{ translate:0 0; }
@media (min-width:1000px){ .how__work{ margin-inline:auto; } }
@media (max-width:480px){
  .how__work{ grid-template-columns:minmax(0,1fr) auto; column-gap:16px; padding:18px 16px 18px 18px; }
  .how__work-ic{ display:none; }
  .how__work-go{ width:44px; height:44px; }
}
@media (prefers-reduced-motion:reduce){
  .how__work:is(:hover,:focus-visible),
  .how__work:is(:hover,:focus-visible) .how__work-go,
  .how__work:is(:hover,:focus-visible) .how__work-orb{ translate:none; }
}

@media (min-width:1000px){
  .how__path{
    --g:clamp(40px,4.2vw,64px);
    max-width:none;
    grid-template-columns:repeat(4,minmax(0,1fr));
    grid-template-rows:auto auto auto auto;   /* node · title · service · outcome */
    column-gap:var(--g); row-gap:0;
  }
  /* one panel behind all four outcomes, so they read as a set */
  .how__path::before{
    content:"";
    grid-row:4; grid-column:1 / -1;
    margin-inline:-32px;
    border-radius:20px;
    background:linear-gradient(90deg,rgba(85,200,243,.075),rgba(126,130,244,.07) 50%,rgba(169,122,246,.09));
    box-shadow:inset 0 0 0 1px rgba(126,130,244,.1);
  }
  /* node 01 to node 04, centre to centre */
  .how__path::after{
    left:calc(var(--how-in) + var(--how-nd) / 2);
    right:calc(25% - var(--g) * .75 - var(--how-in) - var(--how-nd) / 2);
    top:calc(var(--how-nd) / 2 - .75px); bottom:auto;
    width:auto; height:1.5px;
    background:linear-gradient(90deg,var(--cy),#6A9CF5 34%,var(--pw) 66%,var(--vi));
    display:block;
    /* Cut around each node. The nodes sit at 0, 1/3, 2/3 and the end of the
       line, so four transparent bands of --cut either side of those points
       leave 7px of air outside each ring (2px outside the hover ring): a node
       dimmed on hover never shows the line running through it. */
    --cut:29px;
    -webkit-mask:linear-gradient(90deg,
      transparent var(--cut), #000 var(--cut) calc(33.333% - var(--cut)),
      transparent calc(33.333% - var(--cut)) calc(33.333% + var(--cut)),
      #000 calc(33.333% + var(--cut)) calc(66.667% - var(--cut)),
      transparent calc(66.667% - var(--cut)) calc(66.667% + var(--cut)),
      #000 calc(66.667% + var(--cut)) calc(100% - var(--cut)),
      transparent calc(100% - var(--cut)));
            mask:linear-gradient(90deg,
      transparent var(--cut), #000 var(--cut) calc(33.333% - var(--cut)),
      transparent calc(33.333% - var(--cut)) calc(33.333% + var(--cut)),
      #000 calc(33.333% + var(--cut)) calc(66.667% - var(--cut)),
      transparent calc(66.667% - var(--cut)) calc(66.667% + var(--cut)),
      #000 calc(66.667% + var(--cut)) calc(100% - var(--cut)),
      transparent calc(100% - var(--cut)));
  }
  .how__stage:not(:last-child)::after{ display:none; }
  /* explicit columns: the panel holds row 4, so auto-placement would push
     the stages below it */
  .how__stage{
    grid-row:1 / span 4;
    grid-template-columns:none;
    grid-template-rows:subgrid;
  }
  .how__stage--1{ grid-column:1; }
  .how__stage--2{ grid-column:2; }
  .how__stage--3{ grid-column:3; }
  .how__stage--4{ grid-column:4; }
  .how__n{ grid-row:auto; margin-left:var(--how-in); }
  /* the tick: from the node down towards its title */
  .how__n::after{
    content:"";
    position:absolute; left:50%; top:100%;
    width:1px; height:18px; margin:1.5px 0 0 -.5px;
    background-color:rgba(var(--rgb),.6);
    transform-origin:50% 0;
    transition:scale var(--std) var(--ease), background-color var(--std) var(--ease);
  }
  /* the title's 28px to the panel now belongs to the service label */
  .how__stage h3{ margin:30px 0 10px; padding:0 8px 0 0; }
  .how__svc{ margin:0 0 28px; }
  .how__out{ margin:0; padding:26px 8px 30px 0; background:none; border-radius:0; }
  /* hairlines between the outcome cells, centred in the gap */
  .how__stage + .how__stage .how__out::before{
    content:"";
    position:absolute; left:calc(var(--g) / -2); top:24px; bottom:24px;
    width:1px;
    background:rgba(94,104,206,.16);
  }
  .how__close{ text-align:center; }
}

/* ------ hover: the stage comes forward, the others step back */
@media (hover:hover) and (pointer:fine) and (min-width:1000px){
  .how__out::after{
    content:"";
    position:absolute; z-index:-1;
    top:12px; bottom:12px;
    left:calc(var(--g) / -2 + 8px); right:calc(var(--g) / -2 + 8px);
    border-radius:14px;
    background:rgba(255,255,255,.92);
    box-shadow:0 14px 30px -20px rgba(61,57,168,.5), inset 0 0 0 1px rgba(126,130,244,.16);
    opacity:0; translate:0 4px;
    transition:opacity var(--std) var(--ease), translate var(--std) var(--ease);
  }
  .how__stage:hover .how__n{
    translate:0 -3px;
    background-color:var(--tint2);
    box-shadow:0 10px 20px -10px rgba(var(--rgb),.8);
    outline-color:rgba(var(--rgb),.35); outline-offset:4px;
  }
  .how__stage:hover .how__n::after{ scale:1 1.35; background-color:rgb(var(--rgb)); }
  .how__stage:hover h3{ color:var(--brand-ink); }
  .how__stage:hover .how__out::after{ opacity:1; translate:0 0; }
  .how__path:has(.how__stage:hover) .how__stage:not(:hover) :is(.how__n,h3,.how__svc,.how__out){ opacity:.45; }
}

/* ------ arrival, once: the line draws, each node fills as it is reached,
   its title and outcome settle behind it. The staggered delays apply only
   while arriving (.is-in without .is-done), so hover never waits on them.
   Only under .anim: no script or reduced motion shows the finished path. */
.anim .how__path:not(.is-in) .how__stage::after{ clip-path:inset(0 0 100% 0); }
.anim .how__path.is-in:not(.is-done) .how__stage::after{ transition-delay:calc(var(--i) * 200ms + 220ms); }
.anim .how__path:not(.is-in) .how__n{ background-color:#fff; border-color:rgba(94,104,206,.3); }
.anim .how__path:not(.is-in) :is(h3,.how__svc,.how__out){ opacity:.55; translate:0 8px; }
.anim .how__path.is-in:not(.is-done) :is(.how__n,h3){ transition-delay:calc(var(--i) * 200ms + 150ms); }
/* the service label lands between its title and its outcome, 60ms apart */
.anim .how__path.is-in:not(.is-done) .how__svc{ transition-delay:calc(var(--i) * 200ms + 210ms); }
.anim .how__path.is-in:not(.is-done) .how__out{ transition-delay:calc(var(--i) * 200ms + 270ms); }
@media (min-width:1000px){
  .anim .how__path:not(.is-in)::after{ clip-path:inset(0 100% 0 0); }
  .anim .how__path:not(.is-in) .how__n::after{ scale:1 0; }
  .anim .how__path.is-in:not(.is-done) .how__n::after{ transition-delay:calc(var(--i) * 200ms + 260ms); }
}
@media (prefers-reduced-motion:reduce){
  .how__path::after,.how__stage::after,.how__n,.how__stage h3,.how__svc,.how__out{ transition:none; }
  .how__stage:hover .how__n,.how__stage:hover .how__out::after{ translate:none; }
}

/* -------------------------------------------------------------- founder -- */

/* Refined 2026-09-14: an editorial profile row, not a card. The portrait
   (232px on desktop, ~200px on tablets) keeps its caption tight beneath it;
   the biography sits beside it in a capped column that opens on a lead
   sentence, so the row never runs the full shell and the text never becomes
   a wall. Below 740px the identity turns into a compact portrait-and-name
   row above the text. */
/* Relaid out 2026-09-24 at the user's request. ~~Portrait left, bio right in a
   580px column~~ ~~widened to two columns inside that right track 2026-09-24~~ —
   both left the top right of the section empty beside the headline, which is
   where the warm wash was pooling as gold. It is now a masthead and a bio: the
   headline and the portrait share the top row over a hairline, and the three
   paragraphs run the full width beneath in two columns of about 60 characters.
   Nothing is squeezed into a leftover any more. */
/* ~~Masthead over a hairline, bio in two columns beneath~~ superseded
   2026-09-25 at the user's request: the short bio sits directly under the
   headline, and the portrait and name stand to the right of both. One grid,
   three areas, no divider. */
.who{
  display:grid;
  grid-template-columns:minmax(0,1fr) auto;
  grid-template-areas:"head id" "body id";
  column-gap:clamp(40px,5.5vw,88px);
  align-items:start;
}
.who > .head{ grid-area:head; margin:0; }
.who__id{ grid-area:id; align-self:center; width:clamp(190px,21vw,272px); min-width:0; }
.who__pic{
  position:relative;
  border-radius:18px;
  overflow:hidden;
  background:linear-gradient(160deg,var(--ice),#fff 60%);
  border:1px solid var(--rule);
  aspect-ratio:1/1;
}
/* The supplied source is 400x400 with a cool grey cast. Corrected in CSS
   rather than regenerated — an identity-preserving upscale that drifts is
   worse than the original shown small. */
.who__pic img{
  width:100%; height:100%;
  object-fit:cover; object-position:center 18%;
  filter:saturate(1.06) contrast(1.04) brightness(1.03) hue-rotate(-4deg);
  mix-blend-mode:multiply;
}
.who__pic::after{
  content:"";
  position:absolute; inset:0;
  pointer-events:none;
  background:radial-gradient(80% 70% at 80% 6%,rgba(85,200,243,.20),transparent 62%),
             radial-gradient(70% 60% at 6% 96%,rgba(126,130,244,.16),transparent 66%);
  mix-blend-mode:screen;
}
.who__name{
  margin:14px 0 0;
  font-size:var(--t-sm); line-height:1.4;
  color:var(--ink-3);
}
.who__name b{ display:block; margin-bottom:2px; color:var(--ink); font-weight:600; font-size:1.0625rem; }

.who__body{
  grid-area:body;
  max-width:66ch;
  margin-top:clamp(22px,2.4vw,30px);
  font-size:clamp(1.0625rem, .6vw + .8rem, 1.125rem);
  line-height:1.7;
  color:var(--ink-2);
  text-wrap:pretty;
}
.who__body p{ margin:0 0 18px; }
.who__body p:last-child{ margin-bottom:0; }

/* phones: headline, then portrait and name as one compact row, then the bio */
@media (max-width:740px){
  .who{
    grid-template-columns:minmax(0,1fr);
    grid-template-areas:"head" "id" "body";
  }
  .who__id{
    align-self:start;
    width:auto; margin-top:26px;
    display:grid;
    grid-template-columns:clamp(104px, 28vw, 124px) minmax(0,1fr);
    align-items:center; column-gap:18px;
  }
  .who__pic{ border-radius:14px; }
  .who__name{ margin:0; }
  .who__body{ margin-top:24px; font-size:clamp(1rem, .5vw + .9rem, 1.0625rem); line-height:1.68; }
}

/* ----------------------------------------------------- common questions -- */

/* 2026-09-14, the user's locked copy. One centred column (~1000px) replaces
   the old two-column split and its navy closing block: a head, one quiet
   accordion, and the closing line set as plain type. The accordion is native
   <details name="faq">, so the browser keeps one row open at a time and
   supplies the keyboard and screen-reader behaviour; no script. */
.faq-sec > *{ max-width:1000px; margin-inline:auto; }

.faq__head{ text-align:center; }
.faq__head h2{ max-width:20em; margin-inline:auto; text-wrap:balance; }
.faq__intro{
  max-width:46em;
  margin:20px auto 0;
  font-size:var(--t-lead); line-height:1.6;
  color:var(--ink-2);
  text-wrap:pretty;
}

/* one container, rows split by hairlines — never floating cards */
@property --faq-wash{ syntax:"<number>"; inherits:false; initial-value:0; }
.faq{
  margin-top:clamp(40px,5vw,64px);
  border:1px solid var(--rule);
  border-radius:20px;
  background:rgba(255,255,255,.72);
  overflow:clip;
  interpolate-size:allow-keywords;     /* lets the panel run to height:auto */
}
.faq details + details{ border-top:1px solid var(--rule); }
/* the open row takes a very pale cyan → violet wash; no edge stripe */
.faq details{
  --faq-wash:0;
  background:linear-gradient(90deg,rgba(85,200,243,calc(var(--faq-wash) * .06)),rgba(169,122,246,calc(var(--faq-wash) * .07)));
  transition:--faq-wash 220ms var(--ease);
}
.faq details[open]{ --faq-wash:1; }
.faq summary{
  display:flex; align-items:center; justify-content:space-between; gap:24px;
  padding:22px 28px;
  cursor:pointer;
  list-style:none;
  color:var(--ink);
  font-size:clamp(1.125rem,1.6vw,1.3125rem);
  font-weight:500; line-height:1.35; letter-spacing:-.01em;
  transition:color var(--std) var(--ease);
}
.faq summary::-webkit-details-marker{ display:none; }
.faq summary:hover{ color:var(--brand-ink); }
/* inset, so the container's clip never cuts the ring */
.faq summary:focus-visible{ outline:2px solid var(--brand-ink); outline-offset:-5px; border-radius:16px; }
.faq summary::after{
  content:"";
  flex:none; width:10px; height:10px;
  border-right:1.6px solid currentColor;
  border-bottom:1.6px solid currentColor;
  transform:rotate(45deg) translate(-2px,-2px);
  transition:transform 220ms var(--ease);
}
.faq details[open] summary::after{ transform:rotate(-135deg) translate(-3px,-3px); }
/* height and opacity only, 220ms, CSS only. Browsers without
   ::details-content simply open at once. */
.faq details::details-content{
  height:0; opacity:0;
  overflow:clip;
  transition:height 220ms var(--ease), opacity 180ms var(--ease), content-visibility 220ms allow-discrete;
}
.faq details[open]::details-content{ height:auto; opacity:1; }
.faq details p{
  max-width:70ch;
  margin:0; padding:0 28px 24px;
  font-size:1.0625rem; line-height:1.6;
  color:var(--ink-2);
}

/* the resolution, as type: solid ink, the second sentence in brand ink */
.faq__close{
  margin-top:clamp(44px,5vw,68px);
  text-align:center;
  font-size:clamp(1.5rem,2.8vw,2.25rem);
  font-weight:600; line-height:1.2; letter-spacing:-.022em;
  color:var(--ink);
  text-wrap:balance;
}
.faq__close span{ display:block; color:var(--brand-ink); }

@media (max-width:600px){
  .faq{ border-radius:16px; }
  .faq summary{ gap:16px; padding:18px; font-size:1.0625rem; }
  .faq details p{ padding:0 18px 20px; font-size:1rem; }
}
@media (prefers-reduced-motion:reduce){
  .faq details,.faq details::details-content,.faq summary::after{ transition:none; }
}

/* -------------------------------------------------------------- contact -- */

.contact__in{
  display:grid;
  grid-template-columns:minmax(0,1fr) minmax(0,1.1fr);
  gap:clamp(34px,5vw,72px);
  align-items:start;
}
.form{ display:grid; gap:16px; }
.form .btn{ justify-self:start; margin-top:4px; }
.row{ display:grid; grid-template-columns:1fr 1fr; gap:16px; }
.f{ display:grid; gap:7px; }
.f label{
  font-size:var(--t-xs); font-weight:500;
  letter-spacing:.1em; text-transform:uppercase;
  color:var(--on-navy-3);
}
.f input,.f select,.f textarea{
  width:100%;
  padding:13px 15px;
  border:1px solid var(--rule-i2);
  border-radius:11px;
  background:rgba(255,255,255,.05);
  color:var(--on-navy);
  font:inherit;
  font-size:16px;              /* 16px or iOS zooms the page on focus */
  transition:border-color var(--std) var(--ease), background var(--std) var(--ease);
}
.f textarea{ min-height:118px; resize:vertical; }
.f select{
  appearance:none;
  background-image:linear-gradient(45deg,transparent 50%,var(--on-navy-2) 50%),
                   linear-gradient(135deg,var(--on-navy-2) 50%,transparent 50%);
  background-position:calc(100% - 20px) 50%, calc(100% - 14px) 50%;
  background-size:6px 6px, 6px 6px;
  background-repeat:no-repeat;
}
.f select option{ background:var(--navy); color:var(--on-navy); }
.f input:focus,.f select:focus,.f textarea:focus{
  border-color:var(--cy);
  background:rgba(255,255,255,.09);
  outline:none;
}
.f input::placeholder,.f textarea::placeholder{ color:var(--on-navy-3); opacity:.7; }
.f.err input,.f.err select,.f.err textarea{ border-color:var(--stop-i); }
.msg{
  font-size:var(--t-xs);
  color:var(--stop-i);
  min-height:1em;
}
.msg:empty{ min-height:0; }
.hp{ position:absolute; left:-9999px; width:1px; height:1px; overflow:hidden; }

/* The three direct channels under the contact copy. Was .mailto, the GoWise
   address; became .wa on 2026-09-24 when that mailbox proved not to be live,
   and .reach the same day when LinkedIn joined it. The address returned that
   same day once the domain was confirmed, so .reach now carries three rows and
   the grid gap does the spacing. Each row is its own flex
   line, so the mark sits on the text baseline and the rule under a link stops
   at the text rather than running the width of the column. */
.reach{
  display:grid; gap:4px; justify-items:start;
  margin-top:28px; padding-top:22px;
  border-top:1px solid var(--rule-i);
  font-size:1.0625rem;
}
.reach p{ margin:0; }
.reach a{
  display:inline-flex; align-items:center; gap:10px; padding:8px 0 6px;
  color:var(--on-navy); text-decoration:none;
  border-bottom:1px solid var(--rule-i2);
  padding-bottom:2px;
  transition:color var(--std) var(--ease), border-color var(--std) var(--ease);
}
.reach a:hover{ color:var(--cy); border-color:var(--cy); }
.reach__ic{ width:22px; height:22px; flex:none; }

/* The one line the form owes the visitor: what the details are used for, and
   what not to put in them. Added 2026-09-24 at the user's request. It follows
   the live status rather than preceding it, so the status stays next to the
   button it answers. */
.form-priv{
  margin:0;
  max-width:56ch;
  font-size:var(--t-xs); line-height:1.55;
  color:var(--on-navy-3);
}

.sent{
  padding:26px;
  border:1px solid rgba(63,214,154,.4);
  border-radius:14px;
  background:rgba(63,214,154,.08);
  color:var(--on-navy);
}
.sent b{ display:block; margin-bottom:6px; font-size:1.14rem; font-weight:600; }
.form-note{ margin-top:4px; font-size:var(--t-xs); color:var(--on-navy-3); }
/* Before a submit the note is empty and contributes nothing but the grid gap,
   which would otherwise push the line below it 64px off the button. */
.form-note:empty{ margin-top:0; }

/* --------------------------------------------------------------- footer -- */

.foot{
  background:var(--navy-deep);
  color:var(--on-navy-3);
  padding-block:44px;
  font-size:var(--t-sm);
}
.foot__in{
  display:flex; flex-wrap:wrap; align-items:center; gap:18px 30px;
}
.foot .mark{ width:106px; height:23px; }
.foot__links{ display:flex; flex-wrap:wrap; gap:24px; margin-left:auto; }
.foot a{ display:inline-block; padding:6px 0; color:var(--on-navy-2); text-decoration:none; transition:color var(--std) var(--ease); }
.foot a:hover{ color:var(--cy); }
.foot small{ font-size:var(--t-xs); }

/* ------------------------------------------------------ section reveals --

   Floor of 0.55, never 0. If a timeline fails or a browser lands mid-range,
   the content is dimmed — never invisible.                                 */

@media (prefers-reduced-motion:no-preference){
  @supports (animation-timeline: view()){
    .rv{
      animation:rise linear both;
      animation-timeline:view();
      animation-range:entry 4% entry 40%;
    }
  }
}
@keyframes rise{
  from{ opacity:.55; transform:translateY(15px); }
  to  { opacity:1;   transform:none; }
}

/* ----------------------------------------------------------- responsive -- */

@media (max-width:1000px){
  .nav__links{
    display:none;
    position:absolute; top:100%; left:0; right:0;
    flex-direction:column; align-items:stretch; gap:0;
    padding:8px var(--gutter) 20px;
    background:rgba(21,19,66,.98);
    backdrop-filter:blur(14px);
    border-bottom:1px solid var(--rule-i);
  }
  .nav__links.is-open{ display:flex; }
  .nav__links a:not(.btn){ padding:14px 0; border-bottom:1px solid var(--rule-i); font-size:1.0625rem; }
  .nav__links a:not(.btn)::after{ display:none; }
  /* no underline in the panel, so the current page takes the cyan (6.2:1) */
  .nav__links a[aria-current="page"]:not(.btn){ color:var(--cy); }
  .nav__links .btn{ margin-top:16px; align-self:flex-start; }
  .burger{ display:inline-flex; }
  .nav__in{ position:relative; }

  /* A centred stack does not need recomposing here — it simply gets smaller.
     That is most of the point of the centred layout: the split build needed
     a different composition at every breakpoint, this one does not. */
  .hero{ min-height:0; padding-block:clamp(36px,5vw,60px) clamp(24px,3vw,36px); }
  .hero__copy{ max-width:640px; }
  .hero .lede{ max-width:50ch; }
  .hf{ opacity:.86; }
  .caps{ padding-top:clamp(22px,3vw,34px); }

  .contact__in{ grid-template-columns:1fr; }
}

@media (max-width:700px){
  .row{ grid-template-columns:1fr; }
  .acts{ gap:14px 20px; }
  .btn{ width:100%; }
  .acts .ghost{ margin-inline:auto; }
  .hero__copy{ max-width:none; }

  /* Fewer, larger blobs at phone size: three is enough to read as a bloom,
     and six overlapping at this scale just becomes an even wash. The pointer
     layer is off here anyway, so it is dropped outright. */
  .hf__b--4,.hf__b--5,.hf__b--ptr{ display:none; }
  .hf__spark,.hf__dot{ display:none; }
  .hf__s:nth-child(2n){ display:none; }
  .hf__scrim{
    background:
      radial-gradient(80% 34% at 50% 40%, rgba(21,19,66,.58) 0%, rgba(21,19,66,0) 74%),
      linear-gradient(0deg, var(--navy) 0%, var(--navy) 6%, rgba(21,19,66,.86) 16%, rgba(21,19,66,0) 36%);
  }
}

/* The anchors stack and stay substantial — a single column, each row still
   carrying its full-size numeral, the vertical separators becoming horizontal
   so the group still reads as one set.
   860, not 700: three columns still fit at 930, but by 768 the longest label
   was breaking to three lines inside its column. */
@media (max-width:860px){
  .caps{ grid-template-columns:1fr; }
  .caps__i{ padding:14px 0; }
  .caps__i + .caps__i{
    border-left:0; border-top:1px solid var(--rule-i); padding-left:0;
  }
  .caps__t{ font-size:12px; }
}

@media (max-width:560px){
  .hf{ opacity:.9; }
  /* The larger hero eyebrow tipped onto a second line here. Tracking buys the
     line back without giving up the size: .2em over 28 characters is ~78px of
     pure letter-spacing at this scale. */
  .eyebrow{ letter-spacing:.14em; gap:12px; }
  /* 16px at 390, easing to 15px by 360, so it stays on one line */
  .hero .eyebrow{ font-size:clamp(.9375rem, 4.1vw, 1rem); letter-spacing:.11em; gap:10px; }
}

/* -------------------------------------------------------- reduced motion -- */

@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{
    animation-duration:.01ms !important;
    animation-iteration-count:1 !important;
    transition-duration:.01ms !important;
    scroll-behavior:auto !important;
  }
  .btn:hover{ transform:none; }
}
