/* ==========================================================================
   LORENS (lorens.in) — Premium Portfolio Theme
   --------------------------------------------------------------------------
   Table of contents
   01. Design tokens
   02. Base & typography
   03. Layout helpers
   04. Buttons
   05. Navbar
   06. Footer
   07. Hero
   08. Trust bar
   09. Section headings / eyebrow
   10. About blocks
   11. Service cards
   12. Project cards + filters
   13. Process steps
   14. Why-us grid
   15. CTA band
   16. Page hero (inner pages)
   17. Careers
   18. Contact
   19. Legal pages (privacy / terms)
   20. Reveal animations
   21. Responsive refinements
   ========================================================================== */

/* ==========================================================================
   01. DESIGN TOKENS  — change brand colours & fonts in this block only
   ========================================================================== */
:root {
    /* Brand */
    --ink: #101014;
    --ink-soft: #1c1c23;
    --ink-line: #26262f;
    --paper: #f8f6f2;
    --paper-2: #efece6;
    --white: #ffffff;
    --accent: #ff5a34;
    --accent-dark: #e03b12;
    --accent-soft: rgba(255, 90, 52, 0.1);

    /* Text */
    --text: #16161b;
    --text-muted: #6b6b76;
    --text-invert: #f6f4f0;
    --text-invert-muted: rgba(246, 244, 240, 0.62);

    /* Lines & surfaces */
    --line: rgba(16, 16, 20, 0.1);
    --line-strong: rgba(16, 16, 20, 0.18);
    --line-invert: rgba(255, 255, 255, 0.14);

    /* Shape */
    --radius-sm: 10px;
    --radius: 18px;
    --radius-lg: 28px;
    --radius-pill: 999px;

    /* Elevation — each step pairs a tight contact shadow with a wide ambient one.
       A single blur reads flat at these radii; the contact layer is what makes a
       card look like it is resting on the page rather than pasted onto it. */
    --shadow-sm: 0 1px 2px rgba(16, 16, 20, 0.04), 0 4px 14px -8px rgba(16, 16, 20, 0.10);
    --shadow: 0 2px 6px -2px rgba(16, 16, 20, 0.07), 0 18px 40px -22px rgba(16, 16, 20, 0.30);
    --shadow-lg: 0 4px 12px -4px rgba(16, 16, 20, 0.09), 0 40px 80px -40px rgba(16, 16, 20, 0.42);
    --shadow-accent: 0 2px 8px -3px rgba(224, 59, 18, 0.35), 0 20px 40px -22px rgba(255, 90, 52, 0.65);
    --ring: 0 0 0 4px var(--accent-soft);

    /* Motion */
    --ease: cubic-bezier(0.22, 1, 0.36, 1);
    --ease-out: cubic-bezier(0.16, 1, 0.3, 1);
    --speed: 0.45s;
    --speed-fast: 0.22s;

    /* Rhythm */
    --section-y: clamp(4rem, 8vw, 7rem);
    --section-y-tight: clamp(2.75rem, 5.5vw, 4.5rem);
    --gutter: clamp(1.25rem, 4vw, 2.5rem);

    /* Component padding scale — every card, panel and row picks one of these
       three steps instead of inventing its own clamp, so surfaces sitting side
       by side share the same inner margin. */
    --pad-sm: clamp(1.1rem, 2.2vw, 1.45rem);
    --pad-md: clamp(1.5rem, 2.8vw, 2.1rem);
    --pad-lg: clamp(1.85rem, 4vw, 2.9rem);

    /* Type */
    --font-display: "Fraunces", "Playfair Display", Georgia, "Times New Roman", serif;
    --font-body: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;

    /* Bootstrap overrides */
    --bs-body-font-family: var(--font-body);
    --bs-body-color: var(--text);
    --bs-body-bg: var(--paper);
}

/* ==========================================================================
   02. BASE & TYPOGRAPHY
   ========================================================================== */
*,
*::before,
*::after {
    box-sizing: border-box;
}

html {
    scroll-behavior: smooth;
    -webkit-text-size-adjust: 100%;
    /* The header is fixed, so a bare #hash jump (footer → services.html#automation,
       or any link followed from another page) parks the target underneath it. JS
       only offsets same-page clicks; this covers every other route in. */
    scroll-padding-top: 6.5rem;
}

body {
    margin: 0;
    background-color: var(--paper);
    color: var(--text);
    font-family: var(--font-body);
    font-size: clamp(1rem, 0.97rem + 0.15vw, 1.0625rem);
    line-height: 1.7;
    font-weight: 400;
    letter-spacing: -0.005em;
    overflow-x: hidden;
    /* Long unbroken strings — an email address, a URL in the legal pages — would
       otherwise push a 320px layout sideways. */
    overflow-wrap: break-word;
    accent-color: var(--accent);
    caret-color: var(--accent);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

/* Fraunces is an optical-size variable font: letting the browser pick the optical
   axis keeps display sizes elegant and small sizes readable instead of scaling one
   drawing to every size. Synthesis off so no faux-bold creeps in. */
h1,
h2,
h3,
h4,
h5,
.brand,
.hero-badge strong,
.stat-band strong,
.hero-stat strong {
    font-optical-sizing: auto;
    font-synthesis-weight: none;
}

/* Thin, on-brand scrollbars — the default chrome grey is the one part of the page
   the theme never reached. */
* {
    scrollbar-width: thin;
    scrollbar-color: rgba(16, 16, 20, 0.25) transparent;
}

::-webkit-scrollbar {
    width: 10px;
    height: 10px;
}

::-webkit-scrollbar-track {
    background: transparent;
}

::-webkit-scrollbar-thumb {
    background: rgba(16, 16, 20, 0.2);
    border: 3px solid transparent;
    background-clip: content-box;
    border-radius: var(--radius-pill);
}

::-webkit-scrollbar-thumb:hover {
    background: rgba(16, 16, 20, 0.35);
    background-clip: content-box;
}

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

a {
    color: inherit;
    text-decoration: none;
    transition: color var(--speed) var(--ease), opacity var(--speed) var(--ease);
}

h1,
h2,
h3,
h4,
h5 {
    font-family: var(--font-display);
    font-weight: 400;
    line-height: 1.08;
    letter-spacing: -0.02em;
    margin: 0 0 0.6em;
    color: var(--ink);
    text-wrap: balance;
}

h1 {
    font-size: clamp(2.5rem, 1.4rem + 4.8vw, 5rem);
}

h2 {
    font-size: clamp(2rem, 1.35rem + 2.7vw, 3.5rem);
}

h3 {
    font-size: clamp(1.35rem, 1.15rem + 0.9vw, 1.85rem);
}

h4 {
    font-size: clamp(1.1rem, 1rem + 0.4vw, 1.3rem);
}

p {
    margin: 0 0 1.15rem;
    text-wrap: pretty;
}

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

.lead-text {
    font-size: clamp(1.05rem, 1rem + 0.4vw, 1.3rem);
    line-height: 1.65;
    color: var(--text-muted);
    font-weight: 400;
}

.text-muted-soft {
    color: var(--text-muted);
}

.italic-accent {
    font-style: italic;
    color: var(--accent);
}

::selection {
    background: var(--accent);
    color: #fff;
}

:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 3px;
    border-radius: 4px;
}

/* On the ink surfaces a 2px accent line alone is easy to lose against the dark
   background — the soft halo gives the ring something to sit on. */
.section-dark :focus-visible,
.page-hero :focus-visible,
.site-footer :focus-visible,
.cta-band :focus-visible,
.process-step :focus-visible {
    outline-color: #fff;
    box-shadow: var(--ring);
}

.skip-link {
    position: absolute;
    left: -9999px;
    top: 0;
    z-index: 2000;
    background: var(--ink);
    color: #fff;
    padding: 0.75rem 1.25rem;
    border-radius: 0 0 var(--radius-sm) 0;
}

.skip-link:focus {
    left: 0;
}

/* ==========================================================================
   03. LAYOUT HELPERS
   ========================================================================== */
.container,
.container-fluid,
.container-lg,
.container-xl {
    padding-left: var(--gutter);
    padding-right: var(--gutter);
}

.container {
    max-width: 1280px;
}

.section {
    padding-top: var(--section-y);
    padding-bottom: var(--section-y);
    position: relative;
}

.section-tight {
    padding-top: var(--section-y-tight);
    padding-bottom: var(--section-y-tight);
}

/* Neighbouring sections that share a background were stacking a full --section-y
   on each side of the seam, leaving a dead band twice the intended rhythm (up to
   17rem between the last two sections of about/services/careers/contact). The
   first section's bottom padding already supplies the gap, so the second one
   drops its top padding. Sections whose background actually changes are left
   alone — there the padding reads as inset, not as empty space. */
:is(.section, .section-tight):not(.section-alt, .section-dark)
    + :is(.section, .section-tight):not(.section-alt, .section-dark),
.section-alt + .section-alt,
.section-dark + .section-dark,
/* careers.html opens with an ink .page-hero straight into an ink .section-dark —
   same surface, so the seam was reading as 192px of empty black. */
.page-hero + .section-dark {
    padding-top: 0;
}

.section-dark {
    background: var(--ink);
    color: var(--text-invert);
    /* Contains the glow below and gives the section a stacking context of its own. */
    position: relative;
    isolation: isolate;
    overflow: hidden;
}

/* A flat ink panel goes dead across a wide screen. One off-centre warm glow, the
   same move the hero and CTA band already use, keeps the surface alive. */
.section-dark::before {
    content: "";
    position: absolute;
    z-index: -1;
    top: -40%;
    right: -10%;
    width: min(680px, 80vw);
    aspect-ratio: 1;
    border-radius: 50%;
    background: radial-gradient(circle, rgba(255, 90, 52, 0.16), transparent 68%);
    pointer-events: none;
}

.section-dark h1,
.section-dark h2,
.section-dark h3,
.section-dark h4 {
    color: var(--text-invert);
}

.section-dark .lead-text,
.section-dark .text-muted-soft {
    color: var(--text-invert-muted);
}

/* A hair of gradient rather than one flat fill: the band still reads as a single
   tone, but the seam where it meets the paper sections stops looking like a
   printed edge. */
.section-alt {
    background: linear-gradient(180deg, var(--paper) 0%, var(--paper-2) 14%, var(--paper-2) 86%, var(--paper) 100%);
}

/* Two alt sections in a row would show that fade twice through the middle of the
   run — the pair share one continuous tone instead. */
.section-alt + .section-alt {
    background: linear-gradient(180deg, var(--paper-2) 0%, var(--paper-2) 86%, var(--paper) 100%);
}

.divider {
    height: 1px;
    background: var(--line);
    border: 0;
    margin: 0;
    opacity: 1;
}

.divider-invert {
    background: var(--line-invert);
}

/* ==========================================================================
   04. BUTTONS
   ========================================================================== */
.btn {
    --btn-bg: var(--ink);
    --btn-fg: #fff;
    --btn-border: var(--ink);
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.6rem;
    padding: 0.95rem 1.75rem;
    min-height: 50px;
    border-radius: var(--radius-pill);
    border: 1px solid var(--btn-border);
    background: var(--btn-bg);
    color: var(--btn-fg);
    font-family: var(--font-body);
    font-size: 0.9375rem;
    font-weight: 500;
    letter-spacing: 0.01em;
    line-height: 1.2;
    text-align: center;
    cursor: pointer;
    overflow: hidden;
    isolation: isolate;
    transition: color var(--speed) var(--ease), border-color var(--speed) var(--ease),
        background-color var(--speed) var(--ease), transform var(--speed) var(--ease),
        box-shadow var(--speed) var(--ease);
}

.btn::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: -1;
    background: var(--accent);
    transform: translateY(101%);
    transition: transform var(--speed) var(--ease);
}

.btn:hover,
.btn:focus-visible {
    color: #fff;
    border-color: var(--accent);
    transform: translateY(-2px);
    box-shadow: var(--shadow-accent);
}

.btn:hover::after,
.btn:focus-visible::after {
    transform: translateY(0);
}

/* Press reads as the button taking the weight: it settles back down and the
   lift shadow collapses to a contact shadow. */
.btn:active {
    transform: translateY(0) scale(0.985);
    box-shadow: var(--shadow-sm);
    transition-duration: var(--speed-fast);
}

.btn .btn-arrow {
    transition: transform var(--speed) var(--ease);
}

.btn:hover .btn-arrow {
    transform: translate(3px, -3px);
}

/* Arrows that point along the line (→) travel sideways, not diagonally. */
.btn:hover svg:not(.btn-arrow),
.link-underline:hover svg {
    transform: translateX(3px);
}

.btn svg:not(.btn-arrow),
.link-underline svg {
    transition: transform var(--speed) var(--ease);
}

/* Variants */
.btn-primary {
    --btn-bg: var(--ink);
    --btn-fg: #fff;
    --btn-border: var(--ink);
}

/* The primary call to action carries a resting glow so it reads as the one live
   control in a band of quiet outlines. */
.btn-accent {
    --btn-bg: var(--accent);
    --btn-fg: #fff;
    --btn-border: var(--accent);
    background-image: linear-gradient(180deg, rgba(255, 255, 255, 0.16), transparent 60%);
    box-shadow: var(--shadow-accent);
}

.btn-accent::after {
    background: var(--ink);
}

.btn-accent:hover,
.btn-accent:focus-visible {
    border-color: var(--ink);
    box-shadow: var(--shadow-lg);
}

.btn-outline {
    --btn-bg: transparent;
    --btn-fg: var(--ink);
    --btn-border: var(--line-strong);
}

/* Outlines are quiet until touched — the border firms up before the fill runs. */
.btn-outline:hover,
.btn-outline:focus-visible,
.btn-outline-invert:hover,
.btn-outline-invert:focus-visible {
    box-shadow: var(--shadow);
}

.btn-outline-invert {
    --btn-bg: transparent;
    --btn-fg: var(--text-invert);
    --btn-border: var(--line-invert);
}

.btn-light-solid {
    --btn-bg: #fff;
    --btn-fg: var(--ink);
    --btn-border: #fff;
}

/* Keyboard focus has to be legible on ink, on paper and on the accent fill, so
   the ring is drawn outside the button rather than tinted into it. */
.btn:focus-visible,
.filter-btn:focus-visible,
.faq-question:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 3px;
}

.section-dark .btn:focus-visible,
.page-hero .btn:focus-visible,
.cta-band .btn:focus-visible,
.site-footer .btn:focus-visible {
    outline-color: #fff;
}

.btn-sm-pill {
    padding: 0.7rem 1.3rem;
    min-height: 44px;
    font-size: 0.875rem;
}

.btn-block-sm {
    width: 100%;
}

/* Text link with animated underline */
.link-underline {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    font-size: 0.9375rem;
    font-weight: 500;
    color: var(--ink);
    padding-bottom: 2px;
    background-image: linear-gradient(var(--accent), var(--accent));
    background-size: 0% 1px;
    background-position: 0 100%;
    background-repeat: no-repeat;
    transition: background-size var(--speed) var(--ease), color var(--speed) var(--ease);
}

.link-underline:hover,
.link-underline:focus-visible {
    color: var(--accent);
    background-size: 100% 1px;
}

.section-dark .link-underline {
    color: var(--text-invert);
}

/* ==========================================================================
   05. NAVBAR
   ========================================================================== */
.site-header {
    position: fixed;
    inset: 0 0 auto 0;
    z-index: 1030;
    background: transparent;
    transition: background-color var(--speed) var(--ease), box-shadow var(--speed) var(--ease),
        border-color var(--speed) var(--ease);
    border-bottom: 1px solid transparent;
}

.site-header .navbar {
    padding-top: 1.35rem;
    padding-bottom: 1.35rem;
    transition: padding var(--speed) var(--ease);
}

.site-header.is-scrolled {
    background: rgba(248, 246, 242, 0.82);
    backdrop-filter: saturate(185%) blur(18px);
    -webkit-backdrop-filter: saturate(185%) blur(18px);
    border-bottom-color: var(--line);
    box-shadow: var(--shadow-sm);
}

/* Safari and Firefox both support backdrop-filter now, but if it is unavailable
   the bar has to stay readable — fall back to a near-solid paper fill. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
    .site-header.is-scrolled {
        background: rgba(248, 246, 242, 0.98);
    }
}

.site-header.is-scrolled .navbar {
    padding-top: 0.75rem;
    padding-bottom: 0.75rem;
}

/* Reading progress, drawn by the scroll timeline itself — no JS, no layout cost,
   and browsers without scroll-driven animations simply never paint it. */
@supports (animation-timeline: scroll()) {
    .site-header::after {
        content: "";
        position: absolute;
        left: 0;
        bottom: -1px;
        height: 2px;
        width: 100%;
        transform-origin: left center;
        transform: scaleX(0);
        background: linear-gradient(90deg, var(--accent), var(--accent-dark));
        opacity: 0;
        transition: opacity var(--speed) var(--ease);
        animation: headerProgress linear both;
        animation-timeline: scroll(root block);
    }

    .site-header.is-scrolled::after {
        opacity: 1;
    }

    @keyframes headerProgress {
        to { transform: scaleX(1); }
    }
}

/* Inner pages open with a dark .page-hero sitting directly under the fixed,
   transparent header, so the default ink-on-paper header disappears into it.
   JS adds .over-dark while the header is above that hero (removed as soon as
   .is-scrolled paints the light background). Skipped while the mobile panel
   is open, because that panel is light. */
body:not(.nav-open) .site-header.over-dark .brand,
body:not(.nav-open) .site-header.over-dark .nav-list a {
    color: var(--text-invert);
}

body:not(.nav-open) .site-header.over-dark .brand-text small {
    color: var(--text-invert-muted);
}

body:not(.nav-open) .site-header.over-dark .nav-list a:hover,
body:not(.nav-open) .site-header.over-dark .nav-list a.is-active {
    color: var(--accent);
}

body:not(.nav-open) .site-header.over-dark .nav-toggle {
    border-color: var(--line-invert);
}

body:not(.nav-open) .site-header.over-dark .nav-toggle span {
    background: var(--text-invert);
}

body:not(.nav-open) .site-header.over-dark .header-cta {
    --btn-bg: #fff;
    --btn-fg: var(--ink);
    --btn-border: #fff;
}

.brand {
    display: inline-flex;
    align-items: center;
    gap: 0.7rem;
    font-family: var(--font-display);
    font-size: 1.2rem;
    letter-spacing: -0.02em;
    color: var(--ink);
    line-height: 1.1;
}

.brand img {
    width: 38px;
    height: 38px;
    border-radius: 10px;
    box-shadow: var(--shadow-sm);
    transition: transform var(--speed) var(--ease), box-shadow var(--speed) var(--ease);
}

.brand:hover img {
    transform: rotate(-4deg) scale(1.05);
    box-shadow: var(--shadow);
}

.brand-text {
    display: flex;
    flex-direction: column;
}

.brand-text small {
    font-family: var(--font-body);
    font-size: 0.625rem;
    letter-spacing: 0.22em;
    text-transform: uppercase;
    color: var(--text-muted);
    font-weight: 500;
}

.nav-list {
    display: flex;
    align-items: center;
    gap: clamp(1rem, 2vw, 2.1rem);
    list-style: none;
    margin: 0;
    padding: 0;
}

/* The rule is a full row tall so the pointer target matches what the eye reads as
   the link, not just the glyph box. */
.nav-list a {
    position: relative;
    display: inline-flex;
    align-items: center;
    font-size: 0.9375rem;
    font-weight: 500;
    color: var(--text);
    padding: 0.5rem 0;
    letter-spacing: -0.01em;
}

.nav-list a:hover {
    color: var(--accent);
}

.nav-list a::after {
    content: "";
    position: absolute;
    left: 0;
    bottom: 0.15rem;
    width: 100%;
    height: 1.5px;
    border-radius: 2px;
    background: var(--accent);
    transform: scaleX(0);
    transform-origin: right;
    transition: transform var(--speed) var(--ease);
}

.nav-list a:hover::after,
.nav-list a:focus-visible::after,
.nav-list a.is-active::after {
    transform: scaleX(1);
    transform-origin: left;
}

.nav-list a.is-active {
    color: var(--accent);
}

/* Hamburger */
.nav-toggle {
    display: none;
    width: 46px;
    height: 46px;
    border: 1px solid var(--line-strong);
    border-radius: var(--radius-pill);
    background: transparent;
    padding: 0;
    align-items: center;
    justify-content: center;
    flex-direction: column;
    gap: 5px;
    cursor: pointer;
    transition: background-color var(--speed) var(--ease), border-color var(--speed) var(--ease);
}

.nav-toggle:hover {
    border-color: var(--ink);
    background: rgba(16, 16, 20, 0.04);
}

.nav-toggle span {
    display: block;
    width: 18px;
    height: 1.5px;
    background: var(--ink);
    border-radius: 2px;
    transition: transform var(--speed) var(--ease), opacity 0.2s linear,
        background-color var(--speed) var(--ease);
}

.nav-toggle[aria-expanded="true"] span:nth-child(1) {
    transform: translateY(6.5px) rotate(45deg);
}

.nav-toggle[aria-expanded="true"] span:nth-child(2) {
    opacity: 0;
}

.nav-toggle[aria-expanded="true"] span:nth-child(3) {
    transform: translateY(-6.5px) rotate(-45deg);
}

/* Mobile panel */
.mobile-panel {
    position: fixed;
    inset: 0;
    z-index: 1029;
    background: var(--paper);
    /* The same warm glow the hero carries, so opening the menu feels like part of
       the page rather than a plain white sheet dropping over it. */
    background-image: radial-gradient(90% 55% at 100% 0%, var(--accent-soft), transparent 70%);
    padding: 7rem var(--gutter) 2.5rem;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    transform: translateY(-100%);
    visibility: hidden;
    transition: transform 0.55s var(--ease), visibility 0.55s var(--ease);
    overflow-y: auto;
    overscroll-behavior: contain;
}

.mobile-panel.is-open {
    transform: translateY(0);
    visibility: visible;
}

.mobile-nav {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
}

.mobile-nav li {
    border-bottom: 1px solid var(--line);
    opacity: 0;
    transform: translateY(14px);
}

.mobile-panel.is-open .mobile-nav li {
    animation: mobileIn 0.5s var(--ease) forwards;
}

.mobile-panel.is-open .mobile-nav li:nth-child(1) { animation-delay: 0.08s; }
.mobile-panel.is-open .mobile-nav li:nth-child(2) { animation-delay: 0.14s; }
.mobile-panel.is-open .mobile-nav li:nth-child(3) { animation-delay: 0.2s; }
.mobile-panel.is-open .mobile-nav li:nth-child(4) { animation-delay: 0.26s; }
.mobile-panel.is-open .mobile-nav li:nth-child(5) { animation-delay: 0.32s; }
.mobile-panel.is-open .mobile-nav li:nth-child(6) { animation-delay: 0.38s; }

@keyframes mobileIn {
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

.mobile-nav a {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 1.05rem 0;
    font-family: var(--font-display);
    font-size: clamp(1.6rem, 8vw, 2.2rem);
    color: var(--ink);
    min-height: 56px;
    transition: color var(--speed) var(--ease), transform var(--speed) var(--ease),
        padding-left var(--speed) var(--ease);
}

.mobile-nav a:hover,
.mobile-nav a:active {
    color: var(--accent);
    padding-left: 0.5rem;
}

.mobile-nav a.is-active {
    color: var(--accent);
}

/* The active row gets a marker rather than colour alone, which reads at a glance
   on a phone held at arm's length. */
.mobile-nav a.is-active span {
    color: var(--accent);
}

.mobile-nav a span {
    font-family: var(--font-body);
    font-size: 0.75rem;
    letter-spacing: 0.16em;
    color: var(--text-muted);
}

.mobile-panel-footer {
    padding-top: 2rem;
}

.mobile-panel-footer .btn {
    width: 100%;
}

.mobile-panel-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 0.35rem 1.25rem;
    margin-top: 1.5rem;
    font-size: 0.875rem;
    color: var(--text-muted);
}

body.nav-open {
    overflow: hidden;
}

/* ==========================================================================
   06. FOOTER
   ========================================================================== */
.site-footer {
    position: relative;
    isolation: isolate;
    overflow: hidden;
    background: var(--ink);
    color: var(--text-invert);
    padding-top: clamp(3.5rem, 7vw, 6rem);
}

/* A hairline of brand colour along the very top edge, fading out at both ends —
   it separates the footer from the page without drawing a hard rule. */
.site-footer::before {
    content: "";
    position: absolute;
    inset: 0 0 auto 0;
    height: 1px;
    background: linear-gradient(90deg, transparent, rgba(255, 90, 52, 0.55), transparent);
}

.site-footer::after {
    content: "";
    position: absolute;
    z-index: -1;
    left: -10%;
    bottom: -55%;
    width: min(760px, 90vw);
    aspect-ratio: 1;
    border-radius: 50%;
    background: radial-gradient(circle, rgba(255, 90, 52, 0.12), transparent 65%);
    pointer-events: none;
}

.site-footer h2,
.site-footer h3 {
    color: var(--text-invert);
}

.footer-brand .brand {
    color: var(--text-invert);
}

.footer-brand .brand-text small {
    color: var(--text-invert-muted);
}

.footer-tagline {
    color: var(--text-invert-muted);
    max-width: 32ch;
    margin-top: 1.25rem;
    font-size: 0.9375rem;
}

.footer-heading {
    font-family: var(--font-body);
    font-size: 0.6875rem;
    font-weight: 600;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: rgba(246, 244, 240, 0.45);
    margin-bottom: 1.25rem;
}

.footer-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.7rem;
}

.footer-list a,
.footer-list span {
    display: inline-block;
    color: var(--text-invert-muted);
    font-size: 0.9375rem;
    transition: color var(--speed) var(--ease), transform var(--speed) var(--ease);
}

/* A small step to the right on hover — enough to feel responsive, not enough to
   reflow the column. */
.footer-list a:hover,
.footer-list a:focus-visible {
    color: var(--accent);
    transform: translateX(4px);
}

.footer-social {
    display: flex;
    flex-wrap: wrap;
    gap: 0.6rem;
    list-style: none;
    margin: 0;
    padding: 0;
}

.footer-social a {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 44px;
    height: 44px;
    border-radius: var(--radius-pill);
    border: 1px solid var(--line-invert);
    color: var(--text-invert);
    transition: background-color var(--speed) var(--ease), border-color var(--speed) var(--ease),
        transform var(--speed) var(--ease);
}

.footer-social a:hover,
.footer-social a:focus-visible {
    background: var(--accent);
    border-color: var(--accent);
    transform: translateY(-3px);
    box-shadow: var(--shadow-accent);
}

.footer-bottom {
    margin-top: clamp(2.5rem, 5vw, 4rem);
    border-top: 1px solid var(--line-invert);
    padding: 1.75rem 0 2rem;
    font-size: 0.875rem;
    color: var(--text-invert-muted);
}

.footer-bottom a:hover {
    color: var(--accent);
}

.footer-legal {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem 1.25rem;
    list-style: none;
    margin: 0;
    padding: 0;
}

/* ==========================================================================
   07. HERO
   ========================================================================== */
/* Top padding only has to clear the fixed header (~82px) plus breathing room —
   the old clamp topped out at 11rem, which left a dead band on wide screens.
   Every vertical value in the hero is additionally capped against viewport
   height, so the whole block (headline → copy → buttons) still lands above the
   fold on short laptop screens. On tall screens the vh terms never bind and the
   original spacing is what renders. */
.hero {
    position: relative;
    padding-top: min(clamp(7rem, 3.5rem + 5vw, 9rem), 17vh);
    padding-bottom: min(clamp(2.5rem, 5vw, 4rem), 5vh);
    overflow: hidden;
}

.hero::before {
    content: "";
    position: absolute;
    top: -18%;
    right: -12%;
    width: min(760px, 90vw);
    aspect-ratio: 1;
    background: radial-gradient(circle at center, var(--accent-soft), transparent 68%);
    pointer-events: none;
    z-index: 0;
}

.hero > .container {
    position: relative;
    z-index: 1;
}

.hero-eyebrow {
    display: inline-flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.45rem 1rem 0.45rem 0.6rem;
    border: 1px solid var(--line-strong);
    border-radius: var(--radius-pill);
    font-size: 0.75rem;
    font-weight: 500;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--text-muted);
    background: rgba(255, 255, 255, 0.62);
    backdrop-filter: blur(8px);
    -webkit-backdrop-filter: blur(8px);
    box-shadow: var(--shadow-sm);
    margin-bottom: min(1.75rem, 3vh);
}

.hero-eyebrow .dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--accent);
    box-shadow: 0 0 0 4px var(--accent-soft);
    animation: pulseDot 2.4s ease-in-out infinite;
}

@keyframes pulseDot {
    0%, 100% { box-shadow: 0 0 0 3px var(--accent-soft); }
    50% { box-shadow: 0 0 0 8px rgba(255, 90, 52, 0.05); }
}

.hero h1 {
    /* 9.5vh keeps the three-line headline from eating the fold on short
       screens; on anything ~840px tall or more the 5rem clamp wins as designed. */
    font-size: min(clamp(2.5rem, 1.4rem + 4.8vw, 5rem), 9.5vh);
    margin-bottom: min(1.5rem, 2.5vh);
}

.hero h1 em {
    font-style: italic;
    color: var(--accent);
}

.hero-copy {
    max-width: 46ch;
}

.hero-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.85rem;
    margin-top: min(2.25rem, 3.5vh);
}

.hero-visual {
    position: relative;
    border-radius: var(--radius-lg);
    overflow: hidden;
    box-shadow: var(--shadow-lg);
    /* A pale rim keeps the artwork from bleeding into the paper background at the
       corners, where the shadow alone is weakest. */
    border: 1px solid rgba(255, 255, 255, 0.7);
}

.hero-visual img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    aspect-ratio: 9 / 10;
    /* Without a cap the 9/10 ratio alone renders ~667px tall at desktop column
       widths, pushing the hero past a laptop viewport. cover crops instead. */
    max-height: min(68vh, 640px);
}

.hero-badge {
    position: absolute;
    /* Kept inside the visual — .hero-visual clips overflow to keep its rounded corners. */
    left: clamp(1rem, 2vw, 1.75rem);
    bottom: clamp(1rem, 3vw, 2rem);
    background: rgba(255, 255, 255, 0.92);
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    border: 1px solid rgba(255, 255, 255, 0.9);
    border-radius: var(--radius);
    padding: var(--pad-sm);
    box-shadow: var(--shadow-lg);
    display: flex;
    align-items: center;
    gap: 0.9rem;
    max-width: 82%;
}

.hero-badge strong {
    font-family: var(--font-display);
    font-size: 1.75rem;
    line-height: 1;
    color: var(--ink);
}

.hero-badge span {
    font-size: 0.8125rem;
    color: var(--text-muted);
    line-height: 1.35;
}

.hero-stats {
    display: flex;
    flex-wrap: wrap;
    gap: clamp(1.5rem, 4vw, 3.5rem);
    margin-top: clamp(2.25rem, 4.5vw, 3.25rem);
    padding-top: clamp(1.5rem, 3vw, 2.1rem);
    border-top: 1px solid var(--line);
}

.hero-stat strong {
    display: block;
    font-family: var(--font-display);
    font-size: clamp(1.9rem, 1.4rem + 1.6vw, 2.75rem);
    line-height: 1;
    color: var(--ink);
    margin-bottom: 0.35rem;
}

.hero-stat span {
    font-size: 0.8125rem;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--text-muted);
}

/* ==========================================================================
   08. TRUST BAR
   ========================================================================== */
.trust-card {
    height: 100%;
    padding: var(--pad-md);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--white);
    transition: transform var(--speed) var(--ease), box-shadow var(--speed) var(--ease),
        border-color var(--speed) var(--ease);
}

/* Hover tints the border toward the brand instead of dropping it to transparent —
   the card keeps its edge while clearly becoming the live one. */
.trust-card:hover {
    transform: translateY(-6px);
    box-shadow: var(--shadow);
    border-color: rgba(255, 90, 52, 0.22);
}

.trust-card h3 {
    font-family: var(--font-body);
    font-size: 1.0625rem;
    font-weight: 600;
    letter-spacing: -0.01em;
    margin-bottom: 0.5rem;
}

.trust-card p {
    font-size: 0.9375rem;
    color: var(--text-muted);
    margin: 0;
}

.icon-badge {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 52px;
    height: 52px;
    border-radius: 14px;
    background: var(--accent-soft);
    /* An inset hairline turns a flat tinted square into a moulded chip. */
    box-shadow: inset 0 0 0 1px rgba(255, 90, 52, 0.14);
    color: var(--accent);
    margin-bottom: 1.25rem;
    transition: background-color var(--speed) var(--ease), color var(--speed) var(--ease),
        transform var(--speed) var(--ease), box-shadow var(--speed) var(--ease);
}

.trust-card:hover .icon-badge,
.service-card:hover .icon-badge,
.perk-item:hover .icon-badge,
.service-detail:hover .icon-badge {
    background: var(--accent);
    color: #fff;
    transform: translateY(-2px) scale(1.04);
    box-shadow: var(--shadow-accent);
}

.section-dark .icon-badge {
    background: rgba(255, 255, 255, 0.08);
    box-shadow: inset 0 0 0 1px var(--line-invert);
    color: var(--accent);
}

/* ==========================================================================
   09. SECTION HEADINGS
   ========================================================================== */
.eyebrow {
    display: inline-flex;
    align-items: center;
    gap: 0.65rem;
    font-size: 0.6875rem;
    font-weight: 600;
    letter-spacing: 0.22em;
    text-transform: uppercase;
    color: var(--accent);
    margin-bottom: 1.1rem;
}

.eyebrow::before {
    content: "";
    width: 28px;
    height: 1px;
    background: var(--accent);
}

.section-head {
    max-width: 42rem;
    margin-bottom: clamp(2.5rem, 5vw, 4rem);
}

.section-head.is-center {
    margin-left: auto;
    margin-right: auto;
    text-align: center;
}

.section-head.is-center .eyebrow {
    justify-content: center;
}

.section-head-split {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    justify-content: space-between;
    gap: 1.5rem;
    margin-bottom: clamp(2.5rem, 5vw, 3.75rem);
}

.section-head-split .section-head {
    margin-bottom: 0;
}

/* The footer heading style reused on a paper background — contact.html carried
   this as an inline colour override. */
.section-label {
    color: var(--text-muted);
}

/* ==========================================================================
   10. ABOUT BLOCKS
   ========================================================================== */
.about-visual {
    border-radius: var(--radius-lg);
    overflow: hidden;
    box-shadow: var(--shadow);
}

/* About: whole block presented as one single card */
.about-panel {
    padding: var(--pad-lg);
    background: var(--white);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-sm);
}

/* Inside the panel the checklist drops its own box — one card, not a card in a card */
.about-panel .value-list {
    background: transparent;
    border: 0;
    border-top: 1px solid var(--line);
    border-radius: 0;
    gap: 0;
    overflow: visible;
}

.about-panel .value-list li {
    background: transparent;
    border-bottom: 1px solid var(--line);
    padding-left: 0;
    padding-right: 0;
}

.about-panel .value-list li:hover {
    background: transparent;
}

.value-list {
    list-style: none;
    margin: 2rem 0 0;
    padding: 0;
    display: grid;
    gap: 1px;
    background: var(--line);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    overflow: hidden;
}

.value-list li {
    background: var(--paper);
    padding: var(--pad-sm);
    display: flex;
    gap: 0.9rem;
    align-items: flex-start;
    font-size: 0.9375rem;
    transition: background-color var(--speed) var(--ease);
}

.value-list li:hover {
    background: var(--white);
}

.value-list strong {
    display: block;
    font-weight: 600;
    margin-bottom: 0.15rem;
}

.value-list p {
    margin: 0;
    color: var(--text-muted);
    font-size: 0.9375rem;
}

.check-icon {
    flex: none;
    width: 22px;
    height: 22px;
    margin-top: 3px;
    color: var(--accent);
}

.stat-band {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
    gap: 1px;
    background: var(--line-invert);
    border-radius: var(--radius);
    overflow: hidden;
}

.stat-band > div {
    background: var(--ink);
    padding: var(--pad-md);
    transition: background-color var(--speed) var(--ease);
}

.stat-band > div:hover {
    background: var(--ink-soft);
}

.stat-band strong {
    display: block;
    font-family: var(--font-display);
    font-size: clamp(2rem, 1.5rem + 1.8vw, 3rem);
    line-height: 1;
    color: var(--text-invert);
    margin-bottom: 0.4rem;
}

.stat-band span {
    font-size: 0.8125rem;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--text-invert-muted);
}

/* Timeline (about story) */
.timeline {
    list-style: none;
    margin: 0;
    padding: 0;
    position: relative;
}

.timeline::before {
    content: "";
    position: absolute;
    left: 7px;
    top: 8px;
    bottom: 8px;
    width: 1px;
    background: var(--line);
}

.timeline li {
    position: relative;
    padding: 0 0 2.25rem 2.75rem;
}

.timeline li:last-child {
    padding-bottom: 0;
}

.timeline li::before {
    content: "";
    position: absolute;
    left: 0;
    top: 7px;
    width: 15px;
    height: 15px;
    border-radius: 50%;
    background: var(--paper);
    border: 2px solid var(--accent);
}

.timeline h4 {
    font-family: var(--font-body);
    font-size: 1.0625rem;
    font-weight: 600;
    margin-bottom: 0.4rem;
}

.timeline .year {
    font-size: 0.75rem;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--accent);
    display: block;
    margin-bottom: 0.35rem;
}

.timeline p {
    color: var(--text-muted);
    font-size: 0.9375rem;
    margin: 0;
}

/* Skill bars */
.skill-row {
    padding: 1.1rem 0;
    border-bottom: 1px solid var(--line);
}

.skill-row:last-child {
    border-bottom: 0;
}

.skill-top {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: 1rem;
    margin-bottom: 0.6rem;
    font-size: 0.9375rem;
    font-weight: 500;
}

.skill-top span:last-child {
    color: var(--text-muted);
    font-size: 0.8125rem;
    letter-spacing: 0.08em;
}

.skill-track {
    height: 6px;
    border-radius: var(--radius-pill);
    background: var(--line);
    overflow: hidden;
}

/* A gradient along the fill gives the bar direction, so a 95% and a 85% row read
   as different lengths of the same journey rather than two flat blocks. */
.skill-fill {
    display: block;
    height: 100%;
    width: 0;
    border-radius: var(--radius-pill);
    background: linear-gradient(90deg, var(--accent-dark), var(--accent));
    box-shadow: 0 0 12px -2px rgba(255, 90, 52, 0.5);
    transition: width 1.4s var(--ease);
}

/* Team */
/* Cards sit in one row, so heading lengths differ — stretch each card and pin the
   role line to the bottom so every role reads on the same baseline. */
.team-card {
    display: flex;
    flex-direction: column;
    height: 100%;
}

.team-card figure {
    margin: 0 0 1.1rem;
    border-radius: var(--radius);
    overflow: hidden;
    background: var(--paper-2);
    box-shadow: var(--shadow-sm);
    transition: box-shadow var(--speed) var(--ease), transform var(--speed) var(--ease);
}

.team-card:hover figure {
    box-shadow: var(--shadow);
    transform: translateY(-4px);
}

.team-card img {
    width: 100%;
    aspect-ratio: 5 / 6;
    object-fit: cover;
    transition: transform 0.7s var(--ease);
}

.team-card:hover img {
    transform: scale(1.05);
}

.team-card h4 {
    font-family: var(--font-body);
    font-size: 1.0625rem;
    font-weight: 600;
    margin-bottom: 0.2rem;
}

.team-card p {
    font-size: 0.875rem;
    color: var(--text-muted);
    margin: auto 0 0;
}

/* ==========================================================================
   11. SERVICE CARDS
   ========================================================================== */
.service-card {
    position: relative;
    height: 100%;
    display: flex;
    flex-direction: column;
    padding: var(--pad-md);
    background: var(--white);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    overflow: hidden;
    transition: transform var(--speed) var(--ease), box-shadow var(--speed) var(--ease),
        border-color var(--speed) var(--ease);
}

.service-card::before {
    content: "";
    position: absolute;
    left: 0;
    top: 0;
    height: 3px;
    width: 100%;
    background: var(--accent);
    transform: scaleX(0);
    transform-origin: left;
    transition: transform 0.5s var(--ease);
}

.service-card:hover,
.service-card:focus-within {
    transform: translateY(-8px);
    box-shadow: var(--shadow-lg);
    border-color: rgba(255, 90, 52, 0.22);
}

.service-card:hover::before,
.service-card:focus-within::before {
    transform: scaleX(1);
}

.service-card h3 {
    font-family: var(--font-display);
    font-size: clamp(1.25rem, 1.1rem + 0.5vw, 1.5rem);
    margin-bottom: 0.65rem;
}

.service-card p {
    color: var(--text-muted);
    font-size: 0.9375rem;
    margin-bottom: 1.5rem;
}

/* Tool tags sit between the copy and the "Learn more" link. The paragraph
   above already supplies the top gap, and margin-top:auto on the link can
   collapse to zero in the tallest card — so the spacing is set here. */
.service-card .tag-row {
    margin-top: 0;
    margin-bottom: 1.5rem;
}

.service-card .link-underline {
    margin-top: auto;
    align-self: flex-start;
}

/* Anchored to the card's own padding so the index stays on the same optical
   grid as the icon badge and heading beneath it at every viewport. */
.service-index {
    position: absolute;
    top: var(--pad-md);
    right: var(--pad-md);
    font-family: var(--font-display);
    font-size: 2.5rem;
    line-height: 1;
    color: var(--line);
    transition: color var(--speed) var(--ease);
}

.service-card:hover .service-index {
    color: var(--accent-soft);
}

/* Detailed service rows (services.html) */
.service-detail {
    padding: var(--pad-lg);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    background: var(--white);
    height: 100%;
    box-shadow: var(--shadow-sm);
    transition: transform var(--speed) var(--ease), box-shadow var(--speed) var(--ease),
        border-color var(--speed) var(--ease);
}

/* These panels are large, so they lift less than the small cards do — a big
   surface travelling 8px reads as a jump rather than a response. */
.service-detail:hover {
    transform: translateY(-4px);
    box-shadow: var(--shadow);
    border-color: rgba(255, 90, 52, 0.22);
}

.benefit-list {
    list-style: none;
    margin: 1.5rem 0 0;
    padding: 0;
    display: grid;
    gap: 0.7rem;
}

.benefit-list li {
    display: flex;
    gap: 0.7rem;
    align-items: flex-start;
    font-size: 0.9375rem;
    color: var(--text-muted);
}

.tag-row {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin-top: 1.5rem;
}

.tag {
    display: inline-block;
    padding: 0.4rem 0.85rem;
    border: 1px solid var(--line);
    border-radius: var(--radius-pill);
    font-size: 0.75rem;
    letter-spacing: 0.06em;
    color: var(--text-muted);
    background: var(--paper);
    transition: color var(--speed) var(--ease), border-color var(--speed) var(--ease),
        background-color var(--speed) var(--ease);
}

/* Chips warm up with the card they sit in, which ties a long tag row to the
   surface instead of leaving it looking pasted on. */
.service-card:hover .tag,
.service-detail:hover .tag,
.expert-card:hover .tag,
.project-card:hover .tag {
    border-color: rgba(255, 90, 52, 0.28);
    background: var(--accent-soft);
    color: var(--accent-dark);
}

.section-dark .tag {
    background: rgba(255, 255, 255, 0.05);
    border-color: var(--line-invert);
    color: var(--text-invert-muted);
}

/* ==========================================================================
   12. PROJECT CARDS + FILTERS
   ========================================================================== */
.filter-bar {
    display: flex;
    flex-wrap: wrap;
    gap: 0.6rem;
    margin-bottom: clamp(2rem, 4vw, 3rem);
}

.filter-btn {
    padding: 0.65rem 1.25rem;
    min-height: 44px;
    border: 1px solid var(--line-strong);
    border-radius: var(--radius-pill);
    background: transparent;
    color: var(--text);
    font-family: var(--font-body);
    font-size: 0.875rem;
    font-weight: 500;
    letter-spacing: 0.01em;
    cursor: pointer;
    white-space: nowrap;
    transition: background-color 0.3s var(--ease), color 0.3s var(--ease),
        border-color 0.3s var(--ease), transform 0.3s var(--ease);
}

.filter-btn:hover {
    border-color: var(--ink);
    background: var(--white);
    transform: translateY(-2px);
    box-shadow: var(--shadow-sm);
}

.filter-btn.is-active {
    background: var(--ink);
    border-color: var(--ink);
    color: #fff;
    box-shadow: var(--shadow);
}

/* The count is secondary information, so it sits in its own quiet pill rather
   than competing with the label at the same weight. */
.filter-btn .count {
    display: inline-block;
    min-width: 1.5em;
    padding: 0.05rem 0.35rem;
    border-radius: var(--radius-pill);
    background: rgba(16, 16, 20, 0.06);
    opacity: 0.75;
    font-size: 0.6875rem;
    line-height: 1.5;
    margin-left: 0.45rem;
}

.filter-btn.is-active .count {
    background: rgba(255, 255, 255, 0.16);
    opacity: 0.9;
}

.search-field {
    position: relative;
    max-width: 320px;
    width: 100%;
}

.search-field input {
    width: 100%;
    min-height: 48px;
    padding: 0.7rem 1rem 0.7rem 2.75rem;
    border: 1px solid var(--line-strong);
    border-radius: var(--radius-pill);
    background: transparent;
    font-family: var(--font-body);
    font-size: 0.9375rem;
    color: var(--text);
    transition: border-color var(--speed) var(--ease), background-color var(--speed) var(--ease);
}

.search-field input:hover {
    border-color: var(--ink);
}

.search-field input:focus {
    outline: none;
    border-color: var(--accent);
    background: var(--white);
    box-shadow: var(--ring);
}

.search-field input:focus + svg,
.search-field:focus-within svg {
    color: var(--accent);
}

.search-field svg {
    position: absolute;
    left: 1rem;
    top: 50%;
    transform: translateY(-50%);
    width: 18px;
    height: 18px;
    color: var(--text-muted);
    pointer-events: none;
}

/* Grid + card */
.project-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(min(100%, 330px), 1fr));
    gap: clamp(1.25rem, 2.5vw, 2rem);
}

.project-card {
    display: flex;
    flex-direction: column;
    height: 100%;
    background: var(--white);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    overflow: hidden;
    transition: transform var(--speed) var(--ease), box-shadow var(--speed) var(--ease),
        border-color var(--speed) var(--ease), opacity 0.4s var(--ease);
}

.project-card:hover,
.project-card:focus-within {
    transform: translateY(-8px);
    box-shadow: var(--shadow-lg);
    border-color: rgba(255, 90, 52, 0.22);
}

.project-media {
    position: relative;
    overflow: hidden;
    background: var(--paper-2);
    /* Separates artwork from copy when a thumbnail's own edge is pale. */
    border-bottom: 1px solid var(--line);
}

.project-media img {
    width: 100%;
    aspect-ratio: 4 / 3;
    object-fit: cover;
    transition: transform 0.8s var(--ease);
}

.project-card:hover .project-media img {
    transform: scale(1.06);
}

.project-media::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(to top, rgba(16, 16, 20, 0.55), transparent 55%);
    opacity: 0;
    transition: opacity var(--speed) var(--ease);
}

.project-card:hover .project-media::after,
.project-card:focus-within .project-media::after {
    opacity: 1;
}

.project-open {
    position: absolute;
    right: 1rem;
    bottom: 1rem;
    z-index: 2;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 46px;
    height: 46px;
    border-radius: 50%;
    background: var(--white);
    color: var(--ink);
    box-shadow: var(--shadow);
    opacity: 0;
    transform: translateY(10px) scale(0.9);
    transition: opacity var(--speed) var(--ease), transform var(--speed) var(--ease),
        background-color var(--speed) var(--ease), color var(--speed) var(--ease);
}

.project-card:hover .project-open,
.project-card:focus-within .project-open {
    opacity: 1;
    transform: translateY(0) scale(1);
}

.project-open:hover {
    background: var(--accent);
    color: #fff;
}

.project-body {
    display: flex;
    flex-direction: column;
    flex: 1;
    padding: var(--pad-md);
}

/* The category reads as a badge, matching the tag chips further down the card and
   giving the eye a fixed anchor point across a grid of thirteen cards. */
.project-category {
    display: inline-flex;
    align-items: center;
    align-self: flex-start;
    padding: 0.3rem 0.7rem;
    border-radius: var(--radius-pill);
    background: var(--accent-soft);
    font-size: 0.6875rem;
    font-weight: 600;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--accent-dark);
    margin-bottom: 0.9rem;
}

.project-body h3 {
    font-size: clamp(1.15rem, 1.05rem + 0.4vw, 1.4rem);
    margin-bottom: 0.6rem;
}

.project-body p {
    font-size: 0.9375rem;
    color: var(--text-muted);
    margin-bottom: 1.5rem;
}

.project-body .btn {
    margin-top: auto;
    align-self: flex-start;
}

/* Filter transition states.
   Scoped to .project-grid so these win over the [data-reveal].is-visible rule,
   which would otherwise force the card back to opacity: 1 mid-fade. */
.project-grid .project-card.is-hiding {
    opacity: 0;
    transform: scale(0.96);
    pointer-events: none;
}

.project-grid .project-card.is-hidden {
    display: none;
}

.project-empty {
    display: none;
    padding: clamp(2.5rem, 6vw, 4rem) var(--pad-md);
    text-align: center;
    border: 1px dashed var(--line-strong);
    border-radius: var(--radius-lg);
    background: rgba(255, 255, 255, 0.5);
    color: var(--text-muted);
}

.project-empty.is-visible {
    display: block;
}

/* ==========================================================================
   13. PROCESS STEPS
   ========================================================================== */
.process-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 240px), 1fr));
    gap: 1px;
    background: var(--line-invert);
    border-top: 1px solid var(--line-invert);
    border-bottom: 1px solid var(--line-invert);
}

.process-step {
    position: relative;
    background: var(--ink);
    padding: var(--pad-md);
    transition: background-color var(--speed) var(--ease);
}

.process-step:hover {
    background: var(--ink-soft);
}

/* The accent rule wipes in from the left on hover, so moving along the strip
   feels like stepping through the four stages in order. */
.process-step::before {
    content: "";
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 2px;
    background: var(--accent);
    transform: scaleX(0);
    transform-origin: left;
    transition: transform 0.5s var(--ease);
}

.process-step:hover::before {
    transform: scaleX(1);
}

.process-num {
    font-family: var(--font-display);
    font-size: 0.875rem;
    letter-spacing: 0.2em;
    color: var(--accent);
    display: block;
    margin-bottom: 1.75rem;
}

.process-step h3 {
    font-size: clamp(1.2rem, 1.1rem + 0.4vw, 1.45rem);
    margin-bottom: 0.7rem;
}

.process-step p {
    color: var(--text-invert-muted);
    font-size: 0.9375rem;
    margin: 0;
}

/* ==========================================================================
   14. WHY-US GRID
   ========================================================================== */
.why-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(100%, 260px), 1fr));
    gap: 1px;
    background: var(--line);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    overflow: hidden;
}

.why-item {
    background: var(--paper);
    padding: var(--pad-md);
    transition: background-color var(--speed) var(--ease), transform var(--speed) var(--ease);
}

.why-item:hover {
    background: var(--white);
}

.why-item h3 svg {
    transition: transform var(--speed) var(--ease);
}

.why-item:hover h3 svg {
    transform: scale(1.15);
}

.why-item h3 {
    font-family: var(--font-body);
    font-size: 1.0625rem;
    font-weight: 600;
    letter-spacing: -0.01em;
    margin-bottom: 0.55rem;
    display: flex;
    align-items: center;
    gap: 0.65rem;
}

.why-item h3 svg {
    width: 20px;
    height: 20px;
    color: var(--accent);
    flex: none;
}

.why-item p {
    color: var(--text-muted);
    font-size: 0.9375rem;
    margin: 0;
}

/* Expertise cards (6-up, equal size) */
/* The cards ride one endless line rather than a grid. overflow is clipped on the
   slider, so the vertical padding/margin pair below buys room for the hover lift
   and its shadow without letting the row bleed into the sections around it. */
.expert-slider {
    position: relative;
    overflow: hidden;
    padding-block: 1rem;
    margin-block: -1rem;
    -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 5%, #000 95%, transparent 100%);
    mask-image: linear-gradient(90deg, transparent 0, #000 5%, #000 95%, transparent 100%);
}

.expert-track {
    display: flex;
    align-items: stretch;
    width: max-content;
    animation: expertMarquee var(--marquee-duration, 45s) linear infinite;
}

/* Card spacing is margin, not gap: the loop translates by exactly one set width,
   and only margin makes that distance include the space *after* the last card.
   With gap the track would land half a gap short and visibly stutter each cycle. */
.expert-track > .expert-card {
    flex: 0 0 clamp(16.5rem, 24vw, 21rem);
    margin-right: clamp(1rem, 2vw, 1.5rem);
}

@keyframes expertMarquee {
    from { transform: translate3d(0, 0, 0); }
    to { transform: translate3d(-50%, 0, 0); }
}

/* JS adds .is-looping only once the duplicate set exists. Until then the track
   must not animate, or it would slide the real cards away and leave a gap. */
.expert-slider:not(.is-looping) .expert-track {
    animation: none;
    width: auto;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    scrollbar-width: none;
    padding-bottom: 0.25rem;
}

.expert-slider:not(.is-looping) .expert-track::-webkit-scrollbar {
    display: none;
}

.expert-slider:not(.is-looping) .expert-card {
    scroll-snap-align: start;
}

/* Let people stop the line to actually read a card. */
.expert-slider:hover .expert-track,
.expert-slider:focus-within .expert-track {
    animation-play-state: paused;
}

.expert-card {
    position: relative;
    display: flex;
    flex-direction: column;
    padding: var(--pad-md);
    background: var(--white);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    box-shadow: var(--shadow-sm);
    transition: transform var(--speed) var(--ease), box-shadow var(--speed) var(--ease),
        border-color var(--speed) var(--ease);
}

.expert-card:hover {
    transform: translateY(-6px);
    box-shadow: var(--shadow);
    border-color: rgba(255, 90, 52, 0.22);
}

/* Badge and name share one row, so a card without a credited name keeps exactly
   the same header height as one with it and the line stays level. */
.expert-top {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.75rem;
    min-height: 28px;
    margin-bottom: 1.1rem;
}

.expert-years {
    display: inline-flex;
    align-items: center;
    padding: 0.3rem 0.7rem;
    border-radius: var(--radius-pill);
    background: var(--accent-soft, var(--paper-2));
    color: var(--accent);
    font-size: 0.6875rem;
    font-weight: 600;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    white-space: nowrap;
}

.expert-person {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
    min-width: 0;
    font-size: 0.8125rem;
    font-weight: 500;
    color: var(--text);
    letter-spacing: -0.005em;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.expert-avatar {
    flex: none;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 24px;
    height: 24px;
    border-radius: 50%;
    background: var(--paper-2);
    color: var(--text-muted);
    font-family: var(--font-display);
    font-size: 0.75rem;
    line-height: 1;
}

.expert-card:hover .expert-avatar {
    background: var(--accent-soft);
    color: var(--accent);
}

/* Titles run to one or two lines depending on the role, which slid the label and
   description of every card to a different height. Reserving two lines keeps those
   rows level with each other right along the line. */
.expert-card h3 {
    font-family: var(--font-body);
    font-size: 1.0625rem;
    font-weight: 600;
    line-height: 1.35;
    min-height: 2.7em;
    margin-bottom: 0.3rem;
}

.expert-card .expert-prev {
    display: block;
    font-size: 0.75rem;
    font-weight: 500;
    color: var(--text-muted);
    letter-spacing: 0.08em;
    text-transform: uppercase;
    margin-bottom: 0.85rem;
}

.expert-card p {
    font-size: 0.9375rem;
    color: var(--text-muted);
    margin: 0;
}

/* Three tags never fit one line at this card width, so some cards wrap to two
   rows and others don't. Reserving two rows and settling the chips to the bottom
   of that space puts the last chip row of every card on the same baseline, which
   is what stops the line looking ragged as it slides past. */
.expert-card .tag-row {
    margin-top: auto;
    padding-top: 1.35rem;
    gap: 0.4rem;
    min-height: calc(1.35rem + 4.6rem);
    align-content: flex-end;
}

.expert-card .tag {
    white-space: nowrap;
}

/* Testimonial */
.quote-card {
    padding: var(--pad-lg);
    border-radius: var(--radius-lg);
    background: var(--white);
    border: 1px solid var(--line);
    box-shadow: var(--shadow-sm);
}

.quote-card blockquote {
    font-family: var(--font-display);
    font-size: clamp(1.3rem, 1.1rem + 1vw, 2rem);
    line-height: 1.35;
    letter-spacing: -0.02em;
    color: var(--ink);
    margin: 0 0 1.75rem;
}

.quote-meta {
    display: flex;
    align-items: center;
    gap: 0.9rem;
}

.quote-meta img {
    width: 48px;
    height: 48px;
    border-radius: 50%;
    object-fit: cover;
}

.quote-meta strong {
    display: block;
    font-size: 0.9375rem;
}

.quote-meta span {
    font-size: 0.8125rem;
    color: var(--text-muted);
}

/* ==========================================================================
   15. CTA BAND
   ========================================================================== */
.cta-band {
    position: relative;
    background: var(--ink);
    color: var(--text-invert);
    border-radius: var(--radius-lg);
    padding: clamp(2.5rem, 5.5vw, 4.5rem) clamp(1.5rem, 5vw, 4rem);
    overflow: hidden;
    text-align: center;
}

.cta-band::before,
.cta-band::after {
    content: "";
    position: absolute;
    border-radius: 50%;
    pointer-events: none;
}

.cta-band::before {
    width: min(520px, 70vw);
    aspect-ratio: 1;
    top: -35%;
    right: -12%;
    background: radial-gradient(circle, rgba(255, 90, 52, 0.35), transparent 65%);
}

.cta-band::after {
    width: min(420px, 60vw);
    aspect-ratio: 1;
    bottom: -45%;
    left: -8%;
    background: radial-gradient(circle, rgba(255, 255, 255, 0.09), transparent 65%);
}

.cta-band > * {
    position: relative;
    z-index: 1;
}

.cta-band h2 {
    color: var(--text-invert);
    max-width: 18ch;
    margin-left: auto;
    margin-right: auto;
}

.cta-band p {
    color: var(--text-invert-muted);
    max-width: 52ch;
    margin-left: auto;
    margin-right: auto;
}

.cta-actions {
    display: flex;
    flex-wrap: wrap;
    gap: 0.85rem;
    justify-content: center;
    margin-top: 2.25rem;
}

/* ==========================================================================
   16. PAGE HERO (inner pages)
   ========================================================================== */
.page-hero {
    position: relative;
    padding-top: clamp(8rem, 14vw, 11.5rem);
    padding-bottom: clamp(3rem, 6vw, 5rem);
    background: var(--ink);
    color: var(--text-invert);
    overflow: hidden;
}

.page-hero::before {
    content: "";
    position: absolute;
    width: min(620px, 80vw);
    aspect-ratio: 1;
    top: -30%;
    right: -8%;
    border-radius: 50%;
    background: radial-gradient(circle, rgba(255, 90, 52, 0.3), transparent 65%);
    pointer-events: none;
}

/* A cool counter-light low on the opposite side stops the ink block reading as a
   single flat rectangle behind the headline. */
.page-hero::after {
    content: "";
    position: absolute;
    width: min(520px, 70vw);
    aspect-ratio: 1;
    bottom: -50%;
    left: -10%;
    border-radius: 50%;
    background: radial-gradient(circle, rgba(255, 255, 255, 0.07), transparent 65%);
    pointer-events: none;
}

.page-hero > .container {
    position: relative;
    z-index: 1;
}

.page-hero h1 {
    color: var(--text-invert);
    max-width: 20ch;
}

.page-hero p {
    color: var(--text-invert-muted);
    max-width: 56ch;
}

.breadcrumb-mini {
    display: flex;
    align-items: center;
    gap: 0.55rem;
    font-size: 0.75rem;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: rgba(246, 244, 240, 0.5);
    margin-bottom: 1.5rem;
}

.breadcrumb-mini a:hover {
    color: var(--accent);
}

/* ==========================================================================
   17. CAREERS
   ========================================================================== */
.job-card {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 1.25rem;
    padding: var(--pad-md);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--white);
    transition: transform var(--speed) var(--ease), box-shadow var(--speed) var(--ease),
        border-color var(--speed) var(--ease);
}

.job-card:hover {
    transform: translateY(-4px);
    box-shadow: var(--shadow);
    border-color: rgba(255, 90, 52, 0.22);
}

.job-card .btn {
    flex: none;
}

.job-info {
    min-width: min(100%, 260px);
    flex: 1;
}

.job-info h3 {
    font-family: var(--font-display);
    font-size: clamp(1.25rem, 1.1rem + 0.5vw, 1.6rem);
    margin-bottom: 0.6rem;
}

.job-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem 0.75rem;
    margin-bottom: 0.85rem;
}

.job-meta span {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    font-size: 0.75rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--text-muted);
    background: var(--paper);
    border: 1px solid var(--line);
    border-radius: var(--radius-pill);
    padding: 0.3rem 0.75rem;
    transition: color var(--speed) var(--ease), border-color var(--speed) var(--ease),
        background-color var(--speed) var(--ease);
}

.job-card:hover .job-meta span {
    background: var(--accent-soft);
    border-color: rgba(255, 90, 52, 0.28);
    color: var(--accent-dark);
}

.job-info p {
    color: var(--text-muted);
    font-size: 0.9375rem;
    margin: 0;
    max-width: 60ch;
}

.form-embed {
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    background: var(--white);
    padding: clamp(0.5rem, 1.5vw, 1rem);
    overflow: hidden;
    box-shadow: var(--shadow-sm);
    transition: box-shadow var(--speed) var(--ease);
}

.form-embed:hover,
.form-embed:focus-within {
    box-shadow: var(--shadow);
}

.form-embed iframe {
    display: block;
    width: 100%;
    min-height: 780px;
    border: 0;
    border-radius: var(--radius);
    background: var(--white);
}

.form-fallback {
    padding: var(--pad-lg);
    text-align: center;
    border: 1px dashed var(--line-strong);
    border-radius: var(--radius-lg);
    color: var(--text-muted);
}

/* Was an inline border-radius on the element. Given the same treatment as the
   home page hero art, it now sits on the ink hero as a deliberate panel rather
   than a floating illustration. */
.careers-visual {
    width: 100%;
    border-radius: var(--radius-lg);
    border: 1px solid var(--line-invert);
    box-shadow: var(--shadow-lg);
}

.perk-item {
    padding: var(--pad-md);
    border: 1px solid var(--line-invert);
    border-radius: var(--radius);
    height: 100%;
    /* Barely-there fill so the tiles read as surfaces on the ink section rather
       than as four outlines floating on it. */
    background: rgba(255, 255, 255, 0.03);
    transition: background-color var(--speed) var(--ease), border-color var(--speed) var(--ease),
        transform var(--speed) var(--ease);
}

.perk-item:hover {
    background: rgba(255, 255, 255, 0.06);
    border-color: rgba(255, 90, 52, 0.35);
    transform: translateY(-4px);
}

.perk-item h3 {
    font-family: var(--font-body);
    font-size: 1rem;
    font-weight: 600;
    margin-bottom: 0.45rem;
}

.perk-item p {
    font-size: 0.9375rem;
    color: var(--text-invert-muted);
    margin: 0;
}

/* ==========================================================================
   18. CONTACT
   ========================================================================== */
.contact-panel {
    padding: var(--pad-lg);
    border: 1px solid var(--line);
    border-radius: var(--radius-lg);
    background: var(--white);
    box-shadow: var(--shadow-sm);
}

.form-label {
    display: block;
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--text-muted);
    margin-bottom: 0.5rem;
}

.form-control,
.form-select {
    width: 100%;
    min-height: 52px;
    padding: 0.85rem 1.1rem;
    border: 1px solid var(--line-strong);
    border-radius: var(--radius-sm);
    background: var(--paper);
    font-family: var(--font-body);
    font-size: 0.9375rem;
    color: var(--text);
    transition: border-color var(--speed) var(--ease), background-color var(--speed) var(--ease),
        box-shadow var(--speed) var(--ease);
    appearance: none;
}

textarea.form-control {
    min-height: 150px;
    resize: vertical;
    line-height: 1.6;
}

.form-select {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%236b6b76'%3E%3Cpath d='M8 11.5 3.5 7h9z'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 1rem center;
    background-size: 14px;
    padding-right: 2.5rem;
}

.form-control:hover,
.form-select:hover {
    border-color: var(--ink);
}

/* Focus is the one state that has to be unmistakable in a nine-field form, so it
   takes the brand colour rather than another shade of grey. */
.form-control:focus,
.form-select:focus {
    outline: none;
    border-color: var(--accent);
    background: var(--white);
    box-shadow: var(--ring);
}

/* The label above the focused field lights up with it — useful on the two-column
   rows where the eye can lose which pair it is in. */
.form-control:focus + .form-note,
.col-md-6:focus-within > .form-label,
.col-12:focus-within > .form-label {
    color: var(--accent-dark);
}

.form-control::placeholder {
    color: #a4a4ad;
}

.form-note {
    font-size: 0.8125rem;
    color: var(--text-muted);
    margin-top: 1rem;
}

.form-status {
    display: none;
    margin-top: 1.25rem;
    padding: 0.9rem 1.15rem;
    border-radius: var(--radius-sm);
    font-size: 0.9375rem;
    border: 1px solid transparent;
}

.form-status.is-visible {
    display: block;
}

.form-status.is-ok {
    background: rgba(46, 138, 90, 0.08);
    border-color: rgba(46, 138, 90, 0.3);
    color: #256b47;
}

.form-status.is-error {
    background: var(--accent-soft);
    border-color: rgba(255, 90, 52, 0.35);
    color: var(--accent-dark);
}

.contact-list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: grid;
    gap: 1px;
    background: var(--line);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    overflow: hidden;
}

.contact-list li {
    background: var(--paper);
    padding: var(--pad-sm);
    display: flex;
    gap: 1rem;
    align-items: flex-start;
    transition: background-color var(--speed) var(--ease);
}

.contact-list li:hover {
    background: var(--white);
}

.contact-list li:hover .icon-badge {
    background: var(--accent);
    color: #fff;
}

.contact-list .icon-badge {
    width: 42px;
    height: 42px;
    margin-bottom: 0;
    border-radius: 12px;
    flex: none;
}

.contact-list .icon-badge svg {
    width: 18px;
    height: 18px;
}

.contact-list strong {
    display: block;
    font-size: 0.75rem;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--text-muted);
    margin-bottom: 0.3rem;
    font-weight: 600;
}

.contact-list a,
.contact-list p {
    font-size: 1rem;
    margin: 0;
    color: var(--text);
}

.contact-list a:hover {
    color: var(--accent);
}

.map-frame {
    border-radius: var(--radius-lg);
    overflow: hidden;
    border: 1px solid var(--line);
    box-shadow: var(--shadow-sm);
    line-height: 0;
    transition: box-shadow var(--speed) var(--ease);
}

.map-frame:hover {
    box-shadow: var(--shadow);
}

/* Height scales with the viewport instead of sitting at a fixed 340px, which was
   a letterbox on a phone and a stamp on a wide desktop. */
.map-frame iframe {
    width: 100%;
    height: clamp(260px, 34vw, 420px);
    border: 0;
    filter: grayscale(1) contrast(1.05);
    transition: filter var(--speed) var(--ease);
}

.map-frame:hover iframe {
    filter: grayscale(0);
}

/* FAQ */
.faq-item {
    border-bottom: 1px solid var(--line);
    transition: border-color var(--speed) var(--ease);
}

.faq-item.is-open {
    border-bottom-color: var(--line-strong);
}

.faq-question {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    width: 100%;
    padding: 1.35rem 0;
    background: none;
    border: 0;
    text-align: left;
    font-family: var(--font-body);
    font-size: 1.0625rem;
    font-weight: 500;
    color: var(--ink);
    cursor: pointer;
    min-height: 56px;
    transition: color var(--speed) var(--ease);
}

.faq-question:hover {
    color: var(--accent);
}

/* The open row stays marked while its answer is showing. */
.faq-question[aria-expanded="true"] {
    color: var(--accent);
}

.faq-icon {
    flex: none;
    width: 24px;
    height: 24px;
    position: relative;
}

.faq-icon::before,
.faq-icon::after {
    content: "";
    position: absolute;
    background: currentColor;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    transition: transform var(--speed) var(--ease), opacity var(--speed) var(--ease);
}

.faq-icon::before {
    width: 14px;
    height: 1.5px;
}

.faq-icon::after {
    width: 1.5px;
    height: 14px;
}

.faq-question[aria-expanded="true"] .faq-icon::after {
    transform: translate(-50%, -50%) rotate(90deg);
    opacity: 0;
}

.faq-answer {
    display: grid;
    grid-template-rows: 0fr;
    transition: grid-template-rows 0.45s var(--ease);
}

.faq-answer > div {
    overflow: hidden;
}

.faq-item.is-open .faq-answer {
    grid-template-rows: 1fr;
}

.faq-answer p {
    color: var(--text-muted);
    font-size: 0.9375rem;
    padding-bottom: 1.35rem;
    max-width: 68ch;
    margin: 0;
}

/* ==========================================================================
   19. LEGAL PAGES (privacy policy, terms & conditions)
   ========================================================================== */
.legal-layout {
    display: grid;
    grid-template-columns: minmax(0, 240px) minmax(0, 1fr);
    gap: clamp(2rem, 5vw, 4rem);
    align-items: start;
}

.legal-toc {
    position: sticky;
    top: 100px;
    /* The list can run longer than the screen — keep it inside the viewport
       and let it scroll on its own instead of hiding the last few entries. */
    max-height: calc(100vh - 130px);
    overflow-y: auto;
    overscroll-behavior: contain;
    padding: var(--pad-md);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--white);
    box-shadow: var(--shadow-sm);
}

.legal-toc h2 {
    font-family: var(--font-body, inherit);
    font-size: 0.75rem;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--text-muted);
    margin: 0 0 0.9rem;
}

.legal-toc ol {
    list-style: none;
    counter-reset: toc;
    margin: 0;
    padding: 0;
}

.legal-toc li {
    counter-increment: toc;
    margin-bottom: 0.55rem;
}

.legal-toc li:last-child {
    margin-bottom: 0;
}

.legal-toc a {
    display: flex;
    gap: 0.6rem;
    font-size: 0.9375rem;
    color: var(--text-muted);
    text-decoration: none;
    transition: color var(--speed) var(--ease), transform var(--speed) var(--ease);
}

.legal-toc a::before {
    content: counter(toc, decimal-leading-zero);
    font-size: 0.75rem;
    letter-spacing: 0.08em;
    color: var(--accent);
    padding-top: 0.15rem;
}

.legal-toc a:hover,
.legal-toc a:focus-visible {
    color: var(--text);
    transform: translateX(3px);
}

.legal-meta {
    display: flex;
    flex-wrap: wrap;
    gap: 0.6rem;
    margin-bottom: clamp(1.75rem, 4vw, 2.5rem);
}

.legal-meta span {
    display: inline-flex;
    align-items: center;
    padding: 0.4rem 0.9rem;
    border: 1px solid var(--line);
    border-radius: var(--radius-pill);
    background: var(--white);
    font-size: 0.8125rem;
    color: var(--text-muted);
}

.legal-body {
    max-width: 72ch;
}

.legal-body > section {
    padding-bottom: clamp(1.75rem, 4vw, 2.5rem);
    margin-bottom: clamp(1.75rem, 4vw, 2.5rem);
    border-bottom: 1px solid var(--line);
    scroll-margin-top: 110px;
}

.legal-body > section:last-child {
    border-bottom: 0;
    margin-bottom: 0;
    padding-bottom: 0;
}

.legal-body h2 {
    font-size: clamp(1.35rem, 2.6vw, 1.75rem);
    margin-bottom: 1rem;
}

.legal-body h3 {
    font-size: 1.0625rem;
    margin: 1.6rem 0 0.6rem;
}

.legal-body p,
.legal-body li {
    color: var(--text-muted);
    font-size: 1rem;
    line-height: 1.75;
}

.legal-body p {
    margin-bottom: 1rem;
}

.legal-body ul {
    list-style: none;
    margin: 0 0 1rem;
    padding: 0;
}

.legal-body ul li {
    position: relative;
    padding-left: 1.4rem;
    margin-bottom: 0.55rem;
}

.legal-body ul li::before {
    content: "";
    position: absolute;
    left: 0;
    top: 0.7rem;
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--accent);
}

.legal-body strong {
    color: var(--text);
    font-weight: 600;
}

.legal-note {
    padding: var(--pad-md);
    border: 1px solid var(--line);
    border-left: 3px solid var(--accent);
    border-radius: var(--radius-sm);
    background: var(--paper-2);
    margin-bottom: 1.25rem;
}

.legal-note p:last-child {
    margin-bottom: 0;
}

@media (max-width: 991.98px) {
    .legal-layout {
        grid-template-columns: minmax(0, 1fr);
    }

    /* Stacked above the text, the list must show every entry — the sticky
       height cap would otherwise hide the last few items. */
    .legal-toc {
        position: static;
        max-height: none;
        overflow: visible;
    }

    .legal-toc ol {
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
        gap: 0.35rem 1.25rem;
    }
}

/* ==========================================================================
   20. REVEAL ANIMATIONS
   ========================================================================== */
/* The entrance is an animation, not a transition, for two reasons.
   1. `transition` is a shorthand and cannot merge: because [data-reveal] is later
      in the file than .project-card / .service-card, its transition list replaced
      theirs, so those cards lost the box-shadow and border-colour timing that
      makes their hover feel considered — the shadow snapped on.
   2. transition-delay from the stagger below applied to hover as well, holding a
      card's lift for up to 0.4s after the pointer arrived.
   An animation touches neither property. fill-mode is `backwards`, never
   `forwards`: a filled end state would outrank the hover transform in the cascade
   and every card would refuse to lift. */
[data-reveal] {
    opacity: 0;
}

[data-reveal].is-visible {
    opacity: 1;
    animation: revealIn 0.65s var(--ease-out) backwards;
}

@keyframes revealIn {
    from {
        opacity: 0;
        /* A hair of scale so the element settles into place instead of sliding. */
        transform: translateY(18px) scale(0.995);
    }
}

[data-reveal-delay="1"].is-visible { animation-delay: 0.08s; }
[data-reveal-delay="2"].is-visible { animation-delay: 0.16s; }
[data-reveal-delay="3"].is-visible { animation-delay: 0.24s; }
[data-reveal-delay="4"].is-visible { animation-delay: 0.32s; }
[data-reveal-delay="5"].is-visible { animation-delay: 0.4s; }

/* Without JavaScript the class is never added, and everything marked for reveal
   would sit at opacity 0 forever. Browsers that report scripting support get the
   content back unconditionally. */
@media (scripting: none) {
    [data-reveal] {
        opacity: 1;
        animation: none;
    }
}

@media (prefers-reduced-motion: reduce) {
    html {
        scroll-behavior: auto;
    }

    *,
    *::before,
    *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }

    [data-reveal] {
        opacity: 1;
        transform: none;
        animation: none !important;
    }

    /* The blanket 0.01ms above would snap the marquee straight to its end frame
       and park it there. Kill the animation outright instead — JS also skips the
       duplicate set here, leaving a row people scroll themselves. */
    .expert-track {
        animation: none !important;
        transform: none !important;
    }
}

/* ==========================================================================
   21. RESPONSIVE REFINEMENTS
   ========================================================================== */

/* iPad landscape / small laptops. The desktop nav is still on, but the container
   is ~300px narrower than the layouts below were tuned for, so the six-across
   team row and the nav gap both need easing before the 992px breakpoint. */
@media (min-width: 992px) and (max-width: 1199.98px) {
    .nav-list {
        gap: 1.15rem;
    }

    .team-grid > [class*="col-"] {
        flex: 0 0 auto;
        width: 33.3333%;
    }

    .service-detail,
    .about-panel {
        padding: var(--pad-md);
    }
}

/* Tablet & below — switch to the mobile navigation */
@media (max-width: 991.98px) {
    .desktop-nav,
    .header-cta {
        display: none !important;
    }

    .nav-toggle {
        display: inline-flex;
    }

    .hero {
        padding-top: min(7.5rem, 16vh);
    }

    .hero-visual {
        margin-top: 3rem;
        max-width: 560px;
    }

    .hero-visual img {
        aspect-ratio: 4 / 3;
    }

    .hero-badge {
        left: 1rem;
    }

    .section-head-split {
        align-items: flex-start;
    }

    /* Three across on an iPad portrait — six columns of ~110px turned the
       portraits into thumbnails and wrapped every role onto three lines. */
    .team-grid > [class*="col-"] {
        flex: 0 0 auto;
        width: 33.3333%;
    }

    /* The legal pages carry their own sticky-column rules further up; here it is
       just the reading measure that needs to relax once the column is full width. */
    .legal-body {
        max-width: none;
    }
}

/* Small tablets / large phones */
@media (max-width: 767.98px) {
    :root {
        --section-y: clamp(3rem, 10vw, 4.5rem);
        --section-y-tight: clamp(2.25rem, 7vw, 3.25rem);
    }

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

    /* Portrait phones get a stacked column instead of the sliding line — a
       marquee that only shows one card at a time reads as a glitch. */
    .expert-slider {
        overflow: visible;
        padding-block: 0;
        margin-block: 0;
        -webkit-mask-image: none;
        mask-image: none;
    }

    /* minmax(0, 1fr), not 1fr: the nowrap tag chips give the cards a max-content
       min-size that would otherwise push the column past the viewport. */
    .expert-track,
    .expert-slider:not(.is-looping) .expert-track {
        display: grid;
        grid-template-columns: minmax(0, 1fr);
        gap: 1rem;
        width: auto;
        overflow: visible;
        animation: none;
        transform: none;
    }

    .expert-track > .expert-card {
        flex: none;
        margin-right: 0;
    }

    .expert-card.is-clone {
        display: none;
    }

    .filter-bar {
        gap: 0.5rem;
        flex-wrap: nowrap;
        overflow-x: auto;
        scrollbar-width: none;
        -ms-overflow-style: none;
        padding-bottom: 0.5rem;
        margin-left: calc(var(--gutter) * -1);
        margin-right: calc(var(--gutter) * -1);
        padding-left: var(--gutter);
        padding-right: var(--gutter);
    }

    .filter-bar::-webkit-scrollbar {
        display: none;
    }

    .search-field {
        max-width: 100%;
    }

    .job-card {
        flex-direction: column;
        align-items: flex-start;
    }

    .job-card .btn {
        width: 100%;
    }

    .hero-actions .btn,
    .cta-actions .btn {
        width: 100%;
    }

    .form-embed iframe {
        min-height: 900px;
    }

    /* Two across below the tablet breakpoint keeps the portraits legible while
       the roles still fit on one or two lines. */
    .team-grid > [class*="col-"] {
        width: 50%;
    }

    /* The section header and its trailing button stack here, so the button no
       longer needs to hold a corner — full width reads as the deliberate end of
       the block rather than a stray pill. */
    .section-head-split > .btn {
        width: 100%;
    }
}

/* Phones */
@media (max-width: 575.98px) {
    body {
        line-height: 1.65;
    }

    .brand img {
        width: 34px;
        height: 34px;
    }

    .brand {
        font-size: 1.05rem;
    }

    .hero-badge {
        position: static;
        max-width: 100%;
        margin-top: 1rem;
        box-shadow: var(--shadow-sm);
        border: 1px solid var(--line);
    }

    .hero-visual {
        box-shadow: var(--shadow);
    }

    .hero-stats {
        gap: 1.5rem 2rem;
    }

    .hero-stat {
        min-width: 40%;
    }

    .stat-band {
        grid-template-columns: repeat(2, 1fr);
    }

    .cta-band {
        border-radius: var(--radius);
    }

    .footer-bottom {
        text-align: center;
    }

    .footer-legal {
        justify-content: center;
    }

    /* Panels lose their outer inset on a phone: at 375px, 2.9rem of padding on
       both sides was eating a third of the reading width. */
    .about-panel,
    .contact-panel,
    .service-detail,
    .form-fallback {
        padding: var(--pad-md);
        border-radius: var(--radius);
    }

    /* A full-width portrait per row is too tall to scroll past; two keeps the
       whole team on roughly one screen. */
    .team-grid > [class*="col-"] {
        width: 50%;
    }

    .footer-social a {
        width: 42px;
        height: 42px;
    }
}

/* Very small phones (320px) */
@media (max-width: 359.98px) {
    :root {
        --gutter: 1rem;
    }

    .btn {
        padding: 0.85rem 1.25rem;
        font-size: 0.875rem;
    }

    .hero-eyebrow {
        font-size: 0.6875rem;
        letter-spacing: 0.1em;
    }

    /* At 320px a two-up team row leaves ~130px per portrait; one column is the
       honest answer. */
    .team-grid > [class*="col-"] {
        width: 100%;
    }

    .job-meta {
        gap: 0.35rem;
    }
}

/* Large desktops */
@media (min-width: 1600px) {
    .container {
        max-width: 1420px;
    }

    /* The extra 140px of container would otherwise go entirely into line length;
       stepping the body and lead sizes up keeps the measure comfortable. */
    body {
        font-size: 1.09375rem;
    }

    .section-head {
        max-width: 46rem;
    }
}

/* Print */
@media print {
    .site-header,
    .mobile-panel,
    .cta-band,
    .site-footer {
        display: none !important;
    }

    body {
        background: #fff;
    }
}
