/* =========================================================================
   Object Developer — design system
   One stylesheet, no build step. Organised as:
   1 tokens  2 reset  3 typography  4 layout  5 components
   6 sections  7 page-specific  8 utilities  9 responsive  10 motion
   ========================================================================= */

/* ---------- 1. TOKENS ----------------------------------------------------
   Palette is taken from the existing brand: signal orange on deep navy.
   Keeping the hues means the rebuild still looks like Object Developer to
   anyone who already knows the site, while the neutrals around them are
   retuned so long pages of copy stay comfortable to read.
   ------------------------------------------------------------------------- */
:root {
    /* brand ramp — signal orange */
    --brand-50:  #fff4ed;
    --brand-100: #ffe4d3;
    --brand-200: #ffc4a6;
    --brand-300: #ff9d6e;
    --brand-400: #ff7a3d;
    --brand-500: #ff5c00;
    --brand-600: #e04a00;
    --brand-700: #b93a02;
    --brand-800: #932f08;
    --brand-900: #78290b;

    /* ink ramp — deep navy, the second half of the brand */
    --ink-900: #070f1f;
    --ink-800: #09142f;
    --ink-700: #0d1b2a;
    --ink-600: #16263c;
    --ink-500: #24374f;

    /* per-card accent families, used across services and products */
    --a-orange:  #c2410c;  --a-orange-soft:  #fff1e8;
    --a-blue:    #1857b8;  --a-blue-soft:    #eaf1fd;
    --a-teal:    #06786c;  --a-teal-soft:    #e6f6f3;
    --a-violet:  #6b39b5;  --a-violet-soft:  #f2ecfd;
    --a-pink:    #c01566;  --a-pink-soft:    #fdeaf3;
    --a-green:   #3f7a12;  --a-green-soft:   #eff8e5;
    --a-amber:   #a05f04;  --a-amber-soft:   #fff5e2;
    --a-cyan:    #0b6f96;  --a-cyan-soft:    #e8f5fb;

    /* semantic surfaces + text (light is the base definition) */
    --bg:          #fdfcfb;
    --bg-alt:      #f6f3ef;
    --surface:     #ffffff;
    --surface-2:   #f4f1ec;
    --surface-3:   #e8e3db;
    --border:      #e6e1d8;
    --border-soft: #f0ece4;
    /* Card and divider borders are decorative — the surface colour and shadow
       already separate them, so they are not held to 3:1. A form field border
       IS the control boundary, so it is, and gets its own token. */
    --border-input: #8f8878;
    --text:        #16181d;
    --text-2:      #3a3f48;
    --muted:       #666d78;
    --muted-2:     #8b919b;
    /* brand-600 measures 3.98:1 on the page ground — below the 4.5:1 needed
       for body-size link text, so accent text uses brand-700. The lighter
       brand-500/600 remain available for fills, which have no text on them. */
    --accent:      var(--brand-700);
    --accent-soft: var(--brand-50);
    --accent-text: #ffffff;
    --on-dark:     #eef1f6;

    --grad-1: #ff5c00;
    --grad-2: #e04a00;
    --grad-3: #c01566;

    --ring: 0 0 0 3px rgb(255 92 0 / .30);
    --shadow-xs: 0 1px 2px rgb(9 20 47 / .05);
    --shadow-sm: 0 1px 3px rgb(9 20 47 / .08), 0 1px 2px rgb(9 20 47 / .04);
    --shadow-md: 0 4px 12px rgb(9 20 47 / .08), 0 2px 4px rgb(9 20 47 / .04);
    --shadow-lg: 0 12px 32px rgb(9 20 47 / .11), 0 4px 8px rgb(9 20 47 / .05);
    --shadow-xl: 0 24px 64px rgb(9 20 47 / .14), 0 8px 16px rgb(9 20 47 / .06);

    --r-xs: 6px;  --r-sm: 10px; --r-md: 14px;
    --r-lg: 20px; --r-xl: 28px; --r-full: 999px;

    --font-sans:    'Inter', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
    --font-display: 'Sora', var(--font-sans);
    --font-mono:    ui-monospace, 'SFMono-Regular', Menlo, Consolas, monospace;

    --wrap: 1200px;
    --wrap-narrow: 780px;
    --gutter: clamp(1rem, 4vw, 2rem);
    --section-y: clamp(3.5rem, 8vw, 6.5rem);
    --header-h: 74px;
}

/* Dark theme. Every token above is redefined here rather than patched per
   component, so a new component is theme-correct without extra work. */
@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) {
        --bg:          #0a0f1a;
        --bg-alt:      #0e1524;
        --surface:     #121a2b;
        --surface-2:   #182338;
        --surface-3:   #223047;
        --border:      #223047;
        --border-soft: #1a2437;
        --border-input: #63779e;
        --text:        #f2f5fa;
        --text-2:      #cdd5e2;
        --muted:       #98a3b5;
        --muted-2:     #6f7c92;
        --accent:      var(--brand-400);
        --accent-soft: #24170f;
        --accent-text: #1a0d05;
        --on-dark:     #eef1f6;

        --a-orange-soft: #2a1608;  --a-orange: #ff9d6e;
        --a-blue-soft:   #0e1c33;  --a-blue:   #7cadf5;
        --a-teal-soft:   #05231f;  --a-teal:   #57ccbd;
        --a-violet-soft: #1c1330;  --a-violet: #b394ee;
        --a-pink-soft:   #2b0d1c;  --a-pink:   #f186b6;
        --a-green-soft:  #16240a;  --a-green:  #9fd162;
        --a-amber-soft:  #2a1d05;  --a-amber:  #e8b24a;
        --a-cyan-soft:   #06202c;  --a-cyan:   #5cb9dd;

        --grad-1: #ff7a3d;
        --grad-2: #ff5c00;
        --grad-3: #f186b6;

        --shadow-xs: 0 1px 2px rgb(0 0 0 / .3);
        --shadow-sm: 0 1px 3px rgb(0 0 0 / .4);
        --shadow-md: 0 4px 12px rgb(0 0 0 / .45);
        --shadow-lg: 0 12px 32px rgb(0 0 0 / .5);
        --shadow-xl: 0 24px 64px rgb(0 0 0 / .55);
    }
}
[data-theme="dark"] {
    --bg:          #0a0f1a;
    --bg-alt:      #0e1524;
    --surface:     #121a2b;
    --surface-2:   #182338;
    --surface-3:   #223047;
    --border:      #223047;
    --border-soft: #1a2437;
    --border-input: #63779e;
    --text:        #f2f5fa;
    --text-2:      #cdd5e2;
    --muted:       #98a3b5;
    --muted-2:     #6f7c92;
    --accent:      var(--brand-400);
    --accent-soft: #24170f;
    --accent-text: #1a0d05;

    --a-orange-soft: #2a1608;  --a-orange: #ff9d6e;
    --a-blue-soft:   #0e1c33;  --a-blue:   #7cadf5;
    --a-teal-soft:   #05231f;  --a-teal:   #57ccbd;
    --a-violet-soft: #1c1330;  --a-violet: #b394ee;
    --a-pink-soft:   #2b0d1c;  --a-pink:   #f186b6;
    --a-green-soft:  #16240a;  --a-green:  #9fd162;
    --a-amber-soft:  #2a1d05;  --a-amber:  #e8b24a;
    --a-cyan-soft:   #06202c;  --a-cyan:   #5cb9dd;

    --grad-1: #ff7a3d;
    --grad-2: #ff5c00;
    --grad-3: #f186b6;

    --shadow-sm: 0 1px 3px rgb(0 0 0 / .4);
    --shadow-md: 0 4px 12px rgb(0 0 0 / .45);
    --shadow-lg: 0 12px 32px rgb(0 0 0 / .5);
    --shadow-xl: 0 24px 64px rgb(0 0 0 / .55);
}

/* ---------- 2. RESET ----------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }
html {
    -webkit-text-size-adjust: 100%;
    scroll-behavior: smooth;
    scroll-padding-top: calc(var(--header-h) + 1rem);
}
body {
    font-family: var(--font-sans);
    font-size: 1rem;
    line-height: 1.65;
    color: var(--text);
    background: var(--bg);
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
    overflow-x: hidden;
}
img, svg, video { display: block; max-width: 100%; height: auto; }
input, button, textarea, select { font: inherit; color: inherit; }
button { cursor: pointer; background: none; border: 0; }
a { color: var(--accent); text-decoration-thickness: 1px; text-underline-offset: 3px; }
a:hover { text-decoration: none; }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: var(--r-xs); }
::selection { background: var(--brand-200); color: var(--ink-800); }
hr { border: 0; border-top: 1px solid var(--border); margin: 2rem 0; }

/* ---------- 3. TYPOGRAPHY ------------------------------------------------ */
h1, h2, h3, h4, h5 {
    font-family: var(--font-display);
    font-weight: 700;
    line-height: 1.15;
    letter-spacing: -.02em;
    text-wrap: balance;
}
h1 { font-size: clamp(2.1rem, 5.2vw, 3.55rem); letter-spacing: -.035em; }
h2 { font-size: clamp(1.65rem, 3.6vw, 2.5rem);  letter-spacing: -.028em; }
h3 { font-size: clamp(1.25rem, 2.2vw, 1.6rem);  letter-spacing: -.02em; }
h4 { font-size: 1.125rem; }
p  { text-wrap: pretty; }

.lede { font-size: clamp(1.06rem, 1.9vw, 1.28rem); line-height: 1.6; color: var(--text-2); }
.kicker {
    display: inline-flex; align-items: center; gap: .5rem;
    font-size: .78rem; font-weight: 700; letter-spacing: .1em;
    text-transform: uppercase; color: var(--accent);
}
.kicker::before {
    content: ""; width: 22px; height: 2px; border-radius: 2px;
    background: currentColor; opacity: .7;
}
.grad-text {
    background: linear-gradient(100deg, var(--grad-1), var(--grad-2) 45%, var(--grad-3));
    -webkit-background-clip: text; background-clip: text; color: transparent;
}

/* ---------- 4. LAYOUT ---------------------------------------------------- */
.wrap { width: min(var(--wrap), 100% - var(--gutter) * 2); margin-inline: auto; }
.wrap-narrow { width: min(var(--wrap-narrow), 100% - var(--gutter) * 2); margin-inline: auto; }
.section { padding-block: var(--section-y); }
.section-sm { padding-block: clamp(2.5rem, 5vw, 4rem); }
.section-alt { background: var(--bg-alt); }
.section-dark {
    background: linear-gradient(165deg, var(--ink-800), var(--ink-700) 55%, var(--ink-900));
    color: var(--on-dark);
}
.section-dark h1, .section-dark h2, .section-dark h3 { color: #fff; }
.section-dark p  { color: #c6cedb; }

.grid { display: grid; gap: clamp(1rem, 2.4vw, 1.75rem); }
.g-2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.g-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.g-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.g-auto { grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr)); }

.section-head { max-width: 720px; margin-bottom: clamp(2rem, 4vw, 3rem); }
.section-head.center { margin-inline: auto; text-align: center; }
.section-head h2 { margin: .6rem 0 .75rem; }

/* ---------- 5. COMPONENTS ------------------------------------------------ */

/* Buttons */
.btn {
    display: inline-flex; align-items: center; justify-content: center; gap: .55rem;
    padding: .8rem 1.5rem; border-radius: var(--r-full);
    font-weight: 650; font-size: .95rem; line-height: 1;
    text-decoration: none; white-space: nowrap;
    border: 1px solid transparent;
    transition: transform .18s cubic-bezier(.2,.7,.3,1), box-shadow .18s, background .18s, color .18s;
}
.btn:hover { transform: translateY(-2px); }
.btn:active { transform: translateY(0); }
/* Icons inherit the 24px default and, in a full-width button, the flex row
   stretches them to fill. Pin the size so a button's icon is the same whatever
   width the button happens to be. */
.btn svg { width: 18px; height: 18px; flex: none; }
.btn-lg svg { width: 20px; height: 20px; }
.btn-sm svg { width: 16px; height: 16px; }
.btn-primary {
    /* The gradient stops are darker than the brand ramp because the label is
       white: brand-500 gives only 3.10:1, and this is the primary CTA. The
       lightest stop here measures 4.69:1. */
    background: linear-gradient(135deg, #cf4405, #b93a02);
    color: #fff; box-shadow: 0 6px 18px rgb(185 58 2 / .34);
}
.btn-primary:hover { box-shadow: 0 10px 26px rgb(255 92 0 / .40); }
.btn-ghost { background: var(--surface); color: var(--text); border-color: var(--border); box-shadow: var(--shadow-xs); }
.btn-ghost:hover { border-color: var(--accent); color: var(--accent); }
.btn-outline { border-color: currentColor; color: var(--accent); }
.btn-outline:hover { background: var(--accent-soft); }
.btn-on-dark { background: rgb(255 255 255 / .1); color: #fff; border-color: rgb(255 255 255 / .28); backdrop-filter: blur(8px); }
.btn-on-dark:hover { background: rgb(255 255 255 / .18); }
.btn-lg { padding: 1rem 1.9rem; font-size: 1.02rem; }
.btn-sm { padding: .55rem 1.05rem; font-size: .86rem; }

/* Cards */
.card {
    background: var(--surface); border: 1px solid var(--border);
    border-radius: var(--r-lg); padding: clamp(1.3rem, 2.4vw, 1.9rem);
    box-shadow: var(--shadow-xs);
    transition: transform .22s cubic-bezier(.2,.7,.3,1), box-shadow .22s, border-color .22s;
}
a.card, .card-link { text-decoration: none; color: inherit; display: block; }
a.card:hover, .card-hover:hover {
    transform: translateY(-4px); box-shadow: var(--shadow-lg); border-color: var(--brand-200);
}
.card h3 { margin-bottom: .5rem; font-size: 1.18rem; }
.card p { color: var(--muted); font-size: .95rem; }

/* Icon tile inside cards */
.icon-tile {
    width: 48px; height: 48px; border-radius: var(--r-md);
    display: grid; place-items: center; margin-bottom: 1.05rem;
    background: var(--accent-soft); color: var(--accent);
}
.icon-tile svg { width: 24px; height: 24px; }

/* Per-card accent hooks */
.ac-orange { --accent: var(--a-orange); --accent-soft: var(--a-orange-soft); }
.ac-blue   { --accent: var(--a-blue);   --accent-soft: var(--a-blue-soft); }
.ac-teal   { --accent: var(--a-teal);   --accent-soft: var(--a-teal-soft); }
.ac-violet { --accent: var(--a-violet); --accent-soft: var(--a-violet-soft); }
.ac-pink   { --accent: var(--a-pink);   --accent-soft: var(--a-pink-soft); }
.ac-green  { --accent: var(--a-green);  --accent-soft: var(--a-green-soft); }
.ac-amber  { --accent: var(--a-amber);  --accent-soft: var(--a-amber-soft); }
.ac-cyan   { --accent: var(--a-cyan);   --accent-soft: var(--a-cyan-soft); }

/* Pills / tags */
.pill {
    display: inline-flex; align-items: center; gap: .4rem;
    padding: .34rem .8rem; border-radius: var(--r-full);
    font-size: .8rem; font-weight: 600; text-decoration: none;
    background: var(--surface-2); color: var(--text-2); border: 1px solid var(--border-soft);
}
a.pill:hover { background: var(--accent-soft); color: var(--accent); border-color: currentColor; }
.pill-accent { background: var(--accent-soft); color: var(--accent); border-color: transparent; }
/* Icons inside a pill inherit the 24px icon default and blow the pill open —
   they are decoration next to the label, so they get label-sized. */
.pill svg { width: 14px; height: 14px; flex: none; }
.pill { white-space: nowrap; }

/* An icon sitting inline with a line of text. The 24px default towers over
   small copy, so it is matched to the line it sits on and nudged onto the
   baseline rather than the text top. */
.icon-inline,
p > svg:first-child {
    display: inline-block;
    width: 1em; height: 1em;
    vertical-align: -.14em;
    margin-right: .35em;
    flex: none;
}

/* Badge row */
.badges { display: flex; flex-wrap: wrap; gap: .5rem; }

/* Breadcrumbs */
.crumbs { font-size: .84rem; color: var(--muted); margin-bottom: 1rem; }
.crumbs ol { list-style: none; padding: 0; display: flex; flex-wrap: wrap; gap: .4rem; align-items: center; }
.crumbs a { color: inherit; text-decoration: none; }
.crumbs a:hover { color: var(--accent); text-decoration: underline; }
.crumbs li + li::before { content: "/"; margin-right: .4rem; opacity: .45; }
.crumbs [aria-current] { color: var(--text-2); font-weight: 600; }

/* Prose — long-form article body */
.prose { font-size: 1.04rem; line-height: 1.75; color: var(--text-2); }
.prose > * + * { margin-top: 1.15em; }
.prose h2 { margin-top: 2.4em; margin-bottom: .1em; color: var(--text); font-size: clamp(1.4rem, 2.6vw, 1.85rem); }
.prose h3 { margin-top: 1.9em; margin-bottom: .1em; color: var(--text); font-size: clamp(1.15rem, 2vw, 1.35rem); }
.prose h4 { margin-top: 1.6em; color: var(--text); }
.prose ul, .prose ol { padding-left: 1.35em; }
.prose li + li { margin-top: .45em; }
.prose li::marker { color: var(--accent); }
.prose strong { color: var(--text); font-weight: 650; }
.prose a { font-weight: 550; }
.prose img { border-radius: var(--r-md); margin-block: 1.6em; box-shadow: var(--shadow-md); }
.prose blockquote {
    border-left: 3px solid var(--accent); padding: .3rem 0 .3rem 1.25rem;
    color: var(--text); font-size: 1.08em; font-style: italic;
}
.prose pre {
    background: var(--ink-800); color: #e6ecf6; padding: 1.1rem 1.25rem;
    border-radius: var(--r-md); overflow-x: auto; font-family: var(--font-mono); font-size: .88rem;
}
.prose :not(pre) > code {
    background: var(--surface-2); padding: .15em .4em; border-radius: var(--r-xs);
    font-family: var(--font-mono); font-size: .88em; color: var(--brand-700);
}
.prose table { width: 100%; border-collapse: collapse; font-size: .94rem; }
.prose th, .prose td { border: 1px solid var(--border); padding: .6rem .8rem; text-align: left; }
.prose th { background: var(--surface-2); font-weight: 650; color: var(--text); }
/* Wide tables scroll inside their own box instead of pushing the page sideways. */
.table-scroll { overflow-x: auto; }

/* Accordion / FAQ */
.faq-item { border-bottom: 1px solid var(--border); }
.faq-item summary {
    display: flex; align-items: center; justify-content: space-between; gap: 1rem;
    padding: 1.15rem 0; cursor: pointer; list-style: none;
    font-family: var(--font-display); font-weight: 650; font-size: 1.05rem; color: var(--text);
}
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item summary::after {
    content: ""; flex: none; width: 11px; height: 11px;
    border-right: 2px solid var(--accent); border-bottom: 2px solid var(--accent);
    transform: rotate(45deg) translateY(-3px); transition: transform .22s;
}
.faq-item[open] summary::after { transform: rotate(225deg) translateY(-3px); }
.faq-item .faq-body { padding-bottom: 1.15rem; color: var(--muted); }
.faq-item .faq-body > * + * { margin-top: .8rem; }

/* Stats */
.stat { text-align: center; }
.stat .v {
    font-family: var(--font-display); font-weight: 800;
    font-size: clamp(1.9rem, 4.5vw, 2.9rem); line-height: 1;
    letter-spacing: -.04em;
}
.stat .l { font-size: .87rem; color: var(--muted); margin-top: .45rem; }

/* Pagination */
.pager { display: flex; flex-wrap: wrap; gap: .45rem; justify-content: center; margin-top: 3rem; }
.pager a, .pager span {
    min-width: 42px; height: 42px; padding-inline: .7rem;
    display: inline-flex; align-items: center; justify-content: center;
    border-radius: var(--r-sm); border: 1px solid var(--border);
    background: var(--surface); color: var(--text-2);
    text-decoration: none; font-weight: 600; font-size: .92rem;
}
.pager a:hover { border-color: var(--accent); color: var(--accent); }
.pager [aria-current] { background: var(--accent); border-color: var(--accent); color: var(--accent-text); }
.pager .gap { border: 0; background: none; }

/* Form */
.field { display: grid; gap: .4rem; margin-bottom: 1rem; }
.field label { font-size: .87rem; font-weight: 600; color: var(--text-2); }
.field input, .field select, .field textarea {
    width: 100%; padding: .78rem .95rem;
    border: 1px solid var(--border-input); border-radius: var(--r-sm);
    background: var(--surface); color: var(--text); transition: border-color .18s, box-shadow .18s;
}
.field input:focus, .field select:focus, .field textarea:focus {
    outline: none; border-color: var(--accent); box-shadow: var(--ring);
}
.field textarea { min-height: 130px; resize: vertical; }
.field .err { font-size: .82rem; color: #d3382a; }
.alert { padding: .95rem 1.1rem; border-radius: var(--r-md); font-size: .93rem; margin-bottom: 1.25rem; }
.alert-ok  { background: var(--a-green-soft); color: var(--a-green); border: 1px solid currentColor; }
.alert-err { background: #fdecea; color: #b3261e; border: 1px solid currentColor; }

/* ---------- 6. SECTIONS -------------------------------------------------- */

/* Header */
.site-header {
    position: sticky; top: 0; z-index: 50; height: var(--header-h);
    display: flex; align-items: center;
    background: color-mix(in srgb, var(--bg) 82%, transparent);
    backdrop-filter: saturate(1.5) blur(14px);
    border-bottom: 1px solid transparent;
    transition: border-color .2s, box-shadow .2s;
}
.site-header.stuck { border-bottom-color: var(--border); box-shadow: var(--shadow-sm); }
.site-header .wrap { display: flex; align-items: center; gap: 1.25rem; }
/* Brand logo. The lockup already contains the wordmark, so no text sits beside
   it. Two files ship in the header — the standard one and a variant whose
   near-black "DEVELOPER" is recoloured white — and CSS picks by colour scheme,
   which is the only place that decision can be made correctly. */
.brand { display: inline-flex; align-items: center; text-decoration: none; flex: none; }
.brand-logo { width: auto; height: 40px; display: block; }
.brand-logo-inverse { display: none; }

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

/* The footer sits on the dark ground in every theme, so it always uses the
   light variant and must not be swapped back. */
.site-footer .brand-logo { height: 46px; }

.nav { margin-left: auto; display: flex; align-items: center; gap: .2rem; }
.nav > a, .nav-item > button {
    display: inline-flex; align-items: center; gap: .3rem;
    padding: .55rem .8rem; border-radius: var(--r-sm);
    font-size: .93rem; font-weight: 550; color: var(--text-2); text-decoration: none;
    transition: color .16s, background .16s;
}
.nav > a:hover, .nav-item > button:hover { color: var(--accent); background: var(--accent-soft); }
.nav .is-active { color: var(--accent); font-weight: 650; }
.nav-item { position: relative; }
.nav-item > button::after {
    content: ""; width: 7px; height: 7px; margin-left: .1rem;
    border-right: 1.6px solid currentColor; border-bottom: 1.6px solid currentColor;
    transform: rotate(45deg) translateY(-2px); opacity: .65; transition: transform .2s;
}
.nav-item[data-open="true"] > button::after { transform: rotate(225deg) translateY(-2px); }

.mega {
    position: absolute; top: calc(100% + .55rem); left: 50%; translate: -50% 0;
    width: min(720px, 92vw); padding: 1.1rem;
    background: var(--surface); border: 1px solid var(--border);
    border-radius: var(--r-lg); box-shadow: var(--shadow-xl);
    display: none; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: .3rem;
}
.nav-item[data-open="true"] .mega { display: grid; }
.mega a {
    display: flex; gap: .75rem; padding: .7rem .8rem; border-radius: var(--r-md);
    text-decoration: none; color: var(--text); transition: background .16s;
}
.mega a:hover { background: var(--surface-2); }
.mega .mi { width: 34px; height: 34px; flex: none; border-radius: var(--r-sm); display: grid; place-items: center; background: var(--accent-soft); color: var(--accent); }
.mega .mi svg { width: 18px; height: 18px; }
.mega strong { display: block; font-size: .92rem; font-weight: 650; }
.mega small { display: block; color: var(--muted); font-size: .8rem; line-height: 1.4; }
.mega-foot { grid-column: 1 / -1; margin-top: .4rem; padding-top: .8rem; border-top: 1px solid var(--border-soft); }

.nav-cta { margin-left: .5rem; }
.burger { display: none; margin-left: auto; width: 42px; height: 42px; border-radius: var(--r-sm); align-items: center; justify-content: center; color: var(--text); }
.burger svg { width: 24px; height: 24px; }

/* Mobile drawer */
.drawer {
    position: fixed; inset: var(--header-h) 0 0; z-index: 45;
    background: var(--bg); padding: 1.25rem var(--gutter) 3rem;
    overflow-y: auto; display: none;
}
.drawer[data-open="true"] { display: block; }
.drawer details { border-bottom: 1px solid var(--border); }
.drawer summary { padding: .9rem 0; font-weight: 650; font-family: var(--font-display); cursor: pointer; list-style: none; display: flex; justify-content: space-between; align-items: center; }
.drawer summary::-webkit-details-marker { display: none; }
.drawer summary::after { content: ""; width: 9px; height: 9px; border-right: 2px solid var(--accent); border-bottom: 2px solid var(--accent); transform: rotate(45deg); }
.drawer details[open] summary::after { transform: rotate(225deg); }
.drawer .sub { padding-bottom: .9rem; display: grid; gap: .1rem; }
.drawer .sub a, .drawer > a { display: block; padding: .55rem 0; color: var(--text-2); text-decoration: none; font-size: .95rem; }
.drawer > a { border-bottom: 1px solid var(--border); font-weight: 650; font-family: var(--font-display); }
.drawer .sub a:hover, .drawer > a:hover { color: var(--accent); }

/* Hero */
.hero { position: relative; padding-block: clamp(3rem, 7vw, 5.5rem) clamp(3rem, 7vw, 5rem); overflow: hidden; }
.hero-inner { display: grid; grid-template-columns: 1.08fr .92fr; gap: clamp(2rem, 5vw, 4rem); align-items: center; }
.hero h1 { margin: .9rem 0 1.1rem; }
.hero .lede { max-width: 56ch; }
.hero-cta { display: flex; flex-wrap: wrap; gap: .8rem; margin-top: 1.9rem; }
.hero-trust { display: flex; flex-wrap: wrap; gap: 1.4rem; margin-top: 2.2rem; padding-top: 1.6rem; border-top: 1px solid var(--border); }
.hero-trust .t { font-size: .86rem; color: var(--muted); display: flex; align-items: center; gap: .45rem; }
.hero-trust .t svg { width: 17px; height: 17px; color: var(--a-green); flex: none; }

/* Hero illustration. It carries its own light surfaces, so on the dark theme it
   is softened slightly rather than recoloured — flat vector art recoloured by
   filter always looks wrong. */
.hero-illustration { width: 100%; height: auto; display: block; }

/* Centring the art against a tall copy column leaves it sitting low, because
   the drawing carries its weight in the lower half — the ground shadow and the
   figures. Lifting it aligns it optically with the headline rather than with
   the column midpoint. Two-column layout only; stacked, it stays put.

   Translate, not margin: with align-items:center the centring maths re-runs on a
   changed margin box, so a negative margin-top only moves the art by half of it.
   A transform moves it exactly as far as it says. */
@media (min-width: 901px) {
    .hero .hero-art { transform: translateY(clamp(-5.5rem, -4.2vw, -2rem)); }
}
@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) .hero-illustration { opacity: .93; }
}
[data-theme="dark"] .hero-illustration { opacity: .93; }


/* Page and product hero illustrations (lib/scenes.php). Same treatment as the
   homepage art: it carries its own light surfaces, so on the dark theme it is
   softened rather than recoloured. */
.scene-art { width: 100%; height: auto; display: block; }
@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) .scene-art { opacity: .93; }
}
[data-theme="dark"] .scene-art { opacity: .93; }

/* ---- Lead-generation hero -------------------------------------------------
   Copy on the left, enquiry form on the right. The form sits in the hero rather
   than behind a button because sending someone to another page to start typing
   loses most of them on the way. */
.hero-lead { padding-block: clamp(2.5rem, 5vw, 4.5rem) clamp(2.5rem, 5vw, 4rem); }
.hero-lead-grid {
    display: grid;
    grid-template-columns: minmax(0, 1.05fr) minmax(0, .95fr);
    gap: clamp(2rem, 5vw, 4rem);
    align-items: center;
}
.hero-copy h1 { margin: .9rem 0 1.1rem; }
.hero-copy .lede { max-width: 54ch; }

.hero-points { list-style: none; padding: 0; margin: 1.5rem 0 0; display: grid; gap: .6rem; }
.hero-points li { display: flex; align-items: center; gap: .6rem; font-size: .96rem; color: var(--text-2); }
.hero-points svg { width: 19px; height: 19px; flex: none; color: var(--a-green); }

/* The enquiry card itself. */
.quote-card {
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--r-xl);
    box-shadow: var(--shadow-xl);
    padding: clamp(1.5rem, 3vw, 2rem);
    position: relative;
}
/* A hairline of brand colour along the top edge, so the card reads as the
   primary action on the page without shouting. */
.quote-card::before {
    content: ""; position: absolute; inset: 0 0 auto 0; height: 4px;
    border-radius: var(--r-xl) var(--r-xl) 0 0;
    background: linear-gradient(90deg, var(--grad-1), var(--grad-2), var(--grad-3));
}
.quote-head h2 { font-size: clamp(1.3rem, 2.2vw, 1.6rem); }
.quote-head p { color: var(--muted); font-size: .93rem; margin-top: .5rem; }
.quote-form { margin-top: 1.4rem; }
.quote-form .field { margin-bottom: .85rem; }
.quote-submit { width: 100%; margin-top: .4rem; }
.quote-note {
    display: flex; align-items: center; gap: .5rem; justify-content: center;
    margin-top: .9rem; font-size: .84rem; color: var(--muted);
}
.quote-note svg { width: 15px; height: 15px; flex: none; color: var(--a-green); }

.quote-alt {
    margin-top: 1.25rem; padding-top: 1.1rem; border-top: 1px solid var(--border-soft);
    display: flex; flex-wrap: wrap; align-items: center; gap: .5rem 1.1rem;
    font-size: .9rem; color: var(--muted);
}
.quote-alt a { display: inline-flex; align-items: center; gap: .4rem; font-weight: 600; text-decoration: none; }
.quote-alt a:hover { text-decoration: underline; }
.quote-alt svg { width: 16px; height: 16px; }

/* ---- Client reviews -------------------------------------------------------
   No avatars and no stars: the quotes never had ratings, and inventing the
   trappings of a review is worse than presenting the words plainly. */
.reviews .review {
    display: flex; flex-direction: column;
    padding: clamp(1.4rem, 2.4vw, 1.9rem);
    margin: 0;
}
.review-mark {
    display: grid; place-items: center;
    width: 38px; height: 38px; border-radius: var(--r-sm);
    background: var(--accent-soft); color: var(--accent);
    margin-bottom: 1rem;
}
.review-mark svg { width: 20px; height: 20px; }
.reviews blockquote {
    margin: 0; flex: 1;
    font-size: 1rem; line-height: 1.7; color: var(--text-2);
    border: 0; padding: 0; font-style: normal;
}
.reviews blockquote::before { content: "\201C"; }
.reviews blockquote::after  { content: "\201D"; }
.reviews figcaption {
    margin-top: 1.15rem; padding-top: 1rem;
    border-top: 1px solid var(--border-soft);
    display: grid; gap: .15rem;
}
.reviews figcaption strong { font-family: var(--font-display); font-size: .98rem; color: var(--text); }
.reviews figcaption span { font-size: .86rem; color: var(--muted); }


/* Industry cards carry a one-line problem statement rather than a pitch, so
   they read tighter than the service cards above them. */
.industry h3 { font-size: 1.05rem; }
.industry p { font-size: .92rem; }


/* "What people come to us with": the visitor's own words, then the answer.
   A definition list is the honest markup — each complaint is a term and each
   response its definition. */
.problems .problem-col { display: flex; flex-direction: column; }
.problem-head { display: flex; align-items: center; gap: .85rem; margin-bottom: 1.25rem; }
.problem-head .icon-tile { margin-bottom: 0; }
.problem-head h3 { font-size: 1.15rem; margin: 0; }
.problem-list { margin: 0 0 1.5rem; flex: 1; }
.problem-list dt {
    font-family: var(--font-display); font-weight: 650; font-size: 1rem;
    color: var(--text); margin-top: 1.1rem;
}
.problem-list dt:first-child { margin-top: 0; }
.problem-list dd {
    margin: .3rem 0 0; padding-left: 1rem;
    border-left: 2px solid var(--accent-soft);
    font-size: .93rem; color: var(--muted);
}
.problems .btn { align-self: flex-start; }

/* Compact client strip directly under the hero. */
.clients-compact { padding-block: clamp(1.75rem, 3vw, 2.5rem); }
.clients-line { text-align: center; color: var(--muted); font-size: .95rem; }
.clients-line strong { color: var(--text); }

/* The two headline offerings. */
.pillars .pillar { display: flex; flex-direction: column; }
.pillars .pillar h3 { font-size: clamp(1.2rem, 2vw, 1.45rem); margin: .5rem 0 .6rem; }
.pillars .pillar .ticks { flex: 1; }
.pillars .pillar .btn { align-self: flex-start; }

/* Sticky call bar on small screens, where the hero form has scrolled away. */
.mobile-cta {
    display: none;
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 44;
    padding: .6rem .75rem calc(.6rem + env(safe-area-inset-bottom, 0px));
    background: color-mix(in srgb, var(--surface) 94%, transparent);
    backdrop-filter: saturate(1.4) blur(12px);
    border-top: 1px solid var(--border);
    gap: .5rem;
}
.mobile-cta .btn { flex: 1; padding-inline: .75rem; font-size: .9rem; }

/* Decorative background mesh, drawn in CSS so it costs no request. */
.mesh { position: absolute; inset: 0; z-index: -1; pointer-events: none; overflow: hidden; }
.mesh::before, .mesh::after {
    content: ""; position: absolute; border-radius: 50%; filter: blur(70px); opacity: .5;
}
.mesh::before { width: 46vw; height: 46vw; top: -14vw; right: -10vw; background: radial-gradient(circle, var(--brand-300), transparent 68%); }
.mesh::after  { width: 40vw; height: 40vw; bottom: -18vw; left: -12vw; background: radial-gradient(circle, var(--a-pink), transparent 70%); opacity: .28; }

/* CTA band */
.cta-band {
    position: relative; overflow: hidden;
    background: linear-gradient(140deg, var(--ink-800), var(--ink-700) 50%, var(--ink-900));
    color: #fff; border-radius: var(--r-xl); padding: clamp(2.2rem, 5vw, 3.6rem);
    text-align: center;
}
.cta-band::before {
    content: ""; position: absolute; width: 34rem; height: 34rem; border-radius: 50%;
    top: -16rem; right: -10rem; filter: blur(60px); opacity: .3;
    background: radial-gradient(circle, var(--brand-500), transparent 65%);
}
.cta-band > * { position: relative; }
.cta-band h2 { color: #fff; }
.cta-band p { color: #c6cedb; max-width: 60ch; margin-inline: auto; margin-top: .8rem; }
.cta-actions { display: flex; flex-wrap: wrap; gap: .8rem; justify-content: center; margin-top: 1.9rem; }

/* Footer */
.site-footer { background: var(--ink-900); color: #b9c2d1; padding-block: clamp(3rem, 6vw, 4.5rem) 2rem; margin-top: auto; }
.site-footer a { color: #b9c2d1; text-decoration: none; }
.site-footer a:hover { color: #fff; }
.footer-grid { display: grid; grid-template-columns: 1.5fr repeat(3, 1fr); gap: clamp(1.5rem, 4vw, 3rem); }
.site-footer h4 { color: #fff; font-size: .84rem; letter-spacing: .1em; text-transform: uppercase; margin-bottom: 1.05rem; }
.site-footer ul { list-style: none; padding: 0; display: grid; gap: .55rem; font-size: .92rem; }
.footer-brand .brand { color: #fff; margin-bottom: 1rem; }
.footer-brand p { font-size: .93rem; max-width: 38ch; }
.footer-contact { display: grid; gap: .6rem; margin-top: 1.25rem; font-size: .93rem; }
.footer-contact div { display: flex; gap: .6rem; align-items: flex-start; }
.footer-contact svg { width: 17px; height: 17px; flex: none; margin-top: .2rem; color: var(--brand-400); }
.social { display: flex; gap: .55rem; margin-top: 1.4rem; }
.social a { width: 38px; height: 38px; border-radius: var(--r-sm); display: grid; place-items: center; background: rgb(255 255 255 / .07); transition: background .18s, transform .18s; }
.social a:hover { background: var(--brand-500); transform: translateY(-2px); }
.social svg { width: 18px; height: 18px; }
.footer-bottom {
    margin-top: 3rem; padding-top: 1.5rem; border-top: 1px solid rgb(255 255 255 / .1);
    display: flex; flex-wrap: wrap; gap: 1rem; justify-content: space-between;
    font-size: .87rem; color: #8b95a7;
}
.footer-bottom nav { display: flex; flex-wrap: wrap; gap: 1.25rem; }

/* Floating WhatsApp */
.wa-float {
    position: fixed; right: 1.15rem; bottom: 1.15rem; z-index: 40;
    width: 54px; height: 54px; border-radius: 50%; display: grid; place-items: center;
    background: #25d366; color: #fff; box-shadow: 0 8px 24px rgb(37 211 102 / .42);
    transition: transform .2s;
}
.wa-float:hover { transform: scale(1.07); }
.wa-float svg { width: 28px; height: 28px; }

/* ---------- 7. PAGE-SPECIFIC --------------------------------------------- */

/* Page hero used by every inner page */
.page-hero { position: relative; padding-block: clamp(2.4rem, 5vw, 3.8rem) clamp(2rem, 4vw, 3rem); overflow: hidden; }
.page-hero h1 { margin: .7rem 0 .9rem; }
.page-hero .lede { max-width: 62ch; }
.page-hero-cta { display: flex; flex-wrap: wrap; gap: .75rem; margin-top: 1.6rem; }

/* Two-column article layout with a sticky sidebar */
.article-layout { display: grid; grid-template-columns: minmax(0, 1fr) 320px; gap: clamp(2rem, 5vw, 4rem); align-items: start; }
.sidebar { position: sticky; top: calc(var(--header-h) + 1.5rem); display: grid; gap: 1.25rem; }
.sidebar .card { padding: 1.3rem; }
/* Card headings inside a section sit under its h2, so they are h3 — skipping a
   level breaks the document outline for screen readers and for crawlers. The
   small uppercase treatment is unchanged. */
.sidebar h4,
.side-title { font-size: .82rem; letter-spacing: .09em; text-transform: uppercase; color: var(--muted); margin-bottom: .9rem; }
.sidebar ul { list-style: none; padding: 0; display: grid; gap: .55rem; font-size: .92rem; }
.sidebar ul a { color: var(--text-2); text-decoration: none; }
.sidebar ul a:hover { color: var(--accent); }

/* Post + project meta line */
.meta { display: flex; flex-wrap: wrap; gap: .9rem; align-items: center; font-size: .87rem; color: var(--muted); }
.meta .dot { width: 3px; height: 3px; border-radius: 50%; background: currentColor; opacity: .5; }

/* Post cards */
.post-card { display: flex; flex-direction: column; height: 100%; overflow: hidden; padding: 0; }
.post-card .thumb {
    aspect-ratio: 16 / 9; position: relative; overflow: hidden;
    background: var(--surface-2); border-bottom: 1px solid var(--border-soft);
}
.post-card .thumb svg { width: 100%; height: 100%; }
/* Featured images are stored at 16:9 already, so cover only absorbs rounding. */
.post-card .thumb img {
    width: 100%; height: 100%; object-fit: cover; object-position: center;
    transition: transform .4s cubic-bezier(.2,.7,.3,1);
}
.post-card.has-image:hover .thumb img { transform: scale(1.04); }

/* Featured image at the top of an article. */
.post-hero {
    width: 100%; height: auto;
    border-radius: var(--r-lg);
    border: 1px solid var(--border);
    box-shadow: var(--shadow-md);
}
.post-card .body { padding: 1.3rem 1.4rem 1.5rem; display: flex; flex-direction: column; flex: 1; }
.post-card h3 { font-size: 1.08rem; line-height: 1.35; margin-bottom: .55rem; }
.post-card p { font-size: .91rem; flex: 1; }
.post-card .meta { margin-top: 1rem; }

/* Project / portfolio cards */
.project-card { padding: 0; overflow: hidden; display: flex; flex-direction: column; }
.project-card .thumb { aspect-ratio: 16 / 10; overflow: hidden; background: var(--surface-2); border-bottom: 1px solid var(--border-soft); }
.project-card .body { padding: 1.15rem 1.3rem 1.4rem; display: flex; flex-direction: column; gap: .5rem; flex: 1; }
.project-card h3 { font-size: 1.02rem; margin-bottom: 0; }
.project-card .project-sector { margin: 0; }
.project-card .project-live { align-self: flex-start; margin-top: auto; font-size: .75rem; padding: .25rem .6rem; white-space: nowrap; }
.project-card .project-live svg { width: 13px; height: 13px; }

/* Screenshots are captured at the top of the page, so anchoring the crop to the
   top keeps the site's header and hero visible as the card scales. */
.project-card .thumb img {
    width: 100%; height: 100%;
    object-fit: cover; object-position: top center;
    transition: transform .4s cubic-bezier(.2,.7,.3,1);
}
.project-card.has-shot:hover .thumb img { transform: scale(1.04); }

/* Screenshot on the project detail page. */
.work-shot {
    width: 100%; height: auto;
    border-radius: var(--r-lg);
    border: 1px solid var(--border);
    box-shadow: var(--shadow-lg);
}

/* Feature list with ticks */
.ticks { list-style: none; padding: 0; display: grid; gap: .7rem; }
.ticks li { display: flex; gap: .65rem; align-items: flex-start; font-size: .97rem; color: var(--text-2); }
.ticks li::before {
    content: ""; flex: none; width: 20px; height: 20px; margin-top: .18rem; border-radius: 50%;
    background: var(--accent-soft) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23e04a00' stroke-width='3.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'/%3E%3C/svg%3E") center / 12px no-repeat;
}

/* A tick list whose items are links with an explanation under them. The list
   item is a flex row (tick + content), so the description has to be a block
   inside the content cell — otherwise a label that wraps and its own
   description end up fighting for the same line. */
.ticks .tick-sub { display: block; margin-top: .15rem; }

/* Definition list used for the project facts panel. Two columns so the labels
   line up down the left; the value wraps under its own label rather than
   pushing the label out of alignment. */
.facts { display: grid; grid-template-columns: auto 1fr; gap: .45rem .9rem; margin: .2rem 0 0; }
.facts dt { font-size: .8rem; text-transform: uppercase; letter-spacing: .05em; color: var(--muted); white-space: nowrap; }
.facts dd { margin: 0; font-size: .93rem; color: var(--text); }
@media (max-width: 420px) {
    .facts { grid-template-columns: 1fr; gap: .1rem; }
    .facts dd { margin-bottom: .5rem; }
}

/* Numbered process steps */
.steps { counter-reset: step; display: grid; gap: 1.1rem; }
.step { display: flex; gap: 1.1rem; }
.step::before {
    counter-increment: step; content: counter(step, decimal-leading-zero);
    flex: none; width: 46px; height: 46px; border-radius: var(--r-md);
    display: grid; place-items: center;
    font-family: var(--font-display); font-weight: 800; font-size: .95rem;
    background: var(--accent-soft); color: var(--accent);
}
.step h3 { font-size: 1.06rem; margin-bottom: .3rem; }
.step p { color: var(--muted); font-size: .95rem; }

/* Tech stack marquee */
.marquee { overflow: hidden; mask-image: linear-gradient(90deg, transparent, #000 8%, #000 92%, transparent); }
.marquee-track { display: flex; gap: 1rem; width: max-content; animation: slide 38s linear infinite; }
.marquee:hover .marquee-track { animation-play-state: paused; }
.marquee .pill { font-size: .9rem; padding: .5rem 1.1rem; background: var(--surface); }
@keyframes slide { to { transform: translateX(-50%); } }

/* ---- Client logo carousel -------------------------------------------------
   Two rows travelling in opposite directions. Each track holds the row twice,
   so translating by exactly -50% returns to the starting frame and the loop has
   no seam. The mask fades both ends instead of cutting logos off mid-shape. */
.logo-marquee {
    margin-top: clamp(1.5rem, 3vw, 2.5rem);
    display: grid; gap: 1rem;
    mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
    -webkit-mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
}
.logo-row { overflow: hidden; }
.logo-track { display: flex; gap: 1rem; width: max-content; will-change: transform; }
.logo-row-left  .logo-track { animation: logos-left  56s linear infinite; }
.logo-row-right .logo-track { animation: logos-right 56s linear infinite; }
.logo-marquee:hover .logo-track { animation-play-state: paused; }

@keyframes logos-left  { from { transform: translateX(0);    } to { transform: translateX(-50%); } }
@keyframes logos-right { from { transform: translateX(-50%); } to { transform: translateX(0);    } }

.logo-cell {
    flex: none;
    width: 168px; height: 92px;
    display: grid; place-items: center;
    padding: .85rem 1.1rem;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: var(--r-md);
    box-shadow: var(--shadow-xs);
    transition: transform .22s cubic-bezier(.2,.7,.3,1), box-shadow .22s, border-color .22s;
}
.logo-cell img {
    max-width: 100%; max-height: 60px;
    width: auto; height: auto;
    object-fit: contain;
    /* Supplied logos vary enormously in colour and weight; desaturating them
       lets the row read as one set, and hover restores the real brand. */
    filter: grayscale(1);
    opacity: .62;
    transition: filter .22s, opacity .22s;
}
.logo-cell:hover {
    transform: translateY(-3px);
    box-shadow: var(--shadow-md);
    border-color: var(--brand-200);
}
.logo-cell:hover img { filter: none; opacity: 1; }

/* Logos are mostly dark artwork on transparency, so on the dark theme each tile
   keeps a light ground rather than the logo disappearing into the page. */
@media (prefers-color-scheme: dark) {
    :root:not([data-theme="light"]) .logo-cell { background: #f4f6fb; border-color: #223047; }
}
[data-theme="dark"] .logo-cell { background: #f4f6fb; border-color: #223047; }

@media (max-width: 620px) {
    .logo-cell { width: 136px; height: 78px; padding: .7rem .85rem; }
    .logo-cell img { max-height: 48px; }
}

/* Section anchor list used on long service pages */
.toc { display: flex; flex-wrap: wrap; gap: .5rem; }

.toc-center { justify-content: center; }

/* ---- Software product cards ------------------------------------------------
   Kicker, name, one line, and the first modules by name — so twelve products
   can be told apart at a glance. */
.product-card { display: flex; flex-direction: column; height: 100%; }
.pc-head { display: flex; align-items: center; justify-content: space-between; gap: .75rem; margin-bottom: 1rem; }
.pc-head .icon-tile { margin-bottom: 0; }
.pc-kicker {
    font-size: .7rem; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
    color: var(--accent); text-align: right;
}
.product-card h3 { font-size: 1.12rem; }
.pc-feats { list-style: none; padding: 0; margin: 1rem 0 0; display: flex; flex-wrap: wrap; gap: .35rem; }
.pc-feats li {
    font-size: .74rem; font-weight: 550; padding: .22rem .6rem; border-radius: var(--r-full);
    background: var(--surface-2); color: var(--text-2); border: 1px solid var(--border-soft);
}
.pc-more {
    margin-top: auto; padding-top: 1.15rem;
    display: inline-flex; align-items: center; gap: .35rem;
    font-weight: 650; font-size: .9rem; color: var(--accent);
}
.pc-more svg { width: 16px; height: 16px; transition: transform .2s; }
.product-card:hover .pc-more svg { transform: translateX(3px); }

/* Group heading between rows of product cards on /software/. */
.group-head { display: flex; align-items: center; gap: .9rem; margin: clamp(2.2rem, 4vw, 3rem) 0 1.1rem; }
.group-head:first-child { margin-top: 0; }
.group-head h3 { font-size: 1.15rem; margin: 0; white-space: nowrap; }
.group-head::after { content: ""; flex: 1; height: 1px; background: var(--border); }
.group-head .icon-tile { width: 38px; height: 38px; margin: 0; border-radius: var(--r-sm); }
.group-head .icon-tile svg { width: 19px; height: 19px; }

/* Ready product vs custom build. */
.compare { width: 100%; border-collapse: separate; border-spacing: 0; font-size: .95rem; }
.compare th, .compare td { padding: .95rem 1.1rem; text-align: left; vertical-align: top; border-bottom: 1px solid var(--border); }
.compare thead th {
    font-family: var(--font-display); font-size: 1rem; color: var(--text);
    background: var(--surface-2); border-bottom: 2px solid var(--border);
}
.compare thead th:first-child { border-top-left-radius: var(--r-md); }
.compare thead th:last-child  { border-top-right-radius: var(--r-md); }
.compare tbody th { font-weight: 650; color: var(--text); width: 22%; }
.compare td { color: var(--text-2); }
.compare tbody tr:last-child th, .compare tbody tr:last-child td { border-bottom: 0; }
.compare .col-hi { background: var(--accent-soft); }
.compare thead .col-hi { color: var(--accent); background: var(--accent-soft); }
.compare-wrap {
    background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-lg);
    box-shadow: var(--shadow-sm); overflow-x: auto;
}
.compare-wrap .compare { min-width: 620px; }

/* The newest article, wide, at the top of /blog/. */
a.card.post-card-featured { display: grid; grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr); }
/* The migrated banners carry their headline text on the left, so crop from the right. */
.post-card-featured .thumb img { object-position: left center; }
.post-card-featured .thumb { aspect-ratio: auto; min-height: 100%; border-bottom: 0; border-right: 1px solid var(--border-soft); }
.post-card-featured .body { padding: clamp(1.3rem, 3vw, 2rem); justify-content: center; }
.post-card-featured h3 { font-size: clamp(1.2rem, 2.2vw, 1.5rem); margin: .5rem 0 .7rem; }
.post-card-featured p { font-size: .97rem; flex: 0; }
@media (max-width: 760px) {
    a.card.post-card-featured { grid-template-columns: 1fr; }
    .post-card-featured .thumb { aspect-ratio: 16 / 9; border-right: 0; border-bottom: 1px solid var(--border-soft); }
}

/* ---- Blog article ---------------------------------------------------------- */
.toc-box {
    margin-bottom: 2rem; padding: 1rem 1.25rem;
    background: var(--surface); border: 1px solid var(--border); border-left: 3px solid var(--accent);
    border-radius: var(--r-md); box-shadow: var(--shadow-xs);
}
.toc-box summary {
    cursor: pointer; font-family: var(--font-display); font-weight: 700; color: var(--text);
    list-style: none; display: flex; align-items: center; gap: .4rem;
}
.toc-box summary::-webkit-details-marker { display: none; }
.toc-box summary::before {
    content: ""; width: 8px; height: 8px; margin-right: .3rem;
    border-right: 2px solid var(--accent); border-bottom: 2px solid var(--accent);
    transform: rotate(-45deg); transition: transform .2s;
}
.toc-box[open] summary::before { transform: rotate(45deg); }
.toc-box ol { margin: .85rem 0 0; padding-left: 1.4rem; display: grid; gap: .35rem; font-size: .93rem; }
.toc-box li::marker { color: var(--accent); font-weight: 700; }
.toc-box a { color: var(--text-2); text-decoration: none; }
.toc-box a:hover { color: var(--accent); text-decoration: underline; }
/* Long contents lists run in two columns where there is room. */
@media (min-width: 900px) { .toc-box ol:has(li:nth-child(11)) { columns: 2; column-gap: 2rem; display: block; } .toc-box ol li { break-inside: avoid; margin-bottom: .35rem; } }

.prose h2[id], .prose h3[id] { scroll-margin-top: calc(var(--header-h) + 1rem); }
.prose img { height: auto; }

.post-author {
    display: flex; gap: 1rem; align-items: flex-start;
    margin-top: 3rem; padding: 1.25rem 1.4rem;
    background: var(--surface-2); border: 1px solid var(--border-soft); border-radius: var(--r-lg);
}
.post-author img { width: 56px; height: 56px; border-radius: var(--r-md); background: var(--surface); padding: .45rem; flex: none; }
.post-author p { margin: 0; }
.post-author-name { font-family: var(--font-display); font-weight: 700; font-size: 1.05rem; margin: .1rem 0 .35rem !important; }
.post-author-name a { color: var(--text); text-decoration: none; }
.post-author-name a:hover { color: var(--accent); }

/* ---- About and Contact ----------------------------------------------------
   Pages about the company rather than a service. Every component here is built
   from the tokens above, so each is theme-correct without its own dark rules. */

/* Headline numbers in one raised panel, divided rather than floating loose. */
.stat-band {
    gap: 0;
    background: var(--surface); border: 1px solid var(--border);
    border-radius: var(--r-xl); box-shadow: var(--shadow-md);
    padding: clamp(1.2rem, 3vw, 2rem) clamp(.5rem, 2vw, 1.5rem);
}
.stat-band .stat { padding: .7rem 1rem; }
.stat-band .stat + .stat { border-left: 1px solid var(--border); }

/* A card with the brand hairline along its top edge, as on the enquiry card. */
.card-rule { position: relative; }
.card-rule::before {
    content: ""; position: absolute; inset: -1px -1px auto -1px; height: 4px;
    border-radius: var(--r-lg) var(--r-lg) 0 0;
    background: linear-gradient(90deg, var(--grad-1), var(--grad-2), var(--grad-3));
}
.glance .facts { gap: .6rem .9rem; }
.glance .facts dd a { font-weight: 600; }

/* Commitments: a numbered promise, then what it means in practice. */
.pledge { position: relative; overflow: hidden; display: flex; flex-direction: column; }
.pledge-n {
    position: absolute; top: .5rem; right: 1rem;
    font-family: var(--font-display); font-weight: 800; font-size: 3.4rem; line-height: 1;
    letter-spacing: -.05em; color: var(--accent); opacity: .14; pointer-events: none;
}
.card .pledge-proof {
    margin-top: auto; padding-top: .9rem; border-top: 1px dashed var(--border);
    font-size: .86rem; color: var(--text-2);
}
.pledge > p:not(.pledge-proof) { margin-bottom: 1rem; }

/* Process timeline: horizontal with a connecting rule on wide screens, a
   vertical rail when stacked. The ring round each marker is the section's own
   ground colour, so the rule appears to pass behind it. */
.timeline {
    --tl-gap: clamp(1rem, 2vw, 1.5rem);
    --tl-ground: var(--bg);
    list-style: none; padding: 0; counter-reset: tl;
    display: grid; grid-template-columns: repeat(var(--tl-steps, 5), minmax(0, 1fr)); gap: var(--tl-gap);
}
.section-alt .timeline { --tl-ground: var(--bg-alt); }
.timeline li { position: relative; counter-increment: tl; padding-top: 4.1rem; }
.timeline li::before {
    content: counter(tl, decimal-leading-zero);
    position: absolute; top: 0; left: 0; z-index: 1;
    width: 52px; height: 52px; border-radius: 50%;
    display: grid; place-items: center;
    font-family: var(--font-display); font-weight: 800; font-size: .95rem;
    background: var(--surface); color: var(--accent); border: 2px solid var(--accent);
    box-shadow: 0 0 0 6px var(--tl-ground);
}
.timeline li::after {
    content: ""; position: absolute; top: 25px; left: 52px; right: calc(-1 * var(--tl-gap)); height: 2px;
    background: linear-gradient(90deg, var(--accent), var(--border));
}
.timeline li:last-child::after { display: none; }
.timeline h3 { font-size: 1.06rem; margin-bottom: .35rem; }
.timeline p { color: var(--muted); font-size: .93rem; }
.tl-out {
    display: inline-block; margin-top: .7rem; padding: .2rem .6rem; border-radius: var(--r-full);
    font-size: .76rem; font-weight: 650; background: var(--accent-soft); color: var(--accent);
}

/* Where clients are: one card per country, each naming real projects. */
.place { display: flex; flex-direction: column; }
.place-head { display: flex; align-items: center; gap: .85rem; }
.place-code {
    flex: none; width: 46px; height: 46px; border-radius: var(--r-md);
    display: grid; place-items: center;
    font-family: var(--font-display); font-weight: 800; font-size: .9rem; letter-spacing: .04em;
    background: var(--accent-soft); color: var(--accent);
}
.place h3 { font-size: 1.08rem; margin: 0; }
.place-where { display: block; font-size: .84rem; color: var(--muted); }
.place ul { list-style: none; padding: 0; margin-top: 1rem; display: grid; gap: .45rem; font-size: .92rem; }
.place li { display: flex; gap: .5rem; align-items: baseline; }
.place li::before { content: ""; flex: none; width: 6px; height: 6px; border-radius: 50%; background: var(--accent); transform: translateY(-2px); }
.place ul a { color: var(--text-2); text-decoration: none; }
.place ul a:hover { color: var(--accent); text-decoration: underline; }
.place-hq {
    background: linear-gradient(150deg, var(--ink-800), var(--ink-700) 60%, var(--ink-900));
    border-color: rgb(255 92 0 / .45); color: var(--on-dark);
}
.place-hq h3 { color: #fff; }
.place-hq .place-where, .place-hq p { color: #c6cedb; }
.place-hq .place-code { background: var(--brand-500); color: #fff; }
.place-hq ul a { color: #dfe5ee; }
.place-hq ul a:hover { color: #fff; }
.place-hq li::before { background: var(--brand-400); }

/* Links with an icon and a one-line description — the nav's mega-menu item,
   laid out as a list inside a card. */
.link-tiles { list-style: none; padding: 0; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: .25rem; }
.link-tiles a {
    display: flex; gap: .75rem; padding: .65rem .7rem; border-radius: var(--r-md);
    text-decoration: none; color: var(--text); transition: background .16s;
}
.link-tiles a:hover { background: var(--surface-2); }
.link-tiles a:hover strong { color: var(--accent); }
.link-tiles .mi {
    width: 36px; height: 36px; flex: none; border-radius: var(--r-sm);
    display: grid; place-items: center; background: var(--accent-soft); color: var(--accent);
}
.link-tiles .mi svg { width: 18px; height: 18px; }
.link-tiles strong { display: block; font-size: .93rem; font-weight: 650; line-height: 1.35; }
.link-tiles small { display: block; color: var(--muted); font-size: .82rem; line-height: 1.4; margin-top: .1rem; }
.link-tiles-1 { grid-template-columns: 1fr; }
/* Three across, each tile a surface of its own — used on a tinted section. */
.link-tiles-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: .75rem; }
.link-tiles-3 a { height: 100%; padding: .9rem 1rem; background: var(--surface); border: 1px solid var(--border); box-shadow: var(--shadow-xs); }
.link-tiles-3 a:hover { background: var(--surface); border-color: var(--accent); }
@media (max-width: 1024px) { .link-tiles-3 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
/* Eight services beside twelve products: the products card gets the room. */
.hub-grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1.75fr); align-items: start; }
@media (max-width: 1024px) { .hub-grid { grid-template-columns: 1fr; } }

/* Office map. Loaded lazily and framed so it reads as part of the page. */
.map-frame {
    position: relative; overflow: hidden; min-height: 340px; height: 100%;
    border-radius: var(--r-lg); border: 1px solid var(--border);
    background: var(--surface-2); box-shadow: var(--shadow-md);
}
.map-frame iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }

.hours { width: 100%; border-collapse: collapse; font-size: .93rem; margin-top: .4rem; }
.hours th, .hours td { padding: .5rem 0; border-bottom: 1px solid var(--border-soft); text-align: left; font-weight: 500; }
.hours th { color: var(--text-2); }
.hours td { text-align: right; color: var(--muted); }
.hours tr:last-child th, .hours tr:last-child td { border-bottom: 0; }
.hours tr.is-today th, .hours tr.is-today td { color: var(--accent); font-weight: 700; }

/* Filled in by app.js from the configured hours; absent without scripts. */
.open-status {
    display: inline-flex; align-items: center; gap: .45rem;
    padding: .28rem .7rem; border-radius: var(--r-full);
    font-size: .8rem; font-weight: 650;
    background: var(--surface-2); color: var(--muted);
}
.open-status::before { content: ""; width: 8px; height: 8px; border-radius: 50%; background: currentColor; }
.open-status.is-open { background: var(--a-green-soft); color: var(--a-green); }
.open-status[hidden] { display: none; }

/* ---------- 8. UTILITIES ------------------------------------------------- */
.center { text-align: center; }
.mx-auto { margin-inline: auto; }
.muted { color: var(--muted); }
.small { font-size: .88rem; }
.mt-0 { margin-top: 0; } .mt-1 { margin-top: .5rem; } .mt-2 { margin-top: 1rem; }
.mt-3 { margin-top: 1.5rem; } .mt-4 { margin-top: 2rem; } .mt-6 { margin-top: 3rem; }
.mb-2 { margin-bottom: 1rem; } .mb-3 { margin-bottom: 1.5rem; } .mb-4 { margin-bottom: 2rem; }
.flex { display: flex; } .items-center { align-items: center; } .gap-2 { gap: 1rem; }
.flex-wrap { flex-wrap: wrap; }
.sr-only {
    position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.skip-link {
    position: absolute; left: .5rem; top: -3rem; z-index: 100;
    background: var(--accent); color: #fff; padding: .6rem 1rem; border-radius: var(--r-sm);
    text-decoration: none; transition: top .2s;
}
.skip-link:focus { top: .5rem; }

/* ---------- 9. RESPONSIVE ------------------------------------------------ */
@media (max-width: 1024px) {
    .g-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .footer-grid { grid-template-columns: 1fr 1fr; }
    .article-layout { grid-template-columns: 1fr; }
    .sidebar { position: static; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }
    .stat-band.g-4 { row-gap: .5rem; }
    .stat-band .stat:nth-child(odd) { border-left: 0; }
}
@media (max-width: 900px) {
    /* The timeline turns into a vertical rail. */
    .timeline { grid-template-columns: 1fr; }
    .timeline li { padding-top: 0; padding-left: 4.4rem; min-height: 52px; }
    .timeline li::after {
        top: 52px; left: 25px; right: auto; bottom: calc(-1 * var(--tl-gap));
        width: 2px; height: auto;
        background: linear-gradient(180deg, var(--accent), var(--border));
    }
}
@media (max-width: 900px) {
    .nav { display: none; }
    .burger { display: flex; }
    .hero-inner { grid-template-columns: 1fr; }
    .hero-lead-grid { grid-template-columns: 1fr; }
    .pillars { grid-template-columns: 1fr; }
    .hero-art { order: -1; max-width: 460px; margin-inline: auto; }
    .g-3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 620px) {
    .g-2, .g-3, .g-4 { grid-template-columns: 1fr; }
    .mobile-cta { display: flex; }
    body { padding-bottom: 68px; }
    .wa-float { bottom: 78px; }
    .quote-alt { justify-content: center; }
    .footer-grid { grid-template-columns: 1fr; }
    .hero-trust { gap: .8rem 1.1rem; }
    .btn { width: 100%; }
    .hero-cta .btn, .cta-actions .btn, .page-hero-cta .btn { width: auto; flex: 1 1 auto; }
    /* Four numbers stay two-up on a phone; one per row wastes the screen. */
    .stat-band.g-4 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    /* Three stats stack to one column; divide them with rules across instead. */
    .stat-band.g-3 .stat { border-left: 0; }
    .stat-band.g-3 .stat + .stat { border-top: 1px solid var(--border); }
    .link-tiles { grid-template-columns: 1fr; }
}

/* ---------- 10. MOTION --------------------------------------------------- */
/* Scroll-reveal is opt-in via the .js class, which a tiny inline script in the
   head sets. Without it the content is simply visible — a script that fails to
   run, or an observer that never fires, can then never leave a section blank. */
.reveal { transition: opacity .6s ease, transform .6s cubic-bezier(.2,.7,.3,1); }
.js .reveal { opacity: 0; transform: translateY(18px); }
.js .reveal.in { opacity: 1; transform: none; }

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

@media print {
    .site-header, .site-footer, .wa-float, .cta-band, .drawer { display: none !important; }
    body { background: #fff; color: #000; }
}
