/* ============================================================================
   AAKZEN TECHNOLOGIES — site stylesheet

   Requires tokens.css, which must load first. No hex value may appear below
   this header — every colour resolves to a token so both themes stay correct
   without a single duplicated rule.

   The design is one idea: an ascent. The page climbs away from a skyline,
   through cloud, into a field of the pixel squares that break off the logo's
   trajectory. In dark mode that climb happens at night; in light mode it
   happens in daylight. The choreography is identical — only the art differs.

   Translucent surfaces use color-mix() against a token rather than a baked
   rgba(), which is what lets one rule serve a white card and a near-black
   one. Anywhere you see color-mix, that is why.
   ========================================================================= */

/* --- 1. Reset ----------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

html {
    scroll-behavior: smooth;
    -webkit-text-size-adjust: 100%;
    scroll-padding-top: 6rem;   /* so anchor targets clear the sticky header */
}

body {
    margin: 0;
    background: var(--bg);
    color: var(--ink);
    font-family: var(--body);
    font-weight: 400;
    font-size: var(--fs-body);
    line-height: var(--lh-body);
    overflow-x: hidden;
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
}

img, svg { display: block; max-width: 100%; }
img { height: auto; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; }

:focus-visible {
    outline: 2px solid var(--primary);
    outline-offset: 2px;
    border-radius: var(--r-sm);
}

::selection {
    background: color-mix(in srgb, var(--primary) 30%, transparent);
    color: var(--ink);
}

/* --- 2. Utilities ------------------------------------------------------- */
.u-hidden { display: none !important; }

/* Visible to screen readers, invisible on screen. */
.u-sr {
    position: absolute;
    width: 1px; height: 1px;
    padding: 0; margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
}

.u-skip {
    position: absolute;
    left: -9999px;
    top: 0;
    z-index: var(--z-skip);
    background: var(--surface-hi);
    color: var(--ink);
    padding: var(--s-3) var(--s-5);
    border: 1px solid var(--edge-hi);
    border-radius: var(--r-md);
    box-shadow: var(--e-2);
}
.u-skip:focus { left: var(--s-4); top: var(--s-4); }

/* --- 3. Type ------------------------------------------------------------ */
h1, h2, h3, h4 {
    font-family: var(--display);
    font-weight: 600;
    line-height: var(--lh-head);
    letter-spacing: var(--track-tight);
    margin: 0;
    text-wrap: balance;
}

h1 { font-size: var(--fs-h1); line-height: var(--lh-tight); }
h2 { font-size: var(--fs-h2); }
h3 { font-size: var(--fs-h3); letter-spacing: 0; }
h4 { font-size: var(--fs-h4); letter-spacing: 0; }

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

.t-grad {
    background: var(--grad);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
}

.t-lede {
    font-size: var(--fs-lede);
    line-height: 1.6;
    color: var(--ink-muted);
    max-width: 62ch;
}

.t-muted { color: var(--ink-muted); }
.t-dim   { color: var(--ink-dim); }

/* Instrumentation label — eyebrows and data captions.
   Uses --accent-text, never --accent: the raw cyan is 2.5:1 on white. */
.t-tag {
    font-family: var(--mono);
    font-size: var(--fs-label);
    font-weight: 500;
    letter-spacing: var(--track-label);
    text-transform: uppercase;
    color: var(--accent-text);
    display: inline-flex;
    align-items: center;
    gap: var(--s-2);
}
.t-tag::before {
    content: "";
    width: 6px;
    height: 6px;
    background: var(--accent);
    flex-shrink: 0;
}

/* An eyebrow that already carries an icon does not need the square bullet too —
   two decorations on three words reads as clutter. */
.t-tag:has(.ico)::before { display: none; }
.t-tag .ico { color: var(--accent-text); }

/* Sprite icons. Sized in em so an icon always matches the text beside it. */
.ico {
    width: 1.25em;
    height: 1.25em;
    flex-shrink: 0;
    display: inline-block;
    vertical-align: -.22em;
}

/* --- 4. Ascent backdrop -------------------------------------------------- */
.backdrop {
    position: fixed;
    inset: 0;
    z-index: var(--z-backdrop);
    overflow: hidden;
    pointer-events: none;
    background: var(--bg);

    /* Isolate it from the document entirely. The layers are sized in vh, so a
       viewport height change (mobile browser chrome collapsing, an orientation
       flip) reflows them — and without containment those reflows are reported
       as layout shift against a page they cannot actually affect. `contain`
       also lets the browser skip this subtree when laying out the rest. */
    contain: strict;
}

/* <picture> is only a format switch; it must not create a layout box. */
.backdrop picture { display: contents; }

.bd-layer {
    position: absolute;
    left: 50%;
    width: 130%;
    max-width: none;
    transform: translate3d(-50%, 0, 0);
    will-change: transform, opacity;
}

.bd-stars   { top: -8%;  width: 120%; }
.bd-cirrus  { top: 12%; }
.bd-cloudfar{ top: 30%; }
.bd-cityfar { bottom: 6%;  width: 140%; }
.bd-cloudnear { bottom: -6%; width: 155%; }
.bd-citynear{ bottom: -2%; width: 132%; }

.bd-grid {
    top: 0; left: 0;
    width: 100%; height: 100%;
    transform: none;
    background: url("../img/grid.png") repeat;
    background-size: 420px;
    opacity: .30;
    mask-image: radial-gradient(80% 60% at 50% 30%, #000 0%, transparent 75%);
}

/* A soft bloom behind the hero headline, in the brand's own gradient. */
.bd-glow {
    position: absolute;
    top: -22%;
    left: 50%;
    width: min(1100px, 120vw);
    aspect-ratio: 1;
    transform: translateX(-50%);
    background:
        radial-gradient(closest-side,
            color-mix(in srgb, var(--accent) 30%, transparent), transparent 70%),
        radial-gradient(closest-side at 62% 58%,
            color-mix(in srgb, var(--brand-violet) 34%, transparent), transparent 72%);
    opacity: .45;
    filter: blur(12px);
}

.bd-grain {
    position: absolute;
    inset: -50%;
    background: url("../img/grain.png") repeat;
    opacity: .30;
    mix-blend-mode: overlay;
}

/* --- 4b. Light-mode ascent, drawn in SVG --------------------------------- */
/* The same six layer keys, the same engine, daylight instead of night. */
.bd-sky {
    position: absolute;
    inset: 0;
    background: linear-gradient(180deg,
        #dbeafe 0%,
        #eff6ff 34%,
        var(--bg) 72%);
}

.bd-sun {
    position: absolute;
    top: -14%;
    left: 62%;
    width: min(760px, 90vw);
    aspect-ratio: 1;
    transform: translateX(-50%);
    background: radial-gradient(closest-side,
        color-mix(in srgb, var(--accent) 26%, transparent),
        transparent 70%);
    filter: blur(8px);
}

.bd-lt {
    position: absolute;
    left: 50%;
    width: 130%;
    max-width: none;
    height: auto;
    transform: translate3d(-50%, 0, 0);
    will-change: transform, opacity;
}

.bd-lt-cirrus    { top: 8%;  height: 16vh; }
.bd-lt-cloudfar  { top: 22%; height: 30vh; }
.bd-lt-cloudnear { top: 44%; height: 34vh; width: 150%; }

/* Heights are pinned in vh rather than left to the SVG aspect ratio. Left to
   itself a 130%-wide skyline grows to three-quarters of a laptop viewport and
   sits directly behind the hero paragraph, which is unreadable. The mask
   fades each roofline into the sky so the silhouettes dissolve upward instead
   of cutting a hard edge across the copy. */
.bd-lt-cityfar {
    bottom: 4%;
    width: 140%;
    height: 24vh;
    mask-image: linear-gradient(180deg, transparent 0%, #000 55%);
    -webkit-mask-image: linear-gradient(180deg, transparent 0%, #000 55%);
}

.bd-lt-citynear {
    bottom: -2%;
    width: 132%;
    height: 30vh;
    mask-image: linear-gradient(180deg, transparent 0%, #000 48%);
    -webkit-mask-image: linear-gradient(180deg, transparent 0%, #000 48%);
}

/* --- 4c. Which set of art is showing ------------------------------------ */
/* Light is the default, so the night art starts hidden and the two dark
   selectors below turn it on. Written twice because a media query cannot
   share a selector list with an attribute rule. */
.bd-layer, .bd-grain { display: none; }

@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) .bd-layer,
    :root:not([data-theme="light"]) .bd-grain { display: block; }
    :root:not([data-theme="light"]) .bd-lt,
    :root:not([data-theme="light"]) .bd-sky,
    :root:not([data-theme="light"]) .bd-sun  { display: none; }
    :root:not([data-theme="light"]) .bd-glow { mix-blend-mode: screen; opacity: .55; }
}

:root[data-theme="dark"] .bd-layer,
:root[data-theme="dark"] .bd-grain { display: block; }
:root[data-theme="dark"] .bd-lt,
:root[data-theme="dark"] .bd-sky,
:root[data-theme="dark"] .bd-sun  { display: none; }
:root[data-theme="dark"] .bd-glow { mix-blend-mode: screen; opacity: .55; }

/* An explicit light choice must beat the OS preference in both directions. */
:root[data-theme="light"] .bd-layer,
:root[data-theme="light"] .bd-grain { display: none; }
:root[data-theme="light"] .bd-lt,
:root[data-theme="light"] .bd-sky,
:root[data-theme="light"] .bd-sun  { display: block; }

/* Everything readable sits above the backdrop. */
.page { position: relative; z-index: var(--z-page); }

/* --- 5. Shell and bands -------------------------------------------------- */
.shell {
    width: var(--shell);
    margin-inline: auto;
}

.band { padding-block: var(--band-y); }
.band--tight { padding-block: calc(var(--band-y) * .62); }

/* Alternating tone, so long pages have rhythm without extra borders. */
.band--sunk {
    background: var(--bg-sunk);
    border-block: 1px solid var(--edge);
}

/* A readable plate behind long-form copy sitting over the backdrop. */
.plate {
    background: color-mix(in srgb, var(--surface) 90%, transparent);
    border: 1px solid var(--edge);
    border-radius: var(--r-lg);
    backdrop-filter: blur(14px);
    -webkit-backdrop-filter: blur(14px);
}

/* --- 6. Header ---------------------------------------------------------- */
/* Sticky, not fixed.
   Fixed took the header out of flow, which meant the announcement bar above it
   was covered at scroll position 0 and every page needed a top padding big
   enough to clear an invisible header. Sticky sits in flow after the bar,
   scrolls away with it, then pins to the top — the behaviour without the
   arithmetic. */
.hdr {
    position: sticky;
    top: 0;
    z-index: var(--z-header);
    padding-block: var(--s-4);
    transition: background var(--t-slow) var(--ease-in-out),
                padding var(--t-slow) var(--ease-in-out),
                border-color var(--t-slow) var(--ease-in-out);
    border-bottom: 1px solid transparent;
}

.hdr.is-stuck {
    padding-block: var(--s-3);
    background: color-mix(in srgb, var(--bg) 82%, transparent);
    backdrop-filter: blur(16px);
    -webkit-backdrop-filter: blur(16px);
    border-bottom-color: var(--edge);
}

.hdr__in {
    width: var(--shell);
    margin-inline: auto;
    display: flex;
    align-items: center;
    gap: var(--s-5);
}

.brand {
    display: flex;
    align-items: center;
    gap: var(--s-3);
    flex-shrink: 0;
}
.brand__mark { width: 43px; height: auto; }

/* Background rather than <img>, so only the theme in use is downloaded.
   See the comment in head.php. */
/* 129 x 26, not 200 x 26. The source artwork is 460 x 93, an aspect ratio of
   4.95:1, so inside a 200px-wide box `contain` would render 129px of wordmark
   and 71px of empty space that still pushes the nav across. The box has to
   match the art. */
.brand__word {
    display: block;
    width: 129px;
    height: 26px;
    background: url("../img/wordmark-dark.png") no-repeat left center;
    background-size: contain;
}

@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) .brand__word {
        background-image: url("../img/wordmark-ondark.png");
    }
}
:root[data-theme="dark"]  .brand__word { background-image: url("../img/wordmark-ondark.png"); }
:root[data-theme="light"] .brand__word { background-image: url("../img/wordmark-dark.png"); }

/* --- 6a. Theme-swapped assets -------------------------------------------
   The logo ships in two inks: navy artwork for light surfaces and a light
   variant for dark ones. Neither file can serve both, so both are in the
   markup and exactly one is ever displayed.

   .on-light  visible in the light theme
   .on-dark   visible in the dark theme
   Only the .on-light copy carries real alt text; the other is aria-hidden,
   otherwise a screen reader announces the company name twice. */
.on-dark { display: none; }

@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) .on-dark  { display: block; }
    :root:not([data-theme="light"]) .on-light { display: none; }
}
:root[data-theme="dark"] .on-dark  { display: block; }
:root[data-theme="dark"] .on-light { display: none; }
:root[data-theme="light"] .on-dark  { display: none; }
:root[data-theme="light"] .on-light { display: block; }

.nav {
    margin-left: auto;
    display: flex;
    align-items: center;
    gap: clamp(1rem, 2.2vw, 2rem);
}

.nav__link {
    font-size: .9375rem;
    font-weight: 500;
    color: var(--ink-muted);
    position: relative;
    padding-block: var(--s-1);
    transition: color var(--t-fast) ease;
}
.nav__link::after {
    content: "";
    position: absolute;
    left: 0; bottom: 0;
    width: 100%; height: 2px;
    background: var(--grad);
    transform: scaleX(0);
    transform-origin: left;
    transition: transform var(--t-base) var(--ease-out);
}
.nav__link:hover { color: var(--ink); }
.nav__link:hover::after,
.nav__link.is-current::after { transform: scaleX(1); }
.nav__link.is-current { color: var(--ink); }

.nav__cta { margin-left: var(--s-1); }

.nav__icon {
    display: grid;
    place-items: center;
    width: 34px;
    height: 34px;
    border-radius: var(--r-md);
    color: var(--ink-muted);
    transition: color var(--t-fast) ease, background var(--t-fast) ease;
}
.nav__icon:hover { color: var(--ink); background: var(--surface); }

/* --- 6b. Theme toggle ---------------------------------------------------- */
.themer {
    width: 38px; height: 38px;
    display: grid;
    place-items: center;
    background: transparent;
    border: 1px solid var(--edge);
    border-radius: var(--r-md);
    cursor: pointer;
    color: var(--ink-muted);
    transition: border-color var(--t-fast) ease,
                color var(--t-fast) ease,
                background var(--t-fast) ease;
    flex-shrink: 0;
}
.themer:hover {
    border-color: var(--edge-hi);
    color: var(--ink);
    background: var(--surface);
}
/* The icon shows the destination, not the current state — it pairs with an
   aria-label that reads "Switch to dark theme", and the two must agree. */
.themer svg { width: 17px; height: 17px; }

.burger {
    display: none;
    width: 44px; height: 40px;
    background: transparent;
    border: 1px solid var(--edge-hi);
    border-radius: var(--r-md);
    cursor: pointer;
    position: relative;
    flex-shrink: 0;
}
.burger span {
    position: absolute;
    left: 12px;
    width: 18px; height: 2px;
    background: var(--ink);
    border-radius: 2px;
    transition: transform var(--t-base) ease, opacity var(--t-fast) ease;
}
.burger span:nth-child(1) { top: 13px; }
.burger span:nth-child(2) { top: 19px; }
.burger span:nth-child(3) { top: 25px; }
.burger.is-open span:nth-child(1) { transform: translateY(6px) rotate(45deg); }
.burger.is-open span:nth-child(2) { opacity: 0; }
.burger.is-open span:nth-child(3) { transform: translateY(-6px) rotate(-45deg); }

/* --- 6c. Announcement bar ------------------------------------------------ */
.announce {
    position: relative;
    z-index: calc(var(--z-header) + 1);
    background: var(--grad);
    color: #fff;
    font-size: var(--fs-sm);
    text-align: center;
    padding: var(--s-2) var(--s-10) var(--s-2) var(--s-4);
}
.announce a { text-decoration: underline; text-underline-offset: 3px; }
.announce__close {
    position: absolute;
    right: var(--s-3); top: 50%;
    transform: translateY(-50%);
    background: none; border: 0;
    cursor: pointer;
    padding: var(--s-2);
    line-height: 0;
    color: inherit;
    opacity: .8;
}
.announce__close:hover { opacity: 1; }

/* --- 7. Buttons --------------------------------------------------------- */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--s-2);
    padding: .8rem 1.5rem;
    border-radius: var(--r-md);
    border: 1px solid transparent;
    font-family: var(--display);
    font-size: .9375rem;
    font-weight: 600;
    letter-spacing: .01em;
    cursor: pointer;
    text-align: center;
    transition: transform var(--t-base) var(--ease-out),
                box-shadow var(--t-base) ease,
                background var(--t-base) ease,
                border-color var(--t-base) ease;
}

.btn--primary {
    background: var(--primary);
    color: #fff;
    box-shadow: var(--e-1);
}
.btn--primary:hover {
    background: var(--primary-deep);
    transform: translateY(-2px);
    box-shadow: var(--e-brand);
}

.btn--ghost {
    border-color: var(--edge-hi);
    background: var(--surface);
    color: var(--ink);
}
.btn--ghost:hover {
    border-color: var(--primary);
    color: var(--primary);
    transform: translateY(-2px);
}

.btn--link {
    padding: 0;
    background: none;
    color: var(--primary);
    font-weight: 600;
}
.btn--link:hover { color: var(--primary-deep); }

.btn--small { padding: .5rem 1rem; font-size: .85rem; border-radius: var(--r-sm); }
.btn--block { width: 100%; }

.btn[disabled], .btn.is-loading {
    opacity: .55;
    pointer-events: none;
}

.btn__arrow { transition: transform var(--t-base) ease; }
.btn:hover .btn__arrow { transform: translateX(4px); }

/* --- 8. Hero ------------------------------------------------------------ */
/* Top padding is smaller than it was: the header now occupies real space in
   the flow above this, so there is no invisible fixed bar to clear. */
.hero {
    position: relative;
    min-height: 88svh;
    display: grid;
    align-items: center;
    padding-top: clamp(2.5rem, 7vh, 5rem);
    padding-bottom: clamp(4rem, 10vh, 7rem);
}

.hero__in {
    width: var(--shell);
    margin-inline: auto;
    max-width: 900px;
}

.hero__eyebrow { margin-bottom: var(--s-5); }
.hero__title {
    font-size: var(--fs-display);
    line-height: var(--lh-tight);
    margin-bottom: var(--s-5);
}

/* Each line is masked so it can slide up from behind its own edge. */
.hero__line {
    display: block;
    overflow: hidden;
    padding-bottom: .08em;
}
.hero__line > span { display: block; }

.hero__sub {
    max-width: 56ch;
    color: var(--ink-muted);
    font-size: var(--fs-lede);
    margin-bottom: var(--s-6);
}

.hero__actions { display: flex; flex-wrap: wrap; gap: var(--s-3); }

.hero__note {
    display: flex;
    align-items: center;
    gap: var(--s-2);
    margin-top: var(--s-5);
    font-size: .875rem;
    color: var(--ink-dim);
}
.hero__note .ico { color: var(--success); }

/* --- 8b. Industry tile grid ---------------------------------------------- */
/* Twelve sectors need to be scannable in one glance, so they are tiles rather
   than cards — icon plus name, nothing else competing for attention. */
.tiles-grid {
    display: grid;
    gap: var(--s-3);
    grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
}

.tile-link {
    display: flex;
    align-items: center;
    gap: var(--s-3);
    padding: var(--s-4);
    border: 1px solid var(--edge);
    border-radius: var(--r-md);
    background: var(--surface-hi);
    font-size: .9375rem;
    font-weight: 500;
    transition: border-color var(--t-base) ease, transform var(--t-base) var(--ease-out),
                box-shadow var(--t-base) ease;
}
.tile-link .ico { color: var(--primary); font-size: 1.15rem; }
.tile-link:hover {
    border-color: var(--primary);
    transform: translateY(-2px);
    box-shadow: var(--e-2);
}

.hero__scroll {
    position: absolute;
    left: 50%; bottom: var(--s-6);
    transform: translateX(-50%);
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--s-2);
    font-family: var(--mono);
    font-size: .66rem;
    letter-spacing: .26em;
    text-transform: uppercase;
    color: var(--ink-dim);
}
.hero__scroll i {
    width: 2px; height: 46px;
    background: linear-gradient(180deg, var(--primary), transparent);
    animation: drop 2.4s ease-in-out infinite;
}
@keyframes drop {
    0%, 100% { transform: scaleY(.35); transform-origin: top; opacity: .4; }
    50%      { transform: scaleY(1);   transform-origin: top; opacity: 1; }
}

/* --- 9. Altitude rail --------------------------------------------------- */
.rail {
    position: fixed;
    left: max(1.6rem, calc((100vw - var(--shell)) / 2 - 3.2rem));
    top: 50%;
    transform: translateY(-50%);
    z-index: var(--z-rail);
    display: none;
    flex-direction: column;
    gap: var(--s-4);
    pointer-events: none;
}

.rail__item { display: flex; align-items: center; gap: var(--s-3); pointer-events: auto; }

.rail__dot {
    width: 9px; height: 9px;
    /* --edge-hi is a hairline meant for panel borders; against the pale sky
       of the light backdrop it disappears completely. --ink-dim reads in
       both themes. */
    border: 1px solid var(--ink-dim);
    background: var(--bg);
    transform: rotate(45deg);
    transition: background var(--t-base) ease, border-color var(--t-base) ease;
    flex-shrink: 0;
}

.rail__label {
    font-family: var(--mono);
    font-size: .64rem;
    letter-spacing: .18em;
    text-transform: uppercase;
    color: var(--ink-dim);
    opacity: 0;
    transform: translateX(-6px);
    transition: opacity var(--t-base) ease, transform var(--t-base) ease, color var(--t-base) ease;
    white-space: nowrap;
}

.rail__item:hover .rail__label,
.rail__item.is-active .rail__label { opacity: 1; transform: none; }
.rail__item.is-active .rail__dot { background: var(--primary); border-color: var(--primary); }
.rail__item.is-active .rail__label { color: var(--ink); }

/* The rail needs a real gutter beside the 1200px shell, not a sliver.
   At 1180px the shell already fills the viewport and the rail was landing on
   top of the content. 1480px is the first width where 140px of clear space
   exists on each side. */
@media (min-width: 1480px) { .rail { display: flex; } }

/* --- 10. Section heads --------------------------------------------------- */
.head {
    display: grid;
    gap: var(--s-4);
    max-width: 62ch;
    margin-bottom: clamp(2.5rem, 5vw, 3.75rem);
}
.head--wide   { max-width: none; }
.head--center { max-width: 56ch; margin-inline: auto; text-align: center; justify-items: center; }
.head__title  { max-width: 22ch; }
.head--center .head__title { max-width: none; }

/* --- 11. Pillars --------------------------------------------------------- */
.pillars {
    display: grid;
    gap: 1px;
    background: var(--edge);
    border: 1px solid var(--edge);
    border-radius: var(--r-lg);
    overflow: hidden;
    grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
}

.pillar {
    background: var(--surface-hi);
    padding: clamp(1.6rem, 3vw, 2.3rem);
    position: relative;
    transition: background var(--t-slow) ease;
}
.pillar:hover { background: var(--surface); }

.pillar__no {
    font-family: var(--mono);
    font-size: .68rem;
    letter-spacing: .2em;
    color: var(--ink-dim);
    display: block;
    margin-bottom: var(--s-5);
}
.pillar__title { margin-bottom: var(--s-3); }
.pillar__text { color: var(--ink-muted); font-size: var(--fs-sm); }

/* A hairline that fills on hover, echoing the logo's trajectory sweep. */
.pillar::after {
    content: "";
    position: absolute;
    left: 0; bottom: 0;
    height: 2px; width: 100%;
    background: var(--grad);
    transform: scaleX(0);
    transform-origin: left;
    transition: transform .45s var(--ease-out);
}
.pillar:hover::after { transform: scaleX(1); }

/* --- 12. Cards ----------------------------------------------------------- */
.cards {
    display: grid;
    gap: var(--s-5);
    grid-template-columns: repeat(auto-fit, minmax(290px, 1fr));
}
.cards--3 { grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); }

.card {
    position: relative;
    padding: clamp(1.5rem, 3vw, 2.1rem);
    border: 1px solid var(--edge);
    border-radius: var(--r-lg);
    background: var(--surface-hi);
    box-shadow: var(--e-1);
    overflow: hidden;
    transition: transform var(--t-slow) var(--ease-out),
                border-color var(--t-slow) ease,
                box-shadow var(--t-slow) ease;
}
.card:hover {
    transform: translateY(-5px);
    border-color: var(--edge-hi);
    box-shadow: var(--e-3);
}

/* Pointer-tracked sheen. Coordinates come from JS custom properties. */
.card::before {
    content: "";
    position: absolute;
    inset: 0;
    background: radial-gradient(340px circle at var(--mx, 50%) var(--my, 0%),
                color-mix(in srgb, var(--primary) 10%, transparent), transparent 62%);
    opacity: 0;
    transition: opacity var(--t-slow) ease;
    pointer-events: none;
}
.card:hover::before { opacity: 1; }

.card__icon {
    width: 44px; height: 44px;
    display: grid; place-items: center;
    border-radius: var(--r-md);
    background: var(--primary-wash);
    color: var(--primary);
    margin-bottom: var(--s-4);
}
.card__icon svg { width: 22px; height: 22px; }

.card__kicker {
    font-family: var(--mono);
    font-size: .68rem;
    letter-spacing: .2em;
    text-transform: uppercase;
    color: var(--accent-text);
    margin-bottom: var(--s-4);
    display: block;
}

.card__title { margin-bottom: var(--s-3); }
.card__text  { color: var(--ink-muted); font-size: var(--fs-sm); margin-bottom: var(--s-4); }

.card__list {
    list-style: none;
    margin: 0 0 var(--s-5);
    padding: 0;
    display: grid;
    gap: var(--s-2);
}
.card__list li {
    position: relative;
    padding-left: 1.15rem;
    font-size: .885rem;
    color: var(--ink-muted);
}
.card__list li::before {
    content: "";
    position: absolute;
    left: 0; top: .62em;
    width: 5px; height: 5px;
    background: var(--primary);
    transform: rotate(45deg);
}

.card__foot {
    font-family: var(--mono);
    font-size: .7rem;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--ink-dim);
    padding-top: var(--s-4);
    border-top: 1px solid var(--edge);
}

/* Cover image bleeds to the card edges, so the padding is cancelled out
   rather than the image being inset inside it. */
.card__cover {
    width: calc(100% + 2 * clamp(1.5rem, 3vw, 2.1rem));
    margin: calc(-1 * clamp(1.5rem, 3vw, 2.1rem)) calc(-1 * clamp(1.5rem, 3vw, 2.1rem)) var(--s-4);
    aspect-ratio: 16 / 9;
    object-fit: cover;
}

.card__meta {
    font-size: .8125rem;
    color: var(--ink-dim);
    margin-bottom: var(--s-3);
}

/* Makes the whole card clickable while keeping one real link for a11y. */
.card__link::after { content: ""; position: absolute; inset: 0; }

/* --- 12b. Tick list ------------------------------------------------------ */
/* The feature lists on service pages. Multi-column so 18 items read as one
   scannable block rather than a long scroll. */
.ticks {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: var(--s-3) var(--s-6);
    grid-template-columns: repeat(auto-fit, minmax(270px, 1fr));
}

.ticks li {
    display: flex;
    align-items: flex-start;
    gap: var(--s-3);
    font-size: var(--fs-sm);
    color: var(--ink-muted);
    padding-bottom: var(--s-3);
    border-bottom: 1px solid var(--edge);
}

.ticks .ico { color: var(--accent-text); margin-top: .15em; }

/* --- 13. Sequence -------------------------------------------------------- */
.seq { display: grid; gap: 0; }

.seq__row {
    display: grid;
    grid-template-columns: 5.5rem 1fr;
    gap: clamp(1rem, 3vw, 2.5rem);
    padding-block: clamp(1.6rem, 3vw, 2.4rem);
    border-top: 1px solid var(--edge);
    align-items: start;
}
.seq__row:last-child { border-bottom: 1px solid var(--edge); }

.seq__no {
    font-family: var(--mono);
    font-size: .78rem;
    letter-spacing: .18em;
    color: var(--primary);
    padding-top: .35rem;
}
.seq__title { margin-bottom: var(--s-2); }
.seq__text  { color: var(--ink-muted); font-size: var(--fs-sm); max-width: 62ch; }

/* --- 14. Numbers --------------------------------------------------------- */
.stats {
    display: grid;
    gap: 1px;
    background: var(--edge);
    border: 1px solid var(--edge);
    border-radius: var(--r-lg);
    overflow: hidden;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
}

.stat { background: var(--surface-hi); padding: clamp(1.6rem, 3vw, 2.4rem); text-align: center; }

.stat__value {
    font-family: var(--display);
    /* 62px was competing with the hero. A statistic needs to be the largest
       thing in its own band, not on the page. */
    font-size: clamp(2rem, 1.4rem + 2vw, 3rem);
    font-weight: 700;
    line-height: 1;
    background: var(--grad);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
    margin-bottom: var(--s-3);
}

.stat__label {
    font-family: var(--mono);
    font-size: .7rem;
    letter-spacing: var(--track-label);
    text-transform: uppercase;
    color: var(--ink-muted);
}

/* --- 15. Call to action -------------------------------------------------- */
.cta {
    position: relative;
    border: 1px solid var(--edge-hi);
    border-radius: var(--r-lg);
    padding: clamp(2.2rem, 5vw, 4rem);
    background:
        radial-gradient(120% 140% at 15% 0%,
            color-mix(in srgb, var(--primary) 12%, transparent), transparent 58%),
        radial-gradient(100% 130% at 95% 100%,
            color-mix(in srgb, var(--accent) 12%, transparent), transparent 60%),
        var(--surface);
    overflow: hidden;
    display: grid;
    gap: var(--s-6);
    align-items: center;
}
@media (min-width: 860px) { .cta { grid-template-columns: 1.5fr auto; } }

.cta__title { margin-bottom: var(--s-3); max-width: 18ch; }
.cta__text  { color: var(--ink-muted); max-width: 46ch; }

.cta__mark {
    position: absolute;
    right: -3%; bottom: -28%;
    width: min(360px, 42%);
    opacity: .07;
    pointer-events: none;
}

/* --- 16. Forms ----------------------------------------------------------- */
.form { display: grid; gap: var(--s-5); }

.field { display: grid; gap: var(--s-2); }

.field__label {
    font-size: .875rem;
    font-weight: 600;
    color: var(--ink);
}
.field__hint { font-size: .8125rem; color: var(--ink-dim); }

.field__input,
.field__area,
.field__select {
    width: 100%;
    padding: .8rem .95rem;
    background: var(--bg);
    border: 1px solid var(--edge-hi);
    border-radius: var(--r-md);
    color: var(--ink);
    font-family: var(--body);
    font-size: 1rem;   /* 16px stops iOS zooming the page on focus */
    transition: border-color var(--t-base) ease, box-shadow var(--t-base) ease;
}
.field__area { min-height: 148px; resize: vertical; }

.field__input:focus,
.field__area:focus,
.field__select:focus {
    border-color: var(--primary);
    box-shadow: 0 0 0 3px var(--primary-wash);
    outline: none;
}

.field__input::placeholder,
.field__area::placeholder { color: var(--ink-dim); }

.field.is-bad .field__input,
.field.is-bad .field__area,
.field.is-bad .field__select { border-color: var(--danger); }

.field__error { font-size: .82rem; color: var(--danger); }

.field--pair { display: grid; gap: var(--s-5); }
@media (min-width: 620px) { .field--pair { grid-template-columns: 1fr 1fr; } }

.note {
    padding: var(--s-3) var(--s-4);
    border-radius: var(--r-md);
    border: 1px solid var(--edge-hi);
    font-size: .92rem;
}
.note--ok {
    border-color: color-mix(in srgb, var(--success) 50%, transparent);
    background: color-mix(in srgb, var(--success) 10%, transparent);
}
.note--bad {
    border-color: color-mix(in srgb, var(--danger) 50%, transparent);
    background: color-mix(in srgb, var(--danger) 10%, transparent);
}

/* --- 17. Split and detail ------------------------------------------------ */
.split { display: grid; gap: clamp(2rem, 5vw, 4rem); align-items: start; }
@media (min-width: 900px) {
    .split { grid-template-columns: 1fr 1fr; }
    .split--wide-left { grid-template-columns: 1.15fr .85fr; }
    .split--form { grid-template-columns: 1.6fr 1fr; }
}

.detail { display: grid; gap: var(--s-5); padding: clamp(1.5rem, 3vw, 2.2rem); }
.detail__row { display: grid; gap: var(--s-1); }
.detail__key {
    font-family: var(--mono);
    font-size: .66rem;
    letter-spacing: .18em;
    text-transform: uppercase;
    color: var(--ink-dim);
}
.detail__val { font-size: 1rem; color: var(--ink); }
.detail__val a:hover { color: var(--primary); }

/* --- 18. Footer ---------------------------------------------------------- */
.ftr {
    position: relative;
    z-index: var(--z-page);
    margin-top: var(--band-y);
    border-top: 1px solid var(--edge);
    background: var(--bg-sunk);
    /* Generous bottom padding so the fixed WhatsApp and back-to-top buttons,
       which sit in the bottom-right corner of the viewport, never cover the
       legal links when the page is scrolled all the way down. */
    padding-block: clamp(3rem, 6vw, 4.5rem) var(--s-9);
}

/* Column counts are explicit at every breakpoint.
   An earlier version used `1.6fr repeat(auto-fit, minmax(150px, 1fr))`, which
   silently collapsed the whole footer to one column: the grid spec forbids
   combining an auto-fit repeat with a flexible track, so the entire
   declaration was invalid and the browser dropped it. Do not reintroduce it. */
.ftr__grid { display: grid; gap: var(--s-6); margin-bottom: var(--s-7); }

@media (min-width: 700px) {
    .ftr__grid { grid-template-columns: repeat(2, 1fr); }
    .ftr__brand { grid-column: 1 / -1; }
}
@media (min-width: 1100px) {
    .ftr__grid { grid-template-columns: 1.7fr 1fr 1fr 1fr 1.2fr; gap: var(--s-7); }
    .ftr__brand { grid-column: auto; }
}

.ftr__logo { width: 170px; height: auto; margin-bottom: var(--s-4); }
.ftr__text { color: var(--ink-muted); font-size: .93rem; max-width: 38ch; margin-bottom: var(--s-5); }

.ftr__head {
    font-family: var(--mono);
    font-size: .68rem;
    letter-spacing: .2em;
    text-transform: uppercase;
    color: var(--ink);
    margin: 0 0 var(--s-4);
    display: flex;
    align-items: center;
    gap: var(--s-2);
}
/* A short accent rule so the column headings read as headings, not as links. */
.ftr__head::before {
    content: "";
    width: 14px; height: 2px;
    background: var(--grad);
    flex-shrink: 0;
}

.ftr__links { display: grid; gap: var(--s-3); }
.ftr__links a {
    color: var(--ink-muted);
    font-size: .93rem;
    width: fit-content;
    transition: color var(--t-fast) ease, transform var(--t-fast) var(--ease-out);
}
.ftr__links a:hover { color: var(--primary); transform: translateX(3px); }

.ftr__meta { display: grid; gap: var(--s-1); font-size: .93rem; color: var(--ink-muted); }
.ftr__meta strong { color: var(--ink); font-weight: 600; }

/* Registration numbers. Each is hidden while its setting is empty, so the
   block grows as the company's paperwork comes through. */
.ftr__reg {
    display: flex;
    flex-wrap: wrap;
    gap: var(--s-2);
    margin-top: var(--s-4);
}
.ftr__reg span {
    font-family: var(--mono);
    font-size: .68rem;
    letter-spacing: .06em;
    padding: .3rem .6rem;
    border: 1px solid var(--edge);
    border-radius: var(--r-sm);
    color: var(--ink-dim);
    background: var(--surface);
}

/* --- 18b. Newsletter ------------------------------------------------------ */
.ftr__news {
    border-bottom: 1px solid var(--edge);
    padding-bottom: var(--s-6);
    margin-bottom: var(--s-6);
    display: grid;
    gap: var(--s-4);
    align-items: center;
}
@media (min-width: 860px) { .ftr__news { grid-template-columns: 1fr auto; } }

.ftr__news h2 { font-size: var(--fs-h3); margin-bottom: var(--s-1); }
.ftr__news p  { color: var(--ink-muted); font-size: .93rem; max-width: 52ch; }

.news__form { display: flex; flex-wrap: wrap; gap: var(--s-2); }
.news__form input {
    flex: 1 1 240px;
    padding: .72rem .95rem;
    background: var(--bg);
    border: 1px solid var(--edge-hi);
    border-radius: var(--r-md);
    color: var(--ink);
    font-family: var(--body);
    font-size: 1rem;
}
.news__form input:focus {
    border-color: var(--primary);
    box-shadow: 0 0 0 3px var(--primary-wash);
    outline: none;
}

/* --- 18c. Footer columns collapse on small screens ------------------------ */
/* <details> rather than a script: the groups open and close with JavaScript
   disabled, and a screen reader gets a real disclosure widget for free. */
.ftr__group > summary {
    list-style: none;
    cursor: pointer;
    display: none;               /* desktop shows the heading, not a toggle */
}
.ftr__group > summary::-webkit-details-marker { display: none; }

@media (max-width: 699px) {
    .ftr__group { border-bottom: 1px solid var(--edge); }
    .ftr__group > summary {
        display: flex;
        align-items: center;
        justify-content: space-between;
        padding-block: var(--s-3);
    }
    .ftr__group > summary .ftr__head { margin: 0; }
    .ftr__group > .ftr__head { display: none; }   /* the summary carries it */
    .ftr__group .ftr__links { padding-bottom: var(--s-4); }
    .ftr__group .ftr__sign {
        width: 14px; height: 14px;
        position: relative;
        color: var(--primary);
        flex-shrink: 0;
    }
    .ftr__group .ftr__sign::before,
    .ftr__group .ftr__sign::after {
        content: "";
        position: absolute;
        inset: 50% 0 auto;
        height: 2px;
        background: currentColor;
        transition: transform var(--t-base) var(--ease-out);
    }
    .ftr__group .ftr__sign::after { transform: rotate(90deg); }
    .ftr__group[open] .ftr__sign::after { transform: rotate(0); }
}

.ftr__base {
    display: flex;
    flex-wrap: wrap;
    gap: var(--s-4);
    justify-content: space-between;
    align-items: center;
    padding-top: var(--s-5);
    border-top: 1px solid var(--edge);
    font-size: .84rem;
    color: var(--ink-dim);
}

.ftr__social { display: flex; gap: var(--s-2); }
.ftr__social a {
    width: 36px; height: 36px;
    display: grid; place-items: center;
    border: 1px solid var(--edge);
    border-radius: var(--r-md);
    transition: border-color var(--t-base) ease, background var(--t-base) ease, transform var(--t-base) ease;
}
.ftr__social a:hover {
    border-color: var(--primary);
    background: var(--primary-wash);
    transform: translateY(-2px);
}
.ftr__social svg { width: 16px; height: 16px; fill: var(--ink-muted); }
.ftr__social a:hover svg { fill: var(--primary); }

/* --- 18d. Map ------------------------------------------------------------ */
.map {
    position: relative;
    border: 1px solid var(--edge);
    border-radius: var(--r-lg);
    overflow: hidden;
    background:
        /* A faint street-grid suggestion, so the placeholder reads as a map
           rather than as a component that failed to load. */
        repeating-linear-gradient(0deg, transparent 0 38px,
            color-mix(in srgb, var(--ink) 5%, transparent) 38px 39px),
        repeating-linear-gradient(90deg, transparent 0 52px,
            color-mix(in srgb, var(--ink) 5%, transparent) 52px 53px),
        var(--surface);
    min-height: clamp(280px, 42vh, 420px);
}

.map__load {
    width: 100%;
    min-height: inherit;
    display: grid;
    justify-items: center;
    align-content: center;
    gap: var(--s-2);
    padding: var(--s-6);
    background: none;
    border: 0;
    cursor: pointer;
    text-align: center;
    color: var(--ink-muted);
}
.map__load svg { width: 34px; height: 34px; color: var(--primary); }
.map__addr { font-family: var(--display); font-size: 1.125rem; font-weight: 600; color: var(--ink); }
.map__hint {
    font-family: var(--mono);
    font-size: .7rem;
    letter-spacing: var(--track-label);
    text-transform: uppercase;
    color: var(--primary);
}
.map__note { font-size: .8125rem; color: var(--ink-dim); max-width: 34ch; }
.map__load:hover .map__hint { text-decoration: underline; text-underline-offset: 3px; }

.map iframe {
    display: block;
    width: 100%;
    height: clamp(280px, 42vh, 420px);
    border: 0;
}

/* --- 18e. Search bar and results ----------------------------------------- */
.searchbar {
    display: flex;
    align-items: center;
    gap: var(--s-3);
    padding: var(--s-2) var(--s-2) var(--s-2) var(--s-4);
    border: 1px solid var(--edge-hi);
    border-radius: var(--r-pill);
    background: var(--bg);
}
.searchbar:focus-within { border-color: var(--primary); box-shadow: 0 0 0 3px var(--primary-wash); }
.searchbar .ico { color: var(--ink-dim); }

.searchbar input {
    flex: 1;
    min-width: 0;
    border: 0;
    background: none;
    color: var(--ink);
    font-family: var(--body);
    font-size: 1rem;   /* 16px keeps iOS from zooming the page on focus */
}
.searchbar input:focus { outline: none; }
.searchbar input::placeholder { color: var(--ink-dim); }

.results { display: grid; gap: var(--s-2); }

.result {
    display: grid;
    gap: var(--s-1);
    padding: var(--s-4);
    border: 1px solid var(--edge);
    border-radius: var(--r-md);
    background: var(--surface-hi);
    transition: border-color var(--t-base) ease, transform var(--t-base) var(--ease-out);
}
.result:hover { border-color: var(--primary); transform: translateX(3px); }
.result__title { font-family: var(--display); font-weight: 600; font-size: 1.0625rem; }
.result__text  { color: var(--ink-muted); font-size: var(--fs-sm); }

/* --- 18f. Job list ------------------------------------------------------- */
.joblist { display: grid; gap: var(--s-3); }

.job {
    display: grid;
    gap: var(--s-4);
    align-items: center;
    padding: clamp(1.3rem, 3vw, 1.9rem);
    border: 1px solid var(--edge);
    border-radius: var(--r-lg);
    background: var(--surface-hi);
    transition: border-color var(--t-base) ease;
}
.job:hover { border-color: var(--edge-hi); }
@media (min-width: 760px) { .job { grid-template-columns: 1fr auto; } }

.job__title { font-size: var(--fs-h3); margin-bottom: var(--s-2); }

.job__meta {
    display: flex;
    flex-wrap: wrap;
    gap: var(--s-2) var(--s-4);
    font-size: .8125rem;
    color: var(--ink-dim);
    margin-bottom: var(--s-3);
}
.job__meta span { display: inline-flex; align-items: center; gap: var(--s-1); }
.job__text { color: var(--ink-muted); font-size: var(--fs-sm); max-width: 62ch; margin: 0; }

/* --- 19. Reveal ---------------------------------------------------------- */
/* Without JS everything is visible; the .js class opts in to the animation. */
.js .reveal { opacity: 0; transform: translateY(26px); }

/* --- 20. Accordion (FAQ) ------------------------------------------------- */
/* Built on <details> so it opens and closes with JavaScript disabled. */
.acc { display: grid; gap: var(--s-3); }

.acc__item {
    border: 1px solid var(--edge);
    border-radius: var(--r-md);
    background: var(--surface-hi);
    overflow: hidden;
}
.acc__item[open] { border-color: var(--edge-hi); }

.acc__q {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--s-4);
    padding: var(--s-4) var(--s-5);
    font-family: var(--display);
    font-size: 1.0625rem;
    font-weight: 600;
    cursor: pointer;
    list-style: none;
}
.acc__q::-webkit-details-marker { display: none; }
.acc__q:hover { color: var(--primary); }

.acc__sign {
    flex-shrink: 0;
    width: 20px; height: 20px;
    position: relative;
    color: var(--primary);
}
.acc__sign::before,
.acc__sign::after {
    content: "";
    position: absolute;
    inset: 50% 0 auto;
    height: 2px;
    background: currentColor;
    transition: transform var(--t-base) var(--ease-out);
}
.acc__sign::after { transform: rotate(90deg); }
.acc__item[open] .acc__sign::after { transform: rotate(0); }

.acc__a { padding: 0 var(--s-5) var(--s-5); color: var(--ink-muted); max-width: 72ch; }

/* --- 21. Timeline -------------------------------------------------------- */
.tl { display: grid; gap: 0; position: relative; }
.tl__item {
    display: grid;
    grid-template-columns: auto 1fr;
    gap: var(--s-5);
    padding-bottom: var(--s-7);
}
.tl__marker { display: grid; justify-items: center; gap: var(--s-2); }
.tl__dot {
    width: 12px; height: 12px;
    background: var(--primary);
    transform: rotate(45deg);
    margin-top: .4rem;
}
.tl__line { width: 1px; flex: 1; background: var(--edge); height: 100%; }
.tl__year {
    font-family: var(--mono);
    font-size: .7rem;
    letter-spacing: .16em;
    color: var(--primary);
    margin-bottom: var(--s-2);
}
.tl__text { color: var(--ink-muted); font-size: var(--fs-sm); max-width: 62ch; }

/* --- 22. Logo wall and testimonials -------------------------------------- */
/* Both render nothing when they have no rows — see the empty-state rule. */
.logos {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: clamp(2rem, 5vw, 3.5rem);
}
.logos img {
    max-height: 38px;
    width: auto;
    opacity: .55;
    filter: grayscale(1);
    transition: opacity var(--t-base) ease, filter var(--t-base) ease;
}
.logos img:hover { opacity: 1; filter: none; }

.quotes { display: grid; gap: var(--s-5); grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); }

.quotecard {
    padding: clamp(1.5rem, 3vw, 2.1rem);
    border: 1px solid var(--edge);
    border-radius: var(--r-lg);
    background: var(--surface-hi);
    display: grid;
    gap: var(--s-4);
}
.quotecard__text { font-size: 1.0625rem; line-height: 1.6; }
.quotecard__who { display: flex; align-items: center; gap: var(--s-3); }
.quotecard__who img { width: 40px; height: 40px; border-radius: var(--r-pill); }
.quotecard__name { font-weight: 600; font-size: .9375rem; }
.quotecard__role { color: var(--ink-dim); font-size: .8125rem; }

/* --- 23. Technology grid ------------------------------------------------- */
.tech { display: grid; gap: var(--s-6); }
.tech__group { display: grid; gap: var(--s-4); }
.tech__items { display: flex; flex-wrap: wrap; gap: var(--s-2); }

.badge {
    display: inline-flex;
    align-items: center;
    gap: var(--s-2);
    padding: .45rem .9rem;
    border: 1px solid var(--edge);
    border-radius: var(--r-pill);
    background: var(--surface);
    font-size: .8125rem;
    color: var(--ink-muted);
}
.badge svg { width: 15px; height: 15px; }
.badge--brand { background: var(--primary-wash); border-color: transparent; color: var(--primary); }

/* --- 24. Page head and breadcrumbs --------------------------------------- */
.phead {
    padding-top: clamp(3rem, 8vh, 5.5rem);
    padding-bottom: clamp(2.5rem, 5vw, 4rem);
}

.phead__title {
    font-size: var(--fs-h1);
    max-width: 20ch;
    margin: var(--s-4) 0 var(--s-4);
}
.phead .t-lede a { color: var(--primary); text-decoration: underline; text-underline-offset: 3px; }

.crumbs {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--s-2);
    font-size: .8125rem;
    color: var(--ink-dim);
}
.crumbs a:hover { color: var(--primary); }
.crumbs li { display: flex; align-items: center; gap: var(--s-2); }
.crumbs li + li::before { content: "/"; color: var(--edge-hi); }
.crumbs ol { display: flex; flex-wrap: wrap; gap: var(--s-2); list-style: none; margin: 0; padding: 0; }

/* --- 25. Chips ----------------------------------------------------------- */
.chips {
    list-style: none;
    margin: 0; padding: 0;
    display: flex;
    flex-wrap: wrap;
    gap: var(--s-2);
    align-content: start;
}

.chip {
    padding: .5rem 1rem;
    border: 1px solid var(--edge);
    border-radius: var(--r-pill);
    background: var(--surface);
    font-size: .875rem;
    color: var(--ink-muted);
    transition: border-color var(--t-base) ease, color var(--t-base) ease, transform var(--t-base) ease;
}
.chip:hover {
    border-color: var(--primary);
    color: var(--primary);
    transform: translateY(-2px);
}
.chip.is-active { background: var(--primary); border-color: var(--primary); color: #fff; }

/* --- 25b. Fact bar, hero image, share ------------------------------------ */
/* Client / sector / year under a case study heading. */
.factbar {
    display: flex;
    flex-wrap: wrap;
    gap: var(--s-6);
    margin-top: var(--s-6);
    padding-top: var(--s-5);
    border-top: 1px solid var(--edge);
}
.factbar > div { display: grid; gap: var(--s-1); }
.factbar__key {
    font-family: var(--mono);
    font-size: .66rem;
    letter-spacing: var(--track-label);
    text-transform: uppercase;
    color: var(--ink-dim);
}
.factbar__val { font-weight: 600; }

/* The lead image on a case study or article. */
.shot {
    width: 100%;
    border: 1px solid var(--edge);
    border-radius: var(--r-lg);
    object-fit: cover;
}

.share {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--s-2);
    margin-top: var(--s-7);
    padding-top: var(--s-5);
    border-top: 1px solid var(--edge);
    max-width: 68ch;
}
.share__label {
    font-family: var(--mono);
    font-size: .66rem;
    letter-spacing: var(--track-label);
    text-transform: uppercase;
    color: var(--ink-dim);
    margin-right: var(--s-2);
}

/* --- 25c. Filter bar ----------------------------------------------------- */
.filterbar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--s-3) var(--s-4);
}

.filterbar__label {
    font-family: var(--mono);
    font-size: .66rem;
    letter-spacing: var(--track-label);
    text-transform: uppercase;
    color: var(--ink-dim);
}

.filterbar__count {
    font-size: var(--fs-sm);
    color: var(--ink-muted);
    margin-bottom: var(--s-5);
}

/* The chips are <button> here and <a> elsewhere, so the element defaults have
   to be normalised for the shared .chip styling to hold. */
.chip {
    font-family: inherit;
    font-size: .875rem;
    cursor: pointer;
}

/* --- 26. Prose ----------------------------------------------------------- */
.prose {
    max-width: 68ch;
    color: var(--ink-muted);
    line-height: var(--lh-long);
}
.prose h2 {
    font-size: clamp(1.25rem, 1rem + .6vw, 1.5rem);
    color: var(--ink);
    margin: var(--s-7) 0 var(--s-3);
}
.prose h2:first-child { margin-top: 0; }
.prose h3 { color: var(--ink); margin: var(--s-6) 0 var(--s-2); }
.prose p { margin-bottom: 1.05em; }
.prose ul, .prose ol { padding-left: 1.3rem; margin-bottom: 1.05em; }
.prose li { margin-bottom: .4em; }
.prose a { color: var(--primary); text-decoration: underline; text-underline-offset: 3px; }
.prose a:hover { color: var(--primary-deep); }
.prose img { border-radius: var(--r-md); margin-block: var(--s-5); }
.prose blockquote {
    border-left: 3px solid var(--primary);
    padding-left: var(--s-4);
    margin: var(--s-5) 0;
    color: var(--ink);
}

/* Article body: slightly larger and looser than general prose, because this is
   read start to finish rather than scanned. */
.prose--article {
    font-size: 1.0625rem;
    line-height: var(--lh-long);
    max-width: 68ch;
}
.prose--article > p:first-child { font-size: 1.1875rem; color: var(--ink); }

/* --- 26b. HTML sitemap --------------------------------------------------- */
.sitemap {
    display: grid;
    gap: var(--s-7) var(--s-6);
    grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
    align-items: start;
}

/* --- 27. Pull quote ------------------------------------------------------ */
.quote {
    border-left: 2px solid transparent;
    border-image: var(--grad) 1;
    padding-left: clamp(1.2rem, 3vw, 2.4rem);
    max-width: 40ch;
}
.quote__text {
    font-family: var(--display);
    font-size: clamp(1.25rem, 1rem + 1vw, 1.75rem);
    font-weight: 600;
    line-height: 1.3;
    letter-spacing: -.01em;
    color: var(--ink);
    margin-top: var(--s-4);
}

/* --- 28. Pagination ------------------------------------------------------ */
.pager { display: flex; flex-wrap: wrap; gap: var(--s-2); justify-content: center; margin-top: var(--s-7); }
.pager a, .pager span {
    min-width: 40px;
    padding: .5rem .75rem;
    text-align: center;
    border: 1px solid var(--edge);
    border-radius: var(--r-md);
    font-size: .9rem;
    color: var(--ink-muted);
}
.pager a:hover { border-color: var(--primary); color: var(--primary); }
.pager .is-current { background: var(--primary); border-color: var(--primary); color: #fff; }

/* --- 29. Floating chrome ------------------------------------------------- */
.progress {
    position: fixed;
    inset: 0 0 auto;
    height: 3px;
    z-index: calc(var(--z-header) + 2);
    background: var(--grad);
    transform: scaleX(0);
    transform-origin: left;
    pointer-events: none;
}

.floats {
    position: fixed;
    right: var(--s-5);
    bottom: var(--s-5);
    z-index: var(--z-float);
    display: grid;
    gap: var(--s-3);
    justify-items: center;
}

.float {
    width: 48px; height: 48px;
    display: grid; place-items: center;
    border-radius: var(--r-pill);
    border: 1px solid var(--edge);
    background: var(--surface-hi);
    color: var(--ink-muted);
    box-shadow: var(--e-2);
    cursor: pointer;
    transition: transform var(--t-base) var(--ease-out), color var(--t-base) ease;
}
.float:hover { transform: translateY(-3px); color: var(--primary); }
.float svg { width: 22px; height: 22px; }

.float--wa { background: #25d366; border-color: #25d366; color: #fff; }
.float--wa:hover { color: #fff; }

.float--top { opacity: 0; pointer-events: none; transition: opacity var(--t-base) ease, transform var(--t-base) ease; }
.float--top.is-on { opacity: 1; pointer-events: auto; }

/* --- 30. Mobile nav ------------------------------------------------------ */
@media (max-width: 900px) {
    .burger { display: block; }
    .nav {
        position: fixed;
        inset: 0 0 auto;
        margin: 0;
        padding: 6rem var(--gutter) 2.5rem;
        flex-direction: column;
        align-items: flex-start;
        gap: var(--s-5);
        background: var(--bg);
        border-bottom: 1px solid var(--edge);
        box-shadow: var(--e-3);
        transform: translateY(-102%);
        transition: transform .42s var(--ease-out);

        /* The panel must sit under the logo and the burger, or it hides the
           control the visitor needs to close it.
           These values are deliberately small and local: .nav is a descendant
           of .hdr, so its z-index is resolved inside the header's own stacking
           context and comparing it against --z-header would be meaningless.
           It only ever has to beat its siblings. */
        z-index: 1;
    }

    /* Above the drawer panel, in the same stacking context. */
    .brand,
    .themer,
    .burger { position: relative; z-index: 2; }
    .nav.is-open { transform: none; }
    .nav__link { font-family: var(--display); font-size: 1.5rem; }
    .nav__cta { margin-left: 0; }
    .nav__icon { display: none; }   /* the drawer has its own links */

    /* The nav becomes position:fixed here, so its margin-left:auto no longer
       pushes anything to the right and the toggle and burger were left
       stranded mid-header. Moving the auto margin onto the toggle groups them
       both against the right edge again. */
    .themer { margin-left: auto; }

    .floats { right: var(--s-4); bottom: var(--s-4); }
}

/* --- 31. Motion preferences ---------------------------------------------- */
@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
    *, *::before, *::after {
        animation-duration: .001ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .001ms !important;
    }
    .js .reveal { opacity: 1; transform: none; }
    .hero__scroll i { animation: none; }
    .backdrop { display: none; }
}

/* --- 32. Print ----------------------------------------------------------- */
/* Institutional buyers print pages to circulate them. Force the light
   palette, drop the chrome, and expose link targets. */
@media print {
    .backdrop, .rail, .hdr, .hero__scroll, .floats,
    .progress, .announce, .themer { display: none !important; }
    body { background: #fff; color: #000; }
    .card, .pillar, .stat, .cta { break-inside: avoid; box-shadow: none; }
    a[href^="http"]::after { content: " (" attr(href) ")"; font-size: .8em; color: #555; }
}
