/* apps/LIGHT_3 amendment (owner-directed, 2026-09-01) — layout repair + the
 * sites-v2 page vocabulary.
 *
 * NOT part of the ported legacy stylesheet (`index.css`, byte-verbatim per the
 * README's content-provenance note) — kept separate for the same reason
 * `islands.css` is, so that file stays a verbatim port. Nothing here restyles a
 * legacy class: every selector is either a document-level repair (§ 1) or a
 * `sec-*` / `cell-*` class that only the v2 corpus emits (§ 2+).
 *
 * ## 1. The layout repair — why it is here and not in a v2-only file
 *
 * MEASURED 2026-09-01 on the built dist, on EVERY route, legacy included:
 *
 * - `index.css` opens with `body { position: fixed; height: 100% }`. The legacy
 *   build paired that with a `.main` / `.content` wrapper pair
 *   (`.content { height: 100%; overflow-y: auto }`) which was the real scroll
 *   container. The site-kit shell emits `<main id="main">` and no such
 *   wrappers, so the port kept the clamp and lost the scroller:
 *   `document.documentElement.scrollHeight === clientHeight === 720` while
 *   `main` measured 2392px on `/fr/awa-locker` and 1269px on `/suite`.
 *   Nothing below the first viewport was reachable on any page of the site.
 * - `index.css` also sets `header { position: fixed; top: 0 }`, which the
 *   legacy build offset with `.main { top: 45px }`. Without `.main`,
 *   `main.getBoundingClientRect().top === 0`: the first 37px of every page sat
 *   underneath the header.
 *
 * Both are pre-existing defects of the W2 port, not of the `/suite` flip — but
 * a page that cannot scroll cannot be styled, and the M5 banner is specified as
 * "sticky en haut de page AU SCROLL", so they are repaired here.
 *
 * The repair is deliberately the SMALLEST one that restores the legacy intent
 * rather than a re-creation of the `.main`/`.content` pair: the footer is a
 * sibling of `<main>` in the shell, so an absolutely-positioned scroller would
 * push it out of reach. Returning the document to normal flow scrolling and
 * making the header `sticky` gives the same result — a header that stays put
 * while content scrolls — with no hardcoded header height to drift.
 */

/* ── 1. document layout repair (site-wide, legacy pages included) ───────── */

body {
    /* Undo the clamp `index.css` inherited from a layout whose scroll
     * container no longer exists. `position: static` returns the document to
     * normal flow scrolling; the `top`/`bottom`/`left` offsets on the same
     * rule become inert, as intended. */
    position: static;
    height: auto;
    min-height: 100%;

    /* apps/BATCH_16/03 (SUITE-4) — the `/suite` sticky transition banner
     * (§ 5 below) sticks BELOW the header, so it needs the header's own
     * rendered height. Declared here, on `body` (already open, never a NEW
     * `:root` block — `chrome-contrast.test.js` pins `pages.css` to open
     * none), rather than in `tokens.css`: this token has no home in the
     * frozen 9-name `TOKEN_CONTRACT`, and `tokens.css` is outside this
     * task's file list.
     *
     * MEASURED, not a pure token expression: the header's own box IS
     * token-derived (`site-header.js`'s inline `padding: var(--fw-space-4)`
     * = 1rem all sides + `design.css`'s `border-bottom: 0.1875rem` = 2 x
     * 16px + 3px = 35px), but the remaining 37px is the `<a>` content box —
     * `design.css`'s `header[role="banner"] a { padding: var(--fw-space-2)
     * 0 }` (2 x 8px = 16px) plus the text LINE BOX at `line-height: normal`
     * on the `system-ui` stack (`index.css` `body`'s font stack), which no
     * token names (a UA/font-metric value, not a design constant). A real
     * Chromium render of the composed `/suite` document (five sheets
     * inlined, no dist) measured `header[role="banner"]`'s
     * `getBoundingClientRect().height` at a stable 72px == 4.5rem — the
     * literal below, per the plan's fallback rule ("no token expression
     * reproduces the measured height within 1px -> a measured rem
     * literal"). Re-measure and update this comment if the header markup,
     * its padding tokens or the font stack change. */
    --aw-header-h: 4.5rem;
}

header {
    /* `sticky` keeps the legacy `position: fixed`'s INTENT (a header that stays
     * visible while the page scrolls) while leaving the header in flow, so it
     * occupies its own height and occludes nothing. `top: 0` and `z-index: 4`
     * already come from `index.css`; only the positioning scheme changes. */
    position: sticky;
}

/* ── 2. the v2 page surface ────────────────────────────────────── */

/* Every selector below is keyed on `[class^="sec-"]`, the prefix only the v2
 * block renderer emits (`sec-plain` for the unnamed section variant,
 * `sec-<variant>` for a semantic one). VERIFIED against the built dist
 * 2026-09-01: across the 17 emitted documents, zero legacy class starts with
 * — or even contains — `sec-`, and the only two occurrences anywhere are
 * `sec-plain` and `sec-transition_sticky`, both on `/suite`. A starts-with
 * match rather than a substring one keeps that true as classes are added
 * (`sep-light`, the nearest legacy name, is not reached by either, but only
 * the prefix form states the intent).
 *
 * The reading surface goes on `main` rather than on each block: a v2 page's
 * title and intro are `.container` elements at `main` level, and `.container`
 * is a max-width centred column, so painting THEM leaves unpainted rails down
 * both sides and a gap at every margin. `:has()` scopes it to v2 pages without
 * a wrapper element the renderer does not emit; where `:has()` is unsupported
 * the page degrades to the section-by-section surface below, which is
 * readable, not broken. */
main:has(> [class^="sec-"]) {
    background: var(--aw-surface);
    color: var(--aw-text);
    display: block;
}

[class^="sec-"] {
    background: var(--aw-surface);
    color: var(--aw-text);
}

/* The container gutter (design pass, apps/BATCH_17/05): the offset a centred
 * `.container` lands at, mirroring `index.css`'s own max-width ladder, so a
 * rule that must sit ON the page's left spine can ask for it. A `%` inside a
 * custom property resolves at the USE site, so one declaration serves a child
 * of `main` and a child of an inset band alike. It reproduces the measured
 * pre-change container left exactly: 70 / 16 / 24 / 18 at 1280 / 992 / 768 /
 * 576, and 0 below 576 where `.container` has no max-width. */
body { --aw-gutter: 0px }
@media (min-width: 576px) { body { --aw-gutter: calc(50% - 270px) } }
@media (min-width: 768px) { body { --aw-gutter: calc(50% - 360px) } }
@media (min-width: 992px) { body { --aw-gutter: calc(50% - 480px) } }
@media (min-width: 1200px) { body { --aw-gutter: calc(50% - 570px) } }
@media (min-width: 1400px) { body { --aw-gutter: calc(50% - 660px) } }

/* Vertical rhythm between the top-level sections of a v2 page. `1.25rem` was
 * off the spacing scale (.25/.5/.75/1/1.5/2/3/4rem) — CONSTRAINTS.md § 9.1
 * tagged it D, a design decision deferred to the design pass. */
main > [class^="sec-"] {
    padding: var(--fw-space-6) 0;
}

main > [class^="sec-"]:last-child {
    padding-bottom: var(--fw-space-16);
}

/* A v2 page's title sits outside any section. It declares NO font-size (design
 * pass): the `2.75rem` here was off the `--aw-step-*` scale AND outranked
 * `design.css` § 2's ladder, so the title measured a fixed 44px at 1280, 992,
 * 768 AND 576. The v2 vocabulary now reads the one ladder design.css ships. */
main > h1.container {
    padding: 2.25rem var(--fw-space-4) var(--fw-space-2);
    color: var(--aw-heading);
}

/* Inline prose links. `index.css` styles `a` for the NAV — `color: #212529`
 * (identical to body text) and `padding: .5rem .5rem`, which is a hit target
 * for a menu item. Inside a paragraph that makes a link invisible AND injects
 * a visible gap on both sides of it: measured on `/suite`'s "En attendant"
 * section, whose whole content is calls to action, the three links read as
 * plain text with stray spacing. Restored to link semantics inside v2 prose
 * only — no nav, menu, header or footer selector is touched. */
main:has(> [class^="sec-"]) :is(p, li) a,
[class^="sec-"] :is(p, li) a {
    color: var(--aw-accent);
    padding: 0;
    text-decoration: underline;
}

main:has(> [class^="sec-"]) :is(p, li) a:hover,
[class^="sec-"] :is(p, li) a:hover {
    color: var(--aw-heading);
}

/* Body copy. `.subtitle` (1.8rem) is now emitted only for the `sub_title`
 * variant (BL-941), so v2 paragraphs land at body size and take their own
 * measure and rhythm. */
main > p.container,
[class^="sec-"] p.container {
    font-size: 1.0625rem;
    line-height: 1.65;
    margin: 0 auto var(--fw-space-4);
    padding: 0 var(--fw-space-4);
}

/* Measure (design pass). `tokens.css` has declared `--aw-measure: 68ch` since
 * W1 and NOTHING read it, while prose measured 120.9ch at 1280 and 101.3ch at
 * 992 (a real 100-glyph probe span). `--aw-gutter` holds the cap on the page's
 * left spine; tables and headings stay wide on purpose. § 5's M5 banner is
 * excluded — its paragraph is centred by design. */
main > p.container,
[class^="sec-"]:not(.sec-transition_sticky) :is(p, ul, ol).container {
    max-width: var(--aw-measure);
    margin-left: var(--aw-gutter);
}

/* Bare calls to action (design pass). A `link` block authored outside a
 * paragraph renders as a DIRECT child of the band with no `.container`, so it
 * lost both the spine (measured left 0 on `/`, 19 on `/offers`, against a prose
 * spine at 70 / 79.5) and the link voice (`rgb(33,37,41)`, no underline — the
 * nav rule). The structural fix is the renderer's and is routed; this restores
 * the geometry and the voice a prose link already has. */
main > [class^="sec-"]:not(.sec-transition_sticky) > a {
    display: inline-flex;
    align-items: center;
    width: auto;
    min-height: 2.75rem;
    margin: var(--fw-space-2) 0 var(--fw-space-4) calc(var(--aw-gutter) + var(--fw-space-4));
    padding: var(--fw-space-2) var(--fw-space-6);
    border: 1px solid var(--aw-accent);
    border-radius: var(--fw-radius-md);
    background: var(--aw-surface);
    color: var(--aw-accent-strong);
    font-weight: 600;
    line-height: 1.25;
    text-decoration: none;
    text-underline-offset: 0.25em;
    transition: background-color 0.15s ease, border-color 0.15s ease;
}

/* Corporate pass (2026-09-19): the bare call to action takes the BUTTON voice
 * — it is the page's action, not a prose link. Its text keeps one colour in
 * both states and only the surface moves, so it stays legible against the
 * button AND against the band behind it. Consecutive actions share a line;
 * on a phone they stack on the spine. */
main > [class^="sec-"]:not(.sec-transition_sticky) > a + a {
    margin-left: var(--fw-space-3);
}

main > [class^="sec-"]:not(.sec-transition_sticky) > a:hover {
    border-color: var(--aw-accent-strong);
    background: var(--aw-surface-alt);
    color: var(--aw-accent-strong);
}

@media (max-width: 30rem) {
    main > [class^="sec-"]:not(.sec-transition_sticky) > a {
        display: flex;
        width: fit-content;
    }

    main > [class^="sec-"]:not(.sec-transition_sticky) > a + a {
        margin-left: calc(var(--aw-gutter) + var(--fw-space-4));
    }
}

/* The accent is 4.34:1 on `--aw-tint-accent`, below AA — whoever repaints a
 * band owes its states. `[class^="sec-"].sec-sponsors` is deliberate: it TIES
 * the two rules above at (0,2,2)/(0,3,2) and wins by emit order, where
 * `main > .sec-sponsors > a` is (0,1,2) and would silently lose. */
main > [class^="sec-"].sec-sponsors > a,
main > [class^="sec-"].sec-sponsors > a:hover {
    color: var(--aw-heading);
}

[class^="sec-"] h2.container {
    /* No font-size: as above, the class-qualified `1.9rem` outranked
     * design.css's ladder (measured 30.4px at all four widths). `margin-top`
     * was 8px against the preceding paragraph's 18.4px bottom margin — a
     * heading closer to what it ends than to what it opens. */
    margin-top: var(--fw-space-8);
    padding: 0 var(--fw-space-4);
    color: var(--aw-heading);
}

[class^="sec-"] h3.container {
    padding: 0 var(--fw-space-4);
    color: var(--aw-heading);
}

/* ── 3. lists — the `items` loop role ───────────────────────────────── */

[class^="sec-"] ul.container,
[class^="sec-"] ol.container {
    padding: 0 var(--fw-space-4) 0 2.75rem;
    margin: 0 auto var(--fw-space-6);
    font-size: 1.0625rem;
    line-height: 1.65;
}

[class^="sec-"] ul.container {
    list-style: disc;
}

[class^="sec-"] ol.container {
    list-style: decimal;
}

[class^="sec-"] ul.container > li,
[class^="sec-"] ol.container > li {
    margin-bottom: var(--fw-space-3);
    padding-left: var(--fw-space-1);
}

/* A multi-column `items` row emits one `cell-<column>` span per column. The
 * corpus's dominant shape is `lead,text` — a term and its gloss — so the lead
 * reads as the term. Any other column keeps the flow. */
.cell-lead {
    font-weight: 600;
    color: var(--aw-heading);
}

/* ── 4. tables — an `items` loop carrying `col_<column>` headers ──────── */

[class^="sec-"] table.container {
    border-collapse: collapse;
    margin: 0 auto var(--fw-space-6);
    width: calc(100% - var(--fw-space-8));
    font-size: var(--aw-step-0);
}

[class^="sec-"] table.container th,
[class^="sec-"] table.container td {
    border-bottom: 1px solid var(--aw-rule-soft);
    padding: var(--fw-space-3);
    text-align: left;
    vertical-align: top;
}

[class^="sec-"] table.container th {
    background: var(--aw-tint-accent);
    color: var(--aw-heading);
    font-weight: 600;
}

/* ── 4b. media — a catalog `<picture>` with intrinsic dimensions ──────── */

/* apps/BATCH_16/03 (PRC-3). `render-blocks.js`'s `renderMedia` emits `width`/
 * `height` on the `<img>` fallback only when the catalog entry declares BOTH
 * `intrinsicWidth` and `intrinsicHeight` (an aspect-ratio hint, never a fixed
 * box) — this rule is what keeps that hint from fighting the responsive
 * layout: the intrinsic attributes still reserve the right aspect ratio (CLS)
 * while the rendered size stays fluid. */
[class^="sec-"] picture img {
    width: 100%;
    height: auto;
}

/* ── 4c. `coming` / `badge` — the PRC-3 vocabulary ─────────────────────── */

/* A `section` authored `variant: "coming"` (apps/BATCH_16/03, PRC-3) renders
 * through {@link genericSection} like any other {@link
 * SEMANTIC_SECTION_VARIANTS} member: a "coming soon" block reads as
 * present-but-not-yet without a second layout.
 *
 * The design pass retired the `opacity: .72` this rule carried.
 * `getComputedStyle` reports a declared colour VERBATIM, so no contrast gate
 * could see what the dimmer painted: composited on the white surface, an accent
 * prose link here measured 3.00:1, BELOW AA, from a declared 4.84:1. Doctrine:
 * muted by COLOUR, never by opacity. Only the BODY COPY is muted, at exactly
 * the value it already composited to (6.14:1, the same pixel); the heading and
 * the CTA return to full strength — a block that is not yet available must
 * still be scannable, and its only CTA must be a real affordance. */
.sec-coming :is(p, li) {
    color: var(--aw-text-muted);
}

/* Corporate pass (2026-09-19): a `coming` block is a card like the offer and
 * tier cards of `design.css` § 21 (which may not name this class), on the
 * alternate surface with a dashed rule — present, but visibly not yet. The
 * accent is 4.34:1 on that surface, so its CTA takes the strong accent. */
main > .sec-coming {
    width: calc(100% - 2 * var(--fw-space-4));
    max-width: var(--aw-container);
    margin: var(--fw-space-6) auto 0;
    padding: var(--fw-space-8) var(--fw-space-4) var(--fw-space-6);
    border: 1px dashed var(--aw-border-strong);
    border-radius: var(--fw-radius-lg);
    background: var(--aw-surface-alt);
    color: var(--aw-text);
    --aw-gutter: 0px;
}

/* A `coming` strip that only carries the badge and OPENS the page sits on
 * the title surface, above the `main > h1.container` band. */
main > .sec-coming:first-child {
    width: auto;
    max-width: none;
    margin: 0;
    padding: var(--fw-space-12) 0 0;
    border: 0;
    border-radius: 0;
    background: var(--aw-hero-bg);
    color: var(--aw-hero-sub);
    --aw-gutter: max(0px, calc(50% - var(--aw-container) / 2 - var(--fw-space-4)));
}

main > .sec-coming:first-child p.container.badge {
    margin-bottom: 0;
    color: var(--aw-hero-sub);
}

main > .sec-coming:first-child + h1.container {
    padding-top: var(--fw-space-6);
}

/* A `text` block authored `variant: "badge"` renders `class="container badge"`
 * — a small pill label, whose only corpus use today is inside `coming`. The
 * selector carries `p.container` on purpose (design pass): the badge IS a
 * `<p class="container badge">`, so `[class^="sec-"] p.container` above is
 * (0,2,1) and the old `.sec-coming .badge` was (0,2,0) — the pill LOST the
 * cascade to a rule in its own sheet and measured 17px with 16px of horizontal
 * padding. At (0,3,1) the authored values apply. */
[class^="sec-"] p.container.badge {
    display: inline-block;
    margin-left: calc(var(--aw-gutter) + var(--fw-space-4));
    font-size: .8rem;
    letter-spacing: .06em;
    text-transform: uppercase;
    border: 1px solid currentColor;
    padding: var(--fw-space-1) var(--fw-space-2);
    border-radius: var(--fw-radius-md);
}

/* ── 5. the /suite transition banner (M5) ───────────────────────── */

/* M5, verbatim from the page's own gate `marker` cell: « Le bandeau de
 * transition est limité à la page /suite, "persistant" = sticky en haut de
 * page au scroll — jamais un chrome site-wide ». The class IS the scope: only
 * `suite.fr.json` authors `transition_sticky`, and
 * `tests/renderers.integration.test.js` asserts the set of emitted documents
 * carrying it is exactly `['suite/index.html']`. Nothing here is site-wide —
 * no `header`, `footer` or chrome selector is touched.
 *
 * It sticks BELOW the header, not at viewport top: the header is itself
 * `sticky` at `top: 0` with `z-index: 4` (§ 1), so a banner at `top: 0` would
 * slide under it. The lower `z-index` keeps the header on top if they meet.
 *
 * `top` is `--aw-header-h` (declared on `body`, § 1) — the header's own
 * rendered height, not a hardcoded offset. The retired `2.75rem` undershot a
 * TALLER header (SUITE-4: measured 72px == 4.5rem, not 44px), which is what
 * let the banner sit UNDER the header instead of directly below it; see
 * `tests/sticky-banner.integration.test.js` for the browser proof. */
.sec-transition_sticky {
    position: sticky;
    top: var(--aw-header-h);
    z-index: 3;
    background: var(--aw-rule);
    color: var(--aw-surface);
    box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.275);
}

main > .sec-transition_sticky {
    padding: 0;
}

.sec-transition_sticky p.container {
    color: var(--aw-surface);
    font-size: var(--aw-step-0);
    line-height: 1.55;
    margin: 0 auto;
    padding: 0.85rem var(--fw-space-4);
}

/* Specificity note: the prose-link rule above is `[class^="sec-"] :is(p,li) a`
 * (0,1,2) and the banner's paragraph IS a `p` inside a `sec-` block, so the
 * banner needs at least that weight to keep its link white on navy. */
.sec-transition_sticky p.container a {
    color: var(--aw-surface);
    text-decoration: underline;
    padding: 0;
    white-space: nowrap;
}

.sec-transition_sticky p.container a:hover {
    color: #9ad4ef;
}

@media (max-width: 768px) {
    .sec-transition_sticky {
        /* Worth its space on a phone, but not two thirds of the fold: it stops
         * sticking below the header and simply leads the page. */
        position: static;
    }

    .sec-transition_sticky p.container {
        font-size: 0.95rem;
    }

    main > h1.container {
        font-size: 2rem;
    }
}

/* BL-1489: the 404 error document (`src/pages/not-found.js`) — chrome, not a
 * v2 content page, so it stays out of § 2's `sec-*` vocabulary. */
.not-found {
    padding: var(--fw-space-16) var(--fw-space-4);
    text-align: center;
}

.not-found__code {
    color: var(--aw-text-muted);
    font-size: var(--aw-step-3);
    font-weight: 700;
    margin: 0;
}

.not-found__lead {
    margin: var(--fw-space-4) auto;
    max-width: var(--aw-measure);
}

.not-found__other {
    border-top: 1px solid var(--aw-rule-soft);
    margin-top: var(--fw-space-8);
    padding-top: var(--fw-space-8);
}

/* M50/M51: « Apache-2.0 » never breaks across lines (content-level <span class="aw-nowrap">). */
.aw-nowrap { white-space: nowrap; }
