/* /Components/Layout/ReconnectModal.razor.rz.scp.css */
.components-reconnect-first-attempt-visible[b-jnxr6cgsuk],
.components-reconnect-repeated-attempt-visible[b-jnxr6cgsuk],
.components-reconnect-failed-visible[b-jnxr6cgsuk],
.components-pause-visible[b-jnxr6cgsuk],
.components-resume-failed-visible[b-jnxr6cgsuk],
.components-rejoining-animation[b-jnxr6cgsuk] {
    display: none;
}

#components-reconnect-modal.components-reconnect-show .components-reconnect-first-attempt-visible[b-jnxr6cgsuk],
#components-reconnect-modal.components-reconnect-show .components-rejoining-animation[b-jnxr6cgsuk],
#components-reconnect-modal.components-reconnect-paused .components-pause-visible[b-jnxr6cgsuk],
#components-reconnect-modal.components-reconnect-resume-failed .components-resume-failed-visible[b-jnxr6cgsuk],
#components-reconnect-modal.components-reconnect-retrying[b-jnxr6cgsuk],
#components-reconnect-modal.components-reconnect-retrying .components-reconnect-repeated-attempt-visible[b-jnxr6cgsuk],
#components-reconnect-modal.components-reconnect-retrying .components-rejoining-animation[b-jnxr6cgsuk],
#components-reconnect-modal.components-reconnect-failed[b-jnxr6cgsuk],
#components-reconnect-modal.components-reconnect-failed .components-reconnect-failed-visible[b-jnxr6cgsuk] {
    display: block;
}


#components-reconnect-modal[b-jnxr6cgsuk] {
    background-color: white;
    width: 20rem;
    margin: 20vh auto;
    padding: 2rem;
    border: 0;
    border-radius: 0.5rem;
    box-shadow: 0 3px 6px 2px rgba(0, 0, 0, 0.3);
    opacity: 0;
    transition: display 0.5s allow-discrete, overlay 0.5s allow-discrete;
    animation: components-reconnect-modal-fadeOutOpacity-b-jnxr6cgsuk 0.5s both;
    &[open]

{
    animation: components-reconnect-modal-slideUp-b-jnxr6cgsuk 1.5s cubic-bezier(.05, .89, .25, 1.02) 0.3s, components-reconnect-modal-fadeInOpacity-b-jnxr6cgsuk 0.5s ease-in-out 0.3s;
    animation-fill-mode: both;
}

}

#components-reconnect-modal[b-jnxr6cgsuk]::backdrop {
    background-color: rgba(0, 0, 0, 0.4);
    animation: components-reconnect-modal-fadeInOpacity-b-jnxr6cgsuk 0.5s ease-in-out;
    opacity: 1;
}

@keyframes components-reconnect-modal-slideUp-b-jnxr6cgsuk {
    0% {
        transform: translateY(30px) scale(0.95);
    }

    100% {
        transform: translateY(0);
    }
}

@keyframes components-reconnect-modal-fadeInOpacity-b-jnxr6cgsuk {
    0% {
        opacity: 0;
    }

    100% {
        opacity: 1;
    }
}

@keyframes components-reconnect-modal-fadeOutOpacity-b-jnxr6cgsuk {
    0% {
        opacity: 1;
    }

    100% {
        opacity: 0;
    }
}

.components-reconnect-container[b-jnxr6cgsuk] {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1rem;
}

#components-reconnect-modal p[b-jnxr6cgsuk] {
    margin: 0;
    text-align: center;
}

#components-reconnect-modal button[b-jnxr6cgsuk] {
    border: 0;
    background-color: #6b9ed2;
    color: white;
    padding: 4px 24px;
    border-radius: 4px;
}

    #components-reconnect-modal button:hover[b-jnxr6cgsuk] {
        background-color: #3b6ea2;
    }

    #components-reconnect-modal button:active[b-jnxr6cgsuk] {
        background-color: #6b9ed2;
    }

.components-rejoining-animation[b-jnxr6cgsuk] {
    position: relative;
    width: 80px;
    height: 80px;
}

    .components-rejoining-animation div[b-jnxr6cgsuk] {
        position: absolute;
        border: 3px solid #0087ff;
        opacity: 1;
        border-radius: 50%;
        animation: components-rejoining-animation-b-jnxr6cgsuk 1.5s cubic-bezier(0, 0.2, 0.8, 1) infinite;
    }

        .components-rejoining-animation div:nth-child(2)[b-jnxr6cgsuk] {
            animation-delay: -0.5s;
        }

@keyframes components-rejoining-animation-b-jnxr6cgsuk {
    0% {
        top: 40px;
        left: 40px;
        width: 0;
        height: 0;
        opacity: 0;
    }

    4.9% {
        top: 40px;
        left: 40px;
        width: 0;
        height: 0;
        opacity: 0;
    }

    5% {
        top: 40px;
        left: 40px;
        width: 0;
        height: 0;
        opacity: 1;
    }

    100% {
        top: 0px;
        left: 0px;
        width: 80px;
        height: 80px;
        opacity: 0;
    }
}
/* /Components/Pages/LandingPage.razor.rz.scp.css */
/* RPRA Consulting -- landing page (scoped to LandingPage.razor).
   2026-07-29 "Nocturne" redesign: the page is a dark-light-dark arc. Dark
   header and hero on the footer plum (staged headline, drifting ghosted R,
   ledger baseline strip), cream band of ruled service rows, paper About,
   plum contact band. Palette values unchanged; only their distribution moved.
   Layered: base styles, then the accessibility layer (focus, skip link, reduced
   motion, contrast-safe inks), then the mobile layer (max-width 640px).
   Ink rules: small gold on LIGHT bands uses var(--dark-ochre) #7d5719 (AA on
   cream); small gold on the PLUM bands uses var(--gold) #c89a4b (6.06:1 on
   footer plum); the brand gold var(--ochre) #b1832e stays reserved for rules,
   borders, and large-text accents on light (3:1 large-text threshold only). */

/* ---- Accessibility: skip link ---- */
.skip-link[b-zr06p2bsz9] {
    position: absolute;
    left: -9999px;
    top: 0;
    z-index: 100;
    padding: 12px 20px;
    background: var(--aubergine);
    color: var(--ivory);
    font: 600 13px/1 var(--sans);
    letter-spacing: .08em;
}

    .skip-link:focus[b-zr06p2bsz9] {
        left: 0;
    }

/* ---- Accessibility: visible keyboard focus ---- */
a:focus-visible[b-zr06p2bsz9],
.btn-gold-dark:focus-visible[b-zr06p2bsz9] {
    outline: 2px solid var(--dark-ochre);
    outline-offset: 3px;
}

/* On the dark bands the dark-ochre outline is 2.4:1 and effectively invisible;
   gold is 6.06:1 on the footer plum and 5.51:1 on aubergine (the skip link's
   own box), clearing the 3:1 non-text minimum everywhere it applies. */
.skip-link:focus-visible[b-zr06p2bsz9],
.site-header a:focus-visible[b-zr06p2bsz9],
.hero a:focus-visible[b-zr06p2bsz9],
.contact a:focus-visible[b-zr06p2bsz9] {
    outline-color: var(--gold);
}

/* ---- Accessibility: respect reduced-motion (belt to the JS guard's braces) ---- */
@media (prefers-reduced-motion: reduce) {
    [data-reveal][b-zr06p2bsz9] {
        opacity: 1 !important;
        transform: none !important;
        transition: none !important;
    }
}

/* ---- Layout: the content shell ----
   Every band background (plum hero, cream services, plum contact) stays
   FULL-BLEED; only the content inside caps and centres. Without this the page
   had no horizontal limit at all -- each -inner carried `padding: .. 6vw` and
   nothing else, so content ran to `100% - 12vw` forever and a 2560px display
   gave ~2250px line lengths, flinging the nav to the far edge and opening a
   canyon inside every `space-between` row.
   Width lives in --shell (app.css :root). The gutter clamps so it stops growing
   once the shell is reached. These rules own the HORIZONTAL axis only: each
   section keeps its own padding-block, and the <=640px mobile layer below
   deliberately re-asserts the full `padding` shorthand to take both axes back. */
.header-inner[b-zr06p2bsz9],
.hero-inner[b-zr06p2bsz9],
.baseline-inner[b-zr06p2bsz9],
.section-inner[b-zr06p2bsz9],
.about-grid[b-zr06p2bsz9] {
    max-width: var(--shell);
    margin-inline: auto;
    padding-inline: clamp(20px, 6vw, 72px);
}

/* ---- Header (on the plum; SOLID on purpose) ----
   The reverse monogram paints its own #331b36 field (package usage rule), so
   the header background must be exactly footer-plum and opaque; a translucent
   blur would frame the mark in a visible rectangle the moment content scrolls
   underneath. */
.site-header[b-zr06p2bsz9] {
    position: sticky;
    top: 0;
    z-index: 50;
    background: var(--footer-plum);
    border-bottom: 1px solid rgba(247, 241, 230, .16);
}

.header-inner[b-zr06p2bsz9] {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 24px;
    min-height: 72px;
    flex-wrap: wrap;
}

.brand-lockup[b-zr06p2bsz9] {
    display: flex;
    align-items: center;
    gap: 14px;
    padding: 10px 0;
}

    .brand-lockup img[b-zr06p2bsz9] {
        /* 29px, not 26. The 2026-07-25 suite files carry more internal padding than the
           previous generation, so identical CSS rendered the mark 12% smaller. This is
           optical parity with what shipped before, not a size change. */
        height: 29px;
        width: auto;
        display: block;
    }

.lockup-text[b-zr06p2bsz9] {
    display: flex;
    flex-direction: column;
    line-height: 1.25;
}

.lockup-name[b-zr06p2bsz9] {
    font: 600 13px/1.25 var(--sans);
    letter-spacing: .22em;
    color: var(--ivory);
}

/* Sub-line ink is the on-plum gold (6.06:1, AA at 9px). FR "CONSULTATION" is
   two letters longer than "CONSULTING", so its tracking eases to .27em (FR
   logo package: .26-.28em vs .32em EN) to keep a similar footprint. */
.lockup-sub[b-zr06p2bsz9] {
    font: 500 9px/1.25 var(--sans);
    letter-spacing: .32em;
    color: var(--gold);
}

.lockup-sub-fr[b-zr06p2bsz9] {
    letter-spacing: .27em;
}

/* ---- Condensing header (>640px only) ----
   The header opens LARGE and shrinks to the sizes above once the page scrolls.
   The values above are therefore the CONDENSED state, unchanged from what
   shipped; everything here is the new expanded state and its return path.

   Progressive enhancement, same contract as the reveal and the stagger: CSS
   ships the LARGE header as the default and rpra-reveal.js only ever ADDS
   .is-condensed. With JS off the header simply stays large, which is correct
   and fully legible, never broken.

   GATE: min-width 940px AND min-height 600px, both deliberate.
   - 940, raised from 800 on 2026-08-06 when the nav gained a fifth item
     (ENGAGEMENTS / MANDATS). The original 800 was set when the enlarged lockup
     (254px EN, 270px FR) faced a 359-379px nav; ENGAGEMENTS adds ~140px to the
     EN nav, which computes to a one-row fit from roughly a 880px viewport.
     940 clears that with slack. Between 641 and 939 the header keeps its
     shipped compact form, which is correct, not a gap. RAISE THIS if the
     lockup or the nav ever grows again -- they are the binding constraint.
   - min-height 600 keeps a landscape phone (812x375) off the tall header: 104px
     would eat 28% of that screen.

   Letter-spacing is in em on both lockup lines, so the tracking scales with the
   type on its own and needs no separate rule. */
@media (min-width: 940px) and (min-height: 600px) {
    .header-inner[b-zr06p2bsz9] {
        min-height: 104px;
    }

    .brand-lockup[b-zr06p2bsz9] {
        /* 24px, tracking the logo ratio, so the mark and wordmark keep their
           optical spacing at both sizes. */
        gap: 24px;
    }

        .brand-lockup img[b-zr06p2bsz9] {
            /* 58px inside a 104px band. The band height is settled (David
               2026-08-03: "the band height is fine"), so presence comes from
               the mark and wordmark filling it, not from a taller header.
               58 + the lockup's 10px padding either side = 78px in 104, which
               keeps 13px of clearance top and bottom. */
            height: 58px;
        }

    .lockup-name[b-zr06p2bsz9] {
        font-size: 26px;
    }

    .lockup-sub[b-zr06p2bsz9] {
        font-size: 13px;
    }

    /* Back to the shipped sizes once scrolled. */
    .site-header.is-condensed .header-inner[b-zr06p2bsz9] {
        min-height: 72px;
    }

    .site-header.is-condensed .brand-lockup[b-zr06p2bsz9] {
        gap: 14px;
    }

        .site-header.is-condensed .brand-lockup img[b-zr06p2bsz9] {
            height: 29px;
        }

    .site-header.is-condensed .lockup-name[b-zr06p2bsz9] {
        font-size: 13px;
    }

    .site-header.is-condensed .lockup-sub[b-zr06p2bsz9] {
        font-size: 9px;
    }

    /* Only the ANIMATION is reduced-motion gated, not the resize itself: the
       condensed header is a layout state, so reduced-motion users still get it,
       they just get it instantly. Real sizes are animated rather than a
       transform scale, which would leave the wordmark soft in the condensed
       state where the reader actually spends their time. */
    @media (prefers-reduced-motion: no-preference) {
        .header-inner[b-zr06p2bsz9] {
            transition: min-height .28s ease;
        }

        .brand-lockup[b-zr06p2bsz9] {
            transition: gap .28s ease;
        }

            .brand-lockup img[b-zr06p2bsz9] {
                transition: height .28s ease;
            }

        .lockup-name[b-zr06p2bsz9],
        .lockup-sub[b-zr06p2bsz9] {
            transition: font-size .28s ease;
        }
    }
}

/* ---- Anchor targets under the sticky header ----
   Without this, clicking SERVICES lands the section top at the viewport top and
   the sticky header sits on the first 73px of it, hiding the eyebrow.

   TWO tiers, because ANCHOR SWALLOWING IS CAUSED BY STICKINESS, NOT BY
   CONDENSING, and those two do not share a breakpoint. The header is sticky
   everywhere above 640px; it only condenses above 940px AND 600px tall. Gating
   the whole mitigation on the condense query left it missing for every phone in
   landscape (667x375, 844x390, 915x412: all wider than 640, all shorter than
   600), for short desktop windows (a 1366x768 laptop with a bookmarks bar sits
   near 625px and drops below 600 with devtools or 110% zoom), and at 150%
   accessibility zoom on a 1080p screen. */

/* Tier 1, wherever the header is sticky: clear its 73px. */
@media (min-width: 641px) {
    #main[b-zr06p2bsz9],
    #services[b-zr06p2bsz9],
    #engagements[b-zr06p2bsz9],
    #about[b-zr06p2bsz9],
    #contact[b-zr06p2bsz9] {
        scroll-margin-top: 73px;
    }
}

/* Tier 2, where it also CONDENSES: 104 = the condensed 73 plus the 32px the
   document rises when the header shrinks mid-scroll (the browser computes the
   destination while it is still 105px). Lands the section top flush with the
   header's lower edge. Must come after tier 1 to win. */
@media (min-width: 940px) and (min-height: 600px) {
    #main[b-zr06p2bsz9],
    #services[b-zr06p2bsz9],
    #engagements[b-zr06p2bsz9],
    #about[b-zr06p2bsz9],
    #contact[b-zr06p2bsz9] {
        scroll-margin-top: 104px;
    }
}

.main-nav[b-zr06p2bsz9] {
    display: flex;
    align-items: center;
    gap: clamp(16px, 3vw, 36px);
}

/* Contrast-safe: 85% cream is 9.9:1 on the footer plum. */
.nav-link[b-zr06p2bsz9] {
    font: 500 12px/1 var(--sans);
    letter-spacing: .18em;
    color: rgba(247, 241, 230, .85);
    white-space: nowrap;
    padding: 12px 2px; /* enlarged touch/click target */
    transition: color .2s ease;
}

    .nav-link:hover[b-zr06p2bsz9] {
        color: var(--gold); /* on-plum gold ink, AA at 12px */
    }

.nav-lang[b-zr06p2bsz9] {
    border-left: 1px solid rgba(247, 241, 230, .16);
    padding-left: clamp(16px, 3vw, 36px);
    color: var(--gold);
}

/* 641-739: with five links (ENGAGEMENTS added 2026-08-06) the compact lockup
   and the nav no longer share the sticky row at the default tracking -- EN
   wrapped the header to two sticky rows through this band (verified at 660 and
   720). Slightly tighter type keeps it to one row; from 740 the default sizes
   fit again (EN needs ~540px of fixed content plus five 3vw gaps, which the
   88% content box first covers at ~740). */
@media (min-width: 641px) and (max-width: 739px) {
    .main-nav[b-zr06p2bsz9] {
        gap: clamp(12px, 2vw, 24px);
    }

    .nav-link[b-zr06p2bsz9] {
        font-size: 11px;
        letter-spacing: .12em;
    }

    .nav-lang[b-zr06p2bsz9] {
        padding-left: clamp(12px, 2vw, 24px);
    }
}

/* ---- Shared detail system: gold rule + letterspaced eyebrow ---- */
.eyebrow[b-zr06p2bsz9] {
    display: flex;
    align-items: center;
    gap: 16px;
    margin: 0 0 24px;
    font: 600 11px/1 var(--sans);
    letter-spacing: .3em;
    color: var(--dark-ochre);
}

.eyebrow-rule[b-zr06p2bsz9] {
    flex: 0 0 44px;
    height: 1px;
    background: var(--ochre);
}

/* ---- Hero: the dark opening ---- */
.hero[b-zr06p2bsz9] {
    position: relative;
    overflow: hidden;
    background: var(--footer-plum);
}

.hero-inner[b-zr06p2bsz9] {
    position: relative;
    z-index: 1;
    padding-block: clamp(88px, 15vh, 168px) clamp(96px, 16vh, 180px);
}

.hero-copy[b-zr06p2bsz9] {
    max-width: 880px;
}

/* On-plum eyebrow: the light gold reads at 11px where dark-ochre would vanish. */
.hero .eyebrow[b-zr06p2bsz9] {
    color: var(--gold);
}

.hero .eyebrow-rule[b-zr06p2bsz9] {
    background: var(--gold);
}

.hero-title[b-zr06p2bsz9] {
    margin: 0;
    font: 500 clamp(56px, 7.2vw, 104px)/1.04 var(--serif);
    letter-spacing: -0.015em;
    color: var(--ivory);
    text-wrap: balance;
}

    /* Gold accent: --gold is 6.06:1 on the footer plum, AA at any size. */
    .hero-title em[b-zr06p2bsz9] {
        font-style: italic;
        color: var(--gold);
    }

/* Staged headline. These rules are LAYOUT only (overflow-hidden line boxes);
   the hidden state and the transition are set by rpra-reveal.js after its
   reduced-motion check, so no-JS and reduced-motion users see the headline
   plainly (site convention: progressive enhancement, never CSS-hidden).
   The padding/margin pair grows each line's clip box downward without moving
   the lines apart: at line-height 1.04, Cormorant's descenders (ink to
   -0.283em against 0.2015em of room) would otherwise be amputated. The JS
   raises words by 120% to match, so a hidden word cannot peek into the
   enlarged box. */
.stagger-line[b-zr06p2bsz9] {
    display: block;
    overflow: hidden;
    padding-bottom: .12em;
    margin-bottom: -.12em;
}

.stagger-word[b-zr06p2bsz9] {
    display: inline-block;
}

/* Contrast-safe: 72% cream is 7.9:1 on the footer plum. */
.hero-support[b-zr06p2bsz9] {
    margin: 36px 0 20px;
    font: 400 18px/1.7 var(--sans);
    color: rgba(247, 241, 230, .72);
    max-width: 440px;
}

/* The grounding line (2026-08-06 copy set): the concrete nouns under the support
   line. Contrast-safe: 65% cream is 6.60:1 on the footer plum, AA at 16px. */
.hero-grounding[b-zr06p2bsz9] {
    margin: 0 0 48px;
    font: 400 16px/1.75 var(--sans);
    color: rgba(247, 241, 230, .65);
    max-width: 560px;
}

/* The ghosted R: the hero's depth layer, drifting almost imperceptibly.
   Animation is gated to no-preference so reduced-motion users get a still R. */
.hero-ghost[b-zr06p2bsz9] {
    position: absolute;
    /* Tracks the content shell instead of the full-bleed section. Below --shell
       the first term is 0 and this resolves to the original -4%; above it, the
       R follows the shell's right edge inward. Without this the shell stranded
       it in the far corner on ultrawide -- measured at 2560px: 775px of dead
       space between the hero copy and an R whose right half was off-screen. */
    right: calc(max(0px, (100% - var(--shell)) / 2) - 4%);
    top: -14%;
    z-index: 0;
    font: 500 min(58vh, 540px)/1 var(--serif);
    color: rgba(247, 241, 230, .045);
    pointer-events: none;
    user-select: none;
}

@media (prefers-reduced-motion: no-preference) {
    .hero-ghost[b-zr06p2bsz9] {
        animation: hero-drift-b-zr06p2bsz9 46s ease-in-out infinite alternate;
    }
}

@keyframes hero-drift-b-zr06p2bsz9 {
    from {
        transform: translate(0, 0) rotate(0deg);
    }

    to {
        transform: translate(-3.5vw, 4vh) rotate(-2.5deg);
    }
}

/* Hero baseline strip: RESERVED SLOT, CURRENTLY UNREFERENCED ON PURPOSE.
   These rules styled a ledger strip (RECORDS IN / RECORDS OUT / VARIANCE) that David cut on
   2026-08-05 as gimmicky and unclear. **DO NOT DELETE THEM AS DEAD CSS.** He kept the space
   deliberately -- "we may repurpose that space for something else" -- and the markup slot carries
   the matching note in LandingPage.razor. Whatever lands here inherits a working, contrast-checked
   band: 65% cream on plum is 6.60:1 and the gold accent is 6.06:1, both AA at 11px. */
.hero-baseline[b-zr06p2bsz9] {
    position: relative;
    z-index: 1;
    border-top: 1px solid rgba(247, 241, 230, .16);
}

.baseline-inner[b-zr06p2bsz9] {
    padding-block: 18px;
    display: flex;
    flex-wrap: wrap;
    gap: 12px 44px;
    font: 600 11px/1.6 var(--sans);
    letter-spacing: .2em;
    color: rgba(247, 241, 230, .65);
}

    .baseline-inner b[b-zr06p2bsz9] {
        font-weight: 600;
        color: var(--gold);
        font-variant-numeric: tabular-nums;
    }

/* ---- Services (cream band: the light break after the dark opening) ---- */
.services[b-zr06p2bsz9] {
    background: var(--ivory);
}

.section-inner[b-zr06p2bsz9] {
    padding-block: clamp(72px, 11vh, 110px) clamp(76px, 12vh, 120px);
}

.section-head[b-zr06p2bsz9] {
    margin-bottom: clamp(48px, 8vh, 80px);
}

/* Title and intro are direct flex siblings: baseline alignment then pairs the
   title's baseline with the intro's first line. With the eyebrow inside the
   same flex item (the previous shape) the item's first line IS the eyebrow,
   so the intro rode at the top of the row instead. */
.section-head-row[b-zr06p2bsz9] {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 40px;
    flex-wrap: wrap;
}

.section-title[b-zr06p2bsz9] {
    margin: 0;
    font: 500 clamp(40px, 4.2vw, 60px)/1.1 var(--serif);
    color: var(--aubergine);
    text-wrap: balance;
}

.section-intro[b-zr06p2bsz9] {
    margin: 0;
    font: 400 15px/1.7 var(--sans);
    color: var(--muted);
    max-width: 340px;
}

/* Ruled rows, not columns: each service gets the full measure, and the rules
   carry the eye down the page the way the stacked mobile layout always did. */
.pillars[b-zr06p2bsz9] {
    border-top: 1px solid var(--hair-14);
}

.pillar[b-zr06p2bsz9] {
    margin: 0;
    display: grid;
    grid-template-columns: 96px minmax(0, .85fr) minmax(0, 1.15fr);
    gap: 12px 40px;
    align-items: start;
    padding: 46px 0;
    border-bottom: 1px solid var(--hair-08);
}

    .pillar:last-child[b-zr06p2bsz9] {
        border-bottom: none;
        padding-bottom: 8px;
    }

.pillar-numeral[b-zr06p2bsz9] {
    font: 400 italic 19px/1.3 var(--serif);
    color: var(--dark-ochre);
    padding-top: 4px;
}

.pillar-title[b-zr06p2bsz9] {
    margin: 0;
    font: 600 28px/1.2 var(--serif);
    color: var(--aubergine);
    text-wrap: balance;
}

.pillar-desc[b-zr06p2bsz9] {
    margin: 0;
    font: 400 16px/1.75 var(--sans);
    color: var(--muted);
    max-width: 34em;
}

/* Sectors line: closes the service rows under its own hairline. */
.sectors-line[b-zr06p2bsz9] {
    margin: 44px 0 0;
    padding-top: 26px;
    border-top: 1px solid var(--hair-14);
    font: 400 14px/1.7 var(--sans);
    color: var(--muted);
}

/* ---- Engagements (cream continues; a hairline separates it from Services) ----
   Same two-column shape as About (copy left, gold-ruled block right) so the
   MSP/partner block reads with the credentials column's weight. */
.engagements[b-zr06p2bsz9] {
    background: var(--ivory);
    border-top: 1px solid var(--hair-08);
}

.eng-grid[b-zr06p2bsz9] {
    display: grid;
    grid-template-columns: minmax(320px, 1.3fr) minmax(280px, 1fr);
    gap: clamp(48px, 7vw, 120px);
    align-items: start;
}

/* Same hard-floor collapse as .about-grid: below ~780px the two tracks cannot
   both hold their minmax floors, so one column before the page can overflow. */
@media (max-width: 780px) {
    .eng-grid[b-zr06p2bsz9] {
        grid-template-columns: 1fr;
        gap: 48px;
    }
}

.eng-copy > p[b-zr06p2bsz9] {
    margin: 0 0 22px;
    font: 400 16px/1.8 var(--sans);
    color: var(--muted);
    max-width: 520px;
}

    .eng-copy > p:last-child[b-zr06p2bsz9] {
        margin-bottom: 0;
    }

.eng-partner[b-zr06p2bsz9] {
    border-top: 1px solid var(--ochre);
    margin-top: 12px;
    padding-top: 28px;
}

.eng-partner-head[b-zr06p2bsz9] {
    margin: 0 0 14px;
    font: 600 12px/1.6 var(--sans);
    letter-spacing: .2em;
    color: var(--dark-ochre);
}

.eng-partner p[b-zr06p2bsz9] {
    margin: 0;
    font: 400 15px/1.8 var(--sans);
    color: var(--muted);
}

/* ---- About (paper band, copy + credentials column) ---- */
.about[b-zr06p2bsz9] {
    background: var(--ivory-tint);
    border-top: 1px solid var(--hair-08);
}

.about-grid[b-zr06p2bsz9] {
    padding-block: clamp(72px, 11vh, 120px);
    display: grid;
    grid-template-columns: minmax(320px, 1.3fr) minmax(280px, 1fr);
    gap: clamp(48px, 7vw, 120px);
    align-items: start;
}

/* The two columns have HARD floors: 320 + 280 + the gap. Below roughly 740px of
   viewport the content box is narrower than that sum, and a grid track cannot
   shrink past its minmax floor, so the page overflowed horizontally by ~33px
   and the whole document scrolled sideways. The <=640px layer already collapses
   to one column, which is why this only ever bit the 641 to 740 band.
   Collapsing to one column up to 780px covers it with margin: at 780 the two
   columns need 654.6px against 686.4px available, the first width where they
   genuinely fit. Same single-column shape the mobile layer uses, so nothing new
   to maintain. */
@media (max-width: 780px) {
    .about-grid[b-zr06p2bsz9] {
        grid-template-columns: 1fr;
        gap: 48px;
    }
}

.about-copy .section-title[b-zr06p2bsz9] {
    margin-bottom: 32px;
}

.about-copy > p[b-zr06p2bsz9] {
    margin: 0 0 22px;
    font: 400 16px/1.8 var(--sans);
    color: var(--muted);
    max-width: 520px;
}

    .about-copy > p:last-child[b-zr06p2bsz9] {
        margin-bottom: 0;
    }

.credentials[b-zr06p2bsz9] {
    border-top: 1px solid var(--ochre);
    margin-top: 12px;
}

.cred-row[b-zr06p2bsz9] {
    padding: 32px 0;
    border-bottom: 1px solid var(--hair-12);
}

.cred-big[b-zr06p2bsz9] {
    font: 500 40px/1.1 var(--serif);
    color: var(--aubergine);
}

.cred-small[b-zr06p2bsz9] {
    margin-top: 10px;
    font: 600 12px/1.5 var(--sans);
    letter-spacing: .2em;
    color: var(--dark-ochre);
}

/* ---- Contact (plum band; ghosted R; carries the fine print) ---- */
.contact[b-zr06p2bsz9] {
    position: relative;
    overflow: hidden;
    background: var(--footer-plum);
    /* Not in the shell rule: .contact-inner is already max-width 720px centred.
       NOTE .fine-print is a SIBLING of .contact-inner, not a child, so it is
       capped separately below -- it is the one row that would otherwise still
       run the full width of the band. */
    padding: clamp(84px, 13vh, 130px) clamp(20px, 6vw, 72px) clamp(24px, 4vh, 32px);
}

.contact-ghost[b-zr06p2bsz9] {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    font: 500 min(40vw, 520px)/1 var(--serif);
    color: rgba(247, 241, 230, .03);
    pointer-events: none;
    user-select: none;
}

.contact-inner[b-zr06p2bsz9] {
    position: relative;
    max-width: 720px;
    margin: 0 auto;
    display: flex;
    flex-direction: column;
    align-items: center;
    text-align: center;
}

.contact-monogram[b-zr06p2bsz9] {
    width: 96px;
    height: auto;
    display: block;
    opacity: .95;
}

.contact-rule[b-zr06p2bsz9] {
    width: 44px;
    height: 1px;
    background: var(--gold);
    margin: 32px 0;
}

.contact-title[b-zr06p2bsz9] {
    margin: 0 0 24px;
    font: 500 clamp(38px, 4.5vw, 58px)/1.15 var(--serif);
    color: var(--ivory);
    text-wrap: balance;
}

    /* Large-text accent: --gold is 6.06:1 on the footer plum, AA at any size. */
    .contact-title em[b-zr06p2bsz9] {
        font-style: italic;
        color: var(--gold);
    }

/* Contrast-safe: 65% cream is 6.60:1 on the footer plum.
   520px, not 440: the 2026-08-06 contact copy runs ~230 characters and at 440
   it stacked six lines tall under the title. */
.contact-sub[b-zr06p2bsz9] {
    margin: 0 0 44px;
    font: 400 16px/1.7 var(--sans);
    color: rgba(247, 241, 230, .65);
    max-width: 520px;
}

/* Outlined gold button on the plum band */
.btn-gold-dark[b-zr06p2bsz9] {
    display: inline-block;
    padding: 15px 34px;
    border: 1px solid var(--gold);
    color: var(--ivory);
    font: 600 12px/1 var(--sans);
    letter-spacing: .24em;
    transition: all .25s;
}

    .btn-gold-dark:hover[b-zr06p2bsz9] {
        background: var(--gold);
        color: var(--footer-plum);
    }

.contact-email[b-zr06p2bsz9] {
    margin-top: 28px;
    font: 400 14px/1 var(--sans);
    letter-spacing: .04em;
    color: var(--gold);
    padding: 10px 0; /* enlarged touch target */
    transition: color .2s ease;
}

    .contact-email:hover[b-zr06p2bsz9] {
        color: var(--ivory);
    }

/* Fine-print row: the page footer, inside the plum band.
   Contrast-safe: 65% cream (6.60:1); the redesign's 50% sat at the 4.5:1 line. */
.fine-print[b-zr06p2bsz9] {
    position: relative;
    /* Capped here rather than in the shell rule because this row is a SIBLING
       of .contact-inner, not a child, so the band's 720px inner never contained
       it. Left uncapped it was the one `space-between` row still spanning the
       whole 2416px of a 2560px viewport. */
    /* The shell's CONTENT width, not its border width. Every other shell row is
       a 1440px box with padding-inline inside it, so its text starts 72px in.
       Capping this row at a flat 1440 lined up the borders but pushed the text
       and its hairline 72px outboard of every other row on the page. */
    max-width: calc(var(--shell) - 2 * clamp(20px, 6vw, 72px));
    margin-inline: auto;
    margin-top: clamp(64px, 10vh, 100px);
    padding-top: 32px;
    border-top: 1px solid rgba(247, 241, 230, .12);
    display: flex;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 16px;
    font: 400 11px/1.6 var(--sans);
    letter-spacing: .16em;
    color: rgba(247, 241, 230, .65);
}

/* Registration line: its own centred row under the brand/legal pair. */
.fine-print-tax[b-zr06p2bsz9] {
    flex-basis: 100%;
    text-align: center;
}

/* ---- Mobile layer (dedicated small-screen formatting) ---- */
@media (max-width: 640px) {
    /* Two compact rows (lockup, then links) and NOT sticky: the localized lockup
       plus four letterspaced links cannot share one 375px row, and a ~100px
       sticky header eats a third of a phone screen. Design-review fallback. */
    .site-header[b-zr06p2bsz9] {
        position: static;
    }

    .header-inner[b-zr06p2bsz9] {
        justify-content: center;
        row-gap: 0;
        padding: 4px 5vw 10px;
        min-height: 0;
    }

    /* ---- Mobile lockup: sized to the row, not inherited from desktop ----
       The shipped mobile lockup inherited the compact desktop values (29px mark,
       13px name, 9px sub) and measured 164px FR / 153px EN inside a 338px row on
       a 375px phone. It read as lost rather than small: 49% FR, 45% EN of the
       width available to it. These sizes hold it at ~83% of the row instead.

       WHY clamp AND NOT A FIXED SIZE. The desktop EXPANDED values (58/26/13)
       are the obvious candidate and they are not the answer: fixed at 58/26/13
       the FR lockup is 270px, which fits a 320px phone with 18px to spare but
       OVERFLOWS a 280px Galaxy Fold outright (270 into a 252px row). FR is the
       binding case because CONSULTATION is two letters longer than CONSULTING.
       The vw term scales the mark with the viewport; at 280 and 320 it is the vw
       term doing the work, and the floors only bind below ~267px, which is the
       backstop rather than the working mechanism. MEASURED FR widths:
       239px of 288 at 320, 280px of 338 at 375, 292px of 373 at 414. A steady
       ~83% of the row up to 400px, where every clamp caps; above that the lockup
       holds at 292px and the share falls away (78% at 414, 51% at 640).

       SIZING GOTCHA, worth knowing before anyone re-derives these numbers.
       `.lockup-text` is a flex COLUMN, so both lines report the same width: that
       of the WIDER one, which is always the sub (CONSULTING / CONSULTATION), not
       the four-character name. Scaling a measured `.lockup-name` width by the
       name's font-size ratio therefore over-predicts the lockup badly. The sub
       line is what drives the box.

       THIS DOES NOT TOUCH THE 940px HEADER GATE. That gate binds because above
       640px the lockup and the nav share one STICKY row. Here the header is
       position:static and nothing can be swallowed, so the cost is one-time
       scroll: +23px at 320, +32px at 375, +35px EN / +62px FR at 620-640 (FR
       still wraps to two rows up there, which is why the two differ). The lockup owns its
       own centred row up to ~610px; from ~620 to 640 the EN header still fits
       both on one row, which is harmless because flex-wrap absorbs it with no
       overflow. Do not raise the gate for this.

       KNOWN AND ACCEPTED (David 2026-08-05): the mark steps from 64px to 29px
       across the 640/641 boundary, visible only when dragging a desktop browser
       through it, never on a phone. A fourth size tier was not worth it. */
    .brand-lockup[b-zr06p2bsz9] {
        padding: 8px 0 2px;
        gap: clamp(16px, 6vw, 24px);
    }

        .brand-lockup img[b-zr06p2bsz9] {
            height: clamp(44px, 16.3vw, 64px);
        }

    /* Tracking is in em on both lines, so it scales with the type on its own. */
    .lockup-name[b-zr06p2bsz9] {
        font-size: clamp(20px, 7.2vw, 28px);
    }

    .lockup-sub[b-zr06p2bsz9] {
        font-size: clamp(10px, 3.6vw, 14px);
    }

    /* ---- Landscape phones opt OUT of the enlargement ----
       A landscape phone is still inside this layer (568x320, 640x360, 480x320)
       and the enlarged lockup is wrong for it: the wider lockup pushes the nav
       onto a second row, taking the header from 54px to 116px, i.e. 36% of a
       320px-tall screen, with the hero content pushed from y=110 to y=172 and
       the H1 itself from y=145 to y=207, i.e. 65% down a 320px screen.

       THAT IS THE EXACT CASE THIS FILE ALREADY REFUSES. The condensing header's
       `min-height: 600` gate exists because "104px would eat 28% of that
       screen" -- and 36% is worse than the number that was ruled unacceptable.
       So the compact sizes come back and the header returns to its shipped 54px.

       450px is a safe divider: the shortest portrait phone in scope is 320x568,
       well clear of it, so no portrait device is touched. Verified at 568x320
       and 640x360 in BOTH languages. */
    @media (max-height: 450px) {
        .brand-lockup[b-zr06p2bsz9] {
            gap: 14px;
        }

            .brand-lockup img[b-zr06p2bsz9] {
                height: 29px;
            }

        .lockup-name[b-zr06p2bsz9] {
            font-size: 13px;
        }

        .lockup-sub[b-zr06p2bsz9] {
            font-size: 9px;
        }
    }

    /* Five links since 2026-08-06 (ENGAGEMENTS / MANDATS): at 11px/.12em the EN
       row measured ~373px against ~335px available on a 375px phone. 10px/.1em
       and a 10px gap bring it back inside a 320px viewport in both languages;
       flex-wrap is the backstop so an overflow can only ever wrap, never scroll
       the page sideways. */
    .main-nav[b-zr06p2bsz9] {
        gap: 10px;
        flex-wrap: wrap;
        justify-content: center;
    }

    .nav-link[b-zr06p2bsz9] {
        font-size: 10px;
        letter-spacing: .1em;
        padding: 8px 2px;
    }

    .nav-lang[b-zr06p2bsz9] {
        padding-left: 10px;
    }

    .hero-inner[b-zr06p2bsz9] {
        padding: 56px 20px 60px;
    }

    /* FR "Comptabilisées." is one unbreakable 299px word at the 56px clamp floor;
       16vw keeps it inside viewports down to 320px. */
    .hero-title[b-zr06p2bsz9] {
        font-size: clamp(44px, 16vw, 56px);
    }

    .hero-support[b-zr06p2bsz9] {
        margin: 28px 0 14px;
        font-size: 16px;
    }

    .hero-grounding[b-zr06p2bsz9] {
        margin: 0 0 32px;
        font-size: 15px;
    }

    /* The ghost shrinks and tucks right so it stays a texture, not a wall. */
    .hero-ghost[b-zr06p2bsz9] {
        font-size: min(44vh, 320px);
        right: -24%;
        top: -6%;
    }

    .baseline-inner[b-zr06p2bsz9] {
        padding: 14px 20px;
        gap: 8px 24px;
    }

    .btn-gold-dark[b-zr06p2bsz9] {
        width: 100%;
        max-width: 320px;
        text-align: center;
        padding: 16px 20px;
        box-sizing: border-box;
    }

    .section-inner[b-zr06p2bsz9],
    .about-grid[b-zr06p2bsz9] {
        padding: 56px 20px;
    }

    .section-inner[b-zr06p2bsz9] {
        padding-bottom: 40px;
    }

    .section-head[b-zr06p2bsz9] {
        margin-bottom: 8px;
    }

    .about-grid[b-zr06p2bsz9] {
        grid-template-columns: 1fr;
        gap: 48px;
    }

    /* Rows collapse to numeral-above-title; the description takes the full width. */
    .pillar[b-zr06p2bsz9] {
        grid-template-columns: 1fr;
        gap: 8px;
        padding: 28px 0 32px;
    }

        /* the section's own 40px bottom padding carries the gap after the last card */
        .pillar:last-child[b-zr06p2bsz9] {
            padding-bottom: 8px;
        }

    .cred-big[b-zr06p2bsz9] {
        font-size: 32px;
    }

    .contact[b-zr06p2bsz9] {
        padding: 64px 20px 24px;
    }

    .contact-monogram[b-zr06p2bsz9] {
        width: 76px;
    }

    .fine-print[b-zr06p2bsz9] {
        flex-direction: column;
        align-items: center;
        text-align: center;
        gap: 8px;
        margin-top: 56px;
    }
}
