/* ==========================================================================
   ByteX design system
   Single stylesheet, no build step. Structure:
     1. Tokens
     2. Reset and base
     3. Typography
     4. Layout primitives
     5. Sections and surfaces
     6. Components
     7. Hero visual
     8. Forms
     9. Utilities
    10. Motion and print
   ========================================================================== */

/* 0. Fonts =============================================================== */

/*
   Self-hosted so there is no third-party request, no third-party cookie, and
   font-src stays 'self' in the CSP. Latin subset only. font-display: swap means
   text paints immediately in the fallback and reflows once, rather than being
   invisible while the font downloads.

   Inter Tight ships as a single variable file covering 400-700; Google serves
   the same bytes for every static weight, so one file replaces four.
*/
/*
   Barlow Condensed used to set the headings. It is a widely-used free condensed
   face with strong template associations, and it was doing real damage to how
   premium the site read. Geist is a geometric grotesque, shipped as one variable
   file covering 400-800 where Barlow needed two static weights.
*/
@font-face {
    font-family: "Geist";
    src: url("/fonts/geist-var.woff2") format("woff2-variations");
    font-weight: 400 800;
    font-style: normal;
    font-display: swap;
}

/* Technical labels only — the systems figure, chip captions, eyebrow codes.
   Not preloaded: it never appears in the first paint and the system mono
   fallback is a close enough stand-in for the moment it takes to arrive. */
@font-face {
    font-family: "Geist Mono";
    src: url("/fonts/geist-mono-var.woff2") format("woff2-variations");
    font-weight: 400 600;
    font-style: normal;
    font-display: swap;
}

/* 1. Tokens ============================================================== */

:root {
    /* ------------------------------------------------------------------
       Palette — single source of truth.

       Dark-first. The previous theme used dark only for the header, hero and
       footer, so a strong opening gave way to roughly 7,000px of near-identical
       white cards. Dark is now the canvas and light is punctuation, applied
       deliberately via .section--light where a section needs to break the
       rhythm.

       Ratios below are measured against the surface each colour actually sits
       on, not against white, and are re-checked by the contrast audit in
       DesignSystemTests.
       ------------------------------------------------------------------ */

    /* Dark surfaces, lightest-on-top ordering. The ramp carries a slight teal
       cast rather than being neutral black: it ties the canvas to the cyan
       accent so the glow in the hero looks like it belongs to the page instead
       of sitting on top of it. The steps are deliberately
       small: large jumps between adjacent bands read as banding on wide
       screens, where a section edge spans 2,000px of flat colour. */
    --color-bg-deep: #04090b;         /* hero, closing CTA, footer */
    --color-bg-base: #071216;         /* default page canvas */
    --color-bg-raised: #0b1a1f;       /* alternating band */
    --color-bg-sunken: #050f12;       /* alternating band, the other way */
    --color-bg-card: #0e2128;         /* cards and panels on any dark band */
    --color-bg-card-hover: #143038;

    /* Borders on dark are translucent white rather than a fixed grey, so a
       card keeps the same edge weight on every band above. */
    --color-hairline: rgba(255, 255, 255, 0.09);
    --color-hairline-strong: rgba(255, 255, 255, 0.16);

    /* Text on dark. Ratios against --color-bg-base (#0a0d13). */
    --color-text-dk: #e9eef7;         /* 16.3:1 */
    --color-text-dk-2: #a9b5c8;       /*  9.2:1 */
    --color-text-dk-3: #828fa3;       /*  5.8:1 — smallest permitted for body */

    /* Light surfaces, kept for punctuation sections and for print. */
    --color-surface: #ffffff;
    --color-surface-soft: #f4f7fb;
    --color-surface-blue: #eef5fa;
    --color-surface-muted: #f7f9fc;

    /* Text on light. Ratios against --color-surface (#ffffff). */
    --color-text: #141a24;            /* 17.5:1 */
    --color-text-secondary: #4d5867;  /*  7.2:1 */
    --color-text-muted: #667283;      /*  4.9:1 */

    --color-border: #dde4ec;
    --color-border-strong: #c9d4df;

    --color-accent: #08bddd;          /* 8.4:1 on --color-bg-base */
    --color-accent-strong: #0099bd;
    --color-accent-soft: #dff7fb;
    /* Accent dark enough to carry text on white (5.6:1). Never use
       --color-accent for text on a light surface: it fails AA at 2.2:1. */
    --color-accent-ink: #00647f;

    /* Brand blue, sampled from the ByteX logo. The "X" is a blue gradient, not
       cyan, so the logo and any brand gradient must use these rather than the
       interactive accent above. */
    --color-brand-blue: #2f8cf0;
    --color-brand-blue-deep: #1560d8;

    /* One warm accent in an otherwise entirely cold palette. Used sparingly —
       section pills, a hover edge — because unrelieved cyan-on-navy is a large
       part of what reads as machine-generated. */
    --color-warm: #ffb46b;            /* 10.8:1 on --color-bg-base */
    --color-warm-ink: #8a4c00;        /*  6.6:1 on white */

    --color-success: #127a5a;
    --color-focus: #35d6f5;           /* focus ring lives mostly on dark now */

    /* Retained names so existing dark-surface rules keep working. */
    --color-on-dark: var(--color-text-dk);
    --color-on-dark-muted: var(--color-text-dk-2);

    /* ------------------------------------------------------------------
       Legacy aliases. The rules throughout this file were written against
       these names; pointing them at the palette above re-themes the whole
       site without duplicating a colour value in two places.
       ------------------------------------------------------------------ */
    /* Navy names now resolve to the dark scale. Nothing in the components
       layer had to change for the site to re-theme; that indirection is what
       this alias block exists for. */
    --navy-950: var(--color-bg-deep);
    --navy-900: var(--color-bg-base);
    --navy-850: var(--color-bg-raised);
    --navy-800: var(--color-bg-card);
    --navy-700: var(--color-bg-card-hover);
    --navy-600: #223047;

    --cyan-400: var(--color-accent);
    --cyan-300: #5ce1f5;
    --cyan-500: var(--color-accent-strong);
    --cyan-ink: var(--color-accent-ink);

    /* Was a violet pair that appeared nowhere in the brand. The logo is white
       "Byte" and a blue "X", so the secondary accent is now a lighter tint of
       that same blue. 7.7:1 on --color-bg-base. */
    --brand-blue-light: #5aa8ff;

    /* The brand gradient: logo blue running into the cyan accent. Used for the
       primary button, the chip and the reach arcs so the logo, the calls to
       action and the artwork are visibly the same system.
       Dark ink stays legible across it — 5.8:1 at the blue end, 8.9:1 at the
       cyan end. It deliberately starts at --color-brand-blue rather than
       --color-brand-blue-deep, which measures only 3.5:1 and would fail AA. */
    --brand-gradient: linear-gradient(135deg, var(--color-brand-blue), var(--color-accent));

    /* The surface/ink pair. Overriding just these six inside a scope flips a
       whole subtree between dark and light — see .section--light. */
    --paper: var(--color-bg-base);
    --paper-alt: var(--color-bg-raised);
    --paper-card: var(--color-bg-card);
    --paper-line: var(--color-hairline);

    --ink-900: var(--color-text-dk);
    --ink-700: var(--color-text-dk);
    --ink-600: var(--color-text-dk-2);
    --ink-500: var(--color-text-dk-3);

    --on-dark: var(--color-text-dk);
    --on-dark-muted: var(--color-text-dk-2);

    --success-bg: #e8f7f0;
    --success-ink: #0d6b46;
    --danger-bg: #fdecec;
    --danger-ink: #a3211f;
    --warn-bg: #fff6e6;
    --warn-ink: #8a5a05;

    /* Typography.
       Fallbacks are chosen for similar metrics so the swap is not jarring:
       Segoe UI Semibold approximates a condensed grotesque more closely than
       a default sans, and Segoe UI matches Inter Tight reasonably at text size. */
    /* One family for body and headings. Two variable families cost 74KB on
       first paint against a 102KB budget; Geist alone covers 400-800 and is
       designed for interface text, so Inter Tight no longer earned its 45KB. */
    --font-sans: "Geist", "Segoe UI", -apple-system, BlinkMacSystemFont,
        Roboto, "Helvetica Neue", Arial, sans-serif;
    --font-display: "Geist", "Segoe UI", -apple-system, BlinkMacSystemFont,
        "Helvetica Neue", Arial, sans-serif;
    --font-mono: "Geist Mono", "Cascadia Mono", "SF Mono", Consolas,
        "Liberation Mono", Menlo, monospace;

    /* Retuned for Geist. A condensed face tolerates 0.95 leading because its
       letterforms are narrow; a grotesque at that setting collides ascenders
       with the descenders of the line above. Tracking eases off for the same
       reason — Geist is already generously spaced where Barlow was not. */
    --display-leading: 1.02;
    --display-tracking: -0.022em;

    --step--1: clamp(0.82rem, 0.79rem + 0.15vw, 0.9rem);
    --step-0: clamp(1rem, 0.96rem + 0.2vw, 1.075rem);
    --step-1: clamp(1.16rem, 1.09rem + 0.35vw, 1.35rem);
    --step-2: clamp(1.38rem, 1.24rem + 0.7vw, 1.75rem);
    --step-3: clamp(1.68rem, 1.42rem + 1.25vw, 2.4rem);
    --step-4: clamp(1.85rem, 1.45rem + 1.95vw, 2.85rem);
    --step-5: clamp(2.1rem, 1.45rem + 3.05vw, 3.5rem);

    /* Space scale */
    --space-3xs: 0.25rem;
    --space-2xs: 0.5rem;
    --space-xs: 0.75rem;
    --space-s: 1rem;
    --space-m: 1.5rem;
    --space-l: 2.25rem;
    --space-xl: 3.5rem;
    --space-2xl: 5rem;
    --space-3xl: 7rem;

    --radius-s: 8px;
    --radius-m: 16px;
    --radius-l: 24px;

    --measure: 68ch;
    --container: 1180px;
    --container-narrow: 820px;

    --shadow-s: 0 1px 2px rgba(13, 20, 36, 0.06), 0 2px 8px rgba(13, 20, 36, 0.05);
    --shadow-m: 0 2px 6px rgba(13, 20, 36, 0.07), 0 12px 28px rgba(13, 20, 36, 0.08);
    --shadow-dark: 0 2px 8px rgba(0, 0, 0, 0.3), 0 18px 40px rgba(0, 0, 0, 0.28);

    --header-height: 4.5rem;
    --transition: 180ms cubic-bezier(0.2, 0, 0.2, 1);
}

/* 2. Reset and base ====================================================== */

*,
*::before,
*::after {
    box-sizing: border-box;
}

/*
   The browser's default [hidden] rule is `display: none`, but it is a plain
   element rule and any author `display` declaration beats it. `.card` sets
   `display: flex`, so use-case cards stayed visible after the filter script
   set the hidden attribute — the filter looked active but changed nothing.
   Every use of `hidden` in this project genuinely means "remove from view and
   from the accessibility tree", so enforce it globally.
*/
[hidden] {
    display: none !important;
}

html {
    -webkit-text-size-adjust: 100%;
    scroll-behavior: smooth;
    scroll-padding-top: calc(var(--header-height) + 1rem);
}

body {
    margin: 0;
    font-family: var(--font-sans);
    font-size: var(--step-0);
    line-height: 1.65;
    color: var(--ink-700);
    background: var(--paper);
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
}

img,
svg,
video {
    max-width: 100%;
    height: auto;
    display: block;
}

/* Anything with explicit width/height attributes keeps its aspect ratio,
   which is what prevents layout shift as images load. */
img[width][height] {
    height: auto;
}

ul,
ol {
    padding-left: 1.25em;
}

hr {
    border: 0;
    border-top: 1px solid var(--paper-line);
    margin: var(--space-l) 0;
}

/* Visible focus everywhere. Never remove this without a replacement. */
:focus-visible {
    outline: 3px solid var(--cyan-500);
    outline-offset: 2px;
    border-radius: 3px;
}

.on-dark :focus-visible,
.site-header :focus-visible,
.site-footer :focus-visible {
    outline-color: var(--cyan-300);
}

::selection {
    background: var(--cyan-400);
    color: var(--navy-950);
}

.skip-link {
    position: absolute;
    left: var(--space-s);
    top: -100%;
    z-index: 200;
    padding: var(--space-2xs) var(--space-s);
    background: var(--cyan-400);
    color: var(--navy-950);
    font-weight: 650;
    border-radius: 0 0 var(--radius-s) var(--radius-s);
    transition: top var(--transition);
}

.skip-link:focus {
    top: 0;
}

/* 3. Typography ========================================================== */

h1,
h2,
h3,
h4 {
    font-family: var(--font-display);
    color: var(--ink-900);
    line-height: var(--display-leading);
    letter-spacing: var(--display-tracking);
    margin: 0 0 var(--space-s);
    font-weight: 700;
    text-wrap: balance;
}

/*
   These multipliers existed to compensate for Barlow Condensed setting narrow.
   Geist is a normal-width grotesque, so the compensation is gone: keeping it
   would make every heading oversized, and the H1 would wrap to five lines.
   Tracking is also eased, since Geist does not need the same tightening.
*/
h1 {
    font-size: var(--step-5);
    letter-spacing: -0.028em;
}

h2 {
    font-size: var(--step-4);
}

h3 {
    font-size: calc(var(--step-2) * 1.08);
    line-height: 1.05;
    letter-spacing: -0.02em;
}

h4 {
    font-size: calc(var(--step-1) * 1.06);
    line-height: 1.1;
    letter-spacing: -0.015em;
}

/* Card titles sit close to body copy, so they keep the text face rather than
   the condensed display face, which would look shouty at that size. */
.card h3,
.price-card__name,
.industry-card__name,
.process__item h3,
.process__item h4 {
    font-family: var(--font-sans);
    letter-spacing: -0.01em;
    line-height: 1.25;
}

p {
    margin: 0 0 var(--space-s);
    max-width: var(--measure);
}

a {
    color: var(--cyan-400);
    text-decoration-thickness: 1px;
    text-underline-offset: 0.18em;
    transition: color var(--transition);
}

a:hover {
    color: var(--cyan-300);
}

strong {
    font-weight: 650;
    color: var(--ink-900);
}

.lead {
    font-size: var(--step-1);
    line-height: 1.55;
    color: var(--ink-600);
}

.eyebrow {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2xs);
    font-family: var(--font-sans);
    font-size: var(--step--1);
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--cyan-400);
    margin: 0 0 var(--space-xs);
}

.eyebrow::before {
    content: "";
    width: 1.75rem;
    height: 2px;
    background: linear-gradient(90deg, var(--color-brand-blue), var(--color-accent-strong));
    border-radius: 2px;
}

/* Dark surfaces ---------------------------------------------------------- */

.on-dark {
    color: var(--on-dark-muted);
    background: var(--navy-900);
}

.on-dark h1,
.on-dark h2,
.on-dark h3,
.on-dark h4 {
    color: var(--on-dark);
}

.on-dark strong {
    color: var(--on-dark);
}

.on-dark .lead {
    color: var(--on-dark-muted);
}

.on-dark .eyebrow {
    color: var(--cyan-300);
}

/* Excludes buttons: a bare `.on-dark a` selector outranks `.btn--primary` and would
   paint cyan link text onto the cyan button background. */
.on-dark a:not(.btn) {
    color: var(--cyan-300);
}

.on-dark a:not(.btn):hover {
    color: var(--on-dark);
}

/* 4. Layout primitives =================================================== */

.container {
    width: 100%;
    max-width: var(--container);
    margin-inline: auto;
    padding-inline: var(--space-s);
}

@media (min-width: 40em) {
    .container {
        padding-inline: var(--space-m);
    }
}

.container--narrow {
    max-width: var(--container-narrow);
}

.section {
    padding-block: var(--space-2xl);
}

.section--tight {
    padding-block: var(--space-xl);
}

.section--paper {
    background: var(--paper);
}

.section--alt {
    background: var(--paper-alt);
}

/* The two alternating dark bands. Kept close in value on purpose: a strong
   step between adjacent full-width bands reads as a seam, not as depth. */
.section--blue {
    background: var(--color-bg-raised);
}

.section--muted {
    background: var(--color-bg-sunken);
}

.section--dark {
    background: var(--color-bg-deep);
    color: var(--color-text-dk-2);
}

/*
   Light punctuation.

   Overriding the six surface/ink variables inside this scope flips everything
   beneath it — cards, borders, body copy, chips — without a single component
   needing a light-mode variant. This is the whole reason the alias layer
   exists, and it is why the theme flip touched tokens rather than 1,800 lines
   of rules.

   Use it deliberately and rarely. Its job is to break the rhythm at the two or
   three points that matter, not to reintroduce a wall of white cards.
*/
.section--light {
    --paper: var(--color-surface);
    --paper-alt: var(--color-surface-soft);
    --paper-card: var(--color-surface);
    --paper-line: var(--color-border);

    --ink-900: var(--color-text);
    --ink-700: var(--color-text);
    --ink-600: var(--color-text-secondary);
    --ink-500: var(--color-text-muted);

    --on-dark: var(--color-text);
    --on-dark-muted: var(--color-text-secondary);

    /* Cyan fails AA as text on white (2.2:1), so the accent used for links and
       eyebrows inside a light scope has to be the ink variant. */
    --color-accent: var(--color-accent-ink);
    --cyan-400: var(--color-accent-ink);
    --cyan-300: var(--color-accent-ink);
    --color-focus: var(--color-accent-ink);
    --color-warm: var(--color-warm-ink);

    background: var(--color-surface-soft);
    color: var(--color-text);
    box-shadow: var(--shadow-m);
}

.section--light h1,
.section--light h2,
.section--light h3,
.section--light h4 {
    color: var(--color-text);
}

.section-head {
    max-width: 46rem;
    margin-bottom: var(--space-l);
}

.section-head p {
    margin-bottom: 0;
}

.grid {
    display: grid;
    gap: var(--space-m);
}

@media (min-width: 48em) {
    .grid--2 {
        grid-template-columns: repeat(2, 1fr);
    }

    .grid--3 {
        grid-template-columns: repeat(2, 1fr);
    }
}

@media (min-width: 64em) {
    .grid--3 {
        grid-template-columns: repeat(3, 1fr);
    }
}

.stack > * + * {
    margin-top: var(--space-s);
}

.stack-l > * + * {
    margin-top: var(--space-l);
}

/* 5. Sections and surfaces =============================================== */

/* A restrained grid + glow treatment used behind dark sections. */
.surface-grid {
    position: relative;
    isolation: isolate;
    overflow: hidden;
}

.surface-grid::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -2;
    background-image:
        linear-gradient(to right, rgba(120, 160, 220, 0.07) 1px, transparent 1px),
        linear-gradient(to bottom, rgba(120, 160, 220, 0.07) 1px, transparent 1px);
    background-size: 64px 64px;
    mask-image: radial-gradient(ellipse 80% 60% at 50% 0%, #000 30%, transparent 78%);
}

.surface-grid::after {
    content: "";
    position: absolute;
    z-index: -1;
    top: -30%;
    left: 50%;
    width: min(1100px, 130%);
    aspect-ratio: 2 / 1;
    transform: translateX(-50%);
    background: radial-gradient(
            ellipse at 30% 50%,
            rgba(34, 211, 238, 0.16),
            transparent 62%
        ),
        radial-gradient(ellipse at 72% 40%, rgba(139, 124, 246, 0.13), transparent 62%);
    pointer-events: none;
}

/* 6. Components ========================================================== */

/* Logo ------------------------------------------------------------------- */

.logo {
    display: inline-flex;
    align-items: baseline;
    font-size: 1.45rem;
    font-weight: 750;
    letter-spacing: -0.045em;
    color: var(--on-dark);
    text-decoration: none;
    line-height: 1;
}

.logo:hover {
    color: var(--on-dark);
}

.logo__x {
    position: relative;
    display: inline-block;
    /* Matches the supplied logo: white "Byte", blue gradient "X". */
    background: linear-gradient(135deg, var(--color-brand-blue) 10%, var(--color-brand-blue-deep) 90%);
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
    padding-right: 0.06em;
    font-weight: 800;
}

/* Fallback for browsers that do not support background-clip: text, which would
   otherwise render the X invisible. */
@supports not ((-webkit-background-clip: text) or (background-clip: text)) {
    .logo__x {
        background: none;
        color: var(--color-brand-blue);
    }
}

.logo--ink {
    color: var(--ink-900);
}

.logo--ink:hover {
    color: var(--ink-900);
}

/* Header ----------------------------------------------------------------- */

.site-header {
    position: sticky;
    top: 0;
    z-index: 100;
    /* Opaque fallback first: backdrop-filter is unsupported in Firefox with
       layout.css.backdrop-filter disabled, and a translucent bar without blur
       makes the nav unreadable over scrolling content. */
    background: #071216;
    border-bottom: 1px solid var(--color-hairline);
}

@supports (backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px)) {
    .site-header {
        background: rgba(7, 18, 22, 0.72);
        -webkit-backdrop-filter: blur(14px) saturate(140%);
        backdrop-filter: blur(14px) saturate(140%);
    }
}

.site-header__inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-m);
    min-height: var(--header-height);
}

.site-nav {
    display: none;
}

.site-nav__list {
    display: flex;
    align-items: center;
    gap: var(--space-xs);
    list-style: none;
    margin: 0;
    padding: 0;
}

.site-nav__link {
    display: block;
    padding: var(--space-2xs) var(--space-xs);
    border-radius: var(--radius-s);
    color: var(--on-dark-muted);
    text-decoration: none;
    font-size: 0.95rem;
    font-weight: 550;
    white-space: nowrap;
    transition: color var(--transition), background-color var(--transition);
}

.site-nav__link:hover {
    color: var(--on-dark);
    background: rgba(255, 255, 255, 0.06);
}

.site-nav__link[aria-current="page"],
.site-nav__link[data-active="true"] {
    color: var(--on-dark);
    background: rgba(34, 211, 238, 0.12);
}

.site-header__actions {
    display: flex;
    align-items: center;
    gap: var(--space-2xs);
}

/* Below 26em the header CTA wraps to three lines and crowds the logo. It is
   repeated inside the mobile menu, so hiding it here loses nothing. */
.site-header__actions .btn {
    display: none;
    white-space: nowrap;
}

@media (min-width: 26em) {
    .site-header__actions .btn {
        display: inline-flex;
    }
}

.nav-toggle {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2xs);
    padding: 0.55rem 0.8rem;
    background: rgba(255, 255, 255, 0.07);
    border: 1px solid rgba(140, 170, 220, 0.22);
    border-radius: var(--radius-s);
    color: var(--on-dark);
    font: inherit;
    font-size: 0.9rem;
    font-weight: 600;
    cursor: pointer;
}

.nav-toggle__bars {
    display: grid;
    gap: 3px;
    width: 16px;
}

.nav-toggle__bars span {
    display: block;
    height: 2px;
    background: currentColor;
    border-radius: 2px;
}

/*
   The open panel must never be taller than the screen. Previously it ran to
   1262px in an 800px viewport, so the toggle scrolled out of reach and the menu
   appeared impossible to dismiss. Constrain it and let the panel scroll instead
   of the page.
*/
.mobile-nav {
    border-top: 1px solid rgba(140, 170, 220, 0.14);
    padding-block: var(--space-s) var(--space-m);
    max-height: calc(100vh - var(--header-height) - 1rem);
    max-height: calc(100dvh - var(--header-height) - 1rem);
    overflow-y: auto;
    /* Stops the page behind scrolling once the panel reaches its end. */
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
}

.mobile-nav[hidden] {
    display: none;
}

.mobile-nav__list {
    list-style: none;
    margin: 0 0 var(--space-s);
    padding: 0;
    display: grid;
    gap: 2px;
}

.mobile-nav__link {
    display: block;
    padding: 0.7rem var(--space-xs);
    border-radius: var(--radius-s);
    color: var(--on-dark-muted);
    text-decoration: none;
    font-weight: 550;
}

.mobile-nav__link:hover,
.mobile-nav__link[aria-current="page"] {
    background: rgba(255, 255, 255, 0.06);
    color: var(--on-dark);
}

@media (min-width: 60em) {
    .site-nav {
        display: block;
    }

    .nav-toggle {
        display: none;
    }

    .mobile-nav {
        display: none !important;
    }
}

/* Buttons ---------------------------------------------------------------- */

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    padding: 0.8rem 1.5rem;
    border: 1px solid transparent;
    /* Pill buttons read as more considered than a 6px radius. */
    border-radius: 999px;
    font: inherit;
    font-family: var(--font-sans);
    font-size: 0.86rem;
    font-weight: 700;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    line-height: 1.3;
    text-align: center;
    text-decoration: none;
    cursor: pointer;
    transition: background-color var(--transition), border-color var(--transition),
        color var(--transition), transform var(--transition);
}

.btn:hover {
    transform: translateY(-1px);
}

.btn:active {
    transform: translateY(0);
}

.btn--primary {
    background: var(--brand-gradient);
    color: var(--navy-950);
    box-shadow: 0 1px 2px rgba(47, 140, 240, 0.32), 0 8px 22px rgba(8, 189, 221, 0.24);
}

.btn--primary:hover {
    background: linear-gradient(135deg, var(--brand-blue-light), var(--cyan-300));
    color: var(--navy-950);
}

.btn--secondary {
    background: transparent;
    border-color: rgba(140, 170, 220, 0.35);
    color: var(--on-dark);
}

.btn--secondary:hover {
    border-color: var(--cyan-400);
    background: rgba(34, 211, 238, 0.1);
    color: var(--on-dark);
}

.btn--ink {
    background: var(--navy-900);
    color: var(--on-dark);
}

.btn--ink:hover {
    background: var(--navy-800);
    color: var(--on-dark);
}

.btn--outline-ink {
    background: transparent;
    border-color: var(--paper-line);
    color: var(--ink-900);
}

.btn--outline-ink:hover {
    border-color: var(--cyan-500);
    background: var(--paper-card);
    color: var(--ink-900);
}

.btn--sm {
    padding: 0.5rem 0.9rem;
    font-size: 0.9rem;
}

.btn-row {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-xs);
}

/* Cards ------------------------------------------------------------------ */

.card {
    display: flex;
    flex-direction: column;
    padding: var(--space-m);
    background: var(--paper-card);
    border: 1px solid var(--paper-line);
    border-radius: var(--radius-m);
    box-shadow: var(--shadow-s);
    transition: border-color var(--transition), box-shadow var(--transition),
        transform var(--transition);
}

.card:hover {
    border-color: rgba(6, 182, 212, 0.45);
    box-shadow: var(--shadow-m);
    transform: translateY(-2px);
}

.card h3 {
    margin-bottom: var(--space-2xs);
}

/* Card titles are links, but a permanent underline on a heading reads as noise.
   The whole card is a hover target, so the affordance is not lost. */
.card h3 a {
    color: inherit;
    text-decoration: none;
}

.card h3 a:hover,
.card h3 a:focus-visible {
    color: var(--cyan-400);
    text-decoration: underline;
}

.card--dark h3 a:hover,
.card--dark h3 a:focus-visible {
    color: var(--cyan-300);
}

.card p {
    color: var(--ink-600);
}

.card__link {
    margin-top: auto;
    padding-top: var(--space-s);
    font-weight: 620;
    text-decoration: none;
}

.card__link::after {
    content: " →";
    transition: none;
}

.card__link:hover {
    text-decoration: underline;
}

.card--dark {
    background: var(--navy-850);
    border-color: rgba(140, 170, 220, 0.16);
    box-shadow: none;
}

.card--dark:hover {
    border-color: rgba(34, 211, 238, 0.4);
    box-shadow: var(--shadow-dark);
}

.card--dark h3 {
    color: var(--on-dark);
}

.card--dark p {
    color: var(--on-dark-muted);
}

/* Service icon ----------------------------------------------------------- */

.icon-badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.75rem;
    height: 2.75rem;
    margin-bottom: var(--space-s);
    border-radius: 10px;
    background: linear-gradient(140deg, rgba(47, 140, 240, 0.14), rgba(8, 189, 221, 0.16));
    border: 1px solid rgba(6, 182, 212, 0.28);
    color: var(--cyan-400);
    flex-shrink: 0;
}

.icon-badge svg {
    width: 1.4rem;
    height: 1.4rem;
}

.on-dark .icon-badge,
.card--dark .icon-badge {
    color: var(--cyan-300);
    border-color: rgba(34, 211, 238, 0.32);
}

/* Outcome list ----------------------------------------------------------- */

.outcomes {
    list-style: none;
    margin: var(--space-s) 0 0;
    padding: 0;
    display: grid;
    gap: var(--space-2xs);
    font-size: 0.95rem;
}

.outcomes li {
    position: relative;
    padding-left: 1.4rem;
    color: var(--ink-600);
}

.outcomes li::before {
    content: "";
    position: absolute;
    left: 0;
    top: 0.62em;
    width: 0.5rem;
    height: 0.5rem;
    border-radius: 2px;
    background: linear-gradient(135deg, var(--color-brand-blue), var(--color-accent));
}

.card--dark .outcomes li,
.on-dark .outcomes li {
    color: var(--on-dark-muted);
}

/* Ticked and crossed lists ----------------------------------------------- */

.checklist {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: var(--space-2xs);
}

.checklist li {
    position: relative;
    padding-left: 1.75rem;
}

.checklist li::before {
    content: "";
    position: absolute;
    left: 0.15rem;
    top: 0.42em;
    width: 0.65rem;
    height: 0.38rem;
    border-left: 2px solid var(--cyan-ink);
    border-bottom: 2px solid var(--cyan-ink);
    transform: rotate(-45deg);
}

.on-dark .checklist li::before {
    border-color: var(--cyan-300);
}

/* Problem list ----------------------------------------------------------- */

.problem-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: 0;
}

.problem-list li {
    padding: var(--space-s) 0;
    border-bottom: 1px solid var(--paper-line);
}

.problem-list li:first-child {
    border-top: 1px solid var(--paper-line);
}

.problem-list__title {
    display: block;
    font-weight: 650;
    color: var(--ink-900);
    margin-bottom: 0.15rem;
}

.problem-list__desc {
    color: var(--ink-600);
    font-size: 0.97rem;
}

@media (min-width: 48em) {
    .problem-list {
        grid-template-columns: repeat(2, 1fr);
        column-gap: var(--space-xl);
    }

    .problem-list li:nth-child(2) {
        border-top: 1px solid var(--paper-line);
    }
}

/* Process steps ---------------------------------------------------------- */

.process {
    counter-reset: step;
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: var(--space-m);
}

@media (min-width: 48em) {
    .process--4 {
        grid-template-columns: repeat(2, 1fr);
    }
}

@media (min-width: 64em) {
    .process--4 {
        grid-template-columns: repeat(4, 1fr);
    }
}

.process__item {
    position: relative;
    padding-top: var(--space-m);
    border-top: 2px solid rgba(140, 170, 220, 0.25);
}

.process__num {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.9rem;
    height: 1.9rem;
    margin-bottom: var(--space-2xs);
    border-radius: 6px;
    background: rgba(34, 211, 238, 0.12);
    border: 1px solid rgba(6, 182, 212, 0.35);
    color: var(--cyan-400);
    font-size: 0.85rem;
    font-weight: 700;
    font-family: var(--font-mono);
}

.on-dark .process__num {
    color: var(--cyan-300);
}

.process__item h3 {
    font-size: var(--step-1);
    margin-bottom: var(--space-3xs);
}

.process__item p {
    font-size: 0.96rem;
    margin-bottom: 0;
}

/* Callouts --------------------------------------------------------------- */

.callout {
    padding: var(--space-m);
    border-radius: var(--radius-m);
    border: 1px solid var(--paper-line);
    background: var(--paper-alt);
    border-left: 3px solid var(--cyan-500);
}

.callout > :last-child {
    margin-bottom: 0;
}

.callout__title {
    display: block;
    font-weight: 650;
    color: var(--ink-900);
    margin-bottom: var(--space-3xs);
}

.callout--warn {
    background: var(--warn-bg);
    border-color: #f0dfbc;
    border-left-color: #d99b1c;
}

.callout--warn .callout__title {
    color: var(--warn-ink);
}

.callout--note {
    background: var(--paper-card);
}

.on-dark .callout {
    background: rgba(255, 255, 255, 0.04);
    border-color: rgba(140, 170, 220, 0.2);
    border-left-color: var(--cyan-400);
}

.on-dark .callout__title {
    color: var(--on-dark);
}

/* Tags and filters ------------------------------------------------------- */

.tag-list {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-3xs);
    list-style: none;
    margin: 0;
    padding: 0;
}

.tag {
    display: inline-block;
    padding: 0.2rem 0.55rem;
    border-radius: 999px;
    background: var(--paper-alt);
    border: 1px solid var(--paper-line);
    color: var(--ink-600);
    font-size: 0.78rem;
    font-weight: 600;
    letter-spacing: 0.01em;
}

.card--dark .tag {
    background: rgba(255, 255, 255, 0.06);
    border-color: rgba(140, 170, 220, 0.2);
    color: var(--on-dark-muted);
}

.filter-bar {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-3xs);
    margin-bottom: var(--space-l);
    padding: 0;
    border: 0;
}

.filter-bar legend {
    padding: 0;
    margin-bottom: var(--space-2xs);
    font-size: var(--step--1);
    font-weight: 650;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--ink-600);
    width: 100%;
}

.filter-chip {
    padding: 0.4rem 0.85rem;
    border: 1px solid var(--paper-line);
    border-radius: 999px;
    background: var(--paper-card);
    color: var(--ink-700);
    font: inherit;
    font-size: 0.9rem;
    font-weight: 580;
    cursor: pointer;
    transition: border-color var(--transition), background-color var(--transition),
        color var(--transition);
}

.filter-chip:hover {
    border-color: var(--cyan-500);
    color: var(--ink-900);
}

/*
   The selected chip used to be a dark fill on a light page. On the dark canvas
   --navy-900 resolves to the page background, so the active filter became
   invisible while the unselected chips stayed lighter — the state read exactly
   backwards. Selection is now the accent, which is unambiguous on either theme.
*/
.filter-chip[aria-pressed="true"] {
    background: var(--color-accent);
    border-color: var(--color-accent);
    color: var(--color-bg-deep);
}

.filter-chip[aria-pressed="true"]:hover {
    background: var(--cyan-300);
    border-color: var(--cyan-300);
    color: var(--color-bg-deep);
}

/* Breadcrumbs ------------------------------------------------------------ */

.breadcrumbs {
    padding-block: var(--space-s);
    font-size: 0.9rem;
}

.breadcrumbs ol {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem;
    list-style: none;
    margin: 0;
    padding: 0;
    color: var(--ink-600);
}

.breadcrumbs li:not(:last-child)::after {
    content: "/";
    margin-left: 0.35rem;
    color: var(--paper-line);
}

.breadcrumbs a {
    text-decoration: none;
}

.breadcrumbs a:hover {
    text-decoration: underline;
}

.breadcrumbs [aria-current="page"] {
    color: var(--ink-900);
    font-weight: 550;
}

.on-dark .breadcrumbs ol {
    color: var(--on-dark-muted);
}

.on-dark .breadcrumbs [aria-current="page"] {
    color: var(--on-dark);
}

/* FAQ (native details/summary, no JavaScript) ---------------------------- */

.faq {
    display: grid;
    gap: 0;
    max-width: 52rem;
}

.faq__item {
    border-bottom: 1px solid var(--paper-line);
}

.faq__item:first-child {
    border-top: 1px solid var(--paper-line);
}

.faq__q {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: var(--space-s);
    padding: var(--space-s) 0;
    font-size: var(--step-1);
    font-weight: 620;
    color: var(--ink-900);
    cursor: pointer;
    list-style: none;
}

.faq__q::-webkit-details-marker {
    display: none;
}

.faq__q::after {
    content: "+";
    flex-shrink: 0;
    width: 1.5rem;
    height: 1.5rem;
    display: grid;
    place-items: center;
    border: 1px solid var(--paper-line);
    border-radius: var(--radius-s);
    font-size: 1.1rem;
    font-weight: 400;
    line-height: 1;
    color: var(--cyan-400);
}

.faq__item[open] .faq__q::after {
    content: "−";
}

.faq__q:hover {
    color: var(--cyan-400);
}

.faq__a {
    padding-bottom: var(--space-m);
    color: var(--ink-600);
}

.faq__a > :last-child {
    margin-bottom: 0;
}

/* Definition-style spec lists -------------------------------------------- */

.spec {
    display: grid;
    gap: var(--space-s);
    margin: 0;
}

@media (min-width: 48em) {
    .spec {
        grid-template-columns: minmax(9rem, 14rem) 1fr;
        column-gap: var(--space-l);
    }
}

.spec dt {
    font-weight: 650;
    color: var(--ink-900);
    padding-top: var(--space-2xs);
    border-top: 2px solid var(--paper-line);
}

.spec dd {
    margin: 0;
    padding-top: var(--space-2xs);
    border-top: 2px solid transparent;
    color: var(--ink-600);
}

@media (max-width: 47.99em) {
    .spec dd {
        padding-top: 0;
    }
}

.on-dark .spec dt {
    color: var(--on-dark);
    border-top-color: rgba(140, 170, 220, 0.25);
}

/* Capability grid -------------------------------------------------------- */

.capabilities {
    display: grid;
    gap: var(--space-s);
    list-style: none;
    margin: 0;
    padding: 0;
}

@media (min-width: 48em) {
    .capabilities {
        grid-template-columns: repeat(2, 1fr);
    }
}

@media (min-width: 72em) {
    .capabilities {
        grid-template-columns: repeat(3, 1fr);
    }
}

.capabilities li {
    padding: var(--space-s);
    background: var(--paper-card);
    border: 1px solid var(--paper-line);
    border-radius: var(--radius-m);
}

.capabilities strong {
    display: block;
    margin-bottom: 0.15rem;
}

.capabilities span {
    font-size: 0.94rem;
    color: var(--ink-600);
}

/* Trust strip ------------------------------------------------------------ */

.trust {
    display: grid;
    gap: var(--space-m);
    align-items: start;
}

@media (min-width: 56em) {
    .trust {
        /* Both columns start at the top: vertically centring the short statement
           against a taller paragraph leaves a conspicuous gap above it. */
        grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr);
        gap: var(--space-xl);
    }
}

.trust__statement {
    max-width: 18ch;
}

.trust__statement {
    font-size: var(--step-2);
    font-weight: 650;
    color: var(--on-dark);
    letter-spacing: -0.02em;
    margin: 0;
    text-wrap: balance;
}

.trust__detail {
    margin: 0;
    color: var(--on-dark-muted);
}

/* Footer ----------------------------------------------------------------- */

.site-footer {
    background: var(--navy-950);
    color: var(--on-dark-muted);
    padding-block: var(--space-xl) var(--space-m);
    font-size: 0.94rem;
}

.site-footer h2 {
    font-size: 0.8rem;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--on-dark);
    margin-bottom: var(--space-s);
}

.footer-grid {
    display: grid;
    gap: var(--space-l);
}

@media (min-width: 44em) {
    .footer-grid {
        grid-template-columns: repeat(2, 1fr);
    }
}

@media (min-width: 64em) {
    .footer-grid {
        grid-template-columns: 1.6fr 1fr 1fr 1fr;
        gap: var(--space-xl);
    }
}

.footer-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    /* No extra gap: the 44px rows already separate adjacent targets, and
       stacking both would leave the footer very tall on a phone. */
    gap: 0;
}

@media (min-width: 48em) {
    .footer-list {
        gap: var(--space-3xs);
    }
}

/*
   Footer links were text-height, so the tap target measured 82x19px on a phone
   and taps frequently missed. WCAG 2.2 asks for 24px minimum; 44px is the
   comfortable thumb size. Inline-flex with a min-height gives the anchor a real
   box without changing how the list looks.
*/
.footer-list a {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    color: var(--on-dark-muted);
    text-decoration: none;
}

/* Tighter on wide screens, where a pointer is precise and 44px rows would make
   the footer unnecessarily tall. */
@media (min-width: 48em) {
    .footer-list a {
        min-height: 32px;
    }
}

.footer-list a:hover {
    color: var(--cyan-300);
    text-decoration: underline;
}

.site-footer__brand p {
    max-width: 32ch;
    margin-top: var(--space-s);
}

.site-footer__base {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    gap: var(--space-s);
    margin-top: var(--space-xl);
    padding-top: var(--space-m);
    border-top: 1px solid rgba(140, 170, 220, 0.15);
    font-size: 0.87rem;
    color: var(--on-dark-muted);
}

.site-footer__base p {
    margin: 0;
    max-width: none;
}

/* 7. Hero ================================================================ */

.hero {
    position: relative;
    padding-block: var(--space-2xl) var(--space-2xl);
    background: var(--navy-900);
    color: var(--on-dark-muted);
}

.hero__grid {
    display: grid;
    gap: var(--space-xl);
    align-items: center;
}

@media (min-width: 62em) {
    .hero__grid {
        grid-template-columns: 1.05fr 0.95fr;
        gap: var(--space-2xl);
    }
}

.hero h1 {
    margin-bottom: var(--space-m);
}

.hero__lead {
    font-size: var(--step-1);
    color: var(--on-dark-muted);
    max-width: 40ch;
    margin-bottom: var(--space-l);
}

.hero__meta {
    margin-top: var(--space-l);
    padding-top: var(--space-s);
    border-top: 1px solid rgba(140, 170, 220, 0.18);
    font-size: 0.92rem;
    color: var(--on-dark-muted);
    max-width: 46ch;
}

/* Hero visual: CSS/SVG only, representing connected business systems. */
.systems-figure {
    position: relative;
    width: 100%;
    max-width: 34rem;
    margin-inline: auto;
}

.systems-figure svg {
    width: 100%;
    height: auto;
    overflow: visible;
}

.sf-panel {
    fill: rgba(14, 33, 40, 0.92);
    stroke: rgba(255, 255, 255, 0.14);
    stroke-width: 1;
}

.sf-panel--accent {
    stroke: rgba(34, 211, 238, 0.55);
}

.sf-label {
    fill: #cfdaef;
    font-family: var(--font-sans);
    font-size: 11px;
    font-weight: 600;
    letter-spacing: 0.02em;
}

.sf-sub {
    fill: #7f8fae;
    font-family: var(--font-mono);
    font-size: 8.5px;
    letter-spacing: 0.04em;
}

.sf-bar {
    fill: rgba(140, 170, 220, 0.22);
}

.sf-bar--on {
    fill: rgba(34, 211, 238, 0.65);
}

/*
   Connectors are three stacked layers over the same paths: a blurred bloom, the
   gradient strand, and a dashed overlay that animates along it. Together they
   read as fibre carrying light rather than as diagram lines.
*/
.sf-bloom {
    fill: none;
    stroke: rgba(34, 211, 238, 0.30);
    stroke-width: 3.5;
    stroke-linecap: round;
}

.sf-link {
    fill: none;
    stroke-width: 1.6;
    stroke-linecap: round;
}

.sf-link--in {
    stroke: url(#sf-strand-in);
}

.sf-link--out {
    stroke: url(#sf-strand-out);
}

.sf-flow {
    fill: none;
    stroke: var(--cyan-300);
    stroke-width: 1.6;
    stroke-linecap: round;
    stroke-dasharray: 14 150;
    animation: sf-dash 4.5s linear infinite;
}

@keyframes sf-dash {
    to { stroke-dashoffset: -164; }
}

/* The chip. Pins and a brighter inner die give the core physical weight, so the
   one element every strand converges on is also the heaviest thing on screen. */
.sf-pin {
    fill: rgba(92, 225, 245, 0.55);
}

.sf-chip {
    fill: url(#sf-hub-fill);
    stroke: rgba(92, 225, 245, 0.7);
    stroke-width: 1.25;
}

.sf-chip-die {
    fill: rgba(8, 189, 221, 0.07);
    stroke: rgba(92, 225, 245, 0.28);
    stroke-width: 1;
}

.sf-hub {
    fill: rgba(34, 211, 238, 0.1);
    stroke: rgba(34, 211, 238, 0.6);
    stroke-width: 1.25;
}

.sf-hub-label {
    fill: #eaf6fb;
    font-family: var(--font-sans);
    font-size: 12px;
    font-weight: 700;
    letter-spacing: -0.01em;
}

/* Packets travel the connector paths to suggest data flow, not decoration. */
.sf-packet {
    fill: var(--cyan-300);
    offset-rotate: 0deg;
    animation: sf-flow 5.5s var(--sf-delay, 0s) cubic-bezier(0.45, 0, 0.55, 1) infinite;
}

.sf-packet--brand {
    fill: var(--brand-blue-light);
}

@keyframes sf-flow {
    0% {
        offset-distance: 0%;
        opacity: 0;
    }

    12% {
        opacity: 1;
    }

    78% {
        opacity: 1;
    }

    92%,
    100% {
        offset-distance: 100%;
        opacity: 0;
    }
}

.sf-pulse {
    animation: sf-pulse 4s ease-in-out infinite;
    transform-origin: center;
}

@keyframes sf-pulse {
    0%,
    100% {
        opacity: 0.5;
    }

    50% {
        opacity: 1;
    }
}

/* 8. Forms =============================================================== */

.form-grid {
    display: grid;
    gap: var(--space-m);
}

@media (min-width: 44em) {
    .form-grid--2 {
        grid-template-columns: repeat(2, 1fr);
    }
}

.field {
    display: grid;
    gap: var(--space-3xs);
}

.field label {
    font-weight: 600;
    color: var(--ink-900);
    font-size: 0.95rem;
}

.field__hint {
    font-size: 0.86rem;
    color: var(--ink-600);
}

.field .required {
    color: var(--danger-ink);
    font-weight: 700;
}

.field input[type="text"],
.field input[type="email"],
.field input[type="tel"],
.field select,
.field textarea {
    width: 100%;
    padding: 0.65rem 0.8rem;
    font: inherit;
    font-size: 1rem;
    color: var(--ink-900);
    background: var(--paper-card);
    border: 1px solid var(--paper-line);
    border-radius: var(--radius-s);
    transition: border-color var(--transition), box-shadow var(--transition);
}

.field textarea {
    min-height: 8rem;
    resize: vertical;
    line-height: 1.55;
}

.field select {
    /* Native chevron is inconsistent; a background image keeps it uniform. */
    appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath fill='%234a5878' d='M1.4 0 6 4.6 10.6 0 12 1.4 6 7.4 0 1.4Z'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 0.85rem center;
    background-size: 0.7rem;
    padding-right: 2.2rem;
}

.field input:focus,
.field select:focus,
.field textarea:focus {
    border-color: var(--cyan-500);
    box-shadow: 0 0 0 3px rgba(6, 182, 212, 0.18);
    outline: none;
}

.field input[aria-invalid="true"],
.field select[aria-invalid="true"],
.field textarea[aria-invalid="true"] {
    border-color: var(--danger-ink);
}

.field-error {
    font-size: 0.88rem;
    font-weight: 550;
    color: var(--danger-ink);
}

.field-error:empty {
    display: none;
}

.consent {
    display: flex;
    align-items: flex-start;
    gap: var(--space-2xs);
    padding: var(--space-s);
    background: var(--paper-alt);
    border: 1px solid var(--paper-line);
    border-radius: var(--radius-m);
}

.consent input[type="checkbox"] {
    width: 1.15rem;
    height: 1.15rem;
    margin: 0.2rem 0 0;
    accent-color: var(--cyan-500);
    flex-shrink: 0;
}

.consent label {
    font-weight: 500;
    font-size: 0.95rem;
    color: var(--ink-700);
}

/* Honeypot: hidden from people, reachable by naive bots. Not display:none,
   because some bots skip those; off-screen with aria-hidden works better. */
.hp-field {
    position: absolute;
    left: -9999px;
    width: 1px;
    height: 1px;
    overflow: hidden;
}

.validation-summary {
    padding: var(--space-s) var(--space-m);
    margin-bottom: var(--space-m);
    background: var(--danger-bg);
    border: 1px solid #f3c6c5;
    border-left: 3px solid var(--danger-ink);
    border-radius: var(--radius-m);
    color: var(--danger-ink);
}

.validation-summary h2 {
    font-size: var(--step-0);
    color: var(--danger-ink);
    margin-bottom: var(--space-2xs);
}

.validation-summary ul {
    margin: 0;
    padding-left: 1.2em;
}

.validation-summary a {
    color: var(--danger-ink);
}

/* 8b. Section seams, page headers and pricing ============================ */

/* These two used to redefine .section--blue and .section--muted as light
   bands, overriding the surface rules in section 5 by source order alone.
   The surfaces now live in one place; only the seam and page header remain. */

/* Adjacent bands of the same value need a visible seam. */
.section--paper + .section--paper,
.section--paper + .section--muted,
.section--muted + .section--paper {
    border-top: 1px solid var(--color-hairline);
}

/*
   Page header for inner pages. Sits on the dark canvas with a soft accent wash
   at the top edge, so an inner page opens with the same weight as the home
   hero instead of dropping to a pale band.
*/
.page-header {
    position: relative;
    padding-block: var(--space-xl) var(--space-l);
    background:
        radial-gradient(60rem 22rem at 12% -20%, rgba(8, 189, 221, 0.13), transparent 70%),
        var(--color-bg-base);
    border-bottom: 1px solid var(--color-hairline);
}

.page-header h1 {
    color: var(--color-text-dk);
}

.page-header .lead {
    color: var(--ink-600);
}

/* A short accent bar keeps the brand present on light page headers. */
.page-header::before {
    content: "";
    position: absolute;
    inset-inline: 0;
    top: 0;
    height: 3px;
    background: linear-gradient(90deg, var(--color-accent) 0%, var(--brand-blue-light) 60%, transparent 100%);
}

/* Pricing ---------------------------------------------------------------- */

.pricing-grid {
    display: grid;
    gap: var(--space-m);
}

@media (min-width: 46em) {
    .pricing-grid {
        grid-template-columns: repeat(2, 1fr);
    }
}

@media (min-width: 72em) {
    .pricing-grid {
        grid-template-columns: repeat(4, 1fr);
    }
}

.price-card {
    display: flex;
    flex-direction: column;
    padding: var(--space-m);
    background: var(--paper-card);
    border: 1px solid var(--paper-line);
    border-radius: var(--radius-m);
    transition: border-color var(--transition), box-shadow var(--transition);
}

.price-card:hover {
    border-color: var(--color-border-strong);
    box-shadow: var(--shadow-s);
}

/* The free discovery conversation is the intended entry point, so it carries
   the accent rather than a louder colour block. */
.price-card--feature {
    border-color: var(--color-accent-strong);
    box-shadow: 0 0 0 1px var(--color-accent-strong);
    background: linear-gradient(180deg, rgba(8, 189, 221, 0.14) 0%, var(--paper-card) 62%);
}

.price-card__name {
    font-size: var(--step-0);
    font-weight: 650;
    color: var(--ink-900);
    margin: 0 0 var(--space-3xs);
}

.price-card__amount {
    display: block;
    font-size: var(--step-2);
    font-weight: 700;
    letter-spacing: -0.02em;
    color: var(--ink-900);
    margin-bottom: var(--space-2xs);
}

.price-card__amount .price-card__from {
    display: block;
    font-size: var(--step--1);
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--ink-500);
}

.price-card p {
    font-size: 0.95rem;
    color: var(--ink-600);
    margin-bottom: var(--space-s);
}

.price-card__cta {
    margin-top: auto;
    font-weight: 620;
    font-size: 0.95rem;
    text-decoration: none;
}

.price-card__cta::after {
    content: " \2192";
}

.price-card__cta:hover {
    text-decoration: underline;
}

.pricing-note {
    max-width: 62ch;
    margin-top: var(--space-l);
    padding: var(--space-s) var(--space-m);
    background: var(--paper-alt);
    border: 1px solid var(--color-border);
    border-left: 3px solid var(--color-border-strong);
    border-radius: var(--radius-m);
    font-size: 0.92rem;
    color: var(--ink-600);
}

.pricing-note > :last-child {
    margin-bottom: 0;
}

/* Use-case directory toolbar --------------------------------------------- */

.results-summary {
    margin: 0 0 var(--space-m);
    font-size: 0.95rem;
    font-weight: 550;
    color: var(--ink-600);
}

.load-more {
    display: flex;
    justify-content: center;
    margin-top: var(--space-l);
}

/* Definition list used by the use-case cards. The label carries the meaning,
   so the value needs no repeated prefix. */
.usecase-facts {
    margin: 0;
    display: grid;
    gap: var(--space-2xs);
}

.usecase-facts dt {
    font-size: var(--step--1);
    font-weight: 650;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--ink-500);
}

.usecase-facts dd {
    margin: 0 0 var(--space-2xs);
    font-size: 0.95rem;
    color: var(--ink-600);
}

.usecase-facts dd:last-child {
    margin-bottom: 0;
}

/* 8c. Navigation dropdown menus =========================================== */

.has-menu {
    position: relative;
}

.site-nav__link--menu {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    background: none;
    border: 0;
    font: inherit;
    font-size: 0.95rem;
    font-weight: 550;
    cursor: pointer;
}

.menu-caret {
    width: 0.42rem;
    height: 0.42rem;
    border-right: 2px solid currentColor;
    border-bottom: 2px solid currentColor;
    transform: translateY(-1px) rotate(45deg);
    transition: transform var(--transition);
}

[aria-expanded="true"] .menu-caret {
    transform: translateY(1px) rotate(-135deg);
}

/*
   The panel is flush with the button and creates its visual offset with
   transparent top padding. A literal gap would sit outside the hover area, so
   the menu closed the moment the cursor crossed it on the way down.
*/
.nav-menu {
    position: absolute;
    top: 100%;
    left: 0;
    z-index: 120;
    min-width: 15rem;
    padding-top: 0.5rem;
    background: none;
    border: 0;
}

/* The list carries the panel styling, since .nav-menu is now just the bridge. */
.nav-menu__list {
    list-style: none;
    margin: 0;
    padding: var(--space-2xs);
    display: grid;
    gap: 1px;
    /*
       This referenced --color-navy-800, which the dark-first palette removed.
       An undefined custom property resolves to nothing, so the panel lost its
       background entirely and page text showed straight through the menu.
       A floating panel must be opaque: it sits over arbitrary content.
    */
    background: var(--color-bg-card);
    border: 1px solid var(--color-hairline-strong);
    border-radius: var(--radius-m);
    box-shadow: var(--shadow-dark);
}

/*
   Widen the hover target slightly beyond the panel so a cursor drifting a few
   pixels sideways on the way down does not dismiss the menu.
*/
.nav-menu::before {
    content: "";
    position: absolute;
    top: 0;
    left: -0.75rem;
    right: -0.75rem;
    height: 0.75rem;
}

/* Ten categories in one column is a very tall menu, so split it on wider screens. */
@media (min-width: 60em) {
    .nav-menu__list--two {
        grid-template-columns: repeat(2, minmax(9.5rem, 1fr));
        column-gap: var(--space-2xs);
    }
}

.nav-menu__list a {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-s);
    padding: 0.5rem 0.65rem;
    border-radius: var(--radius-s);
    color: var(--color-on-dark-muted);
    text-decoration: none;
    font-size: 0.92rem;
    font-weight: 500;
    white-space: nowrap;
}

.nav-menu__list a:hover,
.nav-menu__list a:focus-visible {
    background: rgba(255, 255, 255, 0.07);
    color: var(--color-on-dark);
}

.nav-menu__count {
    font-size: 0.78rem;
    font-variant-numeric: tabular-nums;
    color: var(--color-on-dark-muted);
    opacity: 0.75;
}

.nav-menu__all {
    margin-top: var(--space-3xs);
    padding-top: var(--space-3xs);
    border-top: 1px solid rgba(140, 170, 220, 0.18);
}

@media (min-width: 60em) {
    .nav-menu__list--two .nav-menu__all {
        grid-column: 1 / -1;
    }
}

.nav-menu__all a {
    color: var(--cyan-300);
    font-weight: 600;
}

/* Mobile navigation groupings ------------------------------------------- */

.mobile-nav__link--sub {
    padding-left: var(--space-s);
    font-weight: 500;
    font-size: 0.95rem;
}

/* 8d. Trust strip on a light surface ===================================== */

/*
   The trust strip moved from a dark block to a soft blue band. Its text colours
   were still the dark-surface ones, which rendered near-white on pale blue at
   about 1:1. These override them for the light variant.
*/
/* .trust--light was a set of overrides for when this strip sat on a light band.
   The strip is on the dark canvas now and the defaults are already correct, so
   the overrides have been removed rather than left to shadow them. */

/* 8e. Touch target sizing ================================================ */

/*
   WCAG 2.2 AA "Target Size (Minimum)" asks for 24px; 44px is the comfortable
   figure for thumbs. The filter chips and the menu toggle sat just under it, so
   set a floor without changing their visual weight.
*/
.filter-chip,
.nav-toggle {
    min-height: 44px;
}

.filter-chip {
    display: inline-flex;
    align-items: center;
}

/* Menu and card links inside the navigation panels get the same floor. */
.nav-menu__list a,
.mobile-nav__link {
    min-height: 44px;
    display: flex;
    align-items: center;
}

.nav-menu__list a {
    justify-content: space-between;
}

/* 8f. Mobile navigation groups =========================================== */

.mobile-nav__group {
    border-top: 1px solid rgba(140, 170, 220, 0.14);
}

.mobile-nav__summary {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-s);
    min-height: 44px;
    padding: 0.7rem var(--space-xs);
    color: var(--color-on-dark);
    font-size: 0.95rem;
    font-weight: 620;
    cursor: pointer;
    list-style: none;
}

.mobile-nav__summary::-webkit-details-marker {
    display: none;
}

.mobile-nav__summary:hover {
    background: rgba(255, 255, 255, 0.06);
    border-radius: var(--radius-s);
}

/* The shared caret points down when closed and up when the group is open. */
.mobile-nav__group[open] > .mobile-nav__summary .menu-caret {
    transform: translateY(1px) rotate(-135deg);
}

.mobile-nav__group .mobile-nav__list {
    margin-bottom: var(--space-2xs);
}

.mobile-nav__link--sub {
    justify-content: space-between;
}

.mobile-nav__cta {
    margin-top: var(--space-m);
    width: 100%;
}

/* 8g. Mobile composition ================================================= */

/*
   On a phone the homepage previously read as one long column of heading,
   paragraph, heading, paragraph — the rhythm of an article rather than a
   marketing page. These rules tighten the hero, turn the service cards into a
   swipeable row, and give the problem list a visual anchor. Nothing is hidden:
   the same content is present, arranged to be scanned rather than read.
*/
@media (max-width: 47.99em) {
    /* Hero: less stacked prose before the visual ------------------------- */
    .hero {
        padding-block: var(--space-xl) var(--space-l);
    }

    .hero__grid {
        gap: var(--space-l);
    }

    .hero h1 {
        /* The headline is long; a smaller step keeps it to four lines at 390px
           instead of five, which is what pushed everything else down. */
        font-size: clamp(1.95rem, 1.15rem + 4.6vw, 2.5rem);
        line-height: 1.12;
        margin-bottom: var(--space-xs);
    }

    .hero__lead {
        font-size: 1.02rem;
        line-height: 1.55;
        margin-bottom: var(--space-m);
    }

    /*
       The figure lives in a second grid child, so `order` on .hero__meta alone
       could never move it past the figure. display:contents promotes the first
       column's children into the flex container, letting the whole hero be
       ordered as one sequence: headline, supporting line, actions, visual, then
       the secondary note. The visual now arrives before the tertiary text
       instead of after it.
    */
    .hero__grid {
        display: flex;
        flex-direction: column;
    }

    .hero__grid > div:first-child {
        display: contents;
    }

    .hero .eyebrow { order: 1; }
    .hero h1 { order: 2; }
    .hero__lead { order: 3; }
    .hero .btn-row { order: 4; }
    .hero__grid > div:last-child { order: 5; }

    .hero__meta {
        order: 6;
        margin-top: var(--space-s);
        padding-top: var(--space-s);
        font-size: 0.88rem;
    }

    /* Compact enough to sit within the first scroll rather than dominating it. */
    .systems-figure {
        max-width: 20rem;
    }

    /* Services: a swipeable row instead of six stacked blocks ------------ */
    .grid--scroll-mobile {
        display: grid;
        grid-auto-flow: column;
        grid-auto-columns: 82%;
        gap: var(--space-s);
        overflow-x: auto;
        scroll-snap-type: x mandatory;
        overscroll-behavior-x: contain;
        -webkit-overflow-scrolling: touch;
        /* Full-bleed so cards run to the screen edge and the next one peeks. */
        margin-inline: calc(var(--space-s) * -1);
        padding-inline: var(--space-s);
        padding-bottom: var(--space-s);
        scroll-padding-inline: var(--space-s);
    }

    .grid--scroll-mobile > * {
        scroll-snap-align: start;
    }

    /* The row is scrollable, so tell assistive technology and give it focus. */
    .grid--scroll-mobile:focus-visible {
        outline: 3px solid var(--color-focus);
        outline-offset: 4px;
    }

    /* Sits clear of the scrollbar rather than being pulled up over it. */
    .scroll-hint {
        margin: var(--space-2xs) 0 0;
        font-size: 0.85rem;
        color: var(--ink-500);
    }

    /* Problems: scannable rows rather than paragraphs -------------------- */
    .problem-list li {
        padding: var(--space-s) 0 var(--space-s) var(--space-m);
        position: relative;
    }

    .problem-list li::before {
        content: "";
        position: absolute;
        left: 0;
        top: calc(var(--space-s) + 0.45em);
        width: 0.5rem;
        height: 0.5rem;
        border-radius: 2px;
        background: linear-gradient(135deg, var(--color-brand-blue), var(--color-accent));
    }

    .problem-list__desc {
        font-size: 0.93rem;
    }

    /* Section leads sit closer to their heading so each block reads as one
       unit rather than a paragraph of body copy. */
    .section-head .lead {
        font-size: 1.02rem;
    }
}

/* The hint is irrelevant once the strips become grids. */
@media (min-width: 48em) {
    .scroll-hint {
        display: none;
    }
}

@media (min-width: 40em) {
    #industries .scroll-hint {
        display: none;
    }
}

/* 8h. Industry strip ===================================================== */

/*
   A user-controlled scroll strip, deliberately not a rotating carousel: nothing
   animates on its own, nothing is hidden behind a timer, and every card is in
   the DOM and reachable by keyboard.
*/
.industry-strip {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: var(--space-s);
}

@media (min-width: 40em) {
    .industry-strip {
        grid-template-columns: repeat(3, 1fr);
    }
}

@media (min-width: 68em) {
    .industry-strip {
        grid-template-columns: repeat(6, 1fr);
        gap: var(--space-xs);
    }
}

.industry-card {
    display: flex;
    flex-direction: column;
    height: 100%;
    padding: var(--space-s);
    background: var(--paper-card);
    border: 1px solid var(--paper-line);
    border-radius: var(--radius-m);
    text-decoration: none;
    transition: border-color var(--transition), box-shadow var(--transition),
        transform var(--transition);
}

.industry-card:hover {
    border-color: var(--color-accent-strong);
    box-shadow: var(--shadow-s);
    transform: translateY(-2px);
}

.industry-card .icon-badge {
    width: 2.25rem;
    height: 2.25rem;
    margin-bottom: var(--space-2xs);
}

.industry-card .icon-badge svg {
    width: 1.15rem;
    height: 1.15rem;
}

.industry-card__name {
    display: block;
    font-weight: 650;
    color: var(--ink-900);
    margin-bottom: 0.15rem;
    line-height: 1.3;
}

.industry-card__teaser {
    display: block;
    font-size: 0.88rem;
    line-height: 1.45;
    color: var(--ink-600);
}

.section-head--compact {
    margin-bottom: var(--space-m);
}

.section-head--compact h2 {
    font-size: var(--step-3);
}

/* Phones: a swipeable row so six industries take one screen band, not six. */
@media (max-width: 39.99em) {
    .industry-strip {
        grid-auto-flow: column;
        grid-auto-columns: 63%;
        overflow-x: auto;
        scroll-snap-type: x mandatory;
        overscroll-behavior-x: contain;
        -webkit-overflow-scrolling: touch;
        margin-inline: calc(var(--space-s) * -1);
        padding-inline: var(--space-s);
        padding-bottom: var(--space-xs);
        scroll-padding-inline: var(--space-s);
    }

    .industry-strip > li {
        scroll-snap-align: start;
    }

    .industry-strip:focus-visible {
        outline: 3px solid var(--color-focus);
        outline-offset: 4px;
    }
}

/* Scrollbars on the strips: visible enough to signal scrollability, quiet
   enough not to intrude. */
.industry-strip::-webkit-scrollbar,
.grid--scroll-mobile::-webkit-scrollbar {
    height: 4px;
}

.industry-strip::-webkit-scrollbar-thumb,
.grid--scroll-mobile::-webkit-scrollbar-thumb {
    background: var(--color-border-strong);
    border-radius: 2px;
}

/* 8i. Headline accent ==================================================== */

/*
   Colours the closing phrase of the hero headline. On the dark hero this uses
   the light accent; the deep accent is kept for light surfaces where the bright
   cyan would fail contrast.
*/
/*
   Default to the deep accent, which is the one that passes on white. The bright
   accent is switched in only inside a dark section. The earlier version tested
   the phrase's own parent, which is the h1 rather than the section, so the dark
   surface got the dark accent at about 2.6:1.
*/
.accent-phrase {
    color: var(--cyan-400);
}

.on-dark .accent-phrase,
.section--dark .accent-phrase,
.hero .accent-phrase {
    color: var(--cyan-300);
}

/* 8j. External link marker =============================================== */

/* A small glyph so the new-tab behaviour is visible, not just announced. */
.external-icon {
    display: inline-block;
    width: 0.68em;
    height: 0.68em;
    margin-left: 0.3em;
    vertical-align: baseline;
    opacity: 0.65;
}

.footer-list a:hover .external-icon,
.footer-list a:focus-visible .external-icon {
    opacity: 1;
}

/* 8k. Legal page detail ================================================== */

.policy-updated {
    margin-bottom: var(--space-l);
    padding-bottom: var(--space-s);
    border-bottom: 1px solid var(--color-border);
    font-size: 0.9rem;
    color: var(--ink-500);
}

/* 9. Utilities =========================================================== */

.visually-hidden {
    position: absolute !important;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

.text-center {
    text-align: center;
}

.center-block {
    margin-inline: auto;
}

.mb-0 {
    margin-bottom: 0;
}

.mt-l {
    margin-top: var(--space-l);
}

.max-measure {
    max-width: var(--measure);
}

.divider-top {
    border-top: 1px solid var(--paper-line);
    padding-top: var(--space-l);
}

.cta-band {
    text-align: center;
}

.cta-band h2 {
    max-width: 20ch;
    margin-inline: auto;
}

.cta-band p {
    max-width: 52ch;
    margin-inline: auto;
    margin-bottom: var(--space-l);
}

.cta-band .btn-row {
    justify-content: center;
}

.empty-state {
    padding: var(--space-xl);
    text-align: center;
    border: 1px dashed var(--paper-line);
    border-radius: var(--radius-m);
    color: var(--ink-600);
}

/* 10. Motion and print =================================================== */

@media (prefers-reduced-motion: reduce) {
    html {
        scroll-behavior: auto;
    }

    *,
    *::before,
    *::after {
        animation-duration: 0.001ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.001ms !important;
        scroll-behavior: auto !important;
    }

    .sf-flow {
        display: none;
    }

    .btn:hover,
    .card:hover {
        transform: none;
    }

    /* Packets rest at a readable position rather than vanishing. */
    .sf-packet {
        offset-distance: 55%;
        opacity: 1;
    }
}

@media print {
    .site-header,
    .site-footer,
    .btn,
    .filter-bar,
    .nav-toggle {
        display: none !important;
    }

    body {
        color: #000;
        background: #fff;
    }

    .section {
        padding-block: 1rem;
    }

    .faq__a {
        display: block !important;
    }
}

/* Contact routes: label above address so the pairing survives a narrow screen. */
.contact-routes {
    list-style: none;
    margin: 0.75rem 0 0;
    padding: 0;
    display: grid;
    gap: 0.75rem;
}

.contact-routes li {
    display: grid;
    gap: 0.125rem;
}

.contact-routes strong {
    font-size: 0.875rem;
    font-weight: 600;
    color: var(--ink-600);
}

.contact-routes a {
    /* Text-height anchors are not a reachable target on a touch screen. */
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    word-break: break-word;
}

@media (min-width: 48em) {
    .contact-routes a { min-height: 32px; }
}


/* Section identity pill ==================================================
   Each section states its job in the argument — the problem, what we build,
   how it works — rather than being another unlabelled band. Cheap device,
   and it is what stops seven sections reading as one undifferentiated scroll.
   ======================================================================== */
.section-pill {
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.375rem 0.875rem;
    margin: 0 0 var(--space-m);
    border: 1px solid var(--color-hairline-strong);
    border-radius: 999px;
    background: rgba(255, 255, 255, 0.03);
    font-family: var(--font-sans);
    font-size: var(--step--1);
    font-weight: 600;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--ink-600);
}

.section-pill::before {
    content: "";
    inline-size: 0.5rem;
    block-size: 0.5rem;
    border-radius: 50%;
    background: var(--color-accent);
}

/* The one warm note in a cold palette, reserved for the section that names
   the problem — the only one meant to feel uncomfortable. */
.section-pill--warm::before {
    background: var(--color-warm);
}

.section--light .section-pill {
    border-color: var(--color-border-strong);
    background: var(--color-surface);
    color: var(--color-text-secondary);
}

/* Ambient depth ==========================================================
   A single soft light source behind a section, rather than a flat fill. Sits
   under the content and never intercepts pointer events.
   ======================================================================== */
.glow {
    position: relative;
    isolation: isolate;
}

.glow::before {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    pointer-events: none;
    background:
        radial-gradient(48rem 26rem at 15% 0%, rgba(8, 189, 221, 0.10), transparent 68%),
        radial-gradient(38rem 22rem at 88% 12%, rgba(47, 140, 240, 0.09), transparent 66%);
}

@media (prefers-reduced-transparency: reduce) {
    .glow::before { display: none; }
}

/* Australia reach map ====================================================
   Its own band rather than hero decoration. Sharing the hero with the systems
   figure meant two dense visuals competing, and the map lost.
   ======================================================================== */
.reach-band {
    position: relative;
    overflow: hidden;
}

.reach {
    inline-size: 26rem;
    max-inline-size: 100%;
    margin-inline: auto;
}

.reach img {
    inline-size: 100%;
    block-size: auto;
    /*
       The artwork was drawn on its own near-black ground, which showed as a hard
       rectangle against the band. mix-blend-mode: screen was tried first and made
       the image disappear entirely, so the edges are feathered with a mask
       instead: same result, and it degrades to a plain image where mask-image is
       unsupported rather than to nothing at all.
    */
    -webkit-mask-image: radial-gradient(72% 68% at 50% 48%, #000 38%, transparent 100%);
    mask-image: radial-gradient(72% 68% at 50% 48%, #000 38%, transparent 100%);
}





/* Each arc is a static faint line with a brighter travelling segment over it,
   so the network is legible even at the moment no pulse is on a given arc. */










.trust__copy > * + * {
    margin-block-start: var(--space-m);
}

@media (min-width: 48em) {
    /* Wide enough for the map to sit beside the statement rather than above it. */
    .reach-band .trust {
        display: grid;
        grid-template-columns: 26rem minmax(0, 30rem);
        gap: var(--space-xl);
        align-items: center;
        justify-content: start;
    }

    .reach {
        inline-size: 26rem;
        margin-inline: 0;
    }
}



/* Industry card photography ==============================================
   Only present on cards that have an image; the icon layout is untouched.
   The frame is fixed-ratio so a card is the same height whether it carries a
   photograph or an icon, and a mixed strip does not look broken while
   photography is still being added one industry at a time.
   ======================================================================== */
.industry-card__media {
    display: block;
    aspect-ratio: 3 / 2;
    margin-block-end: var(--space-s);
    border-radius: var(--radius-s);
    overflow: hidden;
    background: var(--paper-alt);
}

.industry-card__media img {
    inline-size: 100%;
    block-size: 100%;
    object-fit: cover;
    /* Photographs on a dark canvas read as bright rectangles unless they are
       brought down to meet it. Restored on hover so the card still rewards
       attention. */
    filter: saturate(0.85) brightness(0.82);
    transition: filter var(--transition), scale var(--transition);
}

.industry-card--photo:hover .industry-card__media img,
.industry-card--photo:focus-visible .industry-card__media img {
    filter: saturate(1) brightness(1);
    scale: 1.03;
}

@media (prefers-reduced-motion: reduce) {
    .industry-card__media img {
        transition: none;
    }

    .industry-card--photo:hover .industry-card__media img {
        scale: 1;
    }
}

/* The problem grid =======================================================
   Eight plain list items became eight numbered cards, each ending with the
   current state set against the alternative. The pairing is what turns an
   abstract complaint into something a reader recognises.
   ======================================================================== */
.problem-grid {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: var(--space-s);
}

/* Two-up from 30em. These cards are short, and eight of them in a single
   column was 2,477px of scrolling before the reader reached anything else. */
@media (min-width: 30em) {
    .problem-grid { grid-template-columns: repeat(2, 1fr); }
}

@media (min-width: 68em) {
    .problem-grid { grid-template-columns: repeat(4, 1fr); }
}

.problem-card {
    display: flex;
    flex-direction: column;
    padding: var(--space-m);
    background: var(--paper-card);
    border: 1px solid var(--paper-line);
    border-radius: var(--radius-m);
    transition: border-color var(--transition), transform var(--transition);
}

.problem-card:hover {
    border-color: rgba(255, 255, 255, 0.2);
    transform: translateY(-2px);
}

.problem-card__num {
    font-family: var(--font-mono);
    font-size: 0.8rem;
    letter-spacing: 0.08em;
    color: var(--color-warm);
}

.problem-card__title {
    margin: var(--space-2xs) 0 var(--space-2xs);
    font-family: var(--font-display);
    font-size: var(--step-1);
    line-height: 1.2;
    color: var(--ink-900);
}

.problem-card__desc {
    margin: 0 0 var(--space-m);
    font-size: var(--step--1);
    color: var(--ink-600);
}

/* Pushed to the bottom so the pairing lines up across cards of unequal text. */
.problem-card__shift {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 0.4rem;
    margin: auto 0 0;
    padding-block-start: var(--space-s);
    border-block-start: 1px solid var(--paper-line);
    font-size: 0.8rem;
}

.problem-card__now {
    color: var(--ink-500);
    text-decoration: line-through;
    text-decoration-color: rgba(255, 180, 107, 0.5);
}

.problem-card__arrow { color: var(--color-warm); }

.problem-card__then {
    color: var(--color-accent);
    font-weight: 600;
}

/* Industries, inline above the services ==================================
   Previously a section of its own directly above Services, asking the same
   question twice.
   ======================================================================== */
.industries-inline {
    margin-block-end: var(--space-xl);
    padding-block-end: var(--space-m);
    border-block-end: 1px solid var(--paper-line);
}

.industries-inline__label {
    margin: 0 0 var(--space-s);
    font-family: var(--font-mono);
    font-size: 0.78rem;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--ink-500);
}

/* Method closing notes ===================================================
   The former "Why ByteX" section, folded under the four steps it was
   restating.
   ======================================================================== */
.method-notes {
    display: grid;
    gap: var(--space-m);
    margin-block-start: var(--space-xl);
    padding-block-start: var(--space-l);
    border-block-start: 1px solid var(--paper-line);
}

@media (min-width: 48em) {
    .method-notes { grid-template-columns: repeat(2, 1fr); }
}

.method-note__title {
    margin: 0 0 var(--space-3xs);
    font-size: var(--step-0);
    color: var(--ink-900);
}

.method-note__desc {
    margin: 0;
    font-size: var(--step--1);
    color: var(--ink-600);
}

/* Supplied artwork ======================================================
   Icons and figures generated for ByteX, processed from 2752px JPEGs down to
   WebP. All decorative: every one sits beside text that already carries the
   same meaning, so each is aria-hidden or has an empty alt.
   ======================================================================== */
.process-figure {
    max-inline-size: 30rem;
    margin: 0 auto var(--space-xl);
}

.process-figure img {
    inline-size: 100%;
    block-size: auto;
    border-radius: var(--radius-m);
}

/*
   Floated beside the steps at first. The float reserved its space but painted
   nothing — the box measured 384x321 with the image fully decoded, yet every
   pixel in it came back as the section background. The same image renders
   correctly on its own, so this is the float, not the asset. A centred block
   above the steps is predictable and needs no breakpoint of its own.
*/
@media (min-width: 64em) {
    .process-figure {
        max-inline-size: 34rem;
    }
}

/* Fibre texture behind the closing call to action. Low opacity so it reads as
   depth rather than as a picture competing with the heading. */
.cta--fibre {
    position: relative;
    isolation: isolate;
    overflow: hidden;
}

/*
   The source is portrait (1100x1826) and this band is wide and short, so cover
   crops it hard and the strands ended abruptly partway across. Fading it out
   deliberately turns that into a light source entering from one corner rather
   than a texture that stops. Sized to the height so the strands keep their shape.
*/
.cta--fibre::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    background-image: url("/img/art/fibre-texture.webp");
    background-size: auto 220%;
    background-position: left center;
    background-repeat: no-repeat;
    opacity: 0.3;
    pointer-events: none;
    -webkit-mask-image: linear-gradient(100deg, #000 0%, rgba(0,0,0,0.55) 42%, transparent 78%);
    mask-image: linear-gradient(100deg, #000 0%, rgba(0,0,0,0.55) 42%, transparent 78%);
}

@media (prefers-reduced-transparency: reduce) {
    .cta--fibre::after { display: none; }
}
