:root {
    /* Triangle marker: one fixed size and gap everywhere. Previously 0.44em /
       0.58em, which meant four different sizes across the site because each
       host has a different font-size. */
    --tri-w: 7px;
    --tri-h: 9.25px;
    --tri-gap: 8px;
    /* How far a triangle-led row sits to the right of the body text. */
    --topic-indent: 24px;
}
/* ─── NeonLight Font ─────────────────────────────────── */
/* ── Self-hosted web fonts ─────────────────────────────────────────────────
   Space Grotesk, Syne and Material Symbols are served from this origin rather
   than fonts.gstatic.com. Loading them from Google would send every visitor's
   IP address to Google before they interact with anything, which a Munich
   court held in January 2022 to breach the GDPR when done without consent.
   Self-hosting removes the transfer entirely, and removes a render-blocking
   round trip to a third-party origin.

   Both text families ship as variable fonts, so one file covers the whole
   weight range. Licences: Space Grotesk and Syne are SIL Open Font License
   1.1, Material Symbols is Apache 2.0, and all three permit self-hosting. ── */
@font-face {
    font-family: 'Space Grotesk';
    font-style: normal;
    font-weight: 300 700;
    font-display: swap;
    src: url('fonts/web/space-grotesk-latin.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
    font-family: 'Space Grotesk';
    font-style: normal;
    font-weight: 300 700;
    font-display: swap;
    src: url('fonts/web/space-grotesk-latin-ext.woff2') format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
    font-family: 'Syne';
    font-style: normal;
    font-weight: 400 800;
    font-display: swap;
    src: url('fonts/web/syne-latin.woff2') format('woff2');
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
    font-family: 'Syne';
    font-style: normal;
    font-weight: 400 800;
    font-display: swap;
    src: url('fonts/web/syne-latin-ext.woff2') format('woff2');
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* The icon font is the subset built from the `icon_names` list this site uses,
   so it carries only those glyphs. `block` keeps the ligature name from
   flashing as text before the font arrives. */
@font-face {
    font-family: 'Material Symbols Outlined';
    font-style: normal;
    font-weight: 400;
    font-display: block;
    src: url('fonts/web/material-symbols-outlined.woff2') format('woff2');
}

@font-face { font-family: 'NeonLight'; src: url('fonts/NeonLight.otf') format('opentype'); font-weight: 400; font-display: swap; }

/* ─── Moldie Font ────────────────────────────────────── */
@font-face { font-family: 'Moldie'; src: url('fonts/Moldie Demo.otf') format('opentype'); font-weight: 400; font-display: swap; }

/* ─── Qurova Font ────────────────────────────────────── */
@font-face { font-family: 'Qurova'; src: url('fonts/QurovaDEMO-Light.otf') format('opentype'); font-weight: 300; font-display: swap; }
@font-face { font-family: 'Qurova'; src: url('fonts/QurovaDEMO-Regular.otf') format('opentype'); font-weight: 400; font-display: swap; }
@font-face { font-family: 'Qurova'; src: url('fonts/QurovaDEMO-Medium.otf') format('opentype'); font-weight: 500; font-display: swap; }
@font-face { font-family: 'Qurova'; src: url('fonts/QurovaDEMO-SemiBold.otf') format('opentype'); font-weight: 600; font-display: swap; }
@font-face { font-family: 'Qurova'; src: url('fonts/QurovaDEMO-Bold.otf') format('opentype'); font-weight: 700; font-display: swap; }

/* ─── ARP Fonts ──────────────────────────────────────── */
@font-face { font-family: 'ARP'; src: url('fonts/ARP-20.ttf');  font-weight: 200; font-display: swap; }
@font-face { font-family: 'ARP'; src: url('fonts/ARP-40.ttf');  font-weight: 400; font-display: swap; }
@font-face { font-family: 'ARP'; src: url('fonts/ARP-80.ttf');  font-weight: 600; font-display: swap; }
@font-face { font-family: 'ARP'; src: url('fonts/ARP-150.ttf'); font-weight: 700; font-display: swap; }
@font-face { font-family: 'ARP'; src: url('fonts/ARP-240.ttf'); font-weight: 900; font-display: swap; }

@font-face { font-family: 'ARPDisplay'; src: url('fonts/ARPDisplay-20.ttf');  font-weight: 200; font-display: swap; }
@font-face { font-family: 'ARPDisplay'; src: url('fonts/ARPDisplay-40.ttf');  font-weight: 400; font-display: swap; }
@font-face { font-family: 'ARPDisplay'; src: url('fonts/ARPDisplay-80.ttf');  font-weight: 600; font-display: swap; }
@font-face { font-family: 'ARPDisplay'; src: url('fonts/ARPDisplay-150.ttf'); font-weight: 700; font-display: swap; }
@font-face { font-family: 'ARPDisplay'; src: url('fonts/ARPDisplay-240.ttf'); font-weight: 900; font-display: swap; }

/* ─── Variables ─────────────────────────────────────── */
:root {
    --bg:         #0B5F72;
    --bg-deep:    #073D4D;
    --bg-card:    rgba(255,255,255,0.07);
    --bg-section: #0A5465;
    --accent-1:   #EEFF00;
    --accent-2:   #00C9AD;
    --accent-3:   #00C9AD;
    --accent-4:   #EEFF00;
    --text:       #FFFFFF;
    --text-muted: rgba(255,255,255,0.6);
    --border:     rgba(255,255,255,0.12);
    --font-main:  'Space Grotesk', sans-serif;
    --font-display: 'ARPDisplay', 'Syne', sans-serif;
    /* retired: labels now use --font-main at 600. Kept as an alias so any
       stray reference resolves to the DS sans rather than a system monospace. */
    --font-mono:  'Space Grotesk', sans-serif;
    --divider:   rgba(255,255,255,0.06); /* one hairline for every rule on the site */
    --radius:     14px;
    --transition: 0.28s ease;
    /* One hover for every text link on the site: the dark green over light
       grounds, the bright green over dark ones, both with an underline. */
    --link-hover:      #007C67;
    --link-hover-dark: #46E250;
}

/* ─── Reset ─────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html { scroll-behavior: smooth; background: #131E25; overflow-x: clip; }
body {
    background: linear-gradient(145deg, #0D6878 0%, #094E60 50%, #073D4D 100%);
    background-attachment: fixed;
    color: var(--text);
    font-family: var(--font-main);
    line-height: 1.6;
    /* No overflow here. Clipping horizontal overflow on <body> makes it a
       scroll container, which silently disables position: sticky for every
       descendant: `hidden` does it outright, and `clip` does it too, because
       with overflow-y left visible the browser computes that axis to `auto`.
       The clip lives on <html> instead, where the scroll box is the viewport
       and sticky still works. */
    -webkit-font-smoothing: antialiased;
}

/* ─── Fade-in ────────────────────────────────────────── */
.fade-in {
    opacity: 0;
    transform: translateY(22px);
    transition: opacity 0.6s ease, transform 0.6s ease;
}
.fade-in.visible {
    opacity: 1;
    transform: translateY(0);
}

/* ─── Global grain texture ───────────────────────────── */
body::after {
    /* Global grain removed: it sat over the light sections (and their components) as static
       noise. Dark sections keep their own grain (.hero-grain, .about-grain, footer). */
    display: none;
    content: '';
    position: fixed;
    inset: -50%;
    width: 200%;
    height: 200%;
    z-index: 9998;
    pointer-events: none;
    opacity: 0.055;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='300' height='300'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.72' numOctaves='4' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='300' height='300' filter='url(%23g)'/%3E%3C/svg%3E");
    background-size: 180px 180px;
    animation: grainShift 0.5s steps(3) infinite;
}

/* ─── Navigation ─────────────────────────────────────── */
/* ── One card hover, everywhere ────────────────────────────────────────────
   Copied from the "This is how I deliver growth" cards (#work .case-card-v2):
   a 7px lift, the shadow grown, and a 1px teal ring laid in the box-shadow.
   The ring is the colour you see on hover; the border-box edge underneath it
   is almost invisible, which is why recolouring that edge changed nothing. ── */
#navbar {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: space-between;
    /* 24px from each edge of the page, the same inset the article's chapter
       list carries, so the two line up */
    padding: 0.6rem 24px;
    z-index: 100;
    background: transparent;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    border: none;
    border-radius: 0;
    box-shadow: none;
    transition: background 0.4s ease, box-shadow 0.4s ease, backdrop-filter 0.4s ease;
}

/* After scrolling */
#navbar.nav-light {
    background: rgba(255,255,255,0.06);
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
    border-bottom: 1px solid rgba(255,255,255,0.1);
    box-shadow: 0 4px 24px rgba(0,0,0,0.2);
}
/* Over light sections (How I deliver, contact, etc.), dark text + yellow bars */
#navbar.nav-light .nav-links a,
#navbar.nav-light .nav-logo-name,
#navbar.nav-light .nav-logo-title,
#navbar.nav-light .currently-nav-btn,
#navbar.nav-light .nav-contact,
#navbar.nav-light .nav-right a {
    color: #073D4D;
}
#navbar.nav-light .currently-nav::before {
    color: #007A68;
}
/* Over a light section the bright #46E250 marker blows out. Same rule as
   everywhere else on the site: #46E250 over dark, #007A68 over light. */
#navbar.nav-light .currently-nav::before { background-color: #007A68; }
#navbar.nav-light.nav-over-dark .currently-nav::before { background-color: #46E250; }
/* Pills carry their own hover (lift plus background), so they take the colour
   without the underline that text links get. */
@media (hover: hover) {
#navbar.nav-light .nav-links a:hover,
#navbar.nav-light .nav-right a:hover,
#navbar.nav-light .currently-nav-btn:hover {
    color: var(--link-hover);
}
}

/* Over dark sections (hero, born global), white text + yellow bars */
#navbar.nav-light.nav-over-dark .nav-links a,
#navbar.nav-light.nav-over-dark .nav-logo-name,
#navbar.nav-light.nav-over-dark .nav-logo-title,
#navbar.nav-light.nav-over-dark .currently-nav-btn,
#navbar.nav-light.nav-over-dark .nav-contact,
#navbar.nav-light.nav-over-dark .nav-right a {
    color: #ffffff;
}
#navbar.nav-light.nav-over-dark .currently-nav::before {
    color: #EEFF00;
}
@media (hover: hover) {
#navbar.nav-light.nav-over-dark .nav-links a:hover,
#navbar.nav-light.nav-over-dark .nav-right a:hover,
#navbar.nav-light.nav-over-dark .currently-nav-btn:hover {
    color: var(--accent-1);
}
}


.nav-logo {
    text-decoration: none;
    color: #fff;
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    display: flex;
    flex-direction: column;
    align-items: center;
    line-height: 1.25;
}
.nav-logo-name {
    font-family: var(--font-display);
    font-size: 1.05rem;
    font-weight: 700;
    color: #fff;
    white-space: nowrap;
}
.nav-logo-img {
    display: block;
    height: 16.5px;   /* +10% */
    width: 264px;     /* +10% */
    background-color: #fff; /* recolorable: the wordmark is a mask, so it follows the nav text colours */
    -webkit-mask: url("thales-wordmark.svg") no-repeat center / contain;
    mask: url("thales-wordmark.svg") no-repeat center / contain;
    transition: background-color 0.4s ease;
}
#navbar.nav-light .nav-logo-img { background-color: #073D4D; }
#navbar.nav-light.nav-over-dark .nav-logo-img { background-color: #ffffff; }
/* The burger is a mask like the wordmark, so it takes the wordmark's colour
   states verbatim: #navbar's own `color` stays white in every state, so
   currentColor left the icon white over the light sections. */
#navbar.nav-light .nav-burger-icon { background-color: #073D4D; }
#navbar.nav-light.nav-over-dark .nav-burger-icon { background-color: #ffffff; }
.nav-logo-title {
    font-family: var(--font-display);
    font-size: 0.68rem;
    font-weight: 600;
    color: rgba(255,255,255,0.7);
    letter-spacing: 0.05em;
    white-space: nowrap;
}

.nav-links {
    list-style: none;
    display: flex;
    gap: 0.6rem;
}
.nav-links a {
    text-decoration: none;
    font-family: var(--font-main);
    font-size: 0.972rem;
    font-weight: 500;
    letter-spacing: 0.01em;
    text-transform: none;
    color: #ffffff;
    transition: color var(--transition);
}
/* Home and Cases carry a Material icon where the triangle marker used to be.
   The dropdown items keep no marker (.nav-cases-menu a::before is none). */
/* Each tab is a pill with the same geometry as the LinkedIn button: identical
   font-size, weight, padding and radius. The 1px outline is an inset shadow so
   it adds no height, keeping the pills exactly as tall as .nav-cta. */
.nav-links > li > a,
.nav-contact,
.nav-cta {
    display: inline-flex;
    align-items: center;
    gap: var(--tri-gap);
    font-size: 0.82rem;
    font-weight: 600;
    letter-spacing: normal;
    padding: 0.5rem 1.5rem;
    border: none;
    border-radius: 100px;
    background: rgba(255,255,255,0.05);
    /* Same three-layer chrome as .nav-cta (top highlight, bottom shade, drop
       shadow) plus a hairline stroke, all at much lower opacity. */
    box-shadow: inset 0 1px 0 rgba(255,255,255,0.16),
                inset 0 -2px 0 rgba(0,0,0,0.10),
                inset 0 0 0 1px rgba(255,255,255,0.07),
                0 4px 12px rgba(0,0,0,0.12);
    transition: transform 0.2s ease, background 0.2s ease, box-shadow 0.2s ease, color 0.2s ease;
}
@media (hover: hover) {
.nav-links > li > a:hover,
.nav-contact:hover,
.nav-cta:hover {
    background: rgba(255,255,255,0.10);
    transform: translateY(-2px);
    box-shadow: inset 0 1px 0 rgba(255,255,255,0.22),
                inset 0 -2px 0 rgba(0,0,0,0.10),
                inset 0 0 0 1px rgba(255,255,255,0.10),
                0 8px 20px rgba(0,0,0,0.15);
}
}
/* Over light sections the translucent white would vanish. */
#navbar.nav-light .nav-links > li > a,
#navbar.nav-light .nav-contact,
#navbar.nav-light .nav-cta {
    background: rgba(7,61,77,0.045);
    box-shadow: inset 0 1px 0 rgba(255,255,255,0.5),
                inset 0 -2px 0 rgba(7,61,77,0.07),
                inset 0 0 0 1px rgba(7,61,77,0.07),
                0 4px 12px rgba(7,61,77,0.08);
}
#navbar.nav-light.nav-over-dark .nav-links > li > a,
#navbar.nav-light.nav-over-dark .nav-contact,
#navbar.nav-light.nav-over-dark .nav-cta {
    background: rgba(255,255,255,0.05);
    box-shadow: inset 0 1px 0 rgba(255,255,255,0.16),
                inset 0 -2px 0 rgba(0,0,0,0.10),
                inset 0 0 0 1px rgba(255,255,255,0.07),
                0 4px 12px rgba(0,0,0,0.12);
}
/* The Material icon leads the pill and follows the link colour, so it is white
   on the dark bar and dark navy over light sections. */
.nav-link-icon {
    font-size: 17px;
    color: inherit;
}
@media (hover: hover) {
.nav-links a:hover { color: var(--accent-1); }
}

.nav-right {
    display: flex;
    align-items: center;
    gap: 0.6rem;
}

/* LinkedIn: small secondary button (white pill, dark text, yellow on hover) */
.nav-cta {
    display: inline-flex;
    align-items: center;
    /* the shared --tri-gap, so the marker and the mark sit exactly as they do
       in the Home, UX Cases and Contact pills */
    gap: var(--tri-gap);
    text-decoration: none;
    font-family: var(--font-main);
    font-size: 0.82rem;
    font-weight: 600;
    letter-spacing: normal;
    text-transform: none;
    color: #ffffff;
}
.nav-cta svg { flex-shrink: 0; }
/* keep the button's dark text in every nav state, including hover
   (higher specificity than the .nav-right a:hover colour rules) */
#navbar.nav-light .nav-right a.nav-cta { color: #073D4D; }
#navbar.nav-light.nav-over-dark .nav-right a.nav-cta { color: #ffffff; }

/* ── One hover for every pill in the bar ────────────────────────────────────
   Colour follows the ground the pill sits on: the bright green over dark, the
   dark green over light, the same pair the rest of the site uses. The
   selectors are weighted past the .nav-cta colour pins directly above, which
   otherwise froze LinkedIn's colour and left it the only pill in the bar that
   did not respond to hover. ── */
@media (hover: hover) {
#navbar .nav-links > li > a:hover,
#navbar .nav-contact:hover,
#navbar .currently-nav-btn:hover,
#navbar .nav-right a.nav-cta:hover,
#navbar.nav-light.nav-over-dark .nav-right a.nav-cta:hover {
    color: var(--link-hover-dark);
}
}
@media (hover: hover) {
#navbar.nav-light:not(.nav-over-dark) .nav-links > li > a:hover,
#navbar.nav-light:not(.nav-over-dark) .nav-contact:hover,
#navbar.nav-light:not(.nav-over-dark) .currently-nav-btn:hover,
#navbar.nav-light:not(.nav-over-dark) .nav-right a.nav-cta:hover {
    color: var(--link-hover);
}
}

/* Unified arrow/caret icon weight: every nav-chrome arrow follows the text colour
   (currentColor) at the same 2.2 stroke as the "open in new tab" external-link icons. */
.currently-nav-caret svg,
.nav-cta svg { stroke-width: 2.2; }

/* ─── Cases dropdown (hover) ─────────────────────────── */
.nav-cases { position: relative; }
.nav-cases-trigger { display: inline-flex; align-items: center; gap: 0.3rem; }
/* The leading triangle doubles as the dropdown affordance: it points right at
   rest and turns up while the menu is open. */
/* Dropdown affordance: a Material chevron that flips up while the menu is
   open. It replaces the leading triangle the trigger used to rotate. */
.nav-cases-caret {
    font-size: 17px;
    line-height: 1;
    margin-left: -2px;
    color: inherit;
    transition: transform 0.2s ease;
}
.nav-cases:focus-within .nav-cases-caret { transform: rotate(180deg); }
@media (hover: hover) {
.nav-cases:hover .nav-cases-caret { transform: rotate(180deg); }
}
.nav-cases::after { /* transparent bridge so the menu stays open across the gap */
    content: '';
    position: absolute;
    top: 100%; left: 0; right: 0;
    height: 0.9rem;
}
.nav-cases-menu {
    display: none;
    position: absolute;
    top: calc(100% + 0.9rem);
    left: 0;
    background: rgba(7,18,24,0.92);
    backdrop-filter: blur(20px);
    -webkit-backdrop-filter: blur(20px);
    border: 1px solid rgba(255,255,255,0.12);
    border-radius: 14px;
    overflow: hidden;
    box-shadow: 0 16px 48px rgba(0,0,0,0.4);
    min-width: 210px;
    z-index: 200;
    padding: 0.4rem 0;
}
.nav-cases:focus-within .nav-cases-menu { display: block; }
@media (hover: hover) {
.nav-cases:hover .nav-cases-menu { display: block; }
}
.nav-cases-menu a {
    display: block;
    padding: 0.6rem 1.2rem;
    font-family: var(--font-main);
    font-size: 0.85rem;
    font-weight: 600;
    letter-spacing: normal;
    text-transform: none;
    color: rgba(255,255,255,0.72) !important;
    text-decoration: none;
    transition: color var(--transition), background var(--transition);
}
.nav-cases-menu a::before { content: none !important; }
/* Single-line labels, ellipsis when too long */
.nav-cases-menu a {
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 260px;
}
/* DS divider between cases and papers */
.nav-cases-sep {
    display: block;
    height: 1px;
    margin: 0.4rem 0;
    background: rgba(255,255,255,0.06);
}
@media (hover: hover) {
.nav-cases-menu a:hover { color: var(--link-hover-dark) !important; background: rgba(255,255,255,0.06); }
}

/* Contact: nav-style link in the right-hand cluster, next to LinkedIn.
   Geometry, size and weight come from the shared pill rule above; this only
   adds what is specific to Contact. */
.nav-contact {
    text-decoration: none;
    font-family: var(--font-main);
    text-transform: none;
    color: #ffffff;
}
@media (hover: hover) {
.nav-contact:hover { color: var(--accent-1); }
}

/* ─── Currently nav dropdown ────────────────────────── */
.currently-nav {
    position: relative;
}
.currently-nav::before {
    content: ''; display: inline-block; width: var(--tri-w); height: var(--tri-h); vertical-align: 0.04em; -webkit-mask: url("triangle-right.svg") no-repeat center / contain; mask: url("triangle-right.svg") no-repeat center / contain; margin-right: var(--tri-gap);
    background-color: #46E250;
    font-family: var(--font-main);
    font-size: 0.972rem;
    font-weight: 500;
    letter-spacing: 0.01em; opacity: 0.5;}
.currently-nav-btn {
    font-family: var(--font-main);
    font-size: 0.972rem;
    font-weight: 500;
    letter-spacing: 0.01em;
    text-transform: none;
    color: #ffffff;
    background: transparent;
    border: none;
    cursor: pointer;
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    transition: color var(--transition);
    padding: 0;
}
@media (hover: hover) {
.currently-nav-btn:hover { color: var(--accent-1); }
}
.currently-nav-caret {
    display: inline-flex;
    align-items: center;
    transition: transform 0.2s ease;
}
.currently-nav.open .currently-nav-caret { transform: rotate(180deg); }
.currently-dropdown {
    display: none;
    position: absolute;
    top: calc(100% + 0.85rem);
    right: 0;
    background: rgba(7,18,24,0.92);
    backdrop-filter: blur(20px);
    -webkit-backdrop-filter: blur(20px);
    border: 1px solid rgba(255,255,255,0.12);
    border-radius: 14px;
    overflow: hidden;
    box-shadow: 0 16px 48px rgba(0,0,0,0.4);
    min-width: 220px;
    z-index: 200;
    padding: 0.5rem 0;
}
.currently-nav.open .currently-dropdown { display: block; }
.currently-drop-item {
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    padding: 0.75rem 1.1rem;
    transition: background 0.2s ease;
}
@media (hover: hover) {
.currently-drop-item:hover { background: rgba(255,255,255,0.05); }
}
.currently-drop-cat {
    font-family: var(--font-main); font-weight: 500;
    font-size: 0.8rem;
    letter-spacing: 0.01em;
    text-transform: none;
    color: #00C9AD;
}
.currently-drop-title {
    font-family: var(--font-main);
    font-size: 0.88rem;
    font-weight: 600;
    color: #ffffff;
}
.currently-drop-sub {
    font-family: var(--font-main); font-weight: 600;
    font-size: 0.65rem;
    color: rgba(255,255,255,0.4);
}
.currently-drop-divider {
    height: 1px;
    background: var(--divider);
    margin: 0.1rem 0;
}

/* ─── Hero ───────────────────────────────────────────── */
#hero {
    position: relative;
    overflow: clip;
    display: flex;
    flex-direction: column;
    padding: 1.75rem 0 0;
    z-index: 2;
}


/* Decorative SVG behind hero */
.hero-bg-svg {
    position: absolute;
    top: 0;
    left: 50%;
    transform: translateX(-50%);
    height: 100vh;
    width: 90%;
    max-width: 1000px;
    z-index: 2;
    pointer-events: none;
    user-select: none;
    opacity: 0.15;
    -webkit-mask-image: radial-gradient(ellipse 70% 60% at 50% 50%, black 30%, transparent 100%);
    mask-image: radial-gradient(ellipse 70% 60% at 50% 50%, black 30%, transparent 100%);
    animation: vectorDrift 28s ease-in-out infinite;
}
/* Kanji watermark drifting in the FOOTER, same treatment as the hero's moving watermark */
footer .footer-kanji {
    position: absolute;
    top: 0;
    left: 50%;
    transform: translate(-50%, 0);
    width: 85%;
    max-width: 1400px;
    height: auto;
    z-index: 1;
    opacity: 0.15;
    pointer-events: none;
    user-select: none;
    -webkit-mask-image: linear-gradient(to bottom, transparent 0%, black 32%);
    mask-image: linear-gradient(to bottom, transparent 0%, black 32%);
    animation: kanjiDrift 28s ease-in-out infinite;
}

@keyframes vectorDrift {
    0%   { transform: translateX(-50%) translate(0px, 0px); }
    20%  { transform: translateX(-50%) translate(12px, -10px); }
    40%  { transform: translateX(-50%) translate(-8px, 14px); }
    60%  { transform: translateX(-50%) translate(14px, 8px); }
    80%  { transform: translateX(-50%) translate(-10px, -12px); }
    100% { transform: translateX(-50%) translate(0px, 0px); }
}
/* same drift, but keeps both-axis centering for the footer kanji */
@keyframes kanjiDrift {
    0%   { transform: translate(-50%, 0) translate(0px, 0px); }
    20%  { transform: translate(-50%, 0) translate(12px, -10px); }
    40%  { transform: translate(-50%, 0) translate(-8px, 14px); }
    60%  { transform: translate(-50%, 0) translate(14px, 8px); }
    80%  { transform: translate(-50%, 0) translate(-10px, -12px); }
    100% { transform: translate(-50%, 0) translate(0px, 0px); }
}

.hero-video-wrap {
    position: absolute;
    inset: 0;
    z-index: 0;
    overflow: hidden;
}

/* Base, pure white behind video */
.hero-gradient-base {
    position: absolute;
    inset: 0;
    background: #ffffff;
    z-index: 0;
}

/* Hero video, full cover over gradient */
.hero-video {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    min-width: 100%;
    min-height: 100%;
    width: auto;
    height: auto;
    object-fit: cover;
    opacity: 1;
    pointer-events: none;
    z-index: 1;
}

/* Overlay, dark fade top to bottom */
.hero-overlay {
    position: absolute;
    inset: 0;
    background: linear-gradient(to bottom, rgba(11,34,41,1.0) 0%, rgba(11,34,41,0.87) 100%);
    z-index: 2;
}

/* Psychedelic color blobs */
#hero::before, #hero::after {
    content: '';
    position: absolute;
    border-radius: 50%;
    filter: blur(110px);
    pointer-events: none;
}
#hero::before {
    width: 700px; height: 700px;
    background: radial-gradient(circle, #00C9AD 0%, transparent 70%);
    top: -180px; left: -200px;
    opacity: 0.4;
    z-index: 1;
    animation: blobFloat1 10s ease-in-out infinite;
}
#hero::after {
    display: none; /* yellow glow is now centred on the portrait disc only */
    width: 500px; height: 500px;
    background: radial-gradient(circle, #EEFF00 0%, transparent 70%);
    bottom: 100px; right: -150px;
    opacity: 0.25;
    z-index: 1;
    animation: blobFloat2 12s ease-in-out infinite;
}
.hero-blob-orange {
    display: none; /* yellow glow is now centred on the portrait disc only */
    position: absolute;
    width: 400px; height: 400px;
    border-radius: 50%;
    background: radial-gradient(circle, #EEFF00 0%, transparent 70%);
    bottom: 200px; left: 10%;
    opacity: 0.30;
    filter: blur(100px);
    pointer-events: none;
    z-index: 1;
    animation: blobFloat3 14s ease-in-out infinite;
}
@keyframes blobFloat1 {
    0%, 100% { transform: translate(0,0) scale(1); }
    50%       { transform: translate(40px, 50px) scale(1.08); }
}
@keyframes blobFloat2 {
    0%, 100% { transform: translate(0,0) scale(1); }
    50%       { transform: translate(-35px, -30px) scale(1.1); }
}
@keyframes blobFloat3 {
    0%, 100% { transform: translate(0,0) scale(1); }
    50%       { transform: translate(25px, -40px) scale(1.12); }
}

/* Dot grid texture */
.hero-texture {
    position: absolute;
    inset: 0;
    z-index: 3;
    pointer-events: none;
    opacity: 0.07;
    background-image: radial-gradient(circle, rgba(255,255,255,0.9) 1px, transparent 1px);
    background-size: 22px 22px;
}

/* Film grain overlay */
.hero-grain {
    position: absolute;
    inset: 0; /* confined to its own (dark) section, must not bleed into adjacent light sections */
    z-index: 3;
    pointer-events: none;
    opacity: 0.13;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='300' height='300'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='300' height='300' filter='url(%23n)'/%3E%3C/svg%3E");
    background-size: 200px 200px;
    animation: grainShift 0.4s steps(2) infinite;
}
/* Jitter the grain via background-position (tile repeats, so no edge gaps), lets the grain
   layer be inset:0 (confined to its section) instead of an oversized translate that overflows. */
@keyframes grainShift {
    0%   { background-position: 0 0; }
    25%  { background-position: -8px -6px; }
    50%  { background-position: 8px 8px; }
    75%  { background-position: -6px 8px; }
    100% { background-position: 8px -8px; }
}

.hero-content {
    position: relative;
    z-index: 4;
    text-align: center;
    padding: max(88px, 7vh) 3.5rem 8rem 3.5rem;
    color: #fff;
    max-width: 860px;
    margin: 0 auto;
}

.hero-tag {
    display: inline-flex;
    align-items: center;
    gap: 0.6rem;
    font-family: var(--font-main); font-weight: 500;
    font-size: 0.972rem;
    color: rgba(255,255,255,0.8);
    border: 1px solid rgba(255,255,255,0.2);
    padding: 0.38rem 1rem;
    border-radius: 100px;
    margin-bottom: 1.75rem;
    letter-spacing: 0.01em;
    backdrop-filter: blur(8px);
    background: rgba(255,255,255,0.05);
}
.tag-dot {
    width: 6px; height: 6px;
    border-radius: 50%;
    background: var(--accent-4);
    animation: tagPulse 2s ease-in-out infinite;
}
@keyframes tagPulse {
    0%, 100% { opacity: 1; transform: scale(1); }
    50%       { opacity: 0.4; transform: scale(0.75); }
}

/* Domain tags */
.hero-domains {
    display: none;
    flex-wrap: wrap;
    justify-content: center;
    gap: 0.5rem;
    margin-bottom: 2rem;
    opacity: 0;
    animation: wordReveal 0.7s cubic-bezier(0.16, 1, 0.3, 1) forwards;
    animation-delay: 0.65s;
}
.domain-tag {
    font-family: var(--font-main); font-weight: 500;
    font-size: 0.918rem;
    letter-spacing: 0.01em;
    text-transform: none;
    padding: 0.32rem 0.85rem;
    border-radius: 100px;
    border: 1px solid rgba(255,255,255,0.175);
    color: rgba(255,255,255,0.9);
    background: rgba(255,255,255,0.08);
    backdrop-filter: blur(6px);
    white-space: nowrap;
    cursor: default;
    transition: color 0.28s ease, background 0.28s ease, border-color 0.28s ease, transform 0.28s cubic-bezier(0.16,1,0.3,1), box-shadow 0.28s ease;
}
.domain-tag.tag-active {
    color: #073D4D;
    background: var(--accent-1);
    border-color: var(--accent-1);
    transform: translateY(-3px) scale(1.05);
    box-shadow: 0 6px 24px rgba(238,255,0,0.3);
}
@media (hover: hover) {
.domain-tag:hover {
    color: #073D4D;
    background: var(--accent-1);
    border-color: var(--accent-1);
    transform: translateY(-3px) scale(1.05);
    box-shadow: 0 6px 24px rgba(238,255,0,0.3);
}
}

/* Photo circle */
.hero-photo {
    width: clamp(179.1px, 18.15vw, 225.1px);   /* +10%, twice over the original 186px */
    aspect-ratio: 1 / 1;
    /* The top margin clears the halo rings, which overflow this box by 6%. */
    margin: 2rem auto 2.5rem auto;
    position: relative;
    overflow: visible;
}
/* Two low-opacity halo circles BEHIND the portrait's green disc, same
   proportions as the About card (104.2% and 109.1% of the disc).
   The frame is square with the circle dead centre, measured from its widest
   chord rather than its first visible row, because the hair overlaps the top
   of the circle and would otherwise drag the computed centre downwards. */
.hero-photo::before,
.hero-photo::after {
    content: '';
    position: absolute;
    /* The green disc in thales-hero.webp is centred at 50.00% / 51.33% of the
       image box (measured by circle fit on the disc edge), with a diameter of
       87.66%. The rings are concentric with that disc, not with the box. */
    left: 50%;
    top: 51.33%;
    aspect-ratio: 1;
    border-radius: 50%;
    z-index: 0;
    pointer-events: none;
    will-change: transform;
}
.hero-photo::before {
    width: 112%;
    background: rgba(70, 226, 80, 0.09);
    animation: heroHaloPulse 7s ease-in-out infinite;
}
.hero-photo::after {
    width: 99%;
    background: rgba(70, 226, 80, 0.17);
    animation: heroHaloPulse 7s ease-in-out infinite;
    animation-delay: -2.4s;
}
@keyframes heroHaloPulse {
    0%, 100% { transform: translate(-50%, -50%) scale(1); }
    50%      { transform: translate(-50%, -50%) scale(1.055); }
}
@media (prefers-reduced-motion: reduce) {
    .hero-photo::before,
    .hero-photo::after {
        animation: none;
        transform: translate(-50%, -50%);
    }
    .hero-photo img { animation: none; transform: none; }
}
.hero-photo img {
    position: relative;
    z-index: 1;
    width: 100%;
    height: 100%;
    object-fit: contain;
    display: block;
    /* 9.5s against the rings' 7s, so the two drift in and out of phase instead
       of breathing together. */
    animation: heroPhotoPulse 9.5s ease-in-out infinite;
    will-change: transform;
}
@keyframes heroPhotoPulse {
    0%, 100% { transform: scale(1); }
    50%      { transform: scale(1.03); }
}
.hero-photo-fallback {
    display: none;
    width: 100%;
    height: 100%;
    background: linear-gradient(135deg, var(--accent-1), var(--accent-2));
    align-items: center;
    justify-content: center;
    font-family: var(--font-main);
    font-size: 1.4rem;
    font-weight: 700;
    color: #fff;
    letter-spacing: 0.05em;
}

.hero-name {
    font-family: var(--font-main); font-weight: 500;
    font-size: clamp(0.7rem, 1.1vw, 0.85rem);
    text-transform: none;
    letter-spacing: 0.01em;
    color: rgba(255,255,255,0.85);
    margin-bottom: 1.25rem;
    text-align: center;
    line-height: 1.9;
}
.hero-name-main {
    font-weight: 400;
}
.hero-name-title {
    font-weight: 600;
}

.hero-title {
    font-family: var(--font-display);
    font-size: clamp(2.1rem, 6vw, 3.6rem);
    font-weight: 700;
    line-height: 1.25;
    letter-spacing: -0.02em;
    margin-bottom: 0.3rem;
    color: #fff;
    overflow: visible;
    animation: heroTitleFloat 7s ease-in-out infinite;
}
@keyframes heroTitleFloat {
    0%, 100% { transform: translateY(0px); }
    50%       { transform: translateY(-12px); }
}

.hero-title-fixed {
    display: block;
    font-family: var(--font-display);
    font-weight: 700;
    line-height: 1.2;
    margin-top: -0.45em;
    padding: 0.5em 0.3em 0.6em;
    overflow: visible;
    background: linear-gradient(90deg, #EEFF00 0%, #00C9AD 100%);
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-clip: text;
    filter:
        drop-shadow(0 -1px 0 rgba(255,255,255,0.5))
        drop-shadow(-1px 0 0 rgba(238,255,0,0.7))
        drop-shadow( 1px 0 0 rgba(238,255,0,0.7))
        drop-shadow(0  2px 0 rgba(238,255,0,0.6))
        drop-shadow(0 0 16px rgba(238,255,0,0.65))
        drop-shadow(0 0 40px rgba(238,255,0,0.3));
}
.hero-title-line {
    display: flex;
    justify-content: center;
    clip-path: inset(-1.5em -9999px);
    padding: 0.15em 0;
}

/* Animated title, initial load + cycling */
#animatedTitle {
    display: block;
    font-family: var(--font-display);
    font-weight: 700;
    color: #fff;
    white-space: nowrap;
    text-align: center;
    text-shadow:
        0 -1px 0 rgba(255,255,255,0.9),
        -1px 0 0 rgba(255,255,255,0.55),
         1px 0 0 rgba(255,255,255,0.55),
         0 2px 0 rgba(0,0,0,0.12),
         0 0 22px rgba(255,255,255,0.22),
         0 0 55px rgba(255,255,255,0.1);
    opacity: 0;
    transform: translateY(52px);
    animation: titleIn 0.75s cubic-bezier(0.16, 1, 0.3, 1) 0.12s forwards;
}
#animatedTitle.anim-out {
    animation: titleOut 0.5s cubic-bezier(0.4, 0, 1, 1) forwards;
}
#animatedTitle.anim-in {
    animation: titleIn 0.85s cubic-bezier(0.16, 1, 0.3, 1) forwards;
}
/* Same motion, but transform/opacity only. The glow on .about-title em lives in
   `filter`, so these keyframes must not touch it or it would blink off for the
   length of the animation and snap back afterwards. */
.anim-word.anim-out {
    animation: wordOut 0.5s cubic-bezier(0.4, 0, 1, 1) forwards;
}
.anim-word.anim-in {
    animation: wordIn 0.85s cubic-bezier(0.16, 1, 0.3, 1) forwards;
}
@keyframes wordOut {
    0%   { transform: translateY(0) scale(1);        opacity: 1; }
    100% { transform: translateY(-18px) scale(0.88); opacity: 0; }
}
@keyframes wordIn {
    0%   { transform: translateY(24px) scale(0.92);  opacity: 0; }
    100% { transform: translateY(0) scale(1);        opacity: 1; }
}
@keyframes titleOut {
    0%   { transform: translateY(0) scale(1);     opacity: 1; filter: blur(0px); }
    100% { transform: translateY(-18px) scale(0.88); opacity: 0; filter: blur(10px); }
}
@keyframes titleIn {
    0%   { transform: translateY(24px) scale(0.92); opacity: 0; filter: blur(10px); }
    100% { transform: translateY(0) scale(1);        opacity: 1; filter: blur(0px); }
}

/* per-word slide-up reveal (for "through design.") */
.hero-word {
    display: inline-block;
    opacity: 0;
    transform: translateY(48px);
    animation: wordReveal 0.75s cubic-bezier(0.16, 1, 0.3, 1) forwards;
    animation-delay: calc(0.12s + var(--d) * 0.13s);
}
@keyframes wordReveal {
    to {
        opacity: 1;
        transform: translateY(0);
    }
}

.hero-subtitle {
    font-size: clamp(0.95rem, 1.8vw, 1.1rem);
    color: rgba(255,255,255,0.6);
    max-width: 500px;
    margin: 0 0 2.75rem 0;
    line-height: 1.8;
    font-weight: 400;
}

.hero-actions {
    display: flex;
    gap: 0.9rem;
    justify-content: center;
    flex-wrap: wrap;
}

/* ─── Buttons ────────────────────────────────────────── */
.btn {
    padding: 0.8rem 1.9rem;
    border-radius: 100px;
    font-family: var(--font-main);
    font-size: 0.92rem;
    font-weight: 600;
    text-decoration: none;
    cursor: pointer;
    display: inline-block;
    border: none;
    transition: transform 0.2s ease, box-shadow 0.2s ease,
                background 0.2s ease, border-color 0.2s ease, color 0.2s ease;
}
.btn-sm { padding: 0.55rem 1.2rem; font-size: 0.83rem; }

.btn-primary {
    background: var(--accent-1);
    color: #073D4D;
    font-weight: 700;
    box-shadow: inset 0 1px 0 rgba(255,255,255,0.4), inset 0 -2px 0 rgba(0,0,0,0.15), 0 4px 12px rgba(238,255,0,0.25);
}
.btn-cv {
    font-family: var(--font-main);
    font-size: 0.92rem;
    font-weight: 600;
    text-transform: none;
    letter-spacing: normal;
    padding: 1rem 2.2rem;
}
@media (hover: hover) {
.btn-primary:hover {
    transform: translateY(-2px);
    box-shadow: inset 0 1px 0 rgba(255,255,255,0.4), inset 0 -2px 0 rgba(0,0,0,0.15), 0 12px 30px rgba(238,255,0,0.4);
    background: #f5ff33;
}
}

/* ── Primary over a light section ──────────────────────────────────────────
   The yellow is the accent for the dark ground; over the light body it has no
   contrast to work with and reads as a highlighter. The light-theme primary is
   the DS teal with white lettering, the same one the contact form and the case
   cards already carry, so this states it once for every light section rather
   than per page. ── */
.cs-light-body .btn-primary {
    background: #0B5F72;
    color: #ffffff;
    box-shadow: inset 0 1px 0 rgba(255,255,255,0.18), inset 0 -2px 0 rgba(0,0,0,0.18), 0 4px 14px rgba(11,95,114,0.32);
}
@media (hover: hover) {
.cs-light-body .btn-primary:hover {
    background: #0d7088;
    box-shadow: inset 0 1px 0 rgba(255,255,255,0.18), inset 0 -2px 0 rgba(0,0,0,0.18), 0 12px 30px rgba(11,95,114,0.45);
}
}

/* Ghost button, secondary, matches CV button format */
.btn-ghost {
    font-family: var(--font-main);
    font-size: 0.92rem;
    font-weight: 600;
    text-transform: none;
    letter-spacing: normal;
    padding: 1rem 2.2rem;
    background: #ffffff;
    color: #073D4D;
    border: none;
    box-shadow: inset 0 1px 0 rgba(255,255,255,0.8), inset 0 -2px 0 rgba(0,0,0,0.08), 0 4px 12px rgba(0,0,0,0.12);
}
@media (hover: hover) {
.btn-ghost:hover {
    background: #f0f0f0;
    transform: translateY(-2px);
    box-shadow: inset 0 1px 0 rgba(255,255,255,0.8), inset 0 -2px 0 rgba(0,0,0,0.08), 0 8px 20px rgba(0,0,0,0.15);
}
}

/* Outline button, for light sections */
.btn-outline {
    background: transparent;
    color: var(--text);
    border: 1.5px solid var(--border);
}
@media (hover: hover) {
.btn-outline:hover {
    border-color: var(--accent-1);
    color: var(--accent-1);
}
}


/* ─── Section Shared ─────────────────────────────────── */
section { padding: 8rem 0; }
.container { max-width: 1180px; margin: 0 auto; padding: 0 3.5rem; }

.section-label {
    font-family: var(--font-main); font-weight: 500;
    font-size: 1.0rem;
    color: var(--accent-1);
    letter-spacing: 0.01em;
    text-transform: none;
    margin-bottom: 0.85rem;
}
/* The separator in a hero eyebrow: the glyph is narrow and the plain spaces
   either side of it read as too tight at this size. */
.ds-dot { margin: 0 0.5em; }
.hero-eyebrow {
    color: #ffffff;
    margin-bottom: 0.875rem;
}
.section-title {
    font-family: var(--font-display);
    font-size: clamp(1.55rem, 3.4vw, 3.5rem);
    font-weight: 800;
    letter-spacing: -0.03em;
    line-height: 1.05;
    margin-bottom: 3rem;
    color: var(--text);
}

/* ─── Clients ─────────────────────────────────────────── */
#clients {
    padding: 1.25rem 0 1.75rem;
    position: relative;
    z-index: 3;
    background: transparent;
}
/* ── Green bloom ───────────────────────────────────────────────────────────
   One shared shape, used wherever a section edge needs the glow, so every
   instance matches. --glow-h tunes the size per host. The hosts below each
   make themselves a stacking context so the -1 layer sits behind their own
   text but still above the section background underneath. */
.glow-up::before,
.glow-down::after {
    content: '';
    position: absolute;
    left: 50%;
    transform: translateX(-50%);
    width: min(1500px, 130%);
    height: var(--glow-h, 320px);
    pointer-events: none;
}
.glow-up::before {
    bottom: 0;
    background: radial-gradient(ellipse 55% 100% at 50% 100%,
        rgba(70, 226, 80, 0.26) 0%,
        rgba(70, 226, 80, 0.14) 30%,
        rgba(70, 226, 80, 0.06) 52%,
        rgba(70, 226, 80, 0.00) 76%);
}
.glow-down::after {
    top: 0;
    background: radial-gradient(ellipse 55% 100% at 50% 0%,
        rgba(70, 226, 80, 0.26) 0%,
        rgba(70, 226, 80, 0.14) 30%,
        rgba(70, 226, 80, 0.06) 52%,
        rgba(70, 226, 80, 0.00) 76%);
}

/* Mid-section bloom. The edge-anchored gradients above put peak opacity on the
   box edge, which is invisible at a section boundary because the next section
   starts there, but shows as a hard line anywhere else. This one radiates from
   the box centre and reaches full transparency before every edge, so the layer
   has no boundary at all. */
.glow-soft::after {
    content: '';
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    width: min(1500px, 140%);
    height: var(--glow-h, 440px);
    background: radial-gradient(ellipse 46% 46% at 50% 50%,
        rgba(70, 226, 80, 0.20) 0%,
        rgba(70, 226, 80, 0.11) 30%,
        rgba(70, 226, 80, 0.04) 54%,
        rgba(70, 226, 80, 0.00) 76%);
    pointer-events: none;
    z-index: -1;
}

/* Rising from the boundary with the next section, behind the logo strip.
   #clients is the last block of #hero, so its bottom edge is where #work
   begins, and #hero's overflow:clip stops it bleeding into the light band. */
/* Spans the whole bottom edge of the section rather than blooming only in the
   middle: full viewport width, and the gradient's horizontal extent widened to
   100% so it reaches the edges while staying strongest at the bottom centre. */
#clients.glow-up::before {
    z-index: 0;
    width: 100vw;
    --glow-h: 360px;
    background: radial-gradient(ellipse 100% 100% at 50% 100%,
        rgba(70, 226, 80, 0.26) 0%,
        rgba(70, 226, 80, 0.15) 32%,
        rgba(70, 226, 80, 0.06) 58%,
        rgba(70, 226, 80, 0.00) 80%);
}

/* The bloom behind the wordmark lives on the page, not in the bar. Putting it
   inside #navbar meant the bar's own backdrop-filter picked it up and washed
   green across the whole header as soon as it went light. It is .hero-top-glow
   below instead, which scrolls with the page and leaves the bar alone. */
.nav-logo { position: absolute; }

/* Green bloom at the top of the page, centred behind the wordmark. Sits at
   z-index 3, above the hero's background art and below .hero-content (4). */
.hero-top-glow {
    position: absolute;
    top: 0;
    left: 50%;
    transform: translateX(-50%);
    width: min(1150px, 94vw);
    height: 320px;
    background: radial-gradient(ellipse 50% 50% at 50% 16%,
        rgba(70, 226, 80, 0.18) 0%,
        rgba(70, 226, 80, 0.10) 32%,
        rgba(70, 226, 80, 0.04) 56%,
        rgba(70, 226, 80, 0.00) 78%);
    pointer-events: none;
    z-index: 3;
}

/* The About content sits above the section's decorative layers, mirroring
   .hero-content (z-index 4) in the hero. This is what keeps every glow behind
   the text: the glows live at z-index 1, the content at 4. */
#about > .container {
    position: relative;
    z-index: 4;
}

/* Hosts for the title and practice-label blooms. Deliberately no z-index: they
   must NOT create their own stacking context, so their -1 layer resolves
   against .container and paints behind all of its content, not just their own
   text. */
/* Both edges of the About section. .about-bg sits at z-index 0 and the content
   at 4, so these ride between the two. */
#about.glow-up::before,
#about.glow-down::after {
    --glow-h: 360px;
    z-index: 1;
}

.clients-label {
    margin-bottom: 1rem;
    margin-left: 2rem;
    margin-right: 2rem;
    position: relative;
    z-index: 3;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0;  /* marker margins alone space the triangles */
    white-space: nowrap;
}

.clients-track-wrap {
    overflow: hidden;
    position: relative;
    z-index: 3;
    padding: 6px 0 6px; /* room for hover translateY */
    margin-top: 1.5rem;
    -webkit-mask-image: linear-gradient(to right, transparent 0%, black 12%, black 88%, transparent 100%);
    mask-image: linear-gradient(to right, transparent 0%, black 12%, black 88%, transparent 100%);
}

.clients-track {
    display: flex;
    align-items: center;
    gap: 3.4rem;
    width: max-content;
    animation: logoScroll 18.9s linear infinite;
    /* Hold at the start (Cresol leading-in, Adidas clearly in view) until the
       section scrolls into view, so the loop always begins where the user can see it. */
    animation-play-state: paused;
}

/* Start the marquee only once the clients section scrolls into view, so the
   loop always begins where the user can see it. The class is added by the
   small observer in script.js; it used to ride on the old .fade-in reveal. */
#clients.marquee-on .clients-track {
    animation-play-state: running;
}

/* Pension card: the real prototype screenshot, standing on nothing. The card
   visual drops its gradient so the phone reads as a floating device. */
.case--pension .case-visual {
    background: none;
}
.case-proto-shot {
    height: 300px;
    width: auto;
    display: block;
    object-fit: contain;
    filter: drop-shadow(0 22px 40px rgba(0, 0, 0, 0.45));
}

/* Original: no card, just a transparent holder for each rolling logo. */
.logo-card {
    border: 1px solid transparent;
    background:
        linear-gradient(transparent, transparent) padding-box,
        linear-gradient(transparent, transparent) border-box;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    transition: transform 0.3s ease, box-shadow 0.3s ease,
                background 0.3s ease, border-color 0.3s ease;
}

@media (hover: hover) {
.logo-card:hover {
    background:
        linear-gradient(transparent, transparent) padding-box,
        linear-gradient(135deg, rgba(0,201,173,0.45) 0%, rgba(238,255,0,0.30) 100%) border-box;
    transform: translateY(-7px);
    box-shadow: inset 0 0 0 9999px rgba(0,201,173,0.10), 0 24px 64px rgba(0,0,0,0.22),
                0 0 0 1px rgba(0,201,173,0.50),
                inset 0 1px 0 rgba(255,255,255,0.30);
}
}

.clients-track img {
    height: auto;
    max-height: 181.5px;
    max-width: 437.8px;
    width: auto;
    object-fit: contain;
    filter: brightness(0) invert(1);
    opacity: 1;
    transition: filter 0.4s ease;
    flex-shrink: 0;
    position: relative;
    z-index: 2;
}

@media (hover: hover) {
.logo-card:hover img {
    filter: brightness(0) saturate(100%) invert(98%) sepia(60%) saturate(800%) hue-rotate(20deg);
}
}

@keyframes logoScroll {
    0%   { transform: translate3d(0, 0, 0); }
    100% { transform: translate3d(-50%, 0, 0); }
}

/* ─── About ──────────────────────────────────────────── */
/* ── About: light mode ───────────────────────────────── */
/* ─── About + Skills (merged, hero-inspired) ─────────── */
#about {
    position: relative;
    overflow: visible; /* highlight cards straddle into #contact */
    color: #ffffff;
    /* Same shallow curve as the hero on both edges. #about sits above #work and #contact
       and slides up so its curved top/bottom reveal those sections through the cut. The
       curve only eats into #about's 8rem padding, so no content is clipped. */
    z-index: 2;
    margin-top: 0;
    /* Straight, square edges; stacks cleanly between #work and #contact */
    padding: 9rem 0;
}

.about-bg {
    position: absolute;
    inset: 0;
    background: linear-gradient(145deg, #0D6878 0%, #094E60 50%, #073D4D 100%);
    z-index: 0;
}

.about-grain {
    position: absolute;
    inset: 0;
    z-index: 1;
    pointer-events: none;
    background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.75' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)' opacity='1'/%3E%3C/svg%3E");
    background-size: 160px 160px;
    opacity: 0.14;
    mix-blend-mode: overlay;
}

#about .container { position: relative; z-index: 4; }
#about .hero-gradient-base { background: #0B2229; }
/* Motion graphics sit behind the "Born global, designed local" title only.
   The video box is pinned to the section box (no centring transform) and the fade is set in
   PIXELS from the section top, so the motion stays locked to the title no matter how tall the
   section grows. The dark base and overlay still cover the whole section. */
#about .hero-video {
    top: 0;
    left: 0;
    transform: none;
    width: 100%;
    height: 100%;
    min-width: 0;
    min-height: 0;
    object-fit: cover;
    -webkit-mask-image: linear-gradient(to bottom, #000 0px, #000 430px, rgba(0,0,0,0.4) 520px, transparent 620px);
    mask-image: linear-gradient(to bottom, #000 0px, #000 430px, rgba(0,0,0,0.4) 520px, transparent 620px);
}

/* About section, kanji SVG sits behind the title */
#about .about-bg-svg {
    height: auto;
    width: 82%;
    max-width: 960px;
    top: 18.5rem;
    transform: translate(-50%, -50%);
    animation: aboutSvgDrift 28s ease-in-out infinite;
}
@keyframes aboutSvgDrift {
    0%   { transform: translate(-50%, -50%) translate(0px, 0px); }
    20%  { transform: translate(-50%, -50%) translate(12px, -10px); }
    40%  { transform: translate(-50%, -50%) translate(-8px, 14px); }
    60%  { transform: translate(-50%, -50%) translate(14px, 8px); }
    80%  { transform: translate(-50%, -50%) translate(-10px, -12px); }
    100% { transform: translate(-50%, -50%) translate(0px, 0px); }
}

/* Centered single-column flow */
.about-flow {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 2rem;
}

/* Photo */
.about-photo-wrap {
    width: 140px;
    height: 140px;
    border-radius: 50%;
    overflow: hidden;
    border: 3px solid rgba(238,255,0,0.35);
    box-shadow: 0 0 0 8px rgba(238,255,0,0.07), 0 16px 48px rgba(0,0,0,0.4);
    flex-shrink: 0;
}
.about-photo-wrap img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    object-position: center top;
}

/* Section label */
#about .section-label { color: #ffffff; }

/* Title, matches #animatedTitle (hero "Chasing the edge") */
.about-title {
    font-family: var(--font-display);
    font-size: clamp(2.1rem, 6vw, 3.6rem);
    font-weight: 700;
    letter-spacing: -0.02em;
    line-height: 1.25;
    color: #ffffff;
    white-space: normal;
    text-align: center;
    text-shadow:
        0 -1px 0 rgba(255,255,255,0.9),
        -1px 0 0 rgba(255,255,255,0.55),
         1px 0 0 rgba(255,255,255,0.55),
         0 2px 0 rgba(0,0,0,0.12),
         0 0 22px rgba(255,255,255,0.22),
         0 0 55px rgba(255,255,255,0.1);
}

.about-title em {
    font-style: normal;
    display: inline-block;
    /* Identical treatment to .hero-title-fixed. The padding is what the glow
       needs: without it the drop-shadow is cramped against the tight
       inline-block box and reads as a smudge beside the letters. */
    line-height: 1.2;
    margin-top: -0.45em;
    padding: 0.5em 0.3em 0.6em;
    overflow: visible;
    background: linear-gradient(90deg, #EEFF00 0%, #00C9AD 100%);
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-clip: text;
    text-shadow: none;
    filter:
        drop-shadow(0 -1px 0 rgba(255,255,255,0.5))
        drop-shadow(-1px 0 0 rgba(238,255,0,0.7))
        drop-shadow( 1px 0 0 rgba(238,255,0,0.7))
        drop-shadow(0  2px 0 rgba(238,255,0,0.6))
        drop-shadow(0 0 16px rgba(238,255,0,0.65))
        drop-shadow(0 0 40px rgba(238,255,0,0.3));
}

/* Paragraphs */
.about-p {
    color: #ffffff;
    line-height: 1.85;
    font-size: 1rem;
    max-width: 780px;
}

/* Card rows */
.about-row {
    width: 100%;
    display: grid;
    gap: 0.9rem;
}
/* ── From the CV: intro quote, two paragraphs, six capability cards ── */
.about-cv {
    --cv-measure: 42.3rem; /* matches the span of the location row above */
    width: 100%;
    max-width: 890px;
    margin: 0 auto;
    text-align: left;
}
.cv-quote {
    margin: 0;
    max-width: none;
    font-family: var(--font-main);
    font-size: 1.2rem;
    font-weight: 400;
    line-height: 1.45;
    color: #ffffff;
    text-align: left;
    text-wrap: pretty;
}
.cv-quote em {
    position: relative;
    font-style: normal;
    font-weight: 700;
}
/* A clean stripe in the CV's green fade, replacing the hand-drawn pen pass. */
.cv-quote em::after {
    content: '';
    position: absolute;
    left: 0;
    right: 0;
    bottom: -0.14em;
    height: 0.13em;
    border-radius: 100px;
    background: linear-gradient(90deg, #97F016 0%, #1EDC6D 100%);
    pointer-events: none;
}
.cv-p {
    margin: 0 0 1.1rem;
    max-width: none;
    font-family: var(--font-main);
    font-size: 0.95rem;
    line-height: 1.7;
    color: rgba(255,255,255,0.86);
    text-wrap: pretty;
}
.cv-p strong em { color: #ffffff; font-weight: 700; font-style: normal; }
/* The intro text sits in a card the width of the location row above, with the
   lead line separated from the body by a rule. Static panel, so no hover lift. */
.highlight-card.cv-text-card {
    align-items: stretch;
    text-align: left;
    gap: 0;
    --cv-card-pad-x: 2rem;
    --cv-panel-w: 34%;       /* the green block on the left */
    --cv-photo-overhang: 58px; /* how far the head rises above the card */
    position: relative;
    /* overflow stays visible so the head can break out of the card */
    padding: 1.9rem var(--cv-card-pad-x) 1.75rem;
    padding-left: calc(var(--cv-panel-w) + var(--cv-card-pad-x));
    width: 100%;
    max-width: 100%;
    margin: 0 auto;
    /* Green bloom behind the card, over its existing depth shadow. */
    box-shadow: inset 0 1px 0 rgba(255,255,255,0.08),
                0 22px 60px rgba(0,0,0,0.42),
                0 18px 80px rgba(70, 226, 80, 0.26);
}
@media (hover: hover) {
.highlight-card.cv-text-card:hover {
    transform: translateY(-7px);
    border-color: rgba(0,201,173,0.45);
    box-shadow: inset 0 0 0 9999px rgba(0,201,173,0.10),
                0 24px 64px rgba(0,0,0,0.22),
                0 0 0 1px rgba(0,201,173,0.50),
                inset 0 1px 0 rgba(255,255,255,0.30);
}
}
/* Green block on the left, the card's left corners rounded to match. */
.cv-card-panel {
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    width: var(--cv-panel-w);
    background: linear-gradient(180deg, #97F016 0%, #1EDC6D 100%);
    border-top-left-radius: inherit;
    border-bottom-left-radius: inherit;
    z-index: 1;
    pointer-events: none;
}
/* The portrait stands on the panel and rises past the card's top edge, which is
   why the card keeps overflow visible. The box is the card's height plus the
   overhang, and the image is bottom-anchored inside it. */
.cv-card-figure {
    position: absolute;
    left: 0;
    bottom: 0;
    width: var(--cv-panel-w);
    height: calc(100% + var(--cv-photo-overhang));
    z-index: 3;
    pointer-events: none;
}
.cv-card-photo {
    width: 100%;
    height: 100%;
    object-fit: contain;
    object-position: bottom center;
    display: block;
    /* The subject is not centred in the source file: a per-row scan of the
       opaque pixels puts his midline 1.64% of the width left of the image
       centre, which left 17px of green on one side and 25px on the other.
       This nudges him back onto the panel's centre line. */
    transform: translateX(1.64%);
}
/* Every line of text clears the portrait, so the column keeps one left edge */
.cv-text-card .cv-quote,
.cv-text-card .cv-p { padding-left: 0; }
.cv-text-divider {
    height: 1px;
    background: var(--divider);
    margin: 1.4rem calc(var(--cv-card-pad-x) * -1) 1.45rem
            calc((var(--cv-panel-w) + var(--cv-card-pad-x)) * -1);
    position: relative;
    z-index: 2;
}
.cv-text-card .cv-p:last-child { margin-bottom: 0; }

/* Drifting watermark behind the capability cards, same treatment as the hero's */
.cv-grid-wrap {
    position: relative;
    width: 100%;
}
#about .cv-grid-svg {
    height: auto;
    width: 140%;
    max-width: 1200px;
    top: 50%;
    transform: translate(-50%, -50%);
    animation: aboutSvgDrift 28s ease-in-out infinite;
    z-index: 0;
}
.cv-grid-wrap > .cv-grid {
    position: relative;
    z-index: 1;
    margin-top: 0;
}

/* Eyebrow introducing the capability cards, same component as the section label */
.cv-practice-label {
    /* Breaks out of the container so the rules land on the same axis as .clients-label.
       The negative left margin re-centres a box wider than its parent; body clips any
       overshoot from a classic scrollbar, so this can never add a horizontal scroll. */
    width: calc(100vw - 4rem);
    max-width: calc(100vw - 4rem);
    /* Equal space above and below the label. */
    margin: 4rem 0 4rem calc((100% - (100vw - 4rem)) / 2);
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0;  /* marker margins alone space the triangles */
    white-space: nowrap;
}
.cv-practice-label + .cv-grid { margin-top: 0; }
.cv-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 1.25rem;
    margin-top: 2rem;
}
.highlight-card.cv-card {
    align-items: flex-start;
    text-align: left;
    gap: 0.6rem;
    padding: 1.5rem 1.5rem 1.6rem;
}
.cv-card-icon {
    display: inline-flex;
    width: 30px; height: 30px;
    color: #46E250;   /* CV icon green, from the 97F016 -> 1EDC6D fade */
    margin-bottom: 0.35rem;
}
.cv-card-icon svg { width: 100%; height: 100%; }
.cv-card-title {
    font-family: var(--font-display);
    font-size: 1.15rem;
    font-weight: 700;
    letter-spacing: -0.01em;
    line-height: 1.15;
    color: #ffffff;
}
.cv-card-text {
    margin: 0;
    font-family: var(--font-main);
    font-size: 0.95rem;
    line-height: 1.55;
    color: rgba(255,255,255,0.84);
    text-wrap: pretty;
}
@media (max-width: 900px) { .cv-grid { grid-template-columns: 1fr 1fr; } }
@media (max-width: 560px) {
    .cv-grid { grid-template-columns: 1fr; }
    .cv-quote { font-size: 1.05rem; }
    /* The card keeps its green ground and its standing portrait; the panel
       turns from a left column into a band across the top, the portrait rises
       off the band past the card's top edge exactly as it does on desktop,
       and every line of text runs below it at the card's own gutter. */
    .highlight-card.cv-text-card {
        --cv-card-pad-x: 1.35rem;
        --cv-band-h: 136px;
        --cv-photo-overhang: 44px;
        padding: calc(var(--cv-band-h) + 1.5rem) var(--cv-card-pad-x) 1.4rem;
    }
    .cv-card-panel {
        display: block;
        left: 0;
        right: 0;
        top: 0;
        bottom: auto;
        width: auto;
        height: var(--cv-band-h);
        /* the card's own radius, as the desktop panel takes it */
        border-radius: inherit;
        border-bottom-left-radius: 0;
        border-bottom-right-radius: 0;
    }
    .cv-card-figure {
        position: absolute;
        left: 50%;
        right: auto;
        bottom: auto;
        top: calc(-1 * var(--cv-photo-overhang));
        transform: translateX(-50%);
        width: 240px;
        height: calc(var(--cv-band-h) + var(--cv-photo-overhang));
        margin: 0;
        overflow: hidden;
    }
    /* `contain` fitted the whole figure into the band's height and left him
       118px wide. `cover` anchored to the top fills the box instead: he comes
       up to the band's width and the frame cuts him at the chest. */
    .cv-card-photo {
        transform: none;
        object-fit: cover;
        object-position: 50% 0%;
    }
    .cv-text-card .cv-quote,
    .cv-text-card .cv-p { padding-left: 0; }
    /* The rule is pulled left by the width of the green column, which no
       longer sits on that side: it was running off the screen. */
    .cv-text-divider {
        margin-left: calc(var(--cv-card-pad-x) * -1);
        margin-right: calc(var(--cv-card-pad-x) * -1);
    }
}

.about-loc-row        { grid-template-columns: repeat(3, 1fr); margin-top: -1.1rem; }
.loc-flags {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}
.loc-flags .loc-flag-lg + .loc-flag-lg { margin-left: -0.5rem; }
.loc-flag-lg {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.7rem;
    height: 2.7rem;
    border-radius: 50%;
    background: linear-gradient(90deg, #EEFF00 0%, #00C9AD 100%);
    line-height: 1;
    flex-shrink: 0;
}
/* The flag sits inside the green disc, leaving it as a ring around the icon.
   Larger than the emoji it replaced (2.1rem against the old 1.5rem glyph). */
.loc-flag-lg img {
    display: block;
    width: 2.1rem;
    height: 2.1rem;
    border-radius: 50%;
    flex-shrink: 0;
}
/* Location cards: horizontal layout, flag on the side, text beside it */
.highlight-card.loc-card {
    flex-direction: row;
    align-items: center;
    justify-content: flex-start;
    text-align: left;
    gap: 1rem;
    padding: 1.25rem 1.5rem;
}
.highlight-card.loc-card .highlight-text {
    align-items: flex-start;
    text-align: left;
    gap: 0.05rem;
}

/* Location row: plain elements on the page, no card chrome, sitting close together */
.about-loc-row {
    display: flex;
    justify-content: center;
    align-items: flex-start;
    flex-wrap: wrap;
    gap: 3.2rem;
    margin-top: 2.25rem;
    /* about-flow gap is 2rem; this adds to it, and the portrait overhangs into it */
    margin-bottom: 4rem;
}
.highlight-card.loc-card {
    background: none;
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
    border: none;
    border-radius: 0;
    box-shadow: none;
    padding: 0;
    gap: 0.7rem;
}
/* Display only: nothing here is interactive, so no hover, press, caret or
   selection should ever appear on it. */
.highlight-card.loc-card,
.highlight-card.loc-card:focus,
.highlight-card.loc-card:active {
    transform: none;
    background: none;
    border-color: transparent;
    box-shadow: none;
    transition: none;
}
@media (hover: hover) {
.highlight-card.loc-card:hover {
    transform: none;
    background: none;
    border-color: transparent;
    box-shadow: none;
    transition: none;
}
}
/* The text stays selectable; only the mobile tap flash is suppressed. */
.about-loc-row,
.about-loc-row * {
    -webkit-tap-highlight-color: transparent;
}
.about-skills-row     { grid-template-columns: repeat(4, 1fr); }
.about-langs-row      { grid-template-columns: repeat(5, 1fr); }

/* Highlight cards: same frosted-glass card as the case-study hero stat cards (.cs-meta-item.is-stat) */
.highlight-card {
    border: 1px solid transparent;
    background:
        linear-gradient(135deg, rgba(7,42,52,0.42) 0%, rgba(7,42,52,0.26) 100%) padding-box,
        linear-gradient(rgba(255,255,255,0.10), rgba(255,255,255,0.10)) border-box;
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 0.5rem;
    padding: 1.75rem;
    
    backdrop-filter: blur(18px) saturate(115%);
    -webkit-backdrop-filter: blur(18px) saturate(115%);
    
    border-radius: 16px;
    box-shadow: inset 0 1px 0 rgba(255,255,255,0.08), 0 22px 60px rgba(0,0,0,0.42);
    transition: transform 0.3s ease, box-shadow 0.3s ease,
                background 0.3s ease, border-color 0.3s ease;
}
@media (hover: hover) {
.highlight-card:hover {
    background:
        linear-gradient(transparent, transparent) padding-box,
        linear-gradient(135deg, rgba(0,201,173,0.45) 0%, rgba(238,255,0,0.30) 100%) border-box;
    transform: translateY(-7px);
    
    box-shadow: inset 0 0 0 9999px rgba(0,201,173,0.10), 0 24px 64px rgba(0,0,0,0.22),
                0 0 0 1px rgba(0,201,173,0.50),
                inset 0 1px 0 rgba(255,255,255,0.30);
}
}
.highlight-num {
    font-family: var(--font-display);
    font-size: clamp(1.9rem, 2.4vw, 2.4rem);
    font-weight: 900;
    line-height: 1;
    background: linear-gradient(90deg, #EEFF00 0%, #00C9AD 100%);
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-clip: text;
    flex-shrink: 0;
    letter-spacing: -0.03em;
}
.highlight-text {
    display: flex;
    flex-direction: column;
    gap: 0.3rem;
    text-align: center;
    align-items: center;
}
.highlight-title {
    font-family: var(--font-main);
    font-size: 1.0rem;
    letter-spacing: 0.01em;
    text-transform: none;
    font-weight: 500;
    color: #ffffff;
    line-height: 1.3;
}
.highlight-sub {
    font-size: 0.8rem;
    color: #ffffff;
    font-family: var(--font-main);
    letter-spacing: 0;
}
/* Download CV / Read Cases, two clickable cards below the stat cards, same frosted glass */
.about-cta-row {
    display: flex;
    justify-content: center;
    gap: 0.9rem;
    flex-wrap: wrap;
    margin-top: 1.6rem;
}
.about-cta-card {
    border: 1px solid transparent;
    background:
        linear-gradient(135deg, rgba(7,42,52,0.42) 0%, rgba(7,42,52,0.26) 100%) padding-box,
        linear-gradient(rgba(255,255,255,0.10), rgba(255,255,255,0.10)) border-box;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.7rem;
    padding: 1.5rem 1.75rem;
    
    backdrop-filter: blur(18px) saturate(115%);
    -webkit-backdrop-filter: blur(18px) saturate(115%);
    
    border-radius: 16px;
    box-shadow: inset 0 1px 0 rgba(255,255,255,0.08), 0 22px 60px rgba(0,0,0,0.42);
    text-decoration: none;
    font-family: var(--font-main);
    font-size: 1.0rem;
    font-weight: 500;
    letter-spacing: 0.01em;
    text-transform: none;
    color: #ffffff;
    transition: transform 0.3s ease, box-shadow 0.3s ease,
                background 0.3s ease, border-color 0.3s ease;
}
@media (hover: hover) {
.about-cta-card:hover {
    background:
        linear-gradient(transparent, transparent) padding-box,
        linear-gradient(135deg, rgba(0,201,173,0.45) 0%, rgba(238,255,0,0.30) 100%) border-box;
    transform: translateY(-7px);
    
    box-shadow: inset 0 0 0 9999px rgba(0,201,173,0.10), 0 24px 64px rgba(0,0,0,0.22),
                0 0 0 1px rgba(0,201,173,0.50),
                inset 0 1px 0 rgba(255,255,255,0.30);
}
}
.about-cta-arrow { color: #EEFF00; font-weight: 700; font-size: 1.05em; }

.highlight-num--small {
    font-size: 1.5rem;
    letter-spacing: 0.02em;
}
.highlight-sub--accent {
    color: #EEFF00;
    font-family: var(--font-main);
    font-size: 0.82rem;
    font-weight: 600;
    letter-spacing: 0;
    line-height: 1.5;
}

/* Stat cards */
.stat-card {
    border: 1px solid transparent;
    background:
        linear-gradient(rgba(255,255,255,0.07), rgba(255,255,255,0.07)) padding-box,
        linear-gradient(rgba(255,255,255,0.14), rgba(255,255,255,0.14)) border-box;
    
    backdrop-filter: blur(16px);
    -webkit-backdrop-filter: blur(16px);
    
    border-radius: var(--radius);
    padding: 1.5rem 1.25rem;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.35rem;
    box-shadow: 0 4px 24px rgba(0,0,0,0.15), inset 0 1px 0 rgba(255,255,255,0.12);
    transition: border-color var(--transition), transform var(--transition);
}
@media (hover: hover) {
.stat-card:hover {
    background:
        linear-gradient(transparent, transparent) padding-box,
        linear-gradient(135deg, rgba(0,201,173,0.45) 0%, rgba(238,255,0,0.30) 100%) border-box;
    
    transform: translateY(-7px);
    box-shadow: inset 0 0 0 9999px rgba(0,201,173,0.10), 0 24px 64px rgba(0,0,0,0.22),
                0 0 0 1px rgba(0,201,173,0.50),
                inset 0 1px 0 rgba(255,255,255,0.30);
}
}
.stat-number {
    font-size: 2.2rem;
    font-weight: 700;
    line-height: 1;
    background: linear-gradient(135deg, #EEFF00 0%, #00C9AD 100%);
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-clip: text;
}
.stat-label {
    font-size: 0.918rem;
    color: rgba(255,255,255,0.50);
    font-family: var(--font-main); font-weight: 500;
    letter-spacing: 0.01em;
    text-transform: none;
}

/* Language cards */
.lang-card {
    border: 1px solid transparent;
    background:
        linear-gradient(transparent, transparent) padding-box,
        linear-gradient(transparent, transparent) border-box;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.25rem;
    padding: 1.25rem 0.75rem;
    border-radius: var(--radius);
    backdrop-filter: blur(16px);
    -webkit-backdrop-filter: blur(16px);
    box-shadow: 0 4px 20px rgba(0,0,0,0.2), inset 0 1px 0 rgba(255,255,255,0.12);
    transition: transform 0.3s ease, box-shadow 0.3s ease,
                background 0.3s ease, border-color 0.3s ease;
    text-align: center;
}
@media (hover: hover) {
.lang-card:hover {
    background:
        linear-gradient(transparent, transparent) padding-box,
        linear-gradient(135deg, rgba(0,201,173,0.45) 0%, rgba(238,255,0,0.30) 100%) border-box; transform: translateY(-7px); 
    box-shadow: inset 0 0 0 9999px rgba(0,201,173,0.10), 0 24px 64px rgba(0,0,0,0.22),
                0 0 0 1px rgba(0,201,173,0.50),
                inset 0 1px 0 rgba(255,255,255,0.30); }
}
.lang-card.pill-full { background: rgba(238,255,0,0.09); border: 1px solid rgba(238,255,0,0.28); }
.lang-card.pill-mid  { background: rgba(255,255,255,0.06); border: 1px solid rgba(255,255,255,0.14); }
.lang-card-code {
    font-family: var(--font-main);
    font-size: 1.3rem;
    font-weight: 700;
    letter-spacing: 0.05em;
}
.lang-card.pill-full .lang-card-code { color: #EEFF00; }
.lang-card.pill-mid  .lang-card-code { color: rgba(255,255,255,0.40); }
.lang-card-label {
    font-size: 0.64rem;
    color: rgba(255,255,255,0.55);
    font-family: var(--font-main); font-weight: 600;
}
.lang-card-level {
    font-size: 0.8rem;
    text-transform: none;
    letter-spacing: 0.01em;
    font-family: var(--font-main); font-weight: 500;
}
.lang-card.pill-full .lang-card-level { color: rgba(238,255,0,0.55); }
.lang-card.pill-mid  .lang-card-level { color: rgba(255,255,255,0.28); }

/* Buttons */
.about-actions {
    display: flex;
    gap: 0.9rem;
    flex-wrap: wrap;
    justify-content: center;
}

.skills-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 1.25rem;
}

.skill-group {
    border: 1px solid transparent;
    background:
        linear-gradient(rgba(255,255,255,0.06), rgba(255,255,255,0.06)) padding-box,
        linear-gradient(rgba(255,255,255,0.12), rgba(255,255,255,0.12)) border-box;
    
    backdrop-filter: blur(16px);
    -webkit-backdrop-filter: blur(16px);
    
    border-radius: var(--radius);
    padding: 1.75rem;
    box-shadow: 0 4px 24px rgba(0,0,0,0.15), inset 0 1px 0 rgba(255,255,255,0.10);
    transition: transform 0.3s ease, box-shadow 0.3s ease,
                background 0.3s ease, border-color 0.3s ease;
}

@media (hover: hover) {
.skill-group:hover {
    background:
        linear-gradient(transparent, transparent) padding-box,
        linear-gradient(135deg, rgba(0,201,173,0.45) 0%, rgba(238,255,0,0.30) 100%) border-box;
    
    transform: translateY(-7px);
    box-shadow: inset 0 0 0 9999px rgba(0,201,173,0.10), 0 24px 64px rgba(0,0,0,0.22),
                0 0 0 1px rgba(0,201,173,0.50),
                inset 0 1px 0 rgba(255,255,255,0.30);
}
}

.skill-group-title {
    font-family: var(--font-main); font-weight: 500;
    font-size: 0.945rem;
    color: #00C9AD;
    letter-spacing: 0.01em;
    text-transform: none;
    margin-bottom: 1.1rem;
}

.skill-group ul {
    list-style: none;
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
}

.skill-group li {
    font-size: 0.88rem;
    color: rgba(255,255,255,0.55);
    padding-left: 1rem;
    position: relative;
    transition: color var(--transition);
}

.skill-group li::before {
    content: '·';
    position: absolute;
    left: 0;
    color: #EEFF00;
    font-size: 0.62rem;
    top: 0.2em;
}

@media (hover: hover) {
.skill-group:hover li {
    transform: translateY(-7px); color: rgba(255,255,255,0.90);
    box-shadow: inset 0 0 0 9999px rgba(0,201,173,0.10), 0 24px 64px rgba(0,0,0,0.22),
                0 0 0 1px rgba(0,201,173,0.50),
                inset 0 1px 0 rgba(255,255,255,0.30);
}
}

/* ─── Work ───────────────────────────────────────────── */
/* ── Work: light mode + texture + lights ────────────── */
#work {
    background-color: #E8EBE6;
    position: relative;
    overflow: hidden;
    z-index: 1;
    margin-top: 0;
}

/* Grain texture (matches the case-study .cs-light-body grain), gives the flat translucent
   .work-panel card its depth on the light background; without it the card is invisible. */
#work::before {
    content: '';
    position: absolute;
    inset: 0;
    background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='grain'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='4' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23grain)' opacity='0.45'/%3E%3C/svg%3E");
    background-size: 200px 200px;
    opacity: 0.38;
    pointer-events: none;
    z-index: 1;
    mix-blend-mode: multiply;
}

/* Moving light blobs */
.work-blob-a,
.work-blob-b {
    position: absolute;
    border-radius: 50%;
    pointer-events: none;
    z-index: 0;
}
.work-blob-a {
    width: 1000px; height: 1000px;
    background: radial-gradient(circle, rgba(0,201,173,0.65) 0%, rgba(0,201,173,0.30) 35%, transparent 65%);
    top: -300px; left: -300px;
    filter: blur(38px);
    animation: workBlobA 10s ease-in-out infinite;
}
.work-blob-b {
    width: 950px; height: 950px;
    background: radial-gradient(circle, rgba(238,255,0,0.52) 0%, rgba(238,255,0,0.22) 35%, transparent 65%);
    bottom: -260px; right: -260px;
    filter: blur(45px);
    animation: workBlobB 13s ease-in-out infinite;
}
@keyframes workBlobA {
    0%,100% { transform: translate(0,0) scale(1); }
    25%      { transform: translate(220px, 120px) scale(1.15); }
    50%      { transform: translate(160px, 280px) scale(0.90); }
    75%      { transform: translate(80px,  180px) scale(1.10); }
}
@keyframes workBlobB {
    0%,100% { transform: translate(0,0) scale(1); }
    25%      { transform: translate(-200px,-160px) scale(1.18); }
    50%      { transform: translate(-80px, -260px) scale(0.88); }
    75%      { transform: translate(-160px,-120px) scale(1.12); }
}

/* ── Japanese text stripe ─────────────────────────── */
.work-stripe {
    position: absolute;
    width: 220vw;
    left: -60vw;
    top: 50%;
    height: 160px;
    transform: translateY(-50%) rotate(-45deg);
    z-index: 1;
    overflow: hidden;
    display: flex;
    align-items: center;
    opacity: 0.30;
    background: linear-gradient(
        90deg,
        #073D4D  0%,
        #0B5F72 20%,
        #00C9AD 55%,
        #8AE800 78%,
        #EEFF00 100%
    );
    box-shadow: 0 8px 40px rgba(0,201,173,0.25), 0 -8px 40px rgba(238,255,0,0.15);
}

.work-stripe-track {
    writing-mode: horizontal-tb;
    white-space: nowrap;
    width: max-content;
    animation: stripeScrollHoriz 300s linear infinite;
    color: #ffffff;
    font-family: var(--font-main);
    font-size: 4.5rem;
    font-weight: 700;
    letter-spacing: 0.05em;
    padding: 0 2rem;
}

.stripe-sep {
    opacity: 0.3;
    font-size: 3rem;
}

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

#work .container { position: relative; z-index: 2; }

#work .section-label,
#contact .section-label {
    /* the DS navy, as .cs-section-label carries it on the case pages;
       #0B1A22 was a near-black that is not a token */
    color: #073D4D;
    text-align: left;
    display: block;
    margin-bottom: 1rem;
}
#work .section-title {
    color: #073D4D;
    text-align: left;
    font-size: clamp(1.55rem, 3.4vw, 2.7rem);
    font-weight: 700;
    letter-spacing: -0.02em;
    line-height: 1.25;
}
#work .title-gradient,
#contact .title-gradient {
    background: linear-gradient(130deg, #00C9AD 0%, #00A77F 50%, #007A68 100%);
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-clip: text;
    filter:
        drop-shadow(0 -1px 0 rgba(255,255,255,0.9))
        drop-shadow(-1px 0 0 rgba(255,255,255,0.55))
        drop-shadow( 1px 0 0 rgba(255,255,255,0.55))
        drop-shadow(0  2px 0 rgba(0,0,0,0.12))
        drop-shadow(0  0 22px rgba(255,255,255,0.22))
        drop-shadow(0  0 55px rgba(255,255,255,0.10));
}
/* Contact heading, run the fade left→right (not diagonal/top-down).
   Re-declare the text clip AFTER the background shorthand (which resets it), else it renders as a filled box. */
#contact .title-gradient {
    background: linear-gradient(to right, #00C9AD 0%, #00A77F 50%, #007A68 100%);
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    display: inline-block;
}

#work .case-card-v2 {
    background:
        linear-gradient(rgba(255,255,255,0.10), rgba(255,255,255,0.10)) padding-box,
        linear-gradient(135deg, rgba(255,255,255,0.10), rgba(255,255,255,0.10)) border-box;
    backdrop-filter: blur(14px);
    -webkit-backdrop-filter: blur(14px);
    border: 1px solid transparent;
    box-shadow: 0 8px 40px rgba(0,0,0,0.18), inset 0 1px 0 rgba(255,255,255,0.25);
}
@media (hover: hover) {
#work .case-card-v2:hover {
    transform: translateY(-7px);
    background:
        linear-gradient(rgba(255,255,255,0.15), rgba(255,255,255,0.15)) padding-box,
        linear-gradient(135deg, rgba(0,201,173,0.45) 0%, rgba(238,255,0,0.30) 100%) border-box;
    border: 1px solid transparent;
    box-shadow: inset 0 0 0 9999px rgba(0,201,173,0.10), 0 24px 64px rgba(0,0,0,0.22),
                0 0 0 1px rgba(0,201,173,0.50),
                inset 0 1px 0 rgba(255,255,255,0.30);
}
}

#work .case-card-v2 h3 { color: #073D4D; }
#work .case-card-v2 p  { color: #073D4D; }

#work .case-tag { color: #073D4D; }

#work .meta-item {
    background: rgba(7,61,77,0.07);
    color: rgba(7,61,77,0.65);
    border-color: rgba(7,61,77,0.12);
}

#work .case-num-bg { color: rgba(7,61,77,0.06); }

#work .case-link { color: #073D4D; }

#work .kpi-label { color: #073D4D; }

#work .case-kpis {
    border-top-color: rgba(7,61,77,0.10);
    border-bottom-color: rgba(7,61,77,0.10);
}

#work .vsb-num  { color: #073D4D; }
#work .vsb-label { color: rgba(7,61,77,0.65); }
#work .visual-stat-badge {
    background: rgba(255,255,255,0.55);
    border-color: rgba(255,255,255,0.70);
    box-shadow: 0 8px 32px rgba(0,0,0,0.12), inset 0 1px 0 rgba(255,255,255,0.8);
}

/* ─── Cases 3-column grid ─────────────────────────── */
.cases-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0.9rem;
    align-items: stretch;
}
.cases-grid .case-card-v2 {
    height: 100%;
}

/* Featured (Bradesco), large horizontal card, text left / image right */
.case-card-v2.case-featured {
    grid-column: 1 / -1;
    flex-direction: row-reverse;
    align-items: stretch;
    min-height: 360px;
}
.case-featured .case-visual {
    width: 50%;
    height: auto;
    flex-shrink: 0;
    margin: 0;
    align-items: center;
}
.case-featured .case-body {
    flex: 1;
    justify-content: center;
    padding: 2.75rem 3rem;
}
.case-featured .case-body p { flex: 0 1 auto; }
.case-card-v2.case-featured .case-kpis {
    flex-direction: row;
    gap: 2rem;
    align-items: flex-start;
}

/* Mini work-in-progress cards (no image, no link) */
.case-mini .case-body {
    padding: 1.7rem 1.8rem;
}
@media (hover: hover) {
.case-card-v2.case-mini:hover {
    transform: translateY(-7px);
    transform: none;
    box-shadow: inset 0 0 0 9999px rgba(0,201,173,0.10), 0 24px 64px rgba(0,0,0,0.22),
                0 0 0 1px rgba(0,201,173,0.50),
                inset 0 1px 0 rgba(255,255,255,0.30);
}
}
.case-mini p {
    flex: 0 1 auto;
    margin-bottom: 0;
    font-size: 0.86rem;
}
.case-wip {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    font-family: var(--font-main);
    font-size: 0.81rem;
    font-weight: 500;
    letter-spacing: 0.01em;
    text-transform: none;
    color: #EA580C;
    border: 1px solid rgba(234,88,12,0.32);
    background: rgba(234,88,12,0.08);
    padding: 0.32rem 0.75rem;
    border-radius: 100px;
    margin-bottom: 1rem;
}
.case-wip::before {
    content: '';
    width: 5px; height: 5px;
    border-radius: 50%;
    background: #EA580C;
    animation: tagPulse 2s ease-in-out infinite;
}

/* ── Visual panel decorations ── */
.visual-dec-circle {
    position: absolute;
    border-radius: 50%;
    border: 1px dashed rgba(255,255,255,0.14);
    pointer-events: none;
    z-index: 1;
}
.vc-1 {
    width: 200px; height: 200px;
    top: -60px; left: -60px;
    animation: circSpin 50s linear infinite;
}
.vc-2 {
    width: 340px; height: 340px;
    bottom: -110px; right: -90px;
    animation: circSpin 35s linear infinite reverse;
}
@keyframes circSpin {
    from { transform: rotate(0deg); }
    to   { transform: rotate(360deg); }
}

.visual-glow {
    position: absolute;
    width: 220px; height: 220px;
    border-radius: 50%;
    background: rgba(255,255,255,0.14);
    filter: blur(55px);
    pointer-events: none;
    z-index: 1;
    top: 50%; left: 50%;
    transform: translate(-50%, -55%);
}

/* Floating stat badge */
.visual-stat-badge {
    position: absolute;
    bottom: 2.5rem;
    left: 2rem;
    background: rgba(255,255,255,0.10);
    backdrop-filter: blur(14px);
    -webkit-backdrop-filter: blur(14px);
    border: 1px solid rgba(255,255,255,0.22);
    border-radius: 16px;
    padding: 1rem 1.4rem;
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
    z-index: 10;
    animation: badgeFloat 4.5s ease-in-out infinite;
    box-shadow: 0 8px 32px rgba(0,0,0,0.3), inset 0 1px 0 rgba(255,255,255,0.2);
}
@keyframes badgeFloat {
    0%, 100% { transform: translateY(0px) rotate(-1deg); }
    50%       { transform: translateY(-10px) rotate(0.5deg); }
}
.vsb-num {
    font-family: var(--font-main);
    font-size: 2.2rem;
    font-weight: 700;
    color: #fff;
    line-height: 1;
    letter-spacing: -0.03em;
}
.vsb-label {
    font-family: var(--font-main); font-weight: 500;
    font-size: 0.81rem;
    letter-spacing: 0.01em;
    text-transform: none;
    color: rgba(255,255,255,0.60);
}

/* Phone floating animation in carousel */
.carousel-track .phone-wrap {
    animation: phoneFloat 5.5s ease-in-out infinite;
    position: relative;
    z-index: 5;
}
@keyframes phoneFloat {
    0%, 100% { transform: translateY(0px) rotate(-2deg); }
    50%       { transform: translateY(-14px) rotate(0deg); }
}

/* Shimmer removed */

/* Bigger phone in carousel */
.carousel-track .phone {
    width: 148px;
    height: 296px;
}

/* ── Card body enriched ── */
.case-eyebrow-row {
    display: flex;
    align-items: center;
    gap: 0.7rem;
    margin-bottom: 0.8rem;
    flex-wrap: wrap;
    min-width: 0;
    width: 100%;
}
.case-index {
    font-family: var(--font-main);
    font-size: 0.851rem;
    font-weight: 500;
    letter-spacing: 0.01em;
    text-transform: none;
    color: #EEFF00;
    background: rgba(238,255,0,0.10);
    border: 1px solid rgba(238,255,0,0.22);
    padding: 0.22rem 0.72rem;
    border-radius: 100px;
    transition: background 0.25s, box-shadow 0.25s;
}
@media (hover: hover) {
#work .case-card-v2:hover .case-index {
    transform: translateY(-7px);
    background: rgba(238,255,0,0.18);
    box-shadow: inset 0 0 0 9999px rgba(0,201,173,0.10), 0 24px 64px rgba(0,0,0,0.22),
                0 0 0 1px rgba(0,201,173,0.50),
                inset 0 1px 0 rgba(255,255,255,0.30);
}
}

.case-context {
    font-family: var(--font-main); font-weight: 600;
    font-size: 0.64rem;
    color: rgba(255,255,255,0.32);
    letter-spacing: 0.04em;
    text-transform: none;
    margin-bottom: 0.75rem !important;
    flex: none !important;
    white-space: normal;
    word-break: break-word;
    width: 100%;
}

/* KPI row */
.case-kpis {
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
    padding: 0.85rem 0;
    border-top: 1px solid rgba(255,255,255,0.07);
    border-bottom: 1px solid rgba(255,255,255,0.07);
    margin: 0.75rem 0 0.9rem;
    align-items: flex-start;
}
.kpi-item {
    display: flex;
    flex-direction: column;
    gap: 0.2rem;
    position: relative;
    align-items: flex-start;
    text-align: left;
}
.kpi-num {
    font-family: var(--font-main);
    font-size: 1.65rem;
    font-weight: 700;
    line-height: 1;
    background: linear-gradient(130deg, #073D4D 0%, #0B5F72 50%, #00C9AD 100%);
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-clip: text;
    transition: filter 0.3s;
    letter-spacing: -0.02em;
}
@media (hover: hover) {
#work .case-card-v2:hover .kpi-num {
    transform: translateY(-7px);
    filter: drop-shadow(0 0 8px rgba(0,201,173,0.35));
    box-shadow: inset 0 0 0 9999px rgba(0,201,173,0.10), 0 24px 64px rgba(0,0,0,0.22),
                0 0 0 1px rgba(0,201,173,0.50),
                inset 0 1px 0 rgba(255,255,255,0.30);
}
}
.kpi-label {
    font-family: var(--font-main);
    font-size: 0.8rem;
    letter-spacing: 0;
    text-transform: none;
    line-height: 1.4;
    color: #ffffff;
}

/* Controls row */
.carousel-footer {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 1.25rem;
    margin-top: 1.75rem;
}

/* Prev / Next buttons */
.carousel-btn {
    width: 46px;
    height: 46px;
    border-radius: 50%;
    background: rgba(11,26,34,0.10);
    border: 1px solid rgba(11,26,34,0.18);
    color: #0B1A22;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    transition: background 0.22s, color 0.22s, border-color 0.22s,
                box-shadow 0.22s, transform 0.22s;
}
@media (hover: hover) {
.carousel-btn:hover {
    background: #EEFF00;
    border-color: #EEFF00;
    box-shadow: 0 4px 18px rgba(238,255,0,0.45);
    transform: scale(1.1);
}
}

/* Dot indicators */
.carousel-dots {
    display: flex;
    gap: 0.5rem;
    align-items: center;
}
.carousel-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: rgba(11,26,34,0.20);
    border: none;
    cursor: pointer;
    padding: 0;
    transition: background 0.3s, width 0.3s, border-radius 0.3s;
    flex-shrink: 0;
}
.carousel-dot.active {
    background: #0B1A22;
    width: 28px;
    border-radius: 4px;
}

/* Progress bar */
.carousel-progress {
    height: 2px;
    width: 90px;
    background: rgba(11,26,34,0.12);
    border-radius: 2px;
    overflow: hidden;
}
.carousel-progress-bar {
    height: 100%;
    background: #0B1A22;
    border-radius: 2px;
    width: 0%;
}
@keyframes carouselProgress {
    from { width: 0%; }
    to   { width: 100%; }
}

/* ── New v2 Case Cards ── */
.case-card-v2 {
    border: 1px solid transparent;
    background:
        linear-gradient(rgba(255,255,255,0.06), rgba(255,255,255,0.06)) padding-box,
        linear-gradient(transparent, transparent) border-box;
    border-radius: 12px;
    overflow: hidden;
    
    
    box-shadow: 0 8px 40px rgba(0,0,0,0.3);
    transition: transform 0.3s ease, box-shadow 0.3s ease,
                background 0.3s ease, border-color 0.3s ease;
    display: flex;
    flex-direction: column;
}
@media (hover: hover) {
.case-card-v2:hover {
    background:
        linear-gradient(transparent, transparent) padding-box,
        linear-gradient(135deg, rgba(0,201,173,0.45) 0%, rgba(238,255,0,0.30) 100%) border-box;
    transform: translateY(-7px);
    box-shadow: inset 0 0 0 9999px rgba(0,201,173,0.10), 0 24px 64px rgba(0,0,0,0.22),
                0 0 0 1px rgba(0,201,173,0.50),
                inset 0 1px 0 rgba(255,255,255,0.30);
    
}
}

/* Visual / mockup area */
.case-visual {
    position: relative;
    height: 320px;
    background: linear-gradient(135deg, var(--c1) 0%, var(--c2) 100%);
    display: flex;
    align-items: flex-end;
    justify-content: center;
    overflow: hidden;
    padding-bottom: 0;
    margin: -1px -1px 0 -1px;
    width: calc(100% + 2px);
}
.case-visual::before {
    content: '';
    position: absolute;
    inset: 0;
    background: radial-gradient(ellipse at 30% 20%, rgba(255,255,255,0.18) 0%, transparent 60%);
}

/* Large faded number */
.case-num-bg {
    position: absolute;
    bottom: -10px;
    right: 16px;
    font-family: var(--font-display);
    font-size: 7rem;
    font-weight: 900;
    color: rgba(0,0,0,0.18);
    line-height: 1;
    pointer-events: none;
    user-select: none;
}

/* Phone mockup */
.phone-wrap {
    position: relative;
    z-index: 2;
    display: flex;
    justify-content: center;
    align-items: flex-end;
    padding-top: 2rem;
}
.phone {
    width: 130px;
    height: 260px;
    background: #080c10;
    border-radius: 28px;
    border: 2px solid rgba(255,255,255,0.25);
    position: relative;
    overflow: hidden;
    box-shadow:
        0 24px 64px rgba(0,0,0,0.5),
        inset 0 1px 0 rgba(255,255,255,0.15),
        0 0 0 1px rgba(0,0,0,0.4);
}
.phone-notch {
    position: absolute;
    top: 8px;
    left: 50%;
    transform: translateX(-50%);
    width: 48px;
    height: 10px;
    background: #080c10;
    border-radius: 20px;
    z-index: 10;
    border: 1px solid rgba(255,255,255,0.08);
}
.phone-screen {
    position: absolute;
    inset: 4px;
    border-radius: 24px;
    overflow: hidden;
}

/* Screen UI elements */
.screen-ui {
    padding: 28px 12px 12px;
    display: flex;
    flex-direction: column;
    gap: 7px;
    height: 100%;
}
.ui-bar {
    height: 7px;
    border-radius: 4px;
    flex-shrink: 0;
}
.ui-block {
    height: 50px;
    border-radius: 8px;
    background: rgba(255,255,255,0.12);
    flex-shrink: 0;
    margin: 4px 0;
}
.ui-hero-img {
    height: 80px;
    border-radius: 10px;
    background: rgba(255,255,255,0.1);
    flex-shrink: 0;
    margin-bottom: 4px;
}
.ui-chart {
    display: flex;
    align-items: flex-end;
    gap: 5px;
    height: 70px;
    flex-shrink: 0;
    margin-bottom: 6px;
    padding: 0 4px;
}
.chart-bar {
    flex: 1;
    border-radius: 4px 4px 0 0;
}

/* Card body / text area */
.case-body {
    padding: 1.75rem;
    display: flex;
    flex-direction: column;
    flex: 1;
    align-items: flex-start;
    text-align: left;
}
.case-body .btn {
    align-self: stretch;
    text-align: center;
    margin-top: auto;
    padding-top: 1rem;
}
.case-body .case-kpis {
    width: 100%;
    align-self: stretch;
    justify-content: flex-start;
    align-items: flex-start;
}
.case-tag {
    font-family: var(--font-main); font-weight: 500;
    font-size: 0.878rem;
    color: var(--accent-3);
    letter-spacing: 0.01em;
    text-transform: none;
    margin-bottom: 0.8rem;
    white-space: normal;
    word-break: break-word;
    min-width: 0;
    flex: 1;
}
.case-card-v2 h3 {
    font-family: var(--font-display);
    font-size: 1.45rem;
    font-weight: 700;
    letter-spacing: -0.02em;
    margin-bottom: 0.6rem;
    line-height: 1.2;
    color: var(--text);
}
.case-card-v2 p {
    color: var(--text-muted);
    line-height: 1.7;
    font-size: 0.88rem;
    margin-bottom: 1.2rem;
    flex: 1;
}
.case-card h3 {
    font-size: 1.75rem;
    font-weight: 700;
    letter-spacing: -0.025em;
    margin-bottom: 0.7rem;
    line-height: 1.15;
    color: var(--text);
}
.case-card p {
    color: var(--text-muted);
    line-height: 1.75;
    font-size: 0.92rem;
    margin-bottom: 1.4rem;
    max-width: 500px;
}
.case-meta {
    display: flex;
    gap: 0.45rem;
    flex-wrap: wrap;
    margin-bottom: 1.5rem;
}
.meta-item {
    font-size: 0.7rem;
    padding: 0.26rem 0.75rem;
    border-radius: 100px;
    background: rgba(255,255,255,0.1);
    color: rgba(255,255,255,0.75);
    border: 1px solid rgba(255,255,255,0.15);
}
.case-link {
    font-size: 0.88rem;
    color: var(--accent-1);
    text-decoration: none;
    font-weight: 600;
    letter-spacing: 0.02em;
    transition: letter-spacing var(--transition);
}
@media (hover: hover) {
.case-link:hover { letter-spacing: 0.05em; }
}
.case-link--disabled {
    color: var(--text-muted);
    font-size: 0.82rem;
    font-weight: 600;
    letter-spacing: 0.06em;
    font-family: var(--font-main);
}
.case-number {
    font-family: var(--font-main);
    font-size: 5rem;
    font-weight: 700;
    color: rgba(255,255,255,0.06);
    line-height: 1;
    letter-spacing: -0.06em;
    user-select: none;
    white-space: nowrap;
    padding-left: 2rem;
}

/* ─── Skills tags ────────────────────────────────────── */
.skills-tags {
    width: 100%;
    display: flex;
    flex-direction: column;
    gap: 0;
}
.skill-section {
    display: flex;
    flex-direction: column;
    gap: 1.5rem;
    padding: 1.25rem 0;
}
.skill-section-label {
    display: flex;
    align-items: center;
    gap: 1rem;
    white-space: nowrap;
    margin-bottom: 0;
    color: rgba(255,255,255,0.6);
}
.skill-section-label::before,
.skill-section-label::after {
    content: '';
    flex: 1;
    height: 1px;
    background: var(--divider);
}
.skill-tags-wrap {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    justify-content: center;
}
.skill-tag {
    font-family: var(--font-main); font-weight: 600;
    font-size: 0.7rem;
    letter-spacing: 0.06em;
    padding: 0.32rem 0.9rem;
    border-radius: 100px;
    border: 1px solid rgba(255,255,255,0.175);
    color: rgba(255,255,255,0.85);
    background: rgba(255,255,255,0.07);
    backdrop-filter: blur(6px);
    cursor: default;
    transition: color 0.28s ease, background 0.28s ease, border-color 0.28s ease, transform 0.28s cubic-bezier(0.16,1,0.3,1);
}
@media (hover: hover) {
.skill-tag:hover {
    color: #073D4D;
    background: #EEFF00;
    border-color: #EEFF00;
    transform: translateY(-2px);
    box-shadow: 0 6px 20px rgba(238,255,0,0.3);
}
}
.skill-tag--dim {
    opacity: 0.45;
    border-style: dashed;
}
.skill-tag--lang {
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    padding: 0.28rem 0.85rem 0.28rem 0.38rem;
}
.skill-flag {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.55rem;
    height: 1.55rem;
    border-radius: 50%;
    overflow: hidden;
    font-size: 1.05rem;
    line-height: 1;
    flex-shrink: 0;
    background: rgba(255,255,255,0.08);
}
.skill-lang-name {
    color: rgba(255,255,255,0.85);
}
.skill-lvl {
    font-size: 0.8rem;
    letter-spacing: 0.01em;
    text-transform: none;
    color: rgba(255,255,255,0.35);
    padding-left: 0.5rem;
    border-left: 1px solid rgba(255,255,255,0.14);
    line-height: 1;
}
@media (hover: hover) {
.skill-tag--lang:hover .skill-lang-name { color: #073D4D; }
}
@media (hover: hover) {
.skill-tag--lang:hover .skill-lvl {
    color: rgba(7,61,77,0.65);
    border-left-color: rgba(7,61,77,0.25);
}
}

/* ─── Skills ─────────────────────────────────────────── */

.skills-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 1.25rem;
}
.skill-group {
    border: 1px solid transparent;
    background:
        linear-gradient(rgba(255,255,255,0.07), rgba(255,255,255,0.07)) padding-box,
        linear-gradient(rgba(255,255,255,0.14), rgba(255,255,255,0.14)) border-box;
    
    backdrop-filter: blur(16px);
    -webkit-backdrop-filter: blur(16px);
    
    border-radius: var(--radius);
    padding: 1.75rem;
    box-shadow: 0 4px 24px rgba(0,0,0,0.15), inset 0 1px 0 rgba(255,255,255,0.12), inset 0 -1px 0 rgba(0,0,0,0.1);
    transition: transform 0.3s ease, box-shadow 0.3s ease,
                background 0.3s ease, border-color 0.3s ease;
}
@media (hover: hover) {
.skill-group:hover {
    background:
        linear-gradient(transparent, transparent) padding-box,
        linear-gradient(135deg, rgba(0,201,173,0.45) 0%, rgba(238,255,0,0.30) 100%) border-box;
    
    transform: translateY(-7px);
    box-shadow: inset 0 0 0 9999px rgba(0,201,173,0.10), 0 24px 64px rgba(0,0,0,0.22),
                0 0 0 1px rgba(0,201,173,0.50),
                inset 0 1px 0 rgba(255,255,255,0.30);
}
}
.skill-group-title {
    font-family: var(--font-main); font-weight: 500;
    font-size: 0.945rem;
    color: var(--accent-2);
    letter-spacing: 0.01em;
    text-transform: none;
    margin-bottom: 1.1rem;
}
.skill-group ul {
    list-style: none;
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
}
.skill-group li {
    font-size: 0.88rem;
    color: var(--text-muted);
    padding-left: 1rem;
    position: relative;
    transition: color var(--transition);
}
.skill-group li::before {
    content: '·';
    position: absolute;
    left: 0;
    color: var(--accent-1);
    font-size: 0.62rem;
    top: 0.2em;
}
@media (hover: hover) {
.skill-group:hover li {
    transform: translateY(-7px); color: var(--text);
    box-shadow: inset 0 0 0 9999px rgba(0,201,173,0.10), 0 24px 64px rgba(0,0,0,0.22),
                0 0 0 1px rgba(0,201,173,0.50),
                inset 0 1px 0 rgba(255,255,255,0.30);
}
}

/* ─── Contact ────────────────────────────────────────── */
/* ─── Contact, same look as Work ────────────────────── */
#contact .work-stripe {
    transform: translateY(-50%) rotate(45deg);
}

#contact {
    background-color: #E8EBE6;
    position: relative;
    overflow: hidden;
    z-index: 1;
    margin-top: 0;
}
#contact::before {
    content: '';
    position: absolute;
    inset: 0;
    background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='grain'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='4' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23grain)' opacity='0.45'/%3E%3C/svg%3E");
    background-size: 200px 200px;
    opacity: 0.38;
    pointer-events: none;
    z-index: 1;
    mix-blend-mode: multiply;
}
#contact .container { position: relative; z-index: 2; }

.contact-grid {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 6rem;
    /* The text column is shorter than the form card, so `start` left it hanging
       with all the slack at the bottom. Centred, the two columns balance. */
    align-items: center;
}
.contact-text h2 {
    font-family: var(--font-display);
    font-size: clamp(1.75rem, 3.5vw, 2.7rem);
    font-weight: 700;
    letter-spacing: -0.02em;
    line-height: 1.25;
    margin-bottom: 1rem;
    color: #073D4D;
}
.contact-text p {
    color: #073D4D;
    font-size: 1rem;
    line-height: 1.8;
    margin-bottom: 2rem;
}
/* Triangle-led rows are inset by one --tri-gap, so the marker sits to the
   right of the body text's left edge rather than on it. */
/* No longer a list of topics, so no indent: these are pills now. */
.contact-links { display: flex; flex-direction: column; align-items: flex-start;
                 gap: 0.55rem; margin-top: 1.6rem; }
/* Plain icon + text rows, like the footer contacts (no card) */
/* The header pill, light variant: same radius, same three-layer chrome (top
   highlight, bottom shade, hairline stroke) and the same lift on hover. */
.contact-link {
    color: #073D4D;        /* same as .contact-link-icon */
    text-decoration: none;
    font-size: 0.95rem;
    font-weight: 600;      /* semibold */
    display: inline-flex;
    flex-direction: row;
    align-items: center;
    gap: 0.6rem;
    padding: 0.5rem 1.5rem;
    border: none;
    border-radius: 100px;
    background: rgba(7,61,77,0.045);
    box-shadow: inset 0 1px 0 rgba(255,255,255,0.5),
                inset 0 -2px 0 rgba(7,61,77,0.07),
                inset 0 0 0 1px rgba(7,61,77,0.07),
                0 4px 12px rgba(7,61,77,0.08);
    transition: transform 0.2s ease, background 0.2s ease, box-shadow 0.2s ease, color 0.2s ease;
}
.contact-link-icon,
.contact-link-ext { display: inline-flex; align-items: center; flex-shrink: 0; }
/* One fixed slot per icon, glyph centred inside it. The brand marks are 18px
   and the Material glyph 22px (a Material icon needs more to read the same
   size), which made the slots unequal and pushed each label to a different x.
   A common slot keeps the icons in a column and the labels aligned. */
.contact-link-icon {
    flex: 0 0 22px;
    width: 22px;
    justify-content: center;
}
/* Every glyph in the pill is the DS dark green; the label stays navy. */
.contact-link-icon { color: #007C67; }
/* Brand SVGs fill their box; Material glyphs are inset on a 24px grid, so the
   SVGs are set smaller to read at the same optical size. */
.contact-link-icon svg { width: 18px; height: 18px; }
.contact-link-label { flex: 0 1 auto; text-align: left; }
/* The external-link arrow keeps the label's navy. */
.contact-link-ext { color: #073D4D; margin-left: 0.1rem; }
/* Pills carry the lift, so they take the hover colour without the underline
   that bare text links get. */
@media (hover: hover) {
.contact-link:hover {
    color: var(--link-hover);
    background: rgba(7,61,77,0.075);
    transform: translateY(-2px);
    box-shadow: inset 0 1px 0 rgba(255,255,255,0.6),
                inset 0 -2px 0 rgba(7,61,77,0.07),
                inset 0 0 0 1px rgba(7,61,77,0.10),
                0 8px 20px rgba(7,61,77,0.12);
}
}
@media (hover: hover) {
.contact-link:hover .contact-link-icon,
.contact-link:hover .contact-link-ext { color: var(--link-hover); }
}

/* Form */
.form-group { margin-bottom: 1.1rem; }
.form-group label {
    display: block;
    font-size: 0.93rem;
    font-weight: 600;
    color: #073D4D;
    margin-bottom: 0.4rem;
    letter-spacing: normal;
    text-transform: none;
}
.form-group input,
.form-group textarea {
    width: 100%;
    background: rgba(255,255,255,0.55);
    backdrop-filter: blur(12px);
    -webkit-backdrop-filter: blur(12px);
    border: 1.5px solid rgba(7,61,77,0.15);
    border-radius: 10px;
    padding: 0.85rem 1rem;
    color: #073D4D;
    font-family: var(--font-main);
    font-size: 0.93rem;
    outline: none;
    transition: border-color var(--transition);
    resize: vertical;
}
.form-group input:focus,
.form-group textarea:focus { border-color: #00C9AD; }
.form-group input::placeholder,
.form-group textarea::placeholder { color: rgba(7,61,77,0.85); }
/* Send Message button: same as the case-page "Download PDF" button (teal, white text) */
#contact .contact-form .btn-primary {
    background: #0B5F72;
    color: #ffffff;
    box-shadow: inset 0 1px 0 rgba(255,255,255,0.18), inset 0 -2px 0 rgba(0,0,0,0.18), 0 4px 14px rgba(11,95,114,0.32);
}
@media (hover: hover) {
#contact .contact-form .btn-primary:hover {
    transform: translateY(-7px);
    background: #0d7088;
    box-shadow: inset 0 0 0 9999px rgba(0,201,173,0.10), 0 24px 64px rgba(0,0,0,0.22),
                0 0 0 1px rgba(0,201,173,0.50),
                inset 0 1px 0 rgba(255,255,255,0.30);
}
}

/* Case-card CTA buttons ("View Case Study", "Read paper") match the contact
   "Send Message" button, same teal colour, white text, chrome and padding. */
#work .cases-track .case-body .btn-primary {
    background: #0B5F72;
    color: #ffffff;
    padding-top: 1rem;
    padding-bottom: 1rem;
    line-height: normal; /* match the <button>'s normal line-height so heights are identical */
    box-shadow: inset 0 1px 0 rgba(255,255,255,0.18), inset 0 -2px 0 rgba(0,0,0,0.18), 0 4px 14px rgba(11,95,114,0.32);
}
@media (hover: hover) {
#work .cases-track .case-body .btn-primary:hover {
    background: #0d7088;
    box-shadow: inset 0 1px 0 rgba(255,255,255,0.18), inset 0 -2px 0 rgba(0,0,0,0.18), 0 12px 30px rgba(11,95,114,0.45);
}
}

/* ─── Contact form card, exact match of #work .case-card-v2 ── */
#contact .contact-form {
    padding: 1.75rem;
    border-radius: 12px;
    overflow: hidden;
    background:
        linear-gradient(rgba(255,255,255,0.10), rgba(255,255,255,0.10)) padding-box,
        linear-gradient(135deg, rgba(255,255,255,0.10), rgba(255,255,255,0.10)) border-box;
    backdrop-filter: blur(14px);
    -webkit-backdrop-filter: blur(14px);
    border: 1px solid transparent;
    box-shadow:
        0 8px 40px rgba(0,0,0,0.18),
        0 0 0 1px rgba(255,255,255,0.55),
        inset 0 1px 0 rgba(255,255,255,0.30);
    transition: transform 0.3s ease, box-shadow 0.3s ease,
                background 0.3s ease, border-color 0.3s ease;
}
@media (hover: hover) {
#contact .contact-form:hover {
    transform: translateY(-7px);
    background:
        linear-gradient(rgba(255,255,255,0.15), rgba(255,255,255,0.15)) padding-box,
        linear-gradient(135deg, rgba(0,201,173,0.45) 0%, rgba(238,255,0,0.30) 100%) border-box;
    border: 1px solid transparent;
    box-shadow: inset 0 0 0 9999px rgba(0,201,173,0.10), 0 24px 64px rgba(0,0,0,0.22),
                0 0 0 1px rgba(0,201,173,0.50),
                inset 0 1px 0 rgba(255,255,255,0.30);
}
}


/* ─── Footer ─────────────────────────────────────────── */
footer {
    background:
        radial-gradient(circle, rgba(255,255,255,0.08) 1px, transparent 1px),
        #071218;
    background-size: 22px 22px, 100% 100%;
    padding: 1.5rem 0 1.15rem; /* just clears the 24px gradient bar; the card's top spacing now lives in the grid padding */
    position: relative;
    overflow: hidden;
}
footer::before {
    content: '';
    display: block;
    width: 100%;
    height: 24px;
    background: linear-gradient(90deg, #00C9AD 0%, #EEFF00 100%);
    opacity: 0.55;
    position: absolute;
    top: 0;
    left: 0;
    z-index: 2;
}
/* Green bloom hanging off the footer's top edge and falling into the dark,
   the same gradient and height as the one under the logo strip on the home
   page. Its own element because footer::before (the gradient bar) and
   footer::after (the grain) are both already in use. Sits above the footer's
   base fill and below .container, which is z-index 3. */
.footer-glow {
    position: absolute;
    top: 0;
    left: 50%;
    transform: translateX(-50%);
    width: 100vw;
    height: 360px;
    z-index: 1;
    pointer-events: none;
    background: radial-gradient(ellipse 100% 100% at 50% 0%,
        rgba(70, 226, 80, 0.26) 0%,
        rgba(70, 226, 80, 0.14) 30%,
        rgba(70, 226, 80, 0.06) 52%,
        rgba(70, 226, 80, 0.00) 76%);
}
footer::after {
    content: '';
    position: absolute;
    inset: 0; /* confined to the footer, must not bleed up into the light section above */
    z-index: 1;
    pointer-events: none;
    opacity: 0.13;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='300' height='300'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='300' height='300' filter='url(%23n)'/%3E%3C/svg%3E");
    background-size: 200px 200px;
    animation: grainShift 0.4s steps(2) infinite;
}
footer .container { position: relative; z-index: 3; max-width: 100%; padding-left: 3.5rem; padding-right: 3.5rem; }
.footer-grid {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 2.5rem 0; /* no column gap so the side spacers stay symmetric around the centred card */
    margin: 0 -3.5rem 1.33rem; /* break out of the container padding so the grid spans the full footer width */
    padding: 2.6rem 0; /* top room lets the kanji rise behind the card; bottom keeps the card off the divider line */
    align-items: center;
    position: relative;
    overflow: hidden; /* crops the kanji at the divider line (top/bottom); sides reach the footer edges so no side crop */
}
/* vertical divider, after first column */
.footer-grid::before {
    content: none;
    position: absolute;
    left: calc((100% - 4rem) / 3 + 2rem);
    top: calc(-3.5rem + 24px);
    bottom: 0;
    width: 1px;
    background: rgba(255,255,255,0.08);
    pointer-events: none;
}
/* full-width horizontal line at the bottom of the upper section */
.footer-grid::after {
    content: '';
    position: absolute;
    bottom: 0;
    left: -100vw;
    width: 200vw;
    height: 1px;
    background: var(--divider);
    pointer-events: none;
}
/* Footer brand as a card, frosted layout like the About .highlight-card, stretched to ~half the footer
   and holding the logo, role, a divider line, and the contact links. */
.footer-brand {
    border: 1px solid transparent;
    background:
        linear-gradient(135deg, rgba(7,42,52,0.42) 0%, rgba(7,42,52,0.26) 100%) padding-box,
        linear-gradient(rgba(255,255,255,0.10), rgba(255,255,255,0.10)) border-box;
    position: relative;
    z-index: 2;
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: 1.1rem;
    flex: 0 1 auto;       /* size to content, not 48% of the full-width footer */
    max-width: 100%;
    /* The card's side padding matches the space below the pills, so the gap
       around them reads the same on three sides. */
    --footer-brand-pad-x: 1.05rem;
    padding: 2.35rem var(--footer-brand-pad-x) 1.05rem;
    
    backdrop-filter: blur(18px) saturate(115%);
    -webkit-backdrop-filter: blur(18px) saturate(115%);
    
    border-radius: 16px;
    box-shadow: inset 0 1px 0 rgba(255,255,255,0.08), 0 22px 60px rgba(0,0,0,0.42);
    transition: transform 0.3s ease, box-shadow 0.3s ease,
                background 0.3s ease, border-color 0.3s ease;
}
.footer-logo-img {
    height: 19px;
    width: auto;
    max-width: 100%;
    display: block;
}
/* It is a card, so it hovers like one. */
@media (hover: hover) {
.footer-brand:hover {
    background:
        linear-gradient(transparent, transparent) padding-box,
        linear-gradient(135deg, rgba(0,201,173,0.45) 0%, rgba(238,255,0,0.30) 100%) border-box;
    transform: translateY(-7px);
    
    box-shadow: inset 0 0 0 9999px rgba(0,201,173,0.10), 0 24px 64px rgba(0,0,0,0.22),
                0 0 0 1px rgba(0,201,173,0.50),
                inset 0 1px 0 rgba(255,255,255,0.30);
}
}

.footer-brand-id {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    gap: 0.9rem;
}
.footer-brand-sep {
    /* Spans the card edge to edge. The parent is a flex column with
       align-items:center, so this needs align-self:stretch to fill the cross
       axis; width:auto collapsed it to nothing because it has no content. The
       negative side margins then carry it out past the card's padding. */
    align-self: stretch;
    margin-inline: calc(var(--footer-brand-pad-x) * -1);
    height: 1px;
    background: var(--divider);
    flex-shrink: 0;
}
/* Equal flex spacers keep the card centred; the back-to-top button sits centred in the right gap */
.footer-grid-side {
    flex: 1 1 0;
    min-width: 0;
    display: flex;
    align-items: center;
    justify-content: center;
}
.footer-totop {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    text-decoration: none;   /* the underline was drawing a bar under the arrow */
    width: 48px;
    height: 48px;
    border-radius: 50%;
    /* match the secondary white button (.btn-ghost): no border, same frosted-white chrome */
    background: #ffffff;
    color: #073D4D;
    border: none;
    box-shadow: inset 0 1px 0 rgba(255,255,255,0.8), inset 0 -2px 0 rgba(0,0,0,0.08), 0 4px 12px rgba(0,0,0,0.12);
    transition: transform 0.2s ease, background 0.2s ease, box-shadow 0.2s ease;
    /* sits on the divider band at the very top of the footer, inset to the side margin (3.5rem) */
    position: absolute;
    top: 0;
    right: 3.5rem;
    z-index: 8;
}
@media (hover: hover) {
.footer-totop:hover {
    background: #f0f0f0;
    transform: translateY(-2px);
    box-shadow: inset 0 1px 0 rgba(255,255,255,0.8), inset 0 -2px 0 rgba(0,0,0,0.08), 0 8px 20px rgba(0,0,0,0.15);
}
}
/* Two pills on the first line, the third centred on its own below. A grid
   rather than a wrapping flex row: the track pair sizes the block to the two
   widest pills, so the card hugs them instead of staying as wide as all three
   laid end to end. */
.footer-brand-contacts {
    display: grid;
    grid-template-columns: auto auto;
    justify-content: center;
    justify-items: center;
    align-items: center;
    gap: 0.6rem;   /* pills carry their own padding, so they sit closer */
}
.footer-brand-contacts > a:nth-child(3) { grid-column: 1 / -1; }
.footer-name {
    font-family: var(--font-display);
    font-size: 1.6rem;
    font-weight: 800;
    letter-spacing: -0.02em;
    line-height: 1;
    background: linear-gradient(90deg, #ffffff 0%, rgba(255,255,255,0.75) 100%);
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-clip: text;
}
.footer-role {
    font-family: var(--font-main); font-weight: 500;
    font-size: 1.0rem;
    letter-spacing: 0.01em;
    text-transform: none;
    color: #ffffff;
    margin-top: 0.4rem;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.7rem;
}
.footer-role-text { text-align: center; }
/* the role runs on one line until the column is too narrow for it */
.footer-role-br { display: none; }
.footer-role::before,
.footer-role::after {
    /* the paired slashes become the DS triangle, both pointing inward */
    content: '';
    width: var(--tri-w); height: var(--tri-h);
    background-color: #46E250;
    -webkit-mask: url("triangle-right.svg") no-repeat center / contain;
    mask: url("triangle-right.svg") no-repeat center / contain;
    flex-shrink: 0; opacity: 0.5;}
.footer-role::after { -webkit-mask-image: url("triangle-left.svg"); mask-image: url("triangle-left.svg"); }
/* Location as a horizontal strip below the card: items side by side, split by yellow bars */
.footer-loc-strip {
    position: relative;
    z-index: 2;
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 1.1rem;
    flex-wrap: wrap;
    margin-top: 0.4rem;
}
.footer-loc-sep {
    color: rgba(255, 255, 255, 0.55);
    font-weight: 400;
    flex-shrink: 0;
    line-height: 1;
}
/* White circle sitting behind each flag emoji */
.loc-flag {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 1.55em;
    height: 1.55em;
    border-radius: 50%;
    background: #ffffff;
    font-size: 0.92em;
    line-height: 1;
    flex-shrink: 0;
}
.loc-flag + .loc-flag {
    margin-left: -0.35em; /* overlap the EU/US pair slightly */
}
/* Location items match the Navigation column's link style (white mono, same size/spacing) */
.footer-loc {
    font-family: var(--font-main);
    font-size: 0.972rem;
    font-weight: 500;
    letter-spacing: 0.01em;
    text-transform: none;
    color: #ffffff;
    margin-top: 0;
    display: flex;
    align-items: center;
    gap: 0.45rem;
}
.footer-loc--remote {
    color: #EEFF00;
    margin-top: 0.35rem;
    opacity: 1;
}
.footer-links {
    display: flex;
    align-items: stretch;
    gap: 2.5rem;
    flex: 1;
}
.footer-links > .footer-col { flex: 1; }
.footer-col-sep {
    width: 1px;
    align-self: stretch;
    background: rgba(255,255,255,0.08);
    flex-shrink: 0;
}
/* Location column, split out of the brand to fill the row and shorten the brand */
.footer-where { gap: 1.1rem; }
.footer-where .footer-loc { margin-top: 0; }
.footer-col {
    display: flex;
    flex-direction: column;
    gap: 1.1rem;
}
.footer-col-label {
    font-family: var(--font-main); font-weight: 500;
    font-size: 0.81rem;
    letter-spacing: 0.01em;
    text-transform: none;
    color: #00C9AD;
    padding-bottom: 0.6rem;
    margin-bottom: 0.2rem;
}
footer a {
    font-family: var(--font-main);
    font-size: 0.85rem;
    font-weight: 600;
    letter-spacing: normal;
    text-transform: none;
    color: #ffffff;
    text-decoration: none;
    transition: color var(--transition);
    width: fit-content;
}
footer nav a::before {
    content: ''; display: inline-block; width: var(--tri-w); height: var(--tri-h); vertical-align: 0.04em; -webkit-mask: url("triangle-right.svg") no-repeat center / contain; mask: url("triangle-right.svg") no-repeat center / contain; margin-right: var(--tri-gap);
    background-color: #46E250;
    font-weight: 400; opacity: 0.5;}
@media (hover: hover) {
footer a:hover { color: var(--link-hover-dark); }
}
/* Same underline as the light-ground links, in the green these already use.
   .footer-totop is an icon-only link, so it stays bare. */
@media (hover: hover) {
.footer-policy-link:hover,
.footer-legal-link:hover,
footer nav a:hover { text-decoration: underline; }
}
/* The header pill, dark variant. */
.footer-contact-link {
    display: inline-flex !important;
    align-items: center;
    gap: 0.6rem;
    text-transform: none !important;
    letter-spacing: normal !important;
    font-family: var(--font-main) !important;
    font-size: 0.95rem !important;
    font-weight: 600 !important;   /* semibold */
    color: #ffffff !important;
    padding: 0.5rem 1.5rem;
    border: none;
    border-radius: 100px;
    background: rgba(255,255,255,0.05);
    box-shadow: inset 0 1px 0 rgba(255,255,255,0.16),
                inset 0 -2px 0 rgba(0,0,0,0.10),
                inset 0 0 0 1px rgba(255,255,255,0.07),
                0 4px 12px rgba(0,0,0,0.12);
    transition: transform 0.2s ease, background 0.2s ease, box-shadow 0.2s ease, color 0.2s ease;
}
@media (hover: hover) {
.footer-contact-link:hover {
    color: var(--link-hover-dark) !important;
    background: rgba(255,255,255,0.10);
    transform: translateY(-2px);
    box-shadow: inset 0 1px 0 rgba(255,255,255,0.22),
                inset 0 -2px 0 rgba(0,0,0,0.10),
                inset 0 0 0 1px rgba(255,255,255,0.10),
                0 8px 20px rgba(0,0,0,0.15);
}
}
.footer-contact-link svg { flex-shrink: 0; color: #46E250; opacity: 1; }
/* Leading icon green; the trailing external-link arrow follows the white text. */
.footer-contact-link .material-symbols-outlined:not(.footer-link-ext) { color: #46E250; }
.footer-contact-link .footer-link-ext { color: inherit; }
@media (hover: hover) {
.footer-contact-link:hover svg { opacity: 0.8; }
}
.footer-disclaimer {
    padding: 0.75rem 0 0;
    margin-top: 0;
}
/* The disclaimer is a block of plain prose. The email address inside it is NOT
   a link and must never become one again: it reads as part of the sentence.
   This rule is a guard, so that if an anchor is ever reintroduced it still
   renders as ordinary text. */
.footer-disclaimer a,
.footer-disclaimer a:visited {
    font: inherit;
    letter-spacing: inherit;
    text-transform: none;
    color: inherit;
    text-decoration: none;
    background: none;
    cursor: text;
    pointer-events: none;
}
@media (hover: hover) {
.footer-disclaimer a:hover {
    font: inherit;
    letter-spacing: inherit;
    text-transform: none;
    color: inherit;
    text-decoration: none;
    background: none;
    cursor: text;
    pointer-events: none;
}
}
.footer-disclaimer p {
    font-family: var(--font-main);
    font-size: 0.625rem;   /* 10px at a 16px root */
    font-weight: 400;
    line-height: 1.5;
    color: rgba(255, 255, 255, 0.84);   /* same as .cv-card-text */
    letter-spacing: normal;
    text-align: center;
    margin: 0;
}
/* Copyright and the two policy links share one line, separated by the DS
   triangle. The gap lives on the flex container rather than on .ds-tri's own
   margin-right, so each marker is spaced identically on both sides. */
.footer-bottom {
    display: flex;
    flex-direction: row;
    justify-content: center;
    align-items: center;
    /* Wider than --tri-gap: these markers separate three phrases rather than
       leading one, so the 8px a leading marker uses reads cramped here. */
    gap: 0.75rem;
    flex-wrap: wrap;
}
/* .ds-tri carries its own margin-right, which would land on one side only and
   leave the marker off-centre between its neighbours. Zeroing it hands all the
   spacing to the row's gap, so both sides of every marker measure the same.
   The compound selector is needed because .ds-tri is declared further down. */
.ds-tri.footer-policies-tri {
    color: #46E250;
    margin-right: 0;
    margin-left: 0;
}
/* Same size and weight as .footer-copy beside them, with the external-link
   glyph the footer's contact links already use. */
.footer-policy-link {
    display: inline-flex;
    align-items: center;
    gap: 0.3rem;
    font-family: var(--font-main);
    font-size: 0.75rem;
    font-weight: 600;
    color: #ffffff;
    text-decoration: none;
}
.footer-copy {
    font-family: var(--font-main);
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: normal;
    color: #ffffff;
}
footer p {
    font-family: var(--font-main);
    font-size: 0.78rem;
    font-weight: 600;
    letter-spacing: normal;
    color: #ffffff;
}
.footer-legal {
    display: flex;
    align-items: center;
    gap: 0.75rem;
}
.footer-legal-link {
    font-family: var(--font-main); font-weight: 500;
    font-size: 0.878rem !important;
    letter-spacing: 0.01em;
    text-transform: none !important;
    color: #ffffff !important;
    text-decoration: none;
    transition: color var(--transition);
}
.footer-legal-link::before { content: none !important; }
@media (hover: hover) {
.footer-legal-link:hover { color: var(--link-hover-dark) !important; }
}
.footer-legal-sep {
    color: rgba(255,255,255,0.35);
    font-size: 0.45rem;
    line-height: 1;
}

/* ─── Responsive ─────────────────────────────────────── */
@media (max-width: 1100px) {
    .skills-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 900px) {
    .about-grid   { grid-template-columns: 1fr; gap: 3.5rem; }
    .contact-grid { grid-template-columns: 1fr; gap: 3.5rem; }
    .work-grid    { grid-template-columns: 1fr; }
    .cases-grid   { grid-template-columns: 1fr; }
    .case-card-v2.case-featured { flex-direction: column; min-height: 0; }
    .case-featured .case-visual { width: auto; height: 300px; }
    .case-featured .case-body { padding: 1.75rem; }
    .case-number  { display: none; }
}
@media (max-width: 768px) {
    #navbar { padding: 0.75rem 1.5rem; }
    .nav-links { display: none; }
    .container { padding: 0 1.5rem; }
    footer .container { padding-left: 1.5rem; padding-right: 1.5rem; }
    section { padding: 5rem 0; }
}
@media (max-width: 540px) {
    .skills-grid  { grid-template-columns: 1fr; }
    .about-stats  { grid-template-columns: 1fr 1fr; }
    .footer-inner { flex-direction: column; gap: 0.5rem; text-align: center; }
}

/* ─────────────────────────────────────────────────────────────────────────
   Unified card corner radius, every content card / panel / modal / tile
   across the ENTIRE site matches the "Competitors: the goods & bads"
   cards (.cs-app-card = 12px). Loaded on every page; !important so it wins
   over the per-page inline <style> rules. Grouped/one-sided cards keep their
   square edges. Excludes buttons, pills, badges, avatars, phone mockups,
   images, swatches, progress bars and nav dropdown menus.
   ───────────────────────────────────────────────────────────────────────── */
/* All-corner cards → 12px */
.highlight-card,
.about-cta-card,
.stat-card,
.lang-card,
.skill-group,
.footer-brand,
.case-card-v2,
#work .cases-track > .case-card-v2,
#contact .contact-form,
.csh-box,
.cs-meta-item,
.cs-insight-card,
.cs-nps-card,
.cs-problem-item,
.cs-rstat,
.cs-pcard,
.cs-pcard2,
.cs-pside,
.cs-modal-box,
.cs-sm-item,
.cs-barchart,
.cs-insight-flag,
.cs-persona-panel,
.cs-day-card,
.cs-journey-flow,
.cs-pivot-panel,
.cs-mission-row,
.cs-metric-card,
.cs-revenue,
.cs-lcard,
.cs-more-card,
.cs-dd-card,
.cs-roles-card,
.cs-app-card,
.cs-step-card,
.cs-jp-stage,
.cs-intl-tile,
.ac-lang,
.ac-quote,
.ac-split-card {
    border-radius: 12px !important;
}
/* Grouped / one-sided cards → keep their square edges, round the rest to 12px */
.cs-modal-tabs {
    border-radius: 12px 12px 0 0 !important;
}
.cs-disclaimer,
.cs-quote {
    border-radius: 0 12px 12px 0 !important;
}

/* ─── Home footer back-to-top ─────────────────────────────
   Non-clipping wrapper around the footer so the button can be vertically
   centred on the green strip at the footer's top edge, crossing the border
   without being cropped by the footer's overflow:hidden. */
.footer-anchor { position: relative; }
/* Centre the button on the green strip (sits just below the footer's top edge). */
.footer-anchor > .footer-totop { transform: translateY(calc(-50% + 10px)); }
@media (hover: hover) {
.footer-anchor > .footer-totop:hover { transform: translateY(calc(-50% + 8px)); }
} /* 2px lift, matching the other white buttons */

/* ─── Light-mode sections: no background grain ─────────────
   The multiply grain on the light (#E8EBE6) sections read as static noise behind the
   components, so it's removed on every light section site-wide. !important beats the
   per-page inline .cs-light-body::before rule on the case-study pages. */
#work::before,
#contact::before,
.cs-light-body::before {
    display: none !important;
}

/* ═══════════════════════════════════════════════════════════════════════
   MOBILE SYSTEM, shared by every page.
   Sizing follows the Scissero site: nav 58px tall, side padding 24px on
   mobile and 56px from 1024px up, nav switches to an overlay below 1024px,
   touch targets 44px minimum, breakpoints 1024 / 768 / 640.
   Loaded last so it wins over the per-page inline <style> blocks.
   ═══════════════════════════════════════════════════════════════════════ */

/* ── Burger + overlay: hidden on desktop, shown below 1024px ── */
.nav-burger { display: none; }
.nav-mobile { display: none; }

@media (max-width: 1023px) {
    /* The navbar never fit a phone: links + centred logo + language + CTA all
       on one row made it 421-501px wide on a 390px screen, which is what pushed
       every page sideways. Below 1024px the links move into an overlay. */
    #navbar {
        height: 58px;
        padding: 0 0.75rem 0 1.5rem;   /* Scissero: pl-6 pr-3 */
        justify-content: space-between;
        gap: 0.5rem;
    }
    .nav-links { display: none !important; }
    .nav-logo {
        position: absolute;
        left: 50%;
        top: 50%;
        transform: translate(-50%, -50%);
        min-height: 44px;
        display: flex;
        flex-direction: row;
        align-items: center;
        justify-content: center;   /* the anchor is a column flex box by default */
    }
    /* Scale the wordmark with the viewport; it is 2673x167, so height = width/16.
       The bar is wordmark + burger, so the wordmark can take most of the width:
       at 375px it clears the 44px burger and the 20px gutter with room to spare. */
    .nav-logo-img {
        /* the floor clears the 44px burger on a 320px bar with room to spare */
        width: clamp(190px, 56vw, 264px);
        height: clamp(11.875px, 3.5vw, 16.5px);
    }
    .nav-right { display: none !important; }
    /* The wordmark is absolutely centred below 1024px, so anything else in the
       bar would sit on top of it. Contact and LinkedIn live in the overlay
       instead; the bar is wordmark + burger only. */
    .nav-cta { display: none !important; }

    /* The Material Symbols subset carries `close` but not `menu`, and the font
       cannot be rebuilt here. Both states are the real Material glyph paths
       carried as masks, the same technique .ds-tri and .nav-logo-img use, so
       they follow currentColor and match the font icons' weight. */
    .nav-burger {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        width: 44px;
        height: 44px;
        padding: 0;
        margin-left: auto;
        background: none;
        border: none;
        cursor: pointer;
        z-index: 101;
        color: inherit;
    }
    .nav-burger-icon {
        display: block;
        /* a step down from 26px: it was reading larger than the wordmark
           beside it */
        width: 22px;
        height: 22px;
        /* the wordmark's base, recoloured by the two state rules above it */
        background-color: #ffffff;
        -webkit-mask: url("menu.svg") no-repeat center / contain;
        mask: url("menu.svg") no-repeat center / contain;
        transition: background-color 0.4s ease;
    }
    .nav-burger[aria-expanded="true"] .nav-burger-icon {
        -webkit-mask-image: url("close.svg");
        mask-image: url("close.svg");
    }
    /* Over the open overlay the bar is always on the dark ground, whatever
       section is behind it. */
    body.nav-open #navbar,
    body.nav-open #navbar .nav-logo-img { color: #ffffff; }
    body.nav-open #navbar .nav-logo-img,
    body.nav-open #navbar .nav-burger-icon { background-color: #ffffff; }

    /* The overlay covers the page edge to edge, the navbar riding above it at
       z-index 100. Ground, blur and saturation are the prototype modal's
       backdrop; the alpha is higher than the modal's 0.46 because this sheet
       opens over light sections as well as dark ones and the ground has to
       land on the same deep green either way for the white content to hold. */
    .nav-mobile {
        display: block;
        position: fixed;
        inset: 0;
        z-index: 99;
        background: rgba(0, 48, 40, 0.88);
        backdrop-filter: blur(16px) saturate(1.1);
        -webkit-backdrop-filter: blur(16px) saturate(1.1);
        overflow-y: auto;
        -webkit-overflow-scrolling: touch;
        opacity: 0;
        visibility: hidden;
        transition: opacity .22s ease, visibility .22s ease;
    }
    .nav-mobile[hidden] { display: block; }   /* animate instead of snapping */
    .nav-mobile.is-open { opacity: 1; visibility: visible; }
    .nav-mobile-inner {
        display: flex;
        flex-direction: column;
        align-items: stretch;
        gap: 0.75rem;
        /* clears the 58px bar, then the page gutter */
        padding: calc(58px + 1.25rem) 1.25rem 2.5rem;
    }

    /* The header's own pills, stacked: same geometry, same three-layer chrome,
       sized for a 48px touch target. The ground is dark, so they take the
       dark-nav treatment whatever section sits behind the overlay. */
    .nav-mobile-pill {
        display: flex;
        align-items: center;
        gap: var(--tri-gap);
        width: 100%;
        min-height: 48px;
        padding: 0.5rem 1.5rem;
        border: none;
        border-radius: 100px;
        font-family: var(--font-main);
        font-size: 0.82rem;
        font-weight: 600;
        letter-spacing: normal;
        text-transform: none;
        text-decoration: none;
        color: #ffffff;
        background: rgba(255,255,255,0.05);
        box-shadow: inset 0 1px 0 rgba(255,255,255,0.16),
                    inset 0 -2px 0 rgba(0,0,0,0.10),
                    inset 0 0 0 1px rgba(255,255,255,0.07),
                    0 4px 12px rgba(0,0,0,0.12);
        cursor: pointer;
        transition: background 0.2s ease, box-shadow 0.2s ease, color 0.2s ease;
    }
    .nav-mobile-pill::before { content: none !important; }
    .nav-mobile-pill:active { background: rgba(255,255,255,0.10); }
    /* LinkedIn is the same pill, as it is in the header */
    .nav-mobile-pill--cta .li-mark { flex-shrink: 0; }
    .nav-mobile-ext { font-size: 16px; margin-left: 2px; }
    /* The caret follows its label. `margin-left: auto` had pushed it to the far
       end of a pill that runs the width of the sheet, where it read as a
       separate control 250px from the words it opens; without it the caret
       sits directly after the text, one gap away. */
    .nav-mobile-caret {
        font-size: 18px;
        transition: transform 0.25s ease;
    }
    .nav-mobile-trigger[aria-expanded="true"] .nav-mobile-caret { transform: rotate(180deg); }

    .nav-mobile-group { display: flex; flex-direction: column; }
    /* The dropdown opens directly under its pill, in the header dropdown's
       own chrome. */
    .nav-mobile-menu {
        margin: 0.5rem 0 0;
        padding: 0.4rem 0;
        background: rgba(7,18,24,0.92);
        backdrop-filter: blur(20px);
        -webkit-backdrop-filter: blur(20px);
        border: 1px solid rgba(255,255,255,0.12);
        border-radius: 14px;
        overflow: hidden;
        box-shadow: 0 16px 48px rgba(0,0,0,0.4);
    }
    .nav-mobile-menu[hidden] { display: none; }
    .nav-mobile-menu a {
        display: block;
        min-height: 44px;
        padding: 0.75rem 1.2rem;
        font-family: var(--font-main);
        font-size: 0.85rem;
        font-weight: 600;
        letter-spacing: normal;
        text-transform: none;
        color: rgba(255,255,255,0.72) !important;
        text-decoration: none;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }
    .nav-mobile-menu a::before { content: none !important; }
    .nav-mobile-menu a:active { color: #EEFF00 !important; }

    body.nav-open { overflow: hidden; }
}

/* ── Overflow containment: nothing may push the document sideways ── */
@media (max-width: 1023px) {
    html { overflow-x: clip; }
    body { max-width: 100%; }
    #navbar { max-width: 100vw; overflow-x: clip; }

    /* The case-study hero measured 500px wide on a 390px screen (decorative
       circles and the rotated kanji stripe sit outside the text column). */
    .cs-hero { overflow-x: clip; }

    /* Modals were 501px wide and fixed, so they widened the page even closed. */
    .cs-modal { max-width: 100vw; overflow-x: hidden; }
    .cs-modal-box { max-width: calc(100vw - 2rem); }

    /* index: #about was unclipped at 437px. */
    #about, #work, #contact, .policy-page, footer { overflow-x: clip; }

    /* Anything with an intrinsic width taller than the screen */
    img, video, svg, canvas, iframe { max-width: 100%; height: auto; }
}

/* ── Touch targets: 44px minimum (Scissero uses a 48px CTA) ── */
@media (max-width: 1023px) {
    .footer-contact-link,
    .contact-link,
    .work-tab,
    .cs-mtab,
    .cs-pcard-more,
    .footer-links a {
        min-height: 44px;
        display: inline-flex;
        align-items: center;
    }
    .work-tab { padding-block: 0.9rem; }
}

/* ── Layout: one column, consistent gutters, on every page ── */
@media (max-width: 1023px) {
    .container { padding-left: 1.5rem; padding-right: 1.5rem; }
    section { padding-block: 4.5rem; }
}
@media (max-width: 767px) {
    .about-loc-row { gap: 1.75rem 2.25rem; }
    .cv-grid, .cases-grid, .skills-grid, .about-highlight-row { grid-template-columns: 1fr 1fr; }
    .contact-grid { grid-template-columns: 1fr; }
    .footer-inner { flex-direction: column; gap: 0.75rem; text-align: center; }
}
@media (max-width: 639px) {
    .container { padding-left: 1.25rem; padding-right: 1.25rem; }
    .cv-grid, .cases-grid, .skills-grid, .about-highlight-row,
    .about-loc-row { grid-template-columns: 1fr; }
    .about-loc-row { flex-direction: column; align-items: center; gap: 1.5rem; }
    section { padding-block: 3.5rem; }
}

/* ── Global overflow guard: no viewport width may scroll sideways.
   Decorative layers (rotated stripes, oversized blobs, marquees) sit outside
   the text column by design; they are clipped rather than allowed to widen
   the page. Applies at every width, so tablet-landscape (1024-1180px) behaves
   like phone and desktop. ── */
/* Only <html> clips sideways. Putting overflow on <body> makes it a scroll
   container, which silently disables position: sticky for every descendant:
   `hidden` does it outright, and `clip` does it too, because with overflow-y
   left visible the browser computes that axis to `auto`. */
html { overflow-x: clip; }
body { max-width: 100%; }
#hero, #work, #about, #contact,
.cs-hero, .policy-page, footer { overflow-x: clip; }

/* .cs-card is a full-bleed tonal band now, never a rounded card. */
.cs-card, .cs-band-a, .cs-band-b { border-radius: 0 !important; }

/* ── Label markers: the paired "/" glyphs are the DS triangle, both pointing
   inward at the label (> text <). Drawn as a mask filled with currentColor, so
   each marker takes the colour set on its own span, exactly like the old
   slashes did (#46E250 over the dark green sections, #007A68 over light). ── */
.ds-tri {
    display: inline-block;
    width: var(--tri-w); height: var(--tri-h);
    vertical-align: -0.03em;
    background-color: currentColor;
    -webkit-mask: url("triangle-right.svg") no-repeat center / contain;
    mask: url("triangle-right.svg") no-repeat center / contain;
    flex: 0 0 auto;
    margin-right: var(--tri-gap); opacity: 0.5;}
.ds-tri--end {
    -webkit-mask-image: url("triangle-left.svg");
    mask-image: url("triangle-left.svg");
    margin-right: 0;
    margin-left: var(--tri-gap);
}

/* ── Section-divider markers ────────────────────────────────────────────────
   The two band dividers ("Expertise that made a difference at", "How it works
   in practice") carry five markers a side, all on the standard --tri-gap so
   the run is evenly spaced. Only the opacity steps down, so the markers fade
   out the further they sit from the text.

   Spacing comes from the base .ds-tri / .ds-tri--end rules; these compound
   selectors (0,2,0) only override the shared 0.5 opacity. ── */
.ds-tri.ds-tri--r1 { opacity: 0.50; }
.ds-tri.ds-tri--r2 { opacity: 0.38; }
.ds-tri.ds-tri--r3 { opacity: 0.28; }
.ds-tri.ds-tri--r4 { opacity: 0.19; }
.ds-tri.ds-tri--r5 { opacity: 0.11; }


/* ── Material Symbols (Google Fonts) ──────────────────────────────────────
   Icons are the real library now, loaded as a subsetted variable font and
   written as ligatures. Sizing is font-size, colour is `color`, so they
   inherit like text. `font-display: block` in the Google stylesheet keeps
   the ligature name from flashing before the font arrives. */
.material-symbols-outlined {
    font-family: 'Material Symbols Outlined';
    font-weight: normal;
    font-style: normal;
    line-height: 1;
    letter-spacing: normal;
    text-transform: none;
    display: inline-block;
    white-space: nowrap;
    word-wrap: normal;
    direction: ltr;
    font-variation-settings: 'FILL' 0, 'wght' 400, 'GRAD' 0, 'opsz' 24;
    -webkit-font-feature-settings: 'liga';
    -webkit-font-smoothing: antialiased;
    vertical-align: middle;
    flex: 0 0 auto;
    user-select: none;
}
/* the card icons are sized by their 30px box */
.cv-card-icon .material-symbols-outlined { font-size: 30px; }

/* ── Optical padding on the icon side ──────────────────────────────
   A Material glyph and the brand marks carry blank space inside their own em
   box, so a numerically equal gap reads wider on the icon side than on the
   text side. Every button and pill therefore takes exactly 4px less padding on
   whichever side holds an icon, and 4px off both when icons sit on both sides.

   Each value below is the component's base padding minus 4px, never a trim of
   an already-trimmed value. Order matters: .btn is listed first so .btn-cv and
   .btn-ghost, which share its specificity, still win afterwards. */
.btn { padding-right: 1.65rem; }                 /* trailing icon, 1.9rem - 4px */
.btn-cv,
.btn-ghost { padding-right: 1.95rem; }           /* trailing icon, 2.2rem - 4px */
/* Leading icon instead: the trim moves to the left and the right goes back to
   the untrimmed base. */
.btn--icon-start { padding-left: 1.65rem; padding-right: 1.9rem; }
.btn-cv.btn--icon-start,
.btn-ghost.btn--icon-start { padding-left: 1.95rem; padding-right: 2.2rem; }
/* An icon on each side: both sides trim. */
.btn--icon-both { padding-left: 1.65rem; padding-right: 1.65rem; }
.btn-cv.btn--icon-both,
.btn-ghost.btn--icon-both { padding-left: 1.95rem; padding-right: 1.95rem; }

/* Pills: base 1.5rem (24px), so an icon side sits at 1.25rem (20px). */
.nav-links > li > a,
.nav-contact { padding-left: 1.25rem; }          /* leading icon */
/* .nav-links > li > a is (0,1,2), so the base would outrank a plain
   .nav-cases > a at (0,1,1). Matching the li by class lifts this to (0,2,2). */
.nav-links > li.nav-cases > a { padding-right: 1.25rem; }  /* leading icon + trailing caret */
.nav-cta { padding-left: 1.25rem; padding-right: 1.25rem; }        /* icons both sides */
/* the overlay's pills are the header's, so they follow the same rule */
.nav-mobile-pill { padding-left: 1.25rem; }                        /* leading icon */
.nav-mobile-trigger { padding-right: 1.25rem; }                    /* leading icon + trailing caret */
.nav-mobile-pill--cta { padding-left: 1.25rem; padding-right: 1.25rem; }  /* icons both sides */
.contact-link { padding-left: 1.25rem; padding-right: 1.25rem; }   /* icons both sides */
.footer-contact-link { padding-left: 1.25rem; padding-right: 1.25rem; }  /* icons both sides */

/* Headings: one subtle rise-and-fade, shared by both. Transform and opacity
   only, so nothing reflows and the gradient word is untouched. .is-armed is
   added by script, so without JS the heading simply renders as normal. */
.title-reveal {
    transition: opacity 0.9s cubic-bezier(0.16, 1, 0.3, 1),
                transform 0.9s cubic-bezier(0.16, 1, 0.3, 1);
}
.title-reveal.is-armed {
    opacity: 0;
    transform: translateY(14px);
}
.title-reveal.is-armed.is-revealed {
    opacity: 1;
    transform: none;
}
@media (prefers-reduced-motion: reduce) {
    .title-reveal, .title-reveal.is-armed {
        opacity: 1;
        transform: none;
        transition: none;
    }
}


/* ── Scroll reveal (reveal.js) ─────────────────────────────────────────────
   The hidden state is added by script, so without JS every block renders
   normally.

   `.rv` deliberately has no transition: it must hide instantly. Giving it one
   would animate the element from visible to hidden on load, which reads as a
   flash. The motion lives entirely in the reveal keyframes, whose `both` fill
   holds the start state through the stagger delay. Only opacity and transform
   are animated, so nothing reflows. */
.rv { opacity: 0; }
.rv.rv-in {
    /* `opacity: 1` is declared as well as animated. During the stagger delay and
       the run, the keyframes' `both` fill overrides it; if animations are ever
       disabled or never run, this is what keeps the content visible rather than
       stuck at zero. */
    opacity: 1;
    animation: rvIn 0.8s cubic-bezier(0.16, 1, 0.3, 1) var(--rv-delay, 0ms) both;
}
/* `translate`, never `transform`. This animation fills with `both`, so after
   it finishes its final value keeps winning over any normal declaration on the
   property it animates. On `transform` that silently killed the lift on every
   card carrying .rv, and it would clobber any element's own transform too.
   The independent `translate` property leaves `transform` free, and the two
   compose. */
@keyframes rvIn {
    from { opacity: 0; translate: 0 26px; }
    to   { opacity: 1; translate: 0 0; }
}
@media (prefers-reduced-motion: reduce) {
    .rv, .rv.rv-in { opacity: 1; animation: none; translate: none; }
}

/* ── Contact: success state and field validation ───────────────────────────
   The card swaps its contents instead of showing a strip underneath, so the
   confirmation occupies the same space the form did. */
.form-done {
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
    padding: 0.75rem 0 0.25rem;
    animation: formDoneIn 0.5s cubic-bezier(0.16, 1, 0.3, 1) both;
}
.form-done[hidden] { display: none; }
.form-done-circle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 68px;
    height: 68px;
    border-radius: 50%;
    background: rgba(70, 226, 80, 0.22);
    margin-bottom: 1.1rem;
}
.form-done-circle .material-symbols-outlined {
    font-size: 36px;
    color: #007A68;
}
.form-done-title {
    font-family: var(--font-main);
    font-size: 1.15rem;
    font-weight: 600;
    color: #073D4D;
    margin: 0 0 0.45rem;
}
.form-done-sub {
    font-family: var(--font-main);
    font-size: 0.93rem;
    line-height: 1.5;
    color: rgba(7, 61, 77, 0.72);
    margin: 0 0 1.5rem;
    max-width: 34ch;
}
@keyframes formDoneIn {
    from { opacity: 0; transform: translateY(10px); }
    to   { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
    .form-done { animation: none; }
}

/* Validation shown on the field itself, not by the browser's own bubble. */
.form-error {
    display: none;
    margin-top: 0.35rem;
    font-family: var(--font-main);
    font-size: 0.82rem;
    font-weight: 500;
    color: #C0362C;
}
.form-group.is-invalid .form-error { display: block; }
.form-group.is-invalid input,
.form-group.is-invalid textarea {
    border-color: #C0362C;
}
.form-group.is-invalid input:focus,
.form-group.is-invalid textarea:focus {
    border-color: #C0362C;
}

/* The "in" letterforms have no descender, so they read low against the x-height
   of the text beside them. Each of the three places it appears is nudged on its
   own, since the surrounding type size differs in all three. */
.contact-link .li-mark {
    transform: translateY(-3px);
}
.footer-contact-link .li-mark {
    transform: translateY(-2px);
}
.nav-cta .li-mark {
    transform: translateY(-1px);
}
/* the overlay's pill, the fourth place, had been left without one */
.nav-mobile-pill--cta .li-mark {
    transform: translateY(-2px);
}

/* ── The card lift, one timing everywhere ──────────────────────────────────
   The durations had drifted across the pages, 0.2s to 0.3s, with one card
   carrying no transform transition at all so it snapped. Declared last, at
   single-class specificity, so it settles every card. ── */
.cs-problem-item,
.cs-nps-card,
.cs-dd-card,
.cs-app-card,
.cs-pcard,
.cs-pcard2,
.cs-day-card,
.cs-step-card,
.cs-meta-item,
.cs-more-card,
.cs-insight-card,
.cs-metric-card,
.cs-roles-card,
.cs-carousel-btn,
.csh-topic-card,
.csh-stat,
.case-card-v2,
.highlight-card,
.contact-form,
.footer-brand,
.skill-group,
.logo-card,
.ac-wf,
.ac-tf-card,
.ac-bigq2,
.ac-split-card {
    transition: transform 0.3s ease, box-shadow 0.3s ease,
                background 0.3s ease, border-color 0.3s ease;
}

/* ── Never a single word alone on a last line ──────────────────────────────
   `pretty` lets the browser pull a word down from the line above rather than
   leaving a widow, which is cheaper and more reliable than hand-placed
   non-breaking spaces that go stale the moment the copy changes. ── */
/* Inherited, so it reaches every span, label and list item rather than the
   hand-kept element list this used to carry, which could never cover the
   subtitles and card copy that are spans. */
body { text-wrap: pretty; }
/* Headings read better balanced across their lines than merely widow-free. */
h1, h2, h3, h4, h5,
.hero-title, .about-title, .section-title,
.csh-title, .cs-section h2, .error-title { text-wrap: balance; }

/* ═══════════════════════════════════════════════════════════════════════════
   MOBILE · shared components
   Built against a 375px viewport. `html { overflow-x: clip }` was hiding the
   overflow rather than preventing it, so anything too wide was simply sliced
   off at the right edge instead of showing a scrollbar. Each rule below is
   there because something measured wider than the screen.
   ═══════════════════════════════════════════════════════════════════════════ */
@media (max-width: 639px) {
    /* The hero text block measured 595px inside a 375px section. Two causes:
       3.5rem of side padding, and .hero-title-line being a flex row, which
       gives its item min-width:auto so the headline could never wrap. */
    /* min-width 0: the hero section is a flex container, so this block kept
       min-width:auto and refused to shrink below its own content however small
       the screen got. Without it the padding change alone does nothing. */
    .hero-content { padding: max(72px, 6vh) 1.25rem 4.5rem; min-width: 0; max-width: 100%; }
    .hero-title { font-size: clamp(1.85rem, 8.5vw, 2.6rem); }
    .hero-title-line { flex-wrap: wrap; }
    .hero-title-line > * { min-width: 0; max-width: 100%; }
    /* the headline is one span, so it wraps inside itself rather than between
       flex items; it needs to be allowed to break anywhere a space allows */
    #animatedTitle, .hero-title-fixed { white-space: normal; overflow-wrap: break-word; }
    .hero-title-fixed { padding-left: 0; padding-right: 0; }
    /* the two hero buttons sat side by side at 483px */
    .hero-actions,
    .about-cta-row { flex-wrap: wrap; justify-content: center; }
    .hero-actions .btn,
    .about-cta-row .btn { flex: 1 1 100%; justify-content: center; text-align: center; }

    /* 566px of contact pills on one row. This is a grid of `auto auto`, not a
       flex row, so flex-wrap does nothing to it: the columns have to collapse. */
    .footer-brand-contacts { grid-template-columns: 1fr; }
    /* A pill is one line. When the label is longer than the pill it is cut
       with an ellipsis rather than wrapping the pill to a second row, so the
       icons stay on the ends: [icon] linkedin.com/in/thale... [icon] */
    .footer-contact-link,
    .contact-link {
        max-width: 100%;
        min-width: 0;
        flex-wrap: nowrap;
    }
    .footer-link-label,
    .contact-link-label {
        min-width: 0;
        flex: 0 1 auto;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }
    .footer-contact-link > svg,
    .footer-contact-link > .material-symbols-outlined,
    .contact-link-icon,
    .contact-link-ext { flex: 0 0 auto; }

    /* `section { padding: 8rem 0 }` is 128px of dead space at each end */
    section { padding: 4rem 0; }
    /* #about sets its own 9rem and so is not reached by the rule above */
    #about { padding: 4rem 0; }
    /* The two #about watermarks are placed from their own centres. On a phone
       the section is far shorter, so both landed below the thing they are
       meant to sit behind: one under the headline, one in the middle of the
       card stack instead of behind its label. */
    #about .about-bg-svg { top: 5rem; width: 100%; }
    #about .cv-grid-svg { top: -4.75rem; width: 112%; }

    /* "Transformation" is one unbreakable word: at the 2.1rem floor it ran
       2px off each edge of a 375px screen. */
    .about-title { font-size: clamp(1.55rem, 7.3vw, 3.6rem); }

    /* The three location rows were centred as a group and centred inside
       themselves, so no two labels shared an edge. */
    .about-loc-row {
        flex-direction: column;
        align-items: flex-start;
        gap: 1.4rem;
    }
    .highlight-card.loc-card { flex-direction: row; align-items: center; }
    /* Each label sits the same distance from its own flags, the gap the rows
       keep at every other width. The flags stay flush at the page gutter, so
       the block has one left edge even though the labels do not. */
    .loc-card .loc-flags { justify-content: flex-start; }
    .loc-card .highlight-text { text-align: left; align-items: flex-start; }

    /* The diagonal stripe is centred on the section, which on a phone puts it
       straight across the contact pills. It belongs up beside the label and
       the headline, clear of everything below them. */
    /* far enough down that a full line of the kanji clears the section's top
       edge, still well clear of the pills below the headline */
    #contact .work-stripe { top: 40px; }

    /* 28px of card padding either side on a 335px card left the fields 277px
       wide; they sit closer to the card's edges here. */
    #contact .contact-form { padding: 1rem; }
    /* the text column kept min-width:auto, so the widest pill set the column's
       width and pushed it past the screen instead of truncating */
    #contact .contact-grid > *,
    #contact .contact-text,
    #contact .contact-links { min-width: 0; max-width: 100%; }
    /* The hero watermark covers the whole section on desktop; a blanket
       `height:auto` had collapsed it into a 147px band above the portrait,
       marker label rather than the headline: at 82-90% they read as a small
       patch behind the large type instead of a ground to stand on. */
    /* The artwork sits in the upper half of its own box, so a box pinned to
       the hero's top put it in the gap above the headline. Offset so its mass
       lands on the title block, which is where it sits on desktop. */
    #hero img.hero-bg-svg { height: 100vh; width: 100%; max-width: 100%; top: -39px; }
    /* The capability backdrop is 140% of its wrapper, which is what needed
       clamping; it is also moved up to sit behind its own label. */
    img.hero-bg-svg.cv-grid-svg { max-width: 100%; height: auto; }

    /* These two eyebrows are nowrap flex rows of ten markers plus the label,
       and at 375px the label alone is wider than the column. The markers stay
       on the row and the label wraps inside its own span, so the text breaks
       rather than the marker run. */
    .clients-label,
    .cv-practice-label { flex-wrap: nowrap; white-space: normal; }
    .clients-label .ds-label-text,
    .cv-practice-label .ds-label-text {
        min-width: 0;
        white-space: normal;
        text-align: center;
    }
    /* One line-height for the label component, on every page: a label that
       wraps to two lines was inheriting the body's 1.6 and reading airy
       beside the single-line ones. */
    .section-label,
    .cs-section-label,
    .error-eyebrow,
    .ds-label-text,
    .footer-role,
    .footer-role-text { line-height: 1.25; }
    /* the logo marquee reads as one run rather than isolated marks */
    .clients-track { gap: 1.6rem; }
    /* The cases rail stacks here rather than scrolling (see the page's own
       639px block); it still may not grow past its column. */
    .cases-track { min-width: 0; }
    /* The footer row breaks out of the container padding with -3.5rem side
       margins so it can span the footer's full width. The container pads
       1.25rem here, so that breakout overshoots by 36px a side. */
    /* The grid bleeds back out to the viewport edges so its divider rule can
       run the full width of the page; the card keeps the page gutter. */
    .footer-grid { margin-inline: -1.25rem; min-width: 0; }
    .footer-grid > * { min-width: 0; max-width: 100%; }
    /* the footer container pads 24px while every other section pads 20px, so
       the card used to sit on a different gutter from the rest of the page */
    footer .container { padding-left: 1.25rem; padding-right: 1.25rem; }
    /* card fills the gutter, and the wordmark keeps air on both sides */
    .footer-brand { width: calc(100% - 2.5rem); }
    .footer-logo-img { height: 16px; }
    /* a 60px drop shadow under a card that already sits on a dark ground
       reads as a smudge at this size */
    .footer-brand { box-shadow: inset 0 1px 0 rgba(255,255,255,0.08); }
    /* the drifting watermark is wider than the card it sits behind and only
       crowds it here */
    footer .footer-kanji { display: none; }
    /* the back-to-top button rides the divider band; on a phone it centres */
    /* .footer-anchor > .footer-totop sets the vertical straddle, so the
       centring has to carry it too or the button drops back onto the band. */
    .footer-anchor > .footer-totop {
        right: auto;
        left: 50%;
        transform: translate(-50%, calc(-50% + 10px));
    }
    @media (hover: hover) {
.footer-anchor > .footer-totop:hover { transform: translate(-50%, calc(-50% + 8px)); }
}
    /* the role reads better as two lines than as one long one */
    .footer-role-br { display: block; }
    /* The copyright takes its own line, and the marker that used to trail it
       goes: the markers separate the two policy links, nothing else. */
    .footer-copy { flex: 0 0 100%; text-align: center; }
    .footer-copy + .footer-policies-tri { display: none; }
}


/* ── MOBILE · case-study article components ────────────────────────────────
   Shared by the three case pages, which carry their own inline CSS but all
   build on these class names. Every case component here is scoped through
   `.cs-light-body`, the article wrapper all three pages use: the pages' own
   `<style>` blocks load after this file, so a bare single-class rule here
   loses the cascade to them at equal specificity. ── */
@media (max-width: 639px) {
    /* the article column pads 2rem a side, which is 64px of a 375px screen */
    .cs-light-body .cs-body { padding-left: 1.25rem; padding-right: 1.25rem; }

    /* The NPS card is a two-column flex row: the figure on the left and the
       chart on the right. At 375px the chart had 113px hanging off the edge. */
    .cs-light-body .cs-nps-card { flex-direction: column; gap: 1.25rem; }
    .cs-light-body .cs-nps-card > * { min-width: 0; max-width: 100%; }
    /* the figure panel bleeds out of the card's padding; stacked, it has to
       bleed on both sides or it stops 42px short of the card's right edge */
    .cs-light-body .cs-nps-card-info {
        /* max-width:100% above resolves against the card's content box, which
           is what kept this panel 42px short of the card's right edge */
        max-width: none;
        margin-right: calc(-1.25rem - 1px);
        padding-right: calc(1.25rem + 1px);
        border-radius: 12px 12px 0 0;
    }
    .cs-light-body .cs-nps-chart,
    .cs-light-body .cs-nps-bar-track,
    .cs-light-body .cs-nps-zones { min-width: 0; max-width: 100%; }
    /* Stacked, the figure panel is a centred block rather than a left column,
       and it reads tighter: the score sits straight under its own label and
       the zone name straight under the score. */
    .cs-light-body .cs-nps-card-info {
        align-items: center;
        text-align: center;
        padding-top: 0.9rem;
        padding-bottom: 0.9rem;
    }
    .cs-light-body .cs-nps-tag { margin-bottom: 0.1rem; }
    .cs-light-body .cs-nps-sub { margin-top: 0.1rem; }
    /* the pin needs air between it and the panel above it */
    .cs-light-body .cs-nps-chart { margin-top: 2.6rem; }

    /* The mockup carried 76% of the column, which on a phone is 249px for
       three devices. Larger, and still a step narrower than the cards it
       stands behind, so it reads as their backdrop and not as their width. */
    .cs-light-body .cs-opp { padding-top: 34%; }
    .cs-light-body .cs-opp-bg { width: 92%; }
    .cs-light-body .cs-nps-zones { flex-wrap: nowrap; }
    /* the four zones split the bar's 285px here, so each label has 68px and
       "Improvement" was breaking mid-word */
    .cs-light-body .cs-nps-zone { min-width: 0; }
    .cs-light-body .cs-nps-zone-name,
    .cs-light-body .cs-nps-zone-range {
        font-size: 0.58rem;
        line-height: 1.3;
        overflow-wrap: normal;
        word-break: keep-all;
    }

    /* The Double Diamond is 1150 units wide: in the article column it scaled
       to 0.25 and its 27-unit labels rendered at 7px. The card is not the
       scroller any more; it rides a full-bleed strip, so it begins at the page
       gutter, runs off the right edge, and scrolls until the far gutter shows.
       The band it sits in pads 24px, so the strip bleeds back out by that. */
    .cs-light-body .cs-dd-strip {
        margin-inline: -24px;
        padding-inline: 20px;
        overflow-x: auto;
        overflow-y: hidden;
        -webkit-overflow-scrolling: touch;
        scrollbar-width: none;
        -ms-overflow-style: none;
        scroll-padding-inline: 20px;
    }
    .cs-light-body .cs-dd-strip::-webkit-scrollbar { display: none; }
    .cs-light-body .cs-dd-strip .cs-dd-card {
        width: 600px;
        max-width: none;
        flex: 0 0 auto;
        overflow: visible;
    }
    .cs-light-body .cs-dd-strip .cs-dd-card > svg { width: 100%; height: auto; }

    /* One card padding across every carousel. They ran 17.6 to 28px depending
       on which component the card came from, which reads as sloppy when they
       all scroll past each other in the same column. */
    .cs-light-body .cs-problem-item,
    .cs-light-body .cs-mcard,
    .cs-light-body .cs-app-body,
    .cs-light-body .cs-pcard-body,
    .cs-light-body .cs-day-body,
    .cs-light-body .cs-dd-card { padding: 1.25rem; }
    /* The bleeding card titles pull out by --pc-pad-x to meet the card's
       edges, so the variable has to follow the padding or the title and its
       rule overhang the card by the difference. */
    .cs-light-body .cs-problem-item,
    .cs-light-body .cs-mcard,
    .cs-light-body .cs-pcard-body,
    body .cs-modal .cs-pcard2,
    body .cs-modal .cs-pside-info { --pc-pad-x: 1rem; }
    /* and one card width, wide enough that the next card only peeks */
    .cs-light-body .cs-carousel-track > * { flex: 0 0 90%; }
    /* the app cards carry their own paddings from three different rules; the
       sides land on the shared 20px and a card with a shot above it keeps its
       deliberate zero top */
    .cs-light-body .cs-app-card > .cs-app-body {
        padding-left: 1.25rem;
        padding-right: 1.25rem;
    }
    .cs-light-body .cs-app-card:not(.cs-app-card--feature) > .cs-app-body {
        padding-top: 0;
        padding-bottom: 1.25rem;
    }
    .cs-light-body .cs-app-card--feature > .cs-app-body {
        padding-top: 1.25rem;
        padding-bottom: 1.25rem;
    }

    /* The verdict rows are the card's content, so they run its full width
       rather than sitting inside the text inset. The title above them and the
       Visit site button below keep the card's own gutter. */
    .cs-light-body .cs-app-verdict { margin-inline: -1.25rem; }
    .cs-light-body .cs-app-verdict li {
        padding-left: 1.25rem;
        padding-right: 1.25rem;
        border-radius: 0;
    }

    /* Two logos on the first row, then one per row to the full column width:
       five tiles across two columns left a lone tile stranded. */
    .cs-light-body .cs-intl-tile:nth-child(3),
    .cs-light-body .cs-intl-tile:nth-child(4),
    .cs-light-body .cs-intl-tile:nth-child(5) { grid-column: 1 / -1; }

    /* One size for copy inside a card, a step under the section's own body
       text. Both bottom out at 0.95rem here, so on a phone they collapsed to
       the same size; on desktop the card text is the smaller of the two and
       this keeps that relationship. Card text also ran at three different
       sizes depending on which component the card came from. */
    .cs-light-body .cs-sm-item,
    .cs-light-body .cs-pi-text,
    .cs-light-body .cs-app-verdict li,
    .cs-light-body .cs-mcard-desc,
    .cs-light-body .cs-pcard-summary,
    .cs-light-body .cs-pcard-role,
    .cs-light-body .cs-jcard-text,
    .cs-light-body .cs-opp-text,
    .cs-light-body .cs-day-body li,
    .cs-light-body .cs-intl-tile span,
    .cs-light-body .cs-finding-title small,
    .cs-light-body .cs-problem-item p,
    .cs-light-body .csh-topic-text,
    .cs-readmore .csh-topic-text,
    .cs-hero .csh-topic-text { font-size: 0.9rem; }

    /* The donut, its headline and the question it answers read as one column
       here rather than a figure with text beside it. */
    .cs-light-body .cs-finding-head {
        flex-direction: column;
        align-items: flex-start;
        gap: 0.6rem;
    }

    /* every card body that sits in a flex or grid track needs to be allowed
       to shrink; min-width:auto is what pushes them past the screen */
    .cs-light-body .cs-app-body, .cs-light-body .cs-app-card,
    .cs-light-body .cs-pcard2, .cs-light-body .cs-day-card,
    .cs-light-body .cs-mcard, .cs-light-body .cs-jcard,
    .cs-light-body .cs-opp-card, .cs-light-body .cs-rcase { min-width: 0; }

    /* the case subtitles carry a hard break tuned for a wide line; on a phone
       it lands mid-sentence, so the text wraps on its own instead */
    .csh-subtitle br { display: none; }

    /* The hero column pads 2rem and the nutshell card inside it another
       2.5rem, so 72px of a 375px screen went to padding before any text.
       Scoped through .cs-hero to clear the pages' own single-class rules. */
    .cs-hero .csh-inner { padding-left: 1.25rem; padding-right: 1.25rem; }
    .cs-hero .csh-box { padding: 1.5rem; }

    /* Half the room above the phone. The subtitle's own 7rem and the card
       block's 11.5rem are adjacent margins, so they collapse to the larger:
       both have to come down or nothing moves. */
    .cs-hero .csh-subtitle { margin-bottom: 2rem; }
    .cs-hero .csh-nutshell { margin-top: 5.75rem; }
    /* `position: static` below 1024px let the phone's glow fall through to the
       card block and settle on ITS centre, 420px below the phone it lights.
       The offsets have to go with it: the desktop rule's top/left 50% centre
       the column absolutely, and `relative` would act on them. */
    .cs-hero .csh-phone-col { position: relative; top: auto; left: auto; }
    /* a long run of air under the hero's CTA before the article starts */
    .cs-hero .csh-inner { padding-bottom: 15rem; }
    /* ...and correspondingly less above the first section label. These two
       used to be deliberately equal at 160px; they are not any more. */
    body .cs-light-body { padding-top: 32px; }
    body .cs-light-body .cs-body > .cs-section:first-child { margin-top: 1rem; }

    /* ── Persona modal: full screen ──────────────────────────────────────
       A 16px inset on a phone spends the only room there is on a frame, and
       left the cards floating inside a floating box. The sheet takes the
       whole screen, the tab row is the header, and the cards sit close to
       every edge. ── */
    body .cs-modal { padding: 0; }
    body .cs-modal .cs-modal-box {
        max-width: none;
        max-height: none;
        width: 100%;
        height: 100%;
        border: none;
        border-radius: 0;
        padding: 0 0.75rem 0.9rem;
        box-shadow: none;
    }
    /* The header carries the tabs and the close button on one row. The row
       reserves the button's width so the tabs can never run under it. */
    body .cs-modal .cs-modal-tabs {
        margin: 0 -0.75rem;
        padding: 0.55rem 0.6rem;
        border-radius: 0;
        gap: 0.3rem;
    }
    body .cs-modal .cs-mtab {
        flex: 0 1 auto;
        min-width: 0;
        padding: 0.45rem 0.85rem;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }
    /* the close button is a flex item at the end of the row (it is set
       `position: static; margin-left: auto` further up), so it needs a size
       here and nothing else */
    body .cs-modal .cs-modal-close {
        flex: 0 0 auto;
        width: 32px;
        height: 32px;
    }
    /* Stacked, the identity column is simply the first two cards: sticky is a
       two-column behaviour, and holding it at the top of the scrollport left
       every card below scrolling underneath it. */
    body .cs-modal .cs-pside { position: static; top: auto; }

    /* the cards, close to each other and to the sheet's edges */
    body .cs-modal .cs-pwrap { gap: 0.75rem; }
    body .cs-modal .cs-pmain { gap: 0.75rem; }
    body .cs-modal .cs-pside { gap: 0.75rem; }
    body .cs-modal .cs-pcard2,
    body .cs-modal .cs-pside-info { padding: 1rem; }

    /* a long URL or address in the policy pages has no break opportunity and
       pushes the column wider than the screen */
    .policy-page a, .policy-page p, .footer-disclaimer a { overflow-wrap: anywhere; }
}

/* ── TABLET · 640 to 1023 ──────────────────────────────────────────────────
   The decorative backdrop behind the capability cards is deliberately 140% of
   its wrapper, which is fine on a wide screen and 117px past the edge on a
   tablet. Centred and capped at the viewport it keeps the oversized look
   without running off. ── */
/* up to 1279, not 1023: the backdrop's own cap is 1200px, so between a tablet
   and a small laptop it still stood ~96px past the edge */
@media (max-width: 1279px) {
    /* 100% of its wrapper, not 100vw: vw counts the scrollbar, which left it
       15px past the edge on a tablet */
    #about .cv-grid-svg { width: 118%; max-width: 100%; }
}

/* ── PHONE · the capability backdrop runs edge to edge ─────────────────────
   The tablet cap above is `100%` of a wrapper that a phone's container has
   already inset by 20px a side, so the artwork stopped 20px short of both
   edges while its sibling behind "About me" reached them. Sized from the
   viewport so both watermarks share one bleed. ── */
@media (max-width: 639px) {
    #about .cv-grid-svg { width: 100vw; max-width: 100vw; }
}

/* ── "The 8-Step Journey Architecture" ─────────────────────────────────────
   Carried its size inline, which no breakpoint could reach. `.cs-grad` is an
   inline-block, and a line may break after one whatever follows it, so the
   non-breaking space the widow binder writes was ignored and "Architecture"
   dropped to a line of its own. Inline below 640px lets that space hold, and
   the smaller size gives the bound pair room to sit on one line. ── */
body .cs-light-body h2.cs-h2-journey { font-size: 1.4rem; margin-top: 2.5rem; }
@media (max-width: 639px) {
    /* the page's own `.cs-light-body .cs-section h2` loads after this file, so
       the class alone is not enough to carry the smaller size */
    body .cs-light-body h2.cs-h2-journey { font-size: 1.25rem; }
    body .cs-light-body h2.cs-h2-journey .cs-grad { display: inline; }
}

/* ── PHONE · the contact headline ─────────────────────────────────────────
   At the 1.75rem clamp floor "build themselves." was 3px wider than the
   column, so the widow binder had to give the pair back and "themselves."
   sat alone on the last line. A slightly lower floor buys the room. ── */
@media (max-width: 639px) {
    .contact-text h2 { font-size: 1.6rem; }
}

/* ── PHONE · bare URLs in the policy copy ─────────────────────────────────
   A browser's cookie-settings link is one unbreakable token, 47px wider than
   its list column, so it ran off the right of the screen. Only these two
   pages print raw URLs, so the break stays scoped to them. ── */
@media (max-width: 639px) {
    .policy-light a, .policy-light li, .policy-light p { overflow-wrap: anywhere; }
}

/* ── PHONE · the policy lists ─────────────────────────────────────────────
   The topics index and the body lists are inset from the paragraph column so
   their markers sit clear of the text edge. 24px of that on a 375px screen
   reads as a second column rather than an inset, so the phone keeps only a
   hint of it. ── */
@media (max-width: 639px) {
    :root { --topic-indent: 8px; }
}

/* The form's one failure message: the field-error component, full width, with
   a direct address so a failed send is never a dead end. */
.form-send-error {
    margin: 0 0 0.9rem;
    font-family: var(--font-main);
    font-size: 0.82rem;
    font-weight: 500;
    color: #C0362C;
}
.form-send-error a { color: #C0362C; text-decoration: underline; }
#contactForm.is-sending { opacity: 0.6; pointer-events: none; }
