/* ============================================================
   Homepage — hero ground + bento + SVG
   ============================================================ */

/* Hero ground. Was a three.js canvas; it is now two gradients and a grid drawn
   by the compositor. No request, no rAF loop, no LCP element, nothing to gate
   under reduced motion because nothing moves. */
.hero-ground{position:relative;overflow:hidden;min-height:82vh;padding-top:0;padding-bottom:0}
.hero-ground:before{content:"";position:absolute;inset:0;z-index:0;pointer-events:none;background:radial-gradient(ellipse 80% 60% at 22% 18%,color-mix(in srgb,var(--violet) 22%,transparent),transparent 62%),radial-gradient(ellipse 60% 50% at 82% 76%,color-mix(in srgb,var(--cyan) 12%,transparent),transparent 58%)}
.hero-ground:after{content:"";position:absolute;inset:0;z-index:0;pointer-events:none;opacity:.5;background-image:linear-gradient(color-mix(in srgb,var(--violet) 7%,transparent) 1px,transparent 1px),linear-gradient(90deg,color-mix(in srgb,var(--violet) 7%,transparent) 1px,transparent 1px);background-size:64px 64px;mask-image:radial-gradient(ellipse 70% 70% at 50% 40%,#000 35%,transparent 78%)}
.hero-ground .hero-content{position:relative;z-index:2}
.hero-ground .hero-grid{align-items:center;min-height:82vh;padding:40px 0 60px}

/* The copy column used to split the row almost evenly with the aside (1.1fr /
   .9fr, shared with every other page's hero-matrix). The aside now holds three
   short rows instead of three multi-line family tiles, so it no longer needs
   near-equal billing — widening the copy column is what actually gives the
   guarantee strip and a longer headline room to breathe. Scoped to
   .hero-ground and gated above the 900px breakpoint so it never fights the
   site-wide single-column collapse in site.css. */
@media(min-width:901px){
  .hero-ground .hero-grid{grid-template-columns:1.3fr .7fr}
  .hero-ground .hero-visual{min-height:440px}
}

/* Risk-reversal strip under the hero CTAs — the three SHARED_GUARANTEE lines
   (expertise_sections.py), quoted once at the point of the primary CTA rather
   than left implicit until an offer page. */
.hero-guarantee{list-style:none;display:flex;flex-wrap:wrap;gap:10px 22px;margin:22px 0 0;padding:0}
.hero-guarantee li{display:flex;align-items:center;gap:8px;color:var(--silver);font-size:.82rem;font-weight:620;letter-spacing:-.005em}
.hero-guarantee-mark{display:inline-grid;place-items:center;width:18px;height:18px;border-radius:50%;background:color-mix(in srgb,var(--cyan) 20%,transparent);color:var(--cyan);font-size:.66rem;font-weight:800;flex:none}

/* ---- 01 Intent mosaic — the scene bento ---------------------------------- */
/* A scene card is a router, not a link to one page, so it carries two link
   levels: the headline is stretched over the whole card, and the named routes
   sit above it on their own layer. They are in the resting DOM on purpose —
   routes are controls, and the interaction contract is that hover may enrich
   but never own controls, proof, price or scope.

   This is the page's one spatial block, and nothing in it loops. The dotted
   rule wipes in once when the section arrives, the tiles rise once, and every
   remaining effect is pointer or focus state — so the section costs nothing
   while it sits still and the hero above it keeps the whole LCP budget. */

/* Header. The title and its continuation stay two elements — an h2 and a p, so
   the outline still reads one heading and one paragraph — but both are set
   `display:inline` so they run as a single block of type with the second
   sentence subdued. The actions sit in the remaining columns. */
.intent-head{display:grid;grid-template-columns:minmax(0,8fr) minmax(0,auto);gap:20px 48px;align-items:end;margin-bottom:34px}
.intent-head-copy>*{display:inline;margin:0;max-width:none;font-family:var(--font-display);font-weight:700;font-size:clamp(1.35rem,3.4vw,2.15rem);line-height:1.2;letter-spacing:-.018em;text-wrap:pretty}
.intent-head-copy p{color:color-mix(in srgb,var(--silver) 88%,transparent)}
.intent-head-actions{display:flex;flex-wrap:wrap;align-items:center;gap:10px}
.intent-head-actions .button{min-height:44px;padding:10px 16px;font-size:.86rem}
/* The hairline under a section header, dotted the way the connector paths on
   the reference are, and wiped in once on arrival rather than looping. */
.intent-rule{grid-column:1/-1;display:block;height:1px;margin-top:4px;background-image:repeating-linear-gradient(90deg,color-mix(in srgb,var(--lavender) 55%,transparent) 0 2px,transparent 2px 5px)}

/* Ground. The dot field the tiles sit on. It bleeds past the grid rather than
   sitting under it — six tiles at an 18px gutter occlude nearly all of their
   own box, so a field centred on the bento would be a texture nobody sees. The
   fade is horizontal, so the band that does show ends on nothing rather than on
   a rectangle. Static: a background-image and a mask, no element, no request,
   nothing to animate. */
.scene-bento{position:relative}
.scene-bento:before{content:"";position:absolute;inset:-26px -6px -46px;z-index:0;pointer-events:none;background-image:radial-gradient(circle at center,color-mix(in srgb,var(--lavender) 46%,transparent) 1px,transparent 1.6px);background-size:22px 22px;-webkit-mask-image:linear-gradient(90deg,transparent,#000 14%,#000 86%,transparent);mask-image:linear-gradient(90deg,transparent,#000 14%,#000 86%,transparent)}

/* Twelve columns, dense flow. The span comes off the weight the scene itself
   declares rather than off its position in the list: a pair of equal tiles
   mirrors (7|5, then 5|7) so consecutive rows read as a bento instead of as
   two identical columns, and a tile that loses its pair keeps the base span
   while the dense flow closes the row. */
.scene-grid{position:relative;z-index:1;display:grid;grid-template-columns:repeat(12,minmax(0,1fr));grid-auto-flow:row dense;gap:18px}
.scene-card[data-tile="lg"]{grid-column:span 7}
.scene-card[data-tile="lg"]+.scene-card[data-tile="lg"]{grid-column:span 5}
.scene-card[data-tile="wide"]{grid-column:span 5}
.scene-card[data-tile="wide"]+.scene-card[data-tile="wide"]{grid-column:span 7}
.scene-card[data-tile="sm"]{grid-column:span 6}

.scene-card{--fam:var(--violet);--mx:50%;--my:0%;position:relative;isolation:isolate;display:flex;flex-direction:column;border-radius:var(--radius);background:linear-gradient(160deg,var(--surface),var(--surface-2));border:1px solid var(--line);box-shadow:var(--shadow);overflow:hidden}
.scene-card[data-family="systems"]{--fam:var(--violet)}
.scene-card[data-family="health"]{--fam:var(--cyan)}
.scene-card[data-family="growth"]{--fam:var(--warning)}
/* Pointer spotlight. scene-bento.js writes --mx/--my in card-local pixels on a
   rAF, mouse pointers only. z-index:-1 puts it above the card's own background
   and below every in-flow child, so it lights the surface the body sits on
   without a single change to the stacking the two link levels depend on. */
.scene-card:before{content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;background:radial-gradient(340px circle at var(--mx) var(--my),color-mix(in srgb,var(--fam) 30%,transparent),transparent 66%);opacity:0}
/* Lit edge. A one-pixel ring masked out of a radial that follows the same
   pointer, which is what carries the effect across the photograph — the
   spotlight itself stops at the media. pointer-events stays off: the ring
   covers the routes, and a decoration may not take a control's click. */
.scene-card:after{content:"";position:absolute;inset:0;z-index:3;pointer-events:none;border-radius:inherit;padding:1px;background:radial-gradient(240px circle at var(--mx) var(--my),color-mix(in srgb,var(--fam) 95%,transparent),transparent 60%);-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,linear-gradient(#000 0 0);mask-composite:exclude;opacity:0}
/* The media takes the slack. aspect-ratio still reserves the box, so nothing
   shifts while the image loads, but the tile that ends up shorter than its row
   grows its photograph rather than opening a hole under its last route. */
.scene-card-media{flex:1 1 auto;width:100%;min-height:0;border-radius:0;background:var(--ink)}
.scene-card[data-tile="lg"] .scene-card-media{aspect-ratio:16/9}
.scene-card[data-tile="lg"]+.scene-card[data-tile="lg"] .scene-card-media{aspect-ratio:4/3}
.scene-card[data-tile="wide"] .scene-card-media{aspect-ratio:4/3}
.scene-card[data-tile="wide"]+.scene-card[data-tile="wide"] .scene-card-media{aspect-ratio:16/9}
.scene-card[data-tile="sm"] .scene-card-media{aspect-ratio:21/9}
/* Scrim: the image resolves into the card surface instead of ending on a hard
   edge, and the family accent tints the corner it enters from. */
.scene-card-media:after{background:linear-gradient(180deg,transparent 42%,color-mix(in srgb,var(--ink) 62%,transparent) 78%,var(--surface) 100%),radial-gradient(90% 70% at 100% 0,color-mix(in srgb,var(--fam) 20%,transparent),transparent 58%);opacity:1}
.scene-card-body{display:flex;flex-direction:column;gap:10px;padding:20px 22px 22px}
.scene-card-kicker{display:flex;align-items:center;gap:10px;margin:0;color:color-mix(in srgb,var(--fam) 74%,var(--paper));font-size:.7rem;font-weight:800;letter-spacing:.08em;text-transform:uppercase}
.scene-card-index{display:inline-grid;place-items:center;min-width:26px;height:22px;border-radius:7px;background:color-mix(in srgb,var(--fam) 18%,transparent);font-size:.66rem}
.scene-card-headline{margin:0;font-family:var(--font-body);font-size:1.22rem;line-height:1.28;letter-spacing:-.02em}
.scene-card[data-tile="sm"] .scene-card-headline{font-size:1.05rem}
.scene-card-headline a{color:inherit;text-decoration:none}
/* One large pointer target for the scene itself; the route links below opt out
   of it by sitting on a higher layer. */
.scene-card-headline a:after{content:"";position:absolute;inset:0;z-index:1}
.scene-card-headline a:focus-visible{outline:2px solid var(--cyan);outline-offset:3px;border-radius:6px}
.scene-card-routes{position:relative;z-index:2;display:flex;flex-wrap:wrap;gap:8px 14px;margin:4px 0 0;padding:0;list-style:none}
.scene-card-routes a{display:inline-block;color:var(--silver);font-size:.78rem;font-weight:650;text-decoration:none;border-bottom:1px solid color-mix(in srgb,var(--fam) 34%,transparent);padding-bottom:2px}
.scene-card-routes a:hover{color:var(--paper);border-bottom-color:color-mix(in srgb,var(--fam) 70%,transparent)}
.scene-card-routes a:focus-visible{outline:2px solid var(--cyan);outline-offset:3px;border-radius:4px}

/* The hover arrow: a chevron that grows a tail when the control it belongs to
   is hovered or focused. The tail is parked left of the viewBox and clipped by
   the SVG viewport, so no clip-path — and no per-instance id — is involved. */
.hover-arrow{flex:none;width:5px;height:8px;margin-left:.42em}
.hover-arrow-shaft{transform-box:fill-box;transform-origin:100% 50%;transform:scaleX(0)}

/* Carousel controls and progress rail. Both are inert above the breakpoint:
   the buttons stay `hidden` until scene-bento.js finds the grid genuinely
   scrollable, so a visitor without scripting is never shown a dead control. */
.scene-carousel-controls{display:flex;gap:8px}
.scene-carousel-button{display:grid;place-items:center;width:40px;height:40px;padding:0;border:1px solid var(--line-strong);border-radius:12px;background:color-mix(in srgb,var(--paper) 5%,transparent);color:var(--paper);cursor:pointer;font:inherit}
.scene-carousel-button:hover:not(:disabled){border-color:color-mix(in srgb,var(--cyan) 50%,transparent);background:color-mix(in srgb,var(--cyan) 8%,transparent)}
.scene-carousel-button:focus-visible{outline:2px solid var(--cyan);outline-offset:2px}
.scene-carousel-button:disabled{opacity:.38;cursor:default}
.scene-rail{display:none;position:relative;height:3px;margin-top:18px;border-radius:999px;background:color-mix(in srgb,var(--paper) 10%,transparent);overflow:hidden}
.scene-rail-thumb{position:absolute;top:0;bottom:0;width:var(--scene-rail-width,34%);left:calc(var(--scene-progress,0) * (100% - var(--scene-rail-width,34%)));border-radius:inherit;background:linear-gradient(90deg,var(--violet),var(--cyan))}
/* Announced to assistive technology, taken out of the page. Namespaced rather
   than published as a global `.sr-only`, which this codebase does not ship. */
.scene-status{position:absolute;width:1px;height:1px;margin:-1px;padding:0;border:0;overflow:hidden;clip-path:inset(50%);white-space:nowrap}

@media(prefers-reduced-motion:no-preference){
  .intent-rule{clip-path:inset(0 100% 0 0);transition:clip-path 1.1s cubic-bezier(.22,.75,.3,1) .12s}
  .intent-head.is-visible .intent-rule{clip-path:inset(0 0 0 0)}
  .scene-card{transition:transform .35s cubic-bezier(.22,.75,.3,1),border-color .35s ease,box-shadow .35s ease}
  .scene-card:before,.scene-card:after{transition:opacity .4s ease}
  .scene-card:hover,.scene-card:focus-within{transform:translateY(-4px);border-color:color-mix(in srgb,var(--fam) 50%,transparent);box-shadow:0 26px 74px rgba(6,8,32,.46),0 0 0 1px color-mix(in srgb,var(--fam) 34%,transparent)}
  .scene-card:hover:before,.scene-card:focus-within:before,.scene-card:hover:after,.scene-card:focus-within:after{opacity:1}
  .scene-card:hover .scene-card-media img,.scene-card:focus-within .scene-card-media img{transform:scale(1.025)}
  /* Tiles arrive once, staggered by the index the template already writes.
     `backwards` and not `both`: a filled animation would keep owning transform
     after it ended and the hover lift would never leave the ground. */
  .scene-grid.js-reveal .scene-card{opacity:0}
  .scene-grid.js-reveal.is-visible .scene-card{opacity:1;animation:scene-rise .7s cubic-bezier(.22,.75,.3,1) calc(var(--i,0) * 90ms) backwards}
  .hover-arrow-shaft,.hover-arrow-group{transition:transform .32s cubic-bezier(.22,.75,.3,1)}
  a:hover .hover-arrow-shaft,a:focus-visible .hover-arrow-shaft,.scene-card:hover .hover-arrow-shaft,.scene-card:focus-within .hover-arrow-shaft{transform:scaleX(1)}
  a:hover .hover-arrow-group,a:focus-visible .hover-arrow-group,.scene-card:hover .hover-arrow-group,.scene-card:focus-within .hover-arrow-group{transform:translateX(1.6px)}
  .scene-rail-thumb{transition:left .2s linear,width .2s linear}
}
@keyframes scene-rise{from{opacity:0;transform:translateY(22px) scale(.985)}to{opacity:1;transform:none}}

@media(max-width:900px){
  .intent-head{grid-template-columns:minmax(0,1fr);align-items:start;gap:18px}
  .intent-head-actions{width:100%;justify-content:space-between}
  /* No sideways bleed here: the phone gutter is 13px and a wider inset puts
     the dot field a pixel past the viewport, which is a horizontally
     scrolling page. The mask already keeps the band from ending on an
     edge, so the bleed buys nothing at this width. */
  .scene-bento:before{inset:-16px 0 -32px}
  /* Below the breakpoint the bento becomes a snap carousel: user-driven, never
     autoplaying, with the buttons above as the non-drag path and every tile
     still in source order for the keyboard and the screen reader. */
  .scene-grid{display:flex;grid-template-columns:none;gap:14px;overflow-x:auto;scroll-snap-type:x mandatory;overscroll-behavior-x:contain;scrollbar-width:none;padding-bottom:4px}
  .scene-grid::-webkit-scrollbar{display:none}
  .scene-card[data-tile]{flex:0 0 min(85%,330px);grid-column:auto;scroll-snap-align:start}
  .scene-card[data-tile="lg"] .scene-card-media,
  .scene-card[data-tile="lg"]+.scene-card[data-tile="lg"] .scene-card-media,
  .scene-card[data-tile="wide"] .scene-card-media,
  .scene-card[data-tile="wide"]+.scene-card[data-tile="wide"] .scene-card-media,
  .scene-card[data-tile="sm"] .scene-card-media{flex:0 0 auto;aspect-ratio:16/10}
  .scene-card[data-tile="sm"] .scene-card-headline{font-size:1.12rem}
  .scene-rail{display:block}
}

/* ---- 02 Route panel ----------------------------------------------------- */
/* A ledger, not cards: this is the one section on the page a visitor reads
   line by line, and it sits between two card grids. */
.route-panel{border:1px solid var(--line);border-radius:var(--radius);background:linear-gradient(160deg,var(--surface),var(--surface-2));box-shadow:var(--shadow);padding:clamp(22px,3vw,34px)}
.route-head h2{margin:6px 0 0;font-size:clamp(1.5rem,2.6vw,2.1rem);letter-spacing:-.02em}
.route-depth{margin:22px 0 6px;display:flex;flex-wrap:wrap;align-items:flex-end;gap:14px}
.route-depth fieldset{border:0;padding:0;margin:0;min-width:0;display:flex;flex-wrap:wrap;gap:10px}
.route-depth legend{padding:0;margin-bottom:8px;color:var(--silver);font-size:.78rem;font-weight:700;letter-spacing:.04em}
.route-depth-option{display:inline-flex;align-items:center;gap:8px;border:1px solid var(--line);background:color-mix(in srgb,var(--violet) 6%,transparent);border-radius:999px;padding:8px 15px;font-size:.78rem;font-weight:700;cursor:pointer}
.route-depth-option.is-active{border-color:color-mix(in srgb,var(--cyan) 60%,transparent);background:color-mix(in srgb,var(--cyan) 14%,transparent)}
.route-depth-option input{accent-color:var(--cyan);margin:0}
.route-depth-option:focus-within{outline:2px solid var(--cyan);outline-offset:2px}
.route-ledger{margin:24px 0 22px;border-top:1px solid var(--line)}
.route-row{display:grid;grid-template-columns:minmax(0,.42fr) minmax(0,1fr);gap:10px 24px;padding:14px 0;border-bottom:1px solid var(--line);align-items:baseline}
.route-row dt{color:var(--silver);font-size:.78rem;font-weight:700;letter-spacing:.04em;text-transform:uppercase}
.route-row dd{margin:0;color:var(--paper);font-size:.95rem;line-height:1.5}
.route-row dd a{color:var(--cyan);text-decoration:none;border-bottom:1px solid color-mix(in srgb,var(--cyan) 34%,transparent)}
.route-row dd a:hover{border-bottom-color:var(--cyan)}
.route-signature{color:var(--silver);font-size:.8rem;letter-spacing:.08em}
.route-note{margin-left:10px;font-size:.78rem}
@media(max-width:700px){.route-row{grid-template-columns:1fr;gap:4px}}

/* ---- 06 Proof mesh ------------------------------------------------------ */
/* Media-led like the intent mosaic, but the body is a chain rather than a
   headline: every claim is followed by its stack, its provenance grade and the
   commit audit, and the links open a stranger's browser on the real thing. */
.proof-mesh{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:20px}
.proof-card{position:relative;isolation:isolate;display:flex;flex-direction:column;border-radius:var(--radius);background:linear-gradient(160deg,var(--surface),var(--surface-2));border:1px solid var(--line);box-shadow:var(--shadow);overflow:hidden}
.proof-card-media{aspect-ratio:16/9;width:100%;border-radius:0;background:var(--ink)}
.proof-card-media:after{background:linear-gradient(180deg,transparent 46%,color-mix(in srgb,var(--ink) 60%,transparent) 80%,var(--surface) 100%)}
.proof-card-body{display:flex;flex-direction:column;gap:10px;padding:18px 20px 20px}
.proof-card-meta{margin:0;color:var(--silver);font-size:.7rem;font-weight:700;letter-spacing:.06em;text-transform:uppercase}
.proof-card h3{margin:0;font-family:var(--font-body);font-size:1.08rem;letter-spacing:-.02em;line-height:1.25}
.proof-card-claim{margin:0;color:var(--silver);font-size:.85rem;line-height:1.5}
.proof-card-chain{margin:4px 0 0;border-top:1px solid var(--line)}
.proof-card-chain>div{display:grid;grid-template-columns:minmax(0,.44fr) minmax(0,1fr);gap:8px 14px;padding:9px 0;border-bottom:1px solid var(--line);align-items:baseline}
.proof-card-chain dt{margin:0;color:var(--silver);font-size:.68rem;font-weight:800;letter-spacing:.07em;text-transform:uppercase}
.proof-card-chain dd{margin:0;color:var(--paper);font-size:.78rem;line-height:1.45}
.proof-card-links{display:flex;flex-wrap:wrap;gap:8px 18px;margin:auto 0 0;padding-top:6px}
.proof-more{margin-top:22px}
@media(max-width:980px){.proof-mesh{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media(max-width:700px){.proof-mesh{grid-template-columns:1fr}}
@media(prefers-reduced-motion:no-preference){
  .proof-card{transition:transform .35s cubic-bezier(.22,.75,.3,1),border-color .35s ease}
  .proof-card:hover,.proof-card:focus-within{transform:translateY(-3px);border-color:color-mix(in srgb,var(--cyan) 42%,transparent)}
}

/* ---- 360° service graph -------------------------------------------------- */
/* Replaces the ecosystem block diagram. Two representations of one dataset: an
   interactive ring drawn by js/components/service_graph.js, and the .sg-index
   list of real links the server always renders. The list is the floor — under
   861px, without JavaScript, or before the controller boots, it is the whole
   section, and it never has three columns of cards, so the entropy budget's
   no-three-card-grids rule is untouched here as it was before.

   Every colour is a token. The three domain tones reuse the mega-menu's
   mapping (systems → violet, health → cyan, growth → lavender) so a service
   carries the same colour in the header and on this map. The before/after pair
   is mixed toward --paper for the reason tokens.css gives about the t0 ramp:
   --warning neat is unreadable on the light theme's white card. */
.service-graph-section{
  padding-top:48px;padding-bottom:48px;
  --sg-tone:var(--violet);
  --sg-before:color-mix(in srgb,var(--warning) 64%,var(--paper));
  --sg-after:color-mix(in srgb,var(--cyan) 78%,var(--paper));
}
.sg-head{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:clamp(18px,3vw,36px);align-items:end}
.sg-head-copy{min-width:0}
.sg-head-copy .eyebrow{margin:0 0 10px;color:var(--cyan);font-size:.76rem;font-weight:780;letter-spacing:.07em;text-transform:uppercase}
.sg-head-copy h2{margin:6px 0 0;font-family:var(--font-display);font-size:clamp(1.6rem,3vw,2.3rem);font-weight:700;line-height:1.14;letter-spacing:-.018em;text-wrap:balance}
.sg-head-copy p{margin:14px 0 0;max-width:56ch;color:var(--silver);font-size:.95rem;line-height:1.55;text-wrap:pretty}
.sg-head-copy .actions{margin-top:22px}

.sg-controls{display:flex;flex-wrap:wrap;gap:8px;justify-content:flex-end}
.sg-controls[hidden]{display:none}
.sg-button{appearance:none;padding:8px 14px;border:1px solid var(--line-strong);border-radius:999px;background:color-mix(in srgb,var(--glass) 70%,transparent);color:var(--paper);font:inherit;font-size:.74rem;font-weight:700;letter-spacing:.02em;cursor:pointer;transition:border-color .18s ease,background .18s ease}
.sg-button:hover{border-color:color-mix(in srgb,var(--cyan) 55%,transparent)}
.sg-button:focus-visible{outline:2px solid var(--cyan);outline-offset:2px}
.sg-button--primary{background:color-mix(in srgb,var(--violet) 16%,transparent);border-color:color-mix(in srgb,var(--violet) 42%,transparent)}

/* ---- Stage --------------------------------------------------------------- */
.sg-stage{position:relative;margin-top:clamp(20px,3vw,32px);padding-top:56px;overflow:hidden;border:1px solid var(--line);border-radius:var(--radius);background:
  linear-gradient(color-mix(in srgb,var(--cyan) 4%,transparent) 1px,transparent 1px),
  linear-gradient(90deg,color-mix(in srgb,var(--violet) 4%,transparent) 1px,transparent 1px),
  radial-gradient(ellipse 60% 55% at 50% 48%,color-mix(in srgb,var(--violet) 12%,transparent),transparent 70%),
  var(--surface-2);
  background-size:38px 38px,38px 38px,auto,auto;box-shadow:var(--shadow)}
.sg-stage[hidden]{display:none}
/* On script-enabled wide screens the controller reveals the complete stage
   (SVG + detail panel). Keep that exact content in flow while hidden so its
   measured height, not an SVG-only estimate, is reserved before it boots.
   `scripting` preserves the server-rendered index as the no-JS floor without a
   permanent invisible gap. */
@media (min-width:861px) and (scripting:enabled){
  .sg-stage[hidden]{display:block;visibility:hidden;pointer-events:none}
}
.sg-legend{position:absolute;left:16px;top:14px;z-index:2;display:flex;flex-wrap:wrap;gap:8px;pointer-events:none}
.sg-badge{padding:6px 9px;border:1px solid var(--line);border-radius:999px;background:color-mix(in srgb,var(--ink) 74%,transparent);color:var(--silver);font-size:.6rem;font-weight:660;letter-spacing:.1em;text-transform:uppercase;backdrop-filter:blur(6px)}
.sg-badge b{color:var(--paper);font-weight:820}
.sg-svg{display:block;width:100%;height:auto;font-family:var(--font-body)}

/* ---- Backdrop ------------------------------------------------------------ */
.sg-orbit{fill:none;stroke:color-mix(in srgb,var(--violet) 18%,transparent);stroke-width:1;stroke-dasharray:3 12}
.sg-domain-arc{fill:none;stroke-width:18;stroke-linecap:round;opacity:.1;pointer-events:none;stroke:var(--violet)}
.sg-domain-arc[data-tone="health"]{stroke:var(--cyan)}
.sg-domain-arc[data-tone="growth"]{stroke:var(--lavender)}

/* ---- Core ---------------------------------------------------------------- */
.sg-core-shell{fill:color-mix(in srgb,var(--ink) 86%,transparent);stroke:color-mix(in srgb,var(--violet) 62%,transparent);stroke-width:1.3}
.sg-core-hex{fill:color-mix(in srgb,var(--glass) 78%,transparent);stroke:color-mix(in srgb,var(--cyan) 42%,transparent);stroke-width:1.2}
.sg-core-hex--inner{fill:color-mix(in srgb,var(--violet) 16%,transparent);stroke:color-mix(in srgb,var(--violet) 66%,transparent)}
.sg-core-label{fill:var(--paper);font-size:12px;font-weight:820;letter-spacing:.11em;text-anchor:middle}
.sg-core-tag{fill:var(--cyan);font-size:7.6px;font-weight:820;letter-spacing:.1em;text-anchor:middle}

/* ---- Edges --------------------------------------------------------------- */
.sg-edge{fill:none;stroke-linecap:round;stroke-linejoin:round;pointer-events:none}
.sg-edge--role{stroke:color-mix(in srgb,var(--lavender) 26%,transparent);stroke-width:1.2}
.sg-edge--core{stroke:color-mix(in srgb,var(--violet) 34%,transparent);stroke-width:1.5}
.sg-edge-glow{fill:none;stroke:color-mix(in srgb,var(--cyan) 20%,transparent);stroke-width:7;opacity:0;pointer-events:none}
.sg-edge--core.is-active{stroke:var(--cyan);stroke-width:2.3;stroke-dasharray:5 10}
.sg-edge--role.is-active{stroke:color-mix(in srgb,var(--cyan) 62%,transparent);stroke-dasharray:4 10}
.sg-edge-glow.is-active{opacity:1}
.sg-arrow path{fill:color-mix(in srgb,var(--cyan) 62%,transparent)}
.sg-bridge{fill:none;stroke:color-mix(in srgb,var(--cyan) 22%,transparent);stroke-width:1.2;stroke-dasharray:4 9;opacity:.6;pointer-events:none}
.sg-bridge--strong{stroke-width:1.5;opacity:.82}
.sg-bridge.is-active{stroke:var(--cyan);stroke-width:2.3;opacity:1}
.sg-edge.is-dimmed,.sg-edge-glow.is-dimmed,.sg-bridge.is-dimmed{opacity:.08}
.sg-pulse-dot{fill:var(--cyan);opacity:0;pointer-events:none}
.sg-pulse-dot.is-active{opacity:1}

.sg-bridge-label{pointer-events:none}
.sg-bridge-label-bg{fill:color-mix(in srgb,var(--ink) 88%,transparent);stroke:var(--line-strong);stroke-width:1}
.sg-bridge-label-text{fill:var(--silver);font-size:8.4px;font-weight:700;letter-spacing:.02em;text-anchor:middle}
.sg-bridge-label.is-active .sg-bridge-label-bg{fill:color-mix(in srgb,var(--cyan) 14%,var(--ink));stroke:color-mix(in srgb,var(--cyan) 45%,transparent)}
.sg-bridge-label.is-active .sg-bridge-label-text{fill:var(--paper)}
.sg-bridge-label.is-dimmed{opacity:.12}

/* ---- Nodes --------------------------------------------------------------- */
.sg-node{cursor:pointer;--sg-tone:var(--violet)}
.sg-node[data-tone="health"]{--sg-tone:var(--cyan)}
.sg-node[data-tone="growth"]{--sg-tone:var(--lavender)}
.sg-hit{fill:transparent}
.sg-chip{fill:color-mix(in srgb,var(--ink) 88%,transparent);stroke:color-mix(in srgb,var(--sg-tone) 30%,transparent);stroke-width:1}
.sg-chip-text{fill:var(--silver);font-size:8px;font-weight:800;letter-spacing:.11em;text-transform:uppercase;text-anchor:middle}
.sg-card-shadow{fill:color-mix(in srgb,var(--sg-tone) 12%,transparent)}
.sg-card-face{fill:var(--glass);stroke:color-mix(in srgb,var(--sg-tone) 52%,transparent);stroke-width:1.2}
.sg-card-title{fill:var(--paper);font-size:11.4px;font-weight:820;letter-spacing:-.01em;text-anchor:middle}
.sg-badge-bg{stroke-width:1;fill:color-mix(in srgb,var(--sg-tone) 18%,transparent);stroke:color-mix(in srgb,var(--sg-tone) 44%,transparent)}
.sg-badge-bg--before{fill:color-mix(in srgb,var(--sg-before) 20%,transparent);stroke:color-mix(in srgb,var(--sg-before) 48%,transparent)}
.sg-badge-bg--after{fill:color-mix(in srgb,var(--sg-after) 20%,transparent);stroke:color-mix(in srgb,var(--sg-after) 48%,transparent)}
.sg-badge-text{font-size:7.4px;font-weight:900;letter-spacing:.14em;text-anchor:middle;fill:var(--paper)}
.sg-badge-text--before{fill:var(--sg-before)}
.sg-badge-text--after{fill:var(--sg-after)}
.sg-state-bg{stroke-width:1}
.sg-state-bg--before{fill:color-mix(in srgb,var(--sg-before) 10%,transparent);stroke:color-mix(in srgb,var(--sg-before) 34%,transparent)}
.sg-state-bg--after{fill:color-mix(in srgb,var(--sg-after) 10%,transparent);stroke:color-mix(in srgb,var(--sg-after) 34%,transparent)}
.sg-state-kicker{font-size:7px;font-weight:900;letter-spacing:.16em;text-anchor:middle}
.sg-state-kicker--before{fill:var(--sg-before)}
.sg-state-kicker--after{fill:var(--sg-after)}
.sg-state-text{font-size:10px;font-weight:800;text-anchor:middle;fill:var(--paper)}
.sg-node.is-before .sg-card-face{stroke:color-mix(in srgb,var(--sg-before) 72%,transparent)}
.sg-node.is-after .sg-card-face{stroke:color-mix(in srgb,var(--sg-after) 72%,transparent)}
.sg-node.is-pinned .sg-card-face,.sg-node.is-pinned .sg-chip,.sg-node:focus-visible .sg-card-face,.sg-node:focus-visible .sg-chip{stroke:var(--cyan);stroke-width:1.8}
.sg-node.is-preview .sg-card-face,.sg-node.is-preview .sg-chip{stroke:color-mix(in srgb,var(--cyan) 74%,transparent);stroke-width:1.6}
.sg-node.is-dimmed{opacity:.24}
.sg-node:focus{outline:none}

/* ---- Card glyphs --------------------------------------------------------- */
.sg-glyph .sg-stroke{fill:none;stroke:color-mix(in srgb,var(--sg-tone) 72%,transparent);stroke-width:1.1;stroke-linecap:round;stroke-linejoin:round}
.sg-glyph .sg-accent{fill:none;stroke:var(--cyan);stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round}
.sg-glyph .sg-fill{fill:color-mix(in srgb,var(--sg-tone) 16%,transparent);stroke:color-mix(in srgb,var(--sg-tone) 72%,transparent);stroke-width:1}
.sg-glyph .sg-fill-accent{fill:color-mix(in srgb,var(--cyan) 12%,transparent);stroke:color-mix(in srgb,var(--cyan) 86%,transparent);stroke-width:1}
.sg-glyph .sg-dot{fill:var(--cyan)}
.sg-glyph .sg-dot-2{fill:var(--sg-tone)}
.sg-glyph .sg-faint{opacity:.4}

/* ---- Detail bar ---------------------------------------------------------- */
.sg-detail{display:grid;grid-template-columns:minmax(0,1.15fr) minmax(280px,.85fr);gap:18px;align-items:start;padding:16px 18px;border-top:1px solid var(--line);background:color-mix(in srgb,var(--ink) 62%,transparent)}
.sg-detail-title{margin:0 0 5px;font-size:.85rem;font-weight:820;letter-spacing:-.01em;color:var(--paper)}
.sg-detail-body{margin:0;color:var(--silver);font-size:.8rem;line-height:1.55;text-wrap:pretty}
.sg-detail-link{display:inline-block;margin-top:10px;font-size:.78rem}
.sg-detail-link[hidden]{display:none}
.sg-pills{display:flex;flex-wrap:wrap;gap:7px;justify-content:flex-end}
.sg-pill{padding:5px 9px;border:1px solid var(--line);border-radius:999px;background:color-mix(in srgb,var(--glass) 55%,transparent);color:var(--silver);font-size:.62rem;font-weight:640;letter-spacing:.02em}
.sg-pill b{color:var(--paper);font-weight:820}

/* ---- Index --------------------------------------------------------------- */
/* Resting shape: a readable two-column list, because with no ring on screen it
   is the section. Once the ring is up it collapses to a chip rail under it —
   still the only thing here that navigates, since the ring's nodes pin rather
   than link. */
.sg-index{display:grid;grid-template-columns:repeat(auto-fit,minmax(280px,1fr));gap:10px;margin:clamp(20px,3vw,30px) 0 0;padding:0;list-style:none}
.sg-index-item{--sg-tone:var(--violet);min-width:0}
.sg-index-item[data-tone="health"]{--sg-tone:var(--cyan)}
.sg-index-item[data-tone="growth"]{--sg-tone:var(--lavender)}
.sg-index-item>a{display:flex;gap:12px;align-items:flex-start;padding:12px 14px;border:1px solid var(--line);border-radius:14px;background:color-mix(in srgb,var(--glass) 46%,transparent);color:inherit;text-decoration:none;transition:border-color .18s ease,background .18s ease}
.sg-index-item>a:hover,.sg-index-item>a:focus-visible{border-color:color-mix(in srgb,var(--sg-tone) 46%,transparent);background:color-mix(in srgb,var(--sg-tone) 9%,transparent)}
.sg-index-code{flex:0 0 auto;display:grid;place-items:center;width:34px;height:34px;border-radius:10px;background:color-mix(in srgb,var(--sg-tone) 18%,transparent);border:1px solid color-mix(in srgb,var(--sg-tone) 40%,transparent);color:var(--paper);font-size:.66rem;font-weight:820;letter-spacing:.02em}
.sg-index-body{display:flex;flex-direction:column;gap:2px;min-width:0}
.sg-index-role{color:var(--silver);font-size:.64rem;font-weight:760;letter-spacing:.09em;text-transform:uppercase}
.sg-index-title{color:var(--paper);font-size:.86rem;font-weight:700;letter-spacing:-.01em}
.sg-index-shift{display:flex;flex-wrap:wrap;gap:6px;align-items:baseline;font-size:.72rem;font-weight:660}
.sg-index-shift .sg-before{color:var(--sg-before)}
.sg-index-shift .sg-after{color:var(--sg-after)}
.sg-index-shift .sg-arrowhead{color:var(--silver)}

.sg-has-stage .sg-index{grid-template-columns:none;display:flex;flex-wrap:wrap;gap:7px;margin-top:16px}
.sg-has-stage .sg-index-item>a{gap:8px;align-items:center;padding:6px 12px 6px 8px;border-radius:999px}
.sg-has-stage .sg-index-code{width:24px;height:24px;border-radius:8px;font-size:.56rem}
.sg-has-stage .sg-index-role,.sg-has-stage .sg-index-shift{display:none}
.sg-has-stage .sg-index-title{font-size:.74rem;font-weight:660}

/* ---- Stats --------------------------------------------------------------- */
.ecosystem-stats{display:flex;flex-wrap:wrap;gap:24px;margin-top:36px;padding-top:26px;border-top:1px solid var(--line)}
.ecosystem-stat{display:flex;flex-direction:column;gap:4px;min-width:140px}
.ecosystem-stat strong{font-family:var(--font-body);font-size:1.35rem;font-weight:820;color:var(--paper);letter-spacing:-.01em}
.ecosystem-stat span{color:var(--silver);font-size:.78rem;font-weight:660;letter-spacing:.03em;text-transform:uppercase}

/* ---- Motion -------------------------------------------------------------- */
/* The SMIL pulses that travel along the edges are not created at all under
   reduced motion (CSS cannot pause them once they exist); everything below is
   the part CSS does own. */
@media(prefers-reduced-motion:no-preference){
  .sg-edge--core.is-active,.sg-edge--role.is-active,.sg-bridge.is-active{animation:sg-flow 1.3s linear infinite}
  .sg-node .sg-spin{transform-box:fill-box;transform-origin:center}
  .sg-node.is-pinned .sg-spin,.sg-node.is-preview .sg-spin{animation:sg-spin 5.6s linear infinite}
  .sg-node .sg-pulse,.sg-node .sg-scan{transform-box:fill-box;transform-origin:center}
  .sg-node.is-pinned .sg-pulse,.sg-node.is-preview .sg-pulse{animation:sg-throb 1.7s ease-in-out infinite}
  .sg-node.is-pinned .sg-scan,.sg-node.is-preview .sg-scan{animation:sg-scan 2.2s ease-in-out infinite}
  .sg-node.is-pinned .sg-flow,.sg-node.is-preview .sg-flow{animation:sg-flow 1.15s linear infinite}
  .sg-node .sg-card{transform-box:fill-box;transform-origin:center}
  .sg-node.is-turning .sg-card{animation:sg-turn .4s cubic-bezier(.2,.7,.2,1)}
  .sg-index-item>a{transition:transform .3s cubic-bezier(.22,.75,.3,1),border-color .18s ease,background .18s ease}
  .sg-index-item>a:hover{transform:translateY(-2px)}
}
@keyframes sg-flow{to{stroke-dashoffset:-26}}
@keyframes sg-spin{to{transform:rotate(360deg)}}
@keyframes sg-throb{0%,100%{opacity:.4;transform:scale(.9)}50%{opacity:1;transform:scale(1.1)}}
@keyframes sg-scan{0%,100%{transform:translateY(-7px);opacity:.3}50%{transform:translateY(7px);opacity:1}}
@keyframes sg-turn{0%{transform:scaleX(1)}48%,52%{transform:scaleX(.05)}100%{transform:scaleX(1)}}

@media(max-width:1080px){
  .sg-detail{grid-template-columns:1fr}
  .sg-pills{justify-content:flex-start}
}
@media(max-width:900px){
  .sg-head{grid-template-columns:1fr}
  .sg-controls{justify-content:flex-start}
}
@media(max-width:480px){
  .ecosystem-stats{flex-direction:column;gap:18px}
  .sg-index{grid-template-columns:1fr}
}

/* ---- 07 Engagement ladder ----------------------------------------------- */
/* A timeline with a violet-to-cyan spine, the same grammar the landing pages
   use for phases. Deliberately not a card grid: it sits between the catalogue
   mosaic and the FAQ, and three grids in a row is the failure mode. */
.ladder{position:relative;list-style:none;margin:0;padding:0 0 0 6px;counter-reset:ladder}
.ladder:before{content:"";position:absolute;left:22px;top:14px;bottom:14px;width:1px;background:linear-gradient(180deg,var(--violet),var(--cyan))}
.ladder-step{position:relative;display:grid;grid-template-columns:44px minmax(0,1fr) auto auto;align-items:center;gap:10px 18px;padding:16px 0;border-bottom:1px solid var(--line)}
.ladder-step:last-child{border-bottom:0}
.ladder-glyph{position:relative;z-index:1;display:grid;place-items:center;width:34px;height:34px;border-radius:11px;background:color-mix(in srgb,var(--violet) 18%,var(--ink));border:1px solid color-mix(in srgb,var(--violet) 40%,transparent);color:var(--paper);font-size:.9rem;font-weight:800}
.ladder-body h3{margin:0 0 3px;font-family:var(--font-body);font-size:1rem;letter-spacing:-.01em}
.ladder-body p{margin:0;color:var(--silver);font-size:.85rem;line-height:1.45}
.ladder-unit{color:var(--silver);font-size:.72rem;font-weight:700;letter-spacing:.05em;text-transform:uppercase;white-space:nowrap}
.ladder-link{color:var(--cyan);font-size:.8rem;font-weight:700;text-decoration:none;white-space:nowrap;border-bottom:1px solid color-mix(in srgb,var(--cyan) 34%,transparent)}
.ladder-link:hover{border-bottom-color:var(--cyan)}
.ladder-foot{display:flex;flex-wrap:wrap;gap:10px 26px;margin-top:22px}
@media(max-width:760px){
  .ladder-step{grid-template-columns:34px minmax(0,1fr);align-items:start}
  .ladder-unit,.ladder-link{grid-column:2}
}

/* ---- 08 Editorial system — squeezy canvas carousel, seam, catalogue map */
/* Replaces the current-work list. The section keeps its id and its telemetry
   token; what it carries is one editorial block and one commercial block, and
   each answers exactly one question — what has just been published, and what
   is on sale. The carousel is articles only; the catalogue reaches this page
   as its four families rather than its forty rows.

   The carousel is two elements and the split between them is the design. A
   single <canvas> draws every card at once — the active one taking about two
   thirds of the width, the ones behind it halving down to a row of pips — and
   is `aria-hidden`, because it is a picture of the carousel and holds none of
   its meaning. Underneath it, ordinary DOM carries the kicker, the heading, the
   paragraph and the link, one block at a time, in both locales.

   Visibility of a detail block is driven by its `aria-hidden` attribute and
   nothing else. The controller sets that one attribute; the rules below decide
   what it looks like. Two declarations of one state is how they drift apart.

   Without scripting there is no canvas: the cover image inside the first detail
   block stands in for it, and the whole section stays a heading, a picture, a
   sentence and a link. */

.editorial-head{display:grid;grid-template-columns:minmax(0,8fr) minmax(0,auto);gap:20px 48px;align-items:end;margin-bottom:30px}
.editorial-head-copy>*{display:inline;margin:0;max-width:none;font-family:var(--font-display);font-weight:700;font-size:clamp(1.35rem,3.4vw,2.15rem);line-height:1.2;letter-spacing:-.018em;text-wrap:pretty}
.editorial-head-copy p{color:color-mix(in srgb,var(--silver) 88%,transparent)}
.editorial-head-actions{display:flex;flex-wrap:wrap;align-items:center;gap:10px}
.editorial-head-actions .button{min-height:44px;padding:10px 16px;font-size:.86rem}
.editorial-controls{display:flex;flex:none;gap:8px}

.squeezy-carousel{display:flex;flex-direction:column;gap:clamp(20px,2.6vw,32px)}

/* The canvas is sized in device pixels by the controller; the aspect-ratio here
   only has to hold the space before it runs, so the section does not jump. */
.editorial-canvas-wrap{position:relative;width:100%;margin:0 auto}
.editorial-canvas{display:block;width:100%;aspect-ratio:2.68/1}
.editorial-carousel:not(.is-live) .editorial-canvas-wrap{display:none}
.editorial-carousel.is-live .editorial-detail-cover{display:none}
.editorial-detail-cover{display:block;width:100%;height:auto;aspect-ratio:2.68/1;object-fit:cover;border-radius:var(--radius);border:1px solid var(--line);margin-bottom:20px}

/* Every detail block occupies the same grid cell, so the container is as tall
   as the longest of them and switching items never moves the page. */
.editorial-details{display:grid;align-items:start}
.editorial-detail{grid-area:1/1;display:grid;grid-template-columns:minmax(0,1.55fr) minmax(0,1fr);gap:clamp(18px,3vw,48px);align-items:start;transition:opacity .12s ease}
.editorial-detail[aria-hidden=true]{opacity:0;pointer-events:none;visibility:hidden;transition:opacity .12s ease,visibility 0s linear .12s}
.editorial-detail-copy{min-width:0}
.editorial-detail-copy>*{display:inline;margin:0;font-size:clamp(1rem,1.5vw,1.16rem);line-height:1.55;text-wrap:pretty}
.editorial-detail-kicker{margin-right:.6em!important;color:var(--cyan);font-size:.68rem!important;font-weight:800;letter-spacing:.14em;text-transform:uppercase;vertical-align:.18em}
.editorial-detail[data-accent=violet] .editorial-detail-kicker{color:color-mix(in srgb,var(--violet) 62%,var(--paper))}
.editorial-detail-title{font-family:var(--font-display);font-weight:700;color:var(--paper);letter-spacing:-.012em}
.editorial-detail-title:after{content:" "}
/* The controller paints the title onto the active card, as the reference does.
   Printing the same sentence again two centimetres below it reads as a
   rendering fault, so the heading stops being *shown* — it does not stop
   existing. The canvas is `aria-hidden` and can carry no heading at all, so
   this element remains the item's only accessible name, and its only
   translatable, selectable, crawlable copy. */
.editorial-carousel.is-live .editorial-detail-title{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}
.editorial-carousel.is-live .editorial-detail-title:after{content:none}
.editorial-detail-body{color:color-mix(in srgb,var(--silver) 92%,transparent)}
.editorial-detail-side{display:flex;flex-direction:column;align-items:flex-start;gap:14px}
.editorial-detail-plate{display:flex;flex-wrap:wrap;gap:6px 20px;margin:0}
.editorial-detail-plate>div{display:flex;flex-direction:column;gap:2px}
.editorial-detail-plate dt{color:var(--silver);font-size:.64rem;font-weight:800;letter-spacing:.1em;text-transform:uppercase}
.editorial-detail-plate dd{margin:0;color:var(--paper);font-size:.86rem;font-weight:700}
.editorial-detail-cta{min-height:44px;white-space:nowrap}

/* ---- The seam ----------------------------------------------------------- */
/* Flanks are two elements and not one background because each wipes outward
   from the mark towards its own edge, which one background cannot do. */
.pulse-divider{display:flex;align-items:center;gap:14px;margin:clamp(38px,6vw,62px) 0}
.pulse-divider-rule{flex:1 1 0;height:1px;min-width:0;background-image:repeating-linear-gradient(90deg,color-mix(in srgb,var(--lavender) 55%,transparent) 0 2px,transparent 2px 5px)}
.pulse-divider-mark{flex:none;display:block;width:64px;color:color-mix(in srgb,var(--cyan) 78%,var(--paper))}
.pulse-divider-mark svg{display:block;width:100%;height:auto}
.pulse-divider-label{flex:none;color:var(--silver);font-size:.72rem;font-weight:780;letter-spacing:.07em;text-transform:uppercase}

/* ---- Featured resource -------------------------------------------------- */
.featured-resource{display:grid;grid-template-columns:minmax(0,.82fr) minmax(0,1.18fr);gap:clamp(26px,4vw,52px);align-items:center}
.featured-resource-signup{grid-column:1/-1}
/* The stage. The object on it is built rather than photographed — there is no
   cover art for any product in this catalogue, and a stock book mockup would
   picture a document that does not exist in that form. */
.featured-resource-stage{position:relative;display:grid;place-items:center;aspect-ratio:4/3;border:1px solid var(--line);border-radius:var(--radius);background:linear-gradient(155deg,color-mix(in srgb,var(--violet) 22%,var(--ink)),var(--ink) 68%);overflow:hidden}
.featured-resource-stage:before{content:"";position:absolute;inset:0;background:radial-gradient(52% 46% at 50% 42%,color-mix(in srgb,var(--violet) 46%,transparent),transparent 72%),radial-gradient(38% 32% at 74% 80%,color-mix(in srgb,var(--cyan) 22%,transparent),transparent 70%)}
.featured-resource-stage:after{content:"";position:absolute;inset:0;background-image:linear-gradient(color-mix(in srgb,var(--paper) 5%,transparent) 1px,transparent 1px),linear-gradient(90deg,color-mix(in srgb,var(--paper) 5%,transparent) 1px,transparent 1px);background-size:34px 34px;-webkit-mask-image:radial-gradient(ellipse 62% 58% at 50% 46%,#000,transparent 76%);mask-image:radial-gradient(ellipse 62% 58% at 50% 46%,#000,transparent 76%)}
.featured-resource-object{position:relative;z-index:1;display:flex;flex-direction:column;gap:14px;width:min(62%,240px);aspect-ratio:3/4;padding:20px;border:1px solid color-mix(in srgb,var(--paper) 22%,transparent);border-radius:14px;background:linear-gradient(160deg,color-mix(in srgb,var(--paper) 12%,transparent),color-mix(in srgb,var(--ink) 60%,transparent));box-shadow:0 30px 70px rgba(6,8,32,.5),inset 0 1px 0 color-mix(in srgb,var(--paper) 20%,transparent);backdrop-filter:blur(6px)}
.featured-resource-object-head{display:flex;align-items:center;justify-content:space-between;gap:10px}
.featured-resource-mark{display:block;width:34px;height:auto;color:var(--cyan)}
.featured-resource-object-format{color:var(--silver);font-size:.62rem;font-weight:800;letter-spacing:.14em}
.featured-resource-object-title{font-family:var(--font-display);font-size:1.12rem;line-height:1.16;letter-spacing:-.02em;color:var(--paper);text-wrap:pretty}
.featured-resource-object-foot{margin-top:auto;padding-top:12px;border-top:1px solid color-mix(in srgb,var(--paper) 18%,transparent);color:color-mix(in srgb,var(--cyan) 80%,var(--paper));font-size:.72rem;font-weight:800;letter-spacing:.08em;text-transform:uppercase}

.featured-resource-copy{min-width:0}
.featured-resource-title{margin:14px 0 10px;font-family:var(--font-display);font-size:clamp(1.5rem,2.6vw,2.1rem);line-height:1.14;letter-spacing:-.02em;text-wrap:pretty}
.featured-resource-body{margin:0 0 16px;max-width:60ch;color:var(--silver);line-height:1.6;text-wrap:pretty}
.featured-resource-price{margin:0 0 18px;font-size:.95rem;color:var(--silver)}
.featured-resource-price b{color:var(--cyan);font-size:1.1rem}
.featured-resource-actions{display:flex;flex-wrap:wrap;gap:10px}
.featured-resource-actions .button{min-height:46px}
.featured-resource-signup{margin-top:8px;padding-top:26px;border-top:1px solid var(--line)}

/* ---- Catalogue map ------------------------------------------------------- */
/* What replaced the paid-products grid, and why the shape changed with it.

   The grid drew every active paid product as a card with a 4:3 image: forty
   cards on this page, and thirty of them self-build/operator variants of the
   same fifteen frameworks. It was the largest block of markup on the homepage
   and the heaviest thing in its critical path, to say something /ressources/
   already says better. A hub owes the visitor the *shape* of a collection and
   a way in; the collection itself belongs to the collection's own page.

   So four rows replace forty cards, one per non-empty product family, and the
   row is deliberately the `.sg-index-item` shape from the service graph above
   rather than a new one: both are "a compact list of real links that is the
   only navigating thing in its section", and a hub that invents a second card
   idiom for that is a hub with two vocabularies for one job. The tone mapping
   is the taxonomy's own — systems/health/growth — so a family keeps the colour
   it carries in the mega menu and on the catalogue page.

   No image per row. There is no cover art for any product in this catalogue
   (the grid was drawing atomic-design plates chosen by `{% cycle %}`, i.e. a
   picture unrelated to the product under it), and a family is an abstraction
   anyway. The count and the opening price carry the weight instead, which is
   the pair of facts that actually decides whether a branch is worth opening. */
.catalogue-map{display:grid;gap:clamp(20px,2.6vw,30px)}
.catalogue-map-head .eyebrow{margin-bottom:8px}
.catalogue-map-head h2{font-family:var(--font-display);font-size:clamp(1.5rem,2.6vw,2.1rem);line-height:1.14;letter-spacing:-.02em;text-wrap:pretty;margin:0 0 10px}
.catalogue-map-head p{margin:0;color:var(--silver);line-height:1.6;max-width:70ch}

/* Two columns and not ``auto-fit``: the families are an even number (four
   today, six if the webinar and capacity categories ever fill), and auto-fit
   resolved to three at this container width, which left the fourth alone on
   its own row. A hub block that ends in a ragged orphan reads as a grid that
   ran out rather than as a complete set of choices. */
.catalogue-families{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:12px;margin:0;padding:0;list-style:none}
.catalogue-family{--cm-tone:var(--violet);min-width:0}
.catalogue-family[data-tone="health"]{--cm-tone:var(--cyan)}
.catalogue-family[data-tone="growth"]{--cm-tone:var(--lavender)}
.catalogue-family>a{display:flex;gap:14px;align-items:flex-start;height:100%;padding:16px 18px;border:1px solid var(--line);border-radius:16px;background:color-mix(in srgb,var(--glass) 46%,transparent);color:inherit;text-decoration:none;transition:border-color .18s ease,background .18s ease}
.catalogue-family>a:hover,.catalogue-family>a:focus-visible{border-color:color-mix(in srgb,var(--cm-tone) 46%,transparent);background:color-mix(in srgb,var(--cm-tone) 9%,transparent)}
/* The numeral is emphasis for a fact the meta line states in words, so it is
   aria-hidden in the markup and sized like a figure rather than like copy. */
.catalogue-family-count{flex:0 0 auto;display:grid;place-items:center;min-width:44px;height:44px;padding:0 8px;border-radius:12px;background:color-mix(in srgb,var(--cm-tone) 18%,transparent);border:1px solid color-mix(in srgb,var(--cm-tone) 40%,transparent);color:var(--paper);font-family:var(--font-display);font-size:1.15rem;font-weight:820;letter-spacing:-.02em;font-variant-numeric:tabular-nums}
.catalogue-family-image{flex:0 0 auto;width:56px;height:56px;border-radius:12px;overflow:hidden;border:1px solid var(--line);background:color-mix(in srgb,var(--glass) 46%,transparent)}
.catalogue-family-image img{width:100%;height:100%;object-fit:cover;display:block}
.catalogue-family-body{display:flex;flex-direction:column;gap:4px;min-width:0;flex:1}
.catalogue-family-title{color:var(--paper);font-size:.95rem;font-weight:760;letter-spacing:-.01em}
/* Clamped, because the blurb is the taxonomy’s own and they are not written
   to one length — the packs blurb is five lines where the others are two, and
   left alone it stretches its whole grid row. Two lines is what a family needs
   here; the full sentence is on the category page the row opens. */
.catalogue-family-blurb{display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;line-clamp:2;overflow:hidden;color:var(--silver);font-size:.8rem;line-height:1.5;text-wrap:pretty}
.catalogue-family-meta{display:flex;flex-wrap:wrap;gap:6px 10px;margin-top:2px;color:var(--silver);font-size:.72rem;font-weight:700;letter-spacing:.02em}
.catalogue-family-from{color:color-mix(in srgb,var(--cm-tone) 80%,var(--paper))}
.catalogue-family .hover-arrow{flex:0 0 auto;align-self:center;color:var(--silver)}

.catalogue-map-actions{display:flex;flex-wrap:wrap;gap:10px}
.catalogue-map-actions .button{min-height:46px}
.catalogue-map-signup{margin-top:8px;padding-top:26px;border-top:1px solid var(--line)}

@media(max-width:760px){
  .catalogue-families{grid-template-columns:1fr;gap:10px}
  .catalogue-family>a{padding:14px 15px;gap:12px}
  .catalogue-map-actions .button{width:100%}
}

@media(prefers-reduced-motion:no-preference){
  /* The seam draws itself once on arrival and then holds. `backwards`, not
     `both`: a filled animation keeps owning the property after it ends. */
  .pulse-divider-rule{transform:scaleX(0)}
  .pulse-divider-rule--start{transform-origin:right center}
  .pulse-divider-rule--end{transform-origin:left center}
  .pulse-divider.is-visible .pulse-divider-rule{transform:scaleX(1);transition:transform 1s cubic-bezier(.22,.75,.3,1) .1s}
  .pulse-divider-path{stroke-dasharray:120;stroke-dashoffset:120}
  .pulse-divider.is-visible .pulse-divider-path{stroke-dashoffset:0;transition:stroke-dashoffset .9s cubic-bezier(.22,.75,.3,1)}
  .featured-resource-object{transition:transform .5s cubic-bezier(.22,.75,.3,1)}
  .featured-resource:hover .featured-resource-object{transform:translateY(-6px) rotate(-1.2deg)}
}

@media(max-width:900px){
  .editorial-head{grid-template-columns:minmax(0,1fr);align-items:start;gap:18px}
  .editorial-head-actions{width:100%;justify-content:space-between}
  /* The copy and the link stop competing for one row; the plate and the CTA
     become a footer under the sentence rather than a column beside it. */
  .editorial-detail{grid-template-columns:minmax(0,1fr);gap:16px}
  .editorial-detail-side{flex-direction:row;flex-wrap:wrap;align-items:center;justify-content:space-between;width:100%;gap:12px 20px}
  .editorial-detail-cta{width:100%}
  .editorial-canvas,.editorial-detail-cover{aspect-ratio:2.1/1}
  .featured-resource{grid-template-columns:1fr;gap:24px}
  .featured-resource-stage{aspect-ratio:5/4;max-width:460px}
  .featured-resource-actions .button{width:100%}
}

/* Mirrors the controller's own narrow branch: below this the slivers are gone,
   the active card is full-bleed, and a 2.68:1 crop would be a letterbox strip
   with nothing legible left in it. */
@media(max-width:620px){
  .editorial-canvas,.editorial-detail-cover{aspect-ratio:1.5/1}
}

/* Specialties bento mosaic */
/* Bento grid — dense auto-flow so filtering re-packs without gaps */
.bento-grid{display:grid;grid-template-columns:repeat(4,1fr);grid-auto-rows:minmax(196px,auto);grid-auto-flow:row dense;gap:16px}
.bento-card{--fam:var(--violet);position:relative;text-decoration:none;color:inherit;border-radius:var(--radius);background:linear-gradient(160deg,var(--surface),var(--surface-2));border:1px solid var(--line);box-shadow:var(--shadow);overflow:hidden;transition:transform .35s cubic-bezier(.22,.75,.3,1),border-color .35s ease,box-shadow .35s ease,opacity .5s ease}
.bento-card[data-family="systems"]{--fam:var(--violet)}
.bento-card[data-family="health"]{--fam:var(--cyan)}
.bento-card[data-family="growth"]{--fam:var(--warning)}
.bento-card[data-tile="lg"]{grid-column:span 2;grid-row:span 2}
.bento-card[data-tile="wide"]{grid-column:span 2}
.bento-card:before{content:"";position:absolute;inset:0;background:radial-gradient(120% 90% at 100% 0,color-mix(in srgb,var(--fam) 14%,transparent),transparent 55%);opacity:0;transition:opacity .35s ease;pointer-events:none}
.bento-card:hover,.bento-card:focus-visible{transform:translateY(-4px);border-color:color-mix(in srgb,var(--fam) 50%,transparent);box-shadow:0 26px 74px rgba(6,8,32,.46),0 0 0 1px color-mix(in srgb,var(--fam) 40%,transparent),0 0 32px color-mix(in srgb,var(--fam) 20%,transparent)}
.bento-card:hover:before,.bento-card:focus-visible:before{opacity:1}
.bento-card-inner{display:flex;flex-direction:column;height:100%;padding:22px;position:relative;z-index:1}
.bento-top{display:flex;align-items:center;gap:10px;margin-bottom:12px}
.bento-card .icon-box{width:38px;height:38px;border-radius:11px;font-size:.86rem;background:color-mix(in srgb,var(--fam) 20%,transparent);color:color-mix(in srgb,var(--fam) 62%,var(--paper))}
.bento-badge{display:inline-flex;align-items:center;border:1px solid color-mix(in srgb,var(--fam) 40%,transparent);background:color-mix(in srgb,var(--fam) 12%,transparent);color:color-mix(in srgb,var(--fam) 78%,var(--paper));border-radius:999px;padding:4px 10px;font-size:.62rem;font-weight:800;letter-spacing:.08em;text-transform:uppercase}
.bento-card h3{font-family:var(--font-body);font-size:1.05rem;margin:0 0 8px;letter-spacing:-.02em;line-height:1.25}
.bento-card p{color:var(--silver);font-size:.84rem;line-height:1.5;margin:0 0 14px}
.bento-extra{color:color-mix(in srgb,var(--silver) 82%,transparent);font-size:.82rem}
.bento-card small{display:block;margin-top:auto;color:color-mix(in srgb,var(--fam) 72%,var(--silver));font-size:.72rem;font-weight:700;letter-spacing:.06em;text-transform:uppercase}
.bento-arrow{position:absolute;top:20px;right:20px;width:32px;height:32px;display:grid;place-items:center;border-radius:10px;background:color-mix(in srgb,var(--fam) 16%,transparent);color:color-mix(in srgb,var(--fam) 60%,var(--paper));font-size:1.1rem;font-weight:700;opacity:0;transform:translateX(-6px);transition:opacity .3s ease,transform .3s ease;z-index:2}
.bento-card:hover .bento-arrow,.bento-card:focus-visible .bento-arrow{opacity:1;transform:translateX(0)}
.bento-card[data-tile="lg"] .icon-box{width:46px;height:46px;border-radius:13px;font-size:1rem}
.bento-card[data-tile="lg"] h3{font-size:1.5rem;margin-bottom:10px}
.bento-card[data-tile="lg"] p{font-size:.92rem}
.bento-card.is-hidden{display:none}
.bento-grid.js-reveal .bento-card{opacity:0}
.bento-grid.js-reveal.is-visible .bento-card{opacity:1;transition:opacity .55s ease calc(var(--i) * 45ms),transform .35s cubic-bezier(.22,.75,.3,1),border-color .35s ease,box-shadow .35s ease}

/* Family filter chips (--fam drives each chip's accent) */
.bento-filters{display:flex;flex-wrap:wrap;gap:10px;margin-top:6px;margin-bottom:22px}
.filter-chip{--fam:var(--violet);display:inline-flex;align-items:center;gap:8px;border:1px solid var(--line);background:color-mix(in srgb,var(--fam) 6%,transparent);color:var(--paper);border-radius:999px;padding:8px 15px;font:inherit;font-size:.78rem;font-weight:700;letter-spacing:.02em;cursor:pointer;transition:border-color .25s ease,background .25s ease,color .25s ease}
.filter-chip[data-fam="systems"]{--fam:var(--violet)}
.filter-chip[data-fam="health"]{--fam:var(--cyan)}
.filter-chip[data-fam="growth"]{--fam:var(--warning)}
.chip-dot{width:9px;height:9px;border-radius:50%;background:var(--fam);box-shadow:0 0 12px color-mix(in srgb,var(--fam) 70%,transparent)}
.chip-dot.all{background:conic-gradient(from 210deg,var(--violet),var(--cyan),var(--warning),var(--violet))}
.filter-chip:hover{border-color:color-mix(in srgb,var(--fam) 45%,transparent)}
.filter-chip.is-active{border-color:color-mix(in srgb,var(--fam) 60%,transparent);background:color-mix(in srgb,var(--fam) 16%,transparent)}
.filter-chip:focus-visible{outline:2px solid var(--cyan);outline-offset:2px}

/* Bento reveal + filtering are handled together with the grid rules above. */

/* Consultant band — the face behind the hero promise, paired with the numbers
   that back it. Photo leads on the left so the eye lands on the person before
   the metrics. */
.consultant-section{padding-top:48px;padding-bottom:48px}
.consultant-band{display:grid;grid-template-columns:minmax(0,.92fr) minmax(0,1.08fr);gap:clamp(26px,4vw,54px);align-items:center}
.consultant-photo{aspect-ratio:5/4;border-radius:var(--radius)}
.consultant-copy{min-width:0}
.consultant-name{margin:16px 0 2px;font-family:var(--font-display);font-size:clamp(1.7rem,3vw,2.4rem);line-height:1.1;letter-spacing:-.02em}
.consultant-role{margin:0 0 18px;color:var(--cyan);font-size:.82rem;font-weight:780;letter-spacing:.06em;text-transform:uppercase}
.consultant-line{margin:0 0 14px;max-width:56ch;color:var(--silver);text-wrap:pretty}
.consultant-line:first-of-type{color:color-mix(in srgb,var(--paper) 84%,var(--silver));font-size:1.05rem}
.consultant-band .text-link{margin-top:6px}
.consultant-links{display:flex;flex-wrap:wrap;gap:10px 26px;margin:0}
.consultant-section .stats{margin-top:46px}
@media(max-width:900px){
  .consultant-band{grid-template-columns:1fr;gap:26px}
  .consultant-photo{max-width:540px}
  .consultant-section .stats{margin-top:34px}
}

/* Stats reveal */
.stats-section .stats>div{opacity:0;transform:translateY(18px);transition:opacity .7s ease,transform .7s cubic-bezier(.22,.75,.3,1)}
.stats-section.is-visible .stats>div{opacity:1;transform:translateY(0)}
.stats-section.is-visible .stats>div:nth-child(1){transition-delay:.05s}
.stats-section.is-visible .stats>div:nth-child(2){transition-delay:.15s}
.stats-section.is-visible .stats>div:nth-child(3){transition-delay:.25s}
.stats-section.is-visible .stats>div:nth-child(4){transition-delay:.35s}

/* Positioning animated SVG */
.positioning-section{position:relative;overflow:hidden}
.positioning-copy{position:relative;z-index:2}
.positioning-visual{display:flex;align-items:center;justify-content:center;padding:18px}
.positioning-visual svg{width:100%;max-width:420px;height:auto;filter:drop-shadow(0 0 30px rgba(102,38,239,.12))}
/* The rings used to rotate with SMIL <animateTransform>, which no media query
   can switch off — six indefinite loops that kept running under reduced motion.
   As CSS they inherit the site's static baseline and only start under
   no-preference. The pulsing glow, the blinking dots and the redrawing check
   line are gone entirely: they were motion without a message. */
/* fill-box, not view-box: these groups live inside <g transform="translate(200,200)">,
   so a viewBox-relative origin would resolve 200 units past the centre. Each
   ring's own bounding box is centred on its circles, so 50% 50% is the axis. */
.pv-ring{transform-box:fill-box;transform-origin:50% 50%}
@media(prefers-reduced-motion:no-preference){
  .pv-ring--slow{animation:pv-spin 40s linear infinite}
  .pv-ring--counter{animation:pv-spin 30s linear infinite reverse}
  .pv-ring--wide{animation:pv-spin 50s linear infinite}
}
@keyframes pv-spin{to{transform:rotate(360deg)}}

/* Positioning before/after grid (B&A boolean-intersection micro-grid) */
.ba-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:16px;margin:22px 0 26px}
.ba-col{display:flex;flex-direction:column;gap:10px;padding:20px;text-decoration:none;color:inherit;border:1px solid var(--line);border-radius:var(--radius);background:linear-gradient(160deg,var(--surface),var(--surface-2));transition:transform .3s cubic-bezier(.22,.75,.3,1),border-color .3s ease}
.ba-col:hover,.ba-col:focus-visible{transform:translateY(-3px);border-color:color-mix(in srgb,var(--violet) 46%,transparent)}
.ba-col-kicker{font-size:.72rem;font-weight:800;letter-spacing:.06em;text-transform:uppercase;color:var(--cyan)}
.ba-before,.ba-after{margin:0;font-size:.85rem;line-height:1.5;color:var(--silver)}
.ba-before strong,.ba-after strong{color:var(--paper);font-weight:760;margin-right:4px}
.ba-after strong{color:var(--lavender)}
.ba-link{margin-top:auto;display:inline-flex;align-items:center;gap:6px;font-size:.78rem;font-weight:760;color:var(--cyan)}
.ba-arrow{transition:transform .25s ease}
.ba-col:hover .ba-arrow{transform:translateX(4px)}
@media(max-width:900px){.ba-grid{grid-template-columns:1fr}}

/* The FAQ accordion lives in components/faq.css — one component for the
   homepage, the office hours page and both programme pages. */

/* Scroll reveal utility */
.reveal{opacity:0;transform:translateY(20px);transition:opacity .7s ease,transform .7s cubic-bezier(.22,.75,.3,1)}
.reveal.is-visible{opacity:1;transform:translateY(0)}

/* Responsive */
@media(max-width:1100px){
  /* 3 columns; the flagship stays wide but drops to a single row so a 2x2
     tile does not fight the narrower track. */
  .bento-grid{grid-template-columns:repeat(3,1fr)}
  .bento-card[data-tile="lg"]{grid-row:span 1}
}
@media(max-width:760px){
  .hero-ground{min-height:auto}
  .hero-ground .hero-grid{min-height:auto;padding-top:50px;padding-bottom:44px}
  .bento-grid{grid-template-columns:repeat(2,1fr);grid-auto-rows:minmax(180px,auto)}
  .bento-card[data-tile="lg"],.bento-card[data-tile="wide"]{grid-column:span 2;grid-row:span 1}
  .bento-card[data-tile="lg"] h3{font-size:1.25rem}
  .positioning-visual svg{max-width:280px}
}
@media(max-width:480px){
  .bento-grid{grid-template-columns:1fr}
  .bento-card[data-tile="lg"],.bento-card[data-tile="wide"]{grid-column:span 1}
}

/* Reduced motion */
@media(prefers-reduced-motion:reduce){
  .bento-card,.stats>div,.reveal{transition:none!important;opacity:1!important;transform:none!important}
}


/* Homepage 3D hero and specialty scroller */
.hero{position:relative;padding:50px 0 58px;overflow:hidden}
.hero-canvas{position:absolute;inset:0;z-index:0;pointer-events:none;opacity:.85}
.hero-grid{position:relative;z-index:1;display:grid;grid-template-columns:1.1fr .9fr;gap:44px;align-items:center}
/* Grid items default to min-width:auto, so a long display word can force the
   copy column wider than the viewport and .hero{overflow:hidden} clips it.
   Allowing the tracks to shrink keeps the headline and lead inside the frame. */
.hero-grid>*{min-width:0}
/* The global h1 clamp tops out at 5.8rem, which is sized for a full-width page
   title. In the hero's ~620px copy column that headline breaks into five ragged
   lines and pushes the CTAs under the fold, so the homepage hero scales its
   display size to the column it actually occupies. */
.hero-ground h1{overflow-wrap:break-word;font-size:clamp(2.4rem,4.4vw,4rem);margin:14px 0 18px}
.hero-copy{max-width:720px}
.hero-visual{position:relative;min-height:520px;border-radius:var(--radius);overflow:hidden;border:1px solid var(--line);background:linear-gradient(145deg,var(--surface),var(--surface-2));box-shadow:var(--shadow)}
.hero-visual canvas{display:block;width:100%!important;height:100%!important}
.hero-overlay{position:absolute;inset:0;background:linear-gradient(180deg,rgba(6,8,32,.15) 0%,rgba(6,8,32,.65) 100%);pointer-events:none}

/* Hero capability matrix — the hero visual is composed from real expertise
   data over the 3D shield, not a raster image. */
.hero-matrix{display:flex;flex-direction:column;padding:26px 24px;background:linear-gradient(158deg,color-mix(in srgb,var(--surface) 88%,transparent),color-mix(in srgb,var(--surface-2) 78%,transparent));border-color:var(--line-strong);backdrop-filter:blur(16px);-webkit-backdrop-filter:blur(16px)}
.hero-matrix-head{display:flex;align-items:center;justify-content:space-between;gap:14px}
.hero-matrix-badge{flex:none;padding:6px 11px;border-radius:999px;border:1px solid color-mix(in srgb,var(--violet) 40%,transparent);background:color-mix(in srgb,var(--violet) 15%,transparent);color:var(--lavender);font-size:.68rem;font-weight:760;letter-spacing:.03em;white-space:nowrap}
.hero-matrix-sub{margin:14px 0 6px;color:var(--paper);font-size:1.05rem;font-weight:640;line-height:1.4;max-width:30ch}
.hero-matrix-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;flex:1;justify-content:center}
.hero-matrix-list li+li{border-top:1px solid var(--line)}
.hero-matrix-list a{display:grid;grid-template-columns:auto 1fr auto;align-items:center;gap:15px;padding:16px 4px;text-decoration:none;color:inherit;border-radius:12px;transition:padding-left .3s cubic-bezier(.22,.75,.3,1),background .2s ease}
.hero-matrix-list a:hover{padding-left:12px;background:color-mix(in srgb,var(--violet) 8%,transparent)}
.hero-matrix-list a:hover .mega-tile{transform:scale(1.08)}
.hero-matrix-text{min-width:0}
.hero-matrix-text strong{display:block;font-size:.95rem;font-weight:680;color:var(--paper);letter-spacing:-.01em}
.hero-matrix-text small{display:block;margin-top:3px;color:var(--silver);font-size:.8rem;line-height:1.4}
.hero-matrix-arrow{color:var(--silver);font-size:1.05rem;transition:transform .3s ease,color .3s ease}
.hero-matrix-list a:hover .hero-matrix-arrow{transform:translateX(4px);color:var(--cyan)}
.hero-matrix-foot{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-top:6px;padding-top:16px;border-top:1px solid var(--line);color:var(--silver);font-size:.78rem;font-weight:660;text-decoration:none;transition:color .2s ease}
.hero-matrix-foot:hover{color:var(--cyan)}
.hero-matrix-foot:hover .hero-matrix-arrow{transform:translateX(4px);color:var(--cyan)}

/* Specialty horizontal scroller */
.specialty-scroller{display:flex;gap:16px;overflow-x:auto;scroll-snap-type:x mandatory;padding:18px 4px 24px;margin-top:26px;scrollbar-width:thin;scrollbar-color:var(--line) transparent}
.specialty-scroller::-webkit-scrollbar{height:8px}
.specialty-scroller::-webkit-scrollbar-track{background:transparent}
.specialty-scroller::-webkit-scrollbar-thumb{background:var(--line);border-radius:999px}
.specialty-card{flex:0 0 280px;scroll-snap-align:start;padding:18px;border:1px solid var(--line);border-radius:20px;background:linear-gradient(155deg,var(--surface),var(--surface-2));box-shadow:var(--shadow);text-decoration:none;color:inherit;transition:transform .35s cubic-bezier(.22,.75,.3,1),border-color .35s ease,box-shadow .35s ease;position:relative;overflow:hidden}
.specialty-card:hover{transform:translateY(-6px) rotateX(2deg);border-color:color-mix(in srgb,var(--cyan) 34%,transparent);box-shadow:0 30px 80px rgba(6,8,32,.55)}
.specialty-card:before{content:"";position:absolute;width:160px;height:160px;right:-50px;top:-50px;background:radial-gradient(circle,rgba(102,38,239,.28),transparent 68%);opacity:0;transition:opacity .4s ease}
.specialty-card:hover:before{opacity:1}
.specialty-card .icon-box{width:40px;height:40px;border-radius:12px;display:grid;place-items:center;background:color-mix(in srgb,var(--violet) 18%,transparent);color:color-mix(in srgb,var(--lavender) 55%,var(--paper));font-weight:820;margin-bottom:12px;font-size:.82rem;border:1px solid color-mix(in srgb,var(--violet) 22%,transparent)}
.specialty-card h3{font-family:var(--font-body);font-size:1.05rem;margin-bottom:8px}
.specialty-card p{color:var(--silver);font-size:.84rem;line-height:1.5;margin:0 0 12px}
.specialty-card .meta{display:inline-flex;align-items:center;gap:6px;color:var(--cyan);font-size:.72rem;font-weight:750;letter-spacing:.06em;text-transform:uppercase}
.specialty-card .meta:before{content:"";width:6px;height:6px;border-radius:50%;background:var(--cyan);box-shadow:0 0 10px var(--cyan)}
.scroller-hint{display:flex;align-items:center;justify-content:center;gap:10px;margin-top:14px;color:var(--silver);font-size:.78rem;font-weight:700;letter-spacing:.04em;text-transform:uppercase;opacity:.7}
.scroller-hint span{display:inline-block;animation:scroll-hint 2.4s ease-in-out infinite}
@keyframes scroll-hint{0%,100%{transform:translateX(0);opacity:.6}50%{transform:translateX(6px);opacity:1}}

/* Stats reveal */
.stats-section.is-visible .stats>div{opacity:1;transform:none}
.stats-section.is-visible .stats>div:nth-child(1){transition-delay:.05s}
.stats-section.is-visible .stats>div:nth-child(2){transition-delay:.15s}
.stats-section.is-visible .stats>div:nth-child(3){transition-delay:.25s}
.stats-section.is-visible .stats>div:nth-child(4){transition-delay:.35s}

/* Animated proof ring for brand consistency */
.proof-ring-anim{position:relative;display:inline-grid;place-items:center}
.proof-ring-anim .ring{position:absolute;border-radius:50%;border:1px solid rgba(102,38,239,.18);animation:proof-pulse 4s ease-in-out infinite}
.proof-ring-anim .ring:nth-child(2){inset:14px;animation-delay:.6s;border-style:dashed}
.proof-ring-anim .ring:nth-child(3){inset:28px;animation-delay:1.2s}
.proof-ring-anim .ring:nth-child(4){inset:42px;animation-delay:1.8s;border-color:rgba(25,211,226,.14)}
@keyframes proof-pulse{0%,100%{transform:scale(1);opacity:.45}50%{transform:scale(1.08);opacity:.9}}

/* Grid floor animation */
.grid-floor{position:absolute;inset:0;overflow:hidden;pointer-events:none;opacity:.06;background-image:linear-gradient(var(--cyan) 1px,transparent 1px),linear-gradient(90deg,var(--cyan) 1px,transparent 1px);background-size:60px 60px;transform:perspective(500px) rotateX(55deg) translateY(40px) scale(2);animation:grid-drift 20s linear infinite}
@keyframes grid-drift{0%{background-position:0 0}100%{background-position:60px 60px}}

/* Scroll reveal */
.reveal{opacity:0;transform:translateY(24px);transition:opacity .8s ease,transform .8s cubic-bezier(.22,.75,.3,1)}
.reveal.is-visible{opacity:1;transform:none}

@media(max-width:900px){
  .hero-grid{grid-template-columns:1fr}
  .hero-visual{min-height:360px}
  .specialty-card{flex:0 0 220px}
}

@media(max-width:760px){
  .specialty-card{flex:0 0 200px}
  .hero{padding-top:50px}
  /* The base h1 clamp floors at 3rem, which is too wide for the homepage hero
     on phones; scale it with the viewport so the headline fits the frame. */
  .hero-ground h1{font-size:clamp(2rem,8.6vw,3.2rem)}
}
