/* ══════════════════════════════════════════════════════════════════
   Shell — the app frame: layout grid, sidenav, scrim, toolbar.

   These primitives are inherently coupled — topbar height affects
   sidenav sticky offset, shell grid decides where sidenav lives,
   scrim overlays the drawer. Keeping them together is more correct
   than splitting into one-file-per-component.

   One component, two viewports:
     ≥900px  persistent sidenav column; "closed" collapses to a
             narrow chevron rail
     <900px  sidenav becomes an off-canvas drawer; "open" slides in
             with a scrim

   Open/closed state lives on <html> as data-sidenav="open|closed",
   set by the no-flash inline head script before first paint and
   kept in sync by app-sidenav.js. CSS selects via [data-sidenav] at
   the document root so there's a single source of truth.

   Default (no attribute / missing script): desktop renders open,
   mobile renders closed — the natural first-visit defaults.

   Uses the flipping semantic tokens (--color-ink, --color-line,
   --color-surface) so the whole component inverts inside any
   [data-surface="dark"] ancestor.

   Sections:
     1. Shell layout (grid + main)
     2. Sidenav (desktop column + mobile drawer)
     3. Scrim (mobile drawer overlay)
     4. Sidenav content (list, groups, headings, separators)
     5. Nav links
     6. Hamburger toggle (mobile)
     6b. Mobile drawer close button (×)
     7. Desktop collapse/expand chevrons
     8. Toolbar container
     9. User account dropdown
    10. Page wrapper + title
   ══════════════════════════════════════════════════════════════════ */

@layer components {

    /* ─── 1. Shell layout ─────────────────────────────────────────── */

    /* Body is a flex column (app-base.css). The shell and any <main>
       take `flex: 1` (= 1 1 0%) so they start at zero basis and grow
       to absorb all remaining vertical space. flex-basis: 0% is the
       reliable sticky-footer pattern — flex-basis: auto can let a
       content-sized item resist growth in some browsers/layouts.
       The footer, when present, sits below in normal flow. */
    .app-shell,
    main,
    .app-main {
        flex: 1;
    }

    .app-shell {
        display: grid;
        grid-template-columns: 16rem 1fr;
        /* Stretch the single implicit row to the shell's full height so
           the main cell fills vertically, not just to the taller of
           sidenav/main content sizes. */
        grid-auto-rows: 1fr;
        /* Direct minimum height: viewport minus topbar (approximated at
           4rem). This is a belt-and-suspenders minimum on top of the
           flex: 1 grow behavior — even if the body-flex pattern isn't
           distributing space for any reason, the shell is guaranteed to
           fill the visible viewport below the topbar. Footer still sits
           below the shell in normal flow; scrolls into view on short
           pages. */
        min-height: calc(100vh - 4rem);
        min-height: calc(100dvh - 4rem);
        transition: grid-template-columns var(--dur-base) var(--ease);
    }

    /* Override the legacy .app-main flex/wrap rules inside the shell.
       The legacy stylesheet (app-body.css, @layer legacy) gives
       .app-main a flex-direction: column; flex-wrap: wrap treatment
       and a fixed width from --app-container-width. Those wrap its
       children into extra columns on tall pages and cause content to
       overlap surrounding elements. Inside the shell we want a plain
       block main that fills its grid cell. Layer order (components >
       legacy) wins without !important. */
    .app-shell > .app-main {
        display: block;
        width: 100%;
        margin: 0;
        padding: 0;
    }

    /* Collapsed desktop state: narrow chevron-width rail so the expand
       affordance stays reachable with minimal visual weight — the rail
       is barely wider than the chevron glyph itself. Nav list is
       hidden by a rule below; sidenav horizontal padding is zeroed. */
    [data-sidenav="closed"] .app-shell {
        grid-template-columns: 1.5rem 1fr;
    }

    /* Narrower sidebar on mid-range desktops so tables breathe */
    @media (max-width: 1439px) {
        .app-shell {
            grid-template-columns: 14rem 1fr;
        }
    }

    /* Mobile: shell collapses to single column; sidenav becomes
       a fixed drawer positioned independently of the grid. */
    @media (max-width: 899px) {
        .app-shell,
        [data-sidenav="closed"] .app-shell,
        [data-sidenav="open"] .app-shell {
            grid-template-columns: 1fr;
        }
    }

    /* No-nav pages: sidebar disappears entirely, shell drops the
       sidenav grid column. Relies on AppSidenavTagHelper emitting
       data-empty="true" when the provider returns no items. */
    .app-shell:has(> .c-sidenav[data-empty="true"]) {
        grid-template-columns: 1fr;
    }

    /* Area-empty but topbar-nav present (e.g. /onboarding): on desktop
       there's no area navigation to show, so collapse the shell column.
       The aside is still rendered so the mobile drawer can show topbar
       nav items; the desktop hide rule lives further down on .c-sidenav
       itself. */
    @media (min-width: 900px) {
        .app-shell:has(> .c-sidenav[data-area-empty="true"]) {
            grid-template-columns: 1fr;
        }
    }


    /* ─── 2. Sidenav (desktop persistent + mobile drawer) ─────────── */

    .c-sidenav {
        /* Fill the full grid row height so the sidebar column visually
           extends to the bottom of the shell, not just to the bottom of
           the nav items. Content sits at the top (padding-top) with the
           surface background filling the whole column — matches the
           Linear / Notion / Stripe Dashboard pattern. */
        align-self: stretch;
        /* Sticky behavior: keep the sidenav fixed at viewport top while
           the page scrolls, up to 100vh tall. If the nav has more items
           than fit, it scrolls internally via overflow-y: auto. */
        position: sticky;
        top: 0;
        max-height: 100vh;
        overflow-y: auto;
        overflow-x: hidden;
        padding: var(--space-2) var(--space-5) var(--space-6);
        background: var(--color-surface);
        border-right: 1px solid var(--color-line);
        width: 100%;

        /* Subtle scrollbar — the default browser bar reads as dark and
           obtrusive against the sidenav surface. Modern Firefox + Chromium
           honour scrollbar-width/scrollbar-color; WebKit (Safari) needs the
           ::-webkit-scrollbar pseudos below.

           Track is set to var(--color-surface) (the sidenav's own bg) rather
           than `transparent` — Chromium/Edge on Windows otherwise falls back
           to a dark system-coloured gutter for the track region. */
        scrollbar-width: thin;
        scrollbar-color: var(--color-line) var(--color-surface);
    }

    .c-sidenav::-webkit-scrollbar {
        width: 8px;
        background: var(--color-surface);
    }

    .c-sidenav::-webkit-scrollbar-track {
        background: var(--color-surface);
    }

    .c-sidenav::-webkit-scrollbar-thumb {
        background: var(--color-line);
        border-radius: var(--radius-pill);
    }

    .c-sidenav::-webkit-scrollbar-thumb:hover {
        background: var(--color-ink-mute);
    }

    /* Desktop collapsed: sidenav stays visible as a minimal rail so
       the expand chevron is still clickable. Zero horizontal padding
       so the chevron fills the narrow column edge-to-edge; the nav
       list is hidden by a rule further down. */
    @media (min-width: 900px) {
        [data-sidenav="closed"] .c-sidenav {
            padding-left: 0;
            padding-right: 0;
        }
    }

    /* Sidenav with no items: hide the aside entirely. The shell's
       grid rule above drops the column; this just suppresses the
       surface/border so there's no empty chrome. */
    .c-sidenav[data-empty="true"] {
        display: none;
    }

    /* Area-empty desktop: hide the aside so the 16rem column doesn't
       leave empty chrome (chevrons + surface bg). The aside is still
       used on mobile where the drawer shows topbar-nav items. */
    @media (min-width: 900px) {
        .c-sidenav[data-area-empty="true"] {
            display: none;
        }
    }

    /* Marketing-mode sidenav: mobile drawer only. Desktop hides it
       entirely — marketing shows its nav items inline in the topbar,
       so the drawer is redundant above 900px. (Scrim already has a
       base display: none; only becomes visible inside the mobile
       media query, so it needs no marketing-specific rule.) */
    @media (min-width: 900px) {
        .c-sidenav--marketing {
            display: none;
        }
    }

    /* Mobile drawer behavior */
    @media (max-width: 899px) {
        .c-sidenav {
            position: fixed;
            inset: 0 auto 0 0;
            width: min(85vw, 20rem);
            max-height: none;
            height: 100%;
            /* Tight top padding since the close button sits at the top;
               bigger bottom padding for comfortable scroll-end gap. */
            padding: var(--space-2) var(--space-5) var(--space-6);
            border-right: 1px solid var(--color-line);
            transform: translateX(-100%);
            transition: transform var(--dur-base) var(--ease);
            z-index: 60;
            box-shadow: 8px 0 24px -12px rgb(0 0 0 / .15);
            visibility: hidden;
        }

        [data-sidenav="open"] .c-sidenav {
            transform: translateX(0);
            visibility: visible;
        }

        /* Tighter chevron-row bottom margin on mobile: the close button
           is right there at the top and we want the first nav item to
           sit close underneath it, not floated down by a full space-2. */
        .c-sidenav__chevrons {
            margin-bottom: var(--space-1);
        }
    }


    /* ─── 3. Scrim (mobile drawer overlay) ────────────────────────── */

    .c-sidenav-scrim {
        display: none;
    }

    @media (max-width: 899px) {
        .c-sidenav-scrim {
            display: block;
            position: fixed;
            inset: 0;
            background: rgb(0 0 0 / .4);
            opacity: 0;
            pointer-events: none;
            transition: opacity var(--dur-base) var(--ease);
            z-index: 59;
        }

        [data-sidenav="open"] .c-sidenav-scrim {
            opacity: 1;
            pointer-events: auto;
        }

        /* Lock page scroll while drawer is open on mobile */
        html[data-sidenav="open"] body {
            overflow: hidden;
        }
    }


    /* ─── 4. Sidenav content (list, groups, headings) ─────────────── */

    .c-sidenav__list,
    .c-sidenav__sublist {
        list-style: none;
        margin: 0;
        padding: 0;
    }

    /* Mobile-only top section of the functional drawer: mirrors the
       topbar-nav items so they're reachable via the hamburger. On
       desktop these items are visible in the topbar itself — hide the
       duplicate here to avoid doubling up. A thin divider separates
       the topbar section from the area section on mobile. */
    @media (min-width: 900px) {
        .c-sidenav__list--topbar {
            display: none;
        }
    }

    @media (max-width: 899px) {
        .c-sidenav__list--topbar {
            padding-bottom: var(--space-3);
            margin-bottom: var(--space-3);
            border-bottom: 1px solid var(--color-line);
        }
    }

    .c-sidenav__item {
        margin: 0;
    }

    /* Top-level group (parent with children, e.g. Admin sub-sections) */
    .c-sidenav__group {
        margin-top: var(--space-5);
    }

    .c-sidenav__group:first-child {
        margin-top: 0;
    }

    .c-sidenav__group-heading {
        font-family: var(--font-display);
        font-size: var(--fs-caption);
        font-weight: 500;
        letter-spacing: 0.12em;
        text-transform: uppercase;
        color: var(--color-ink-mute);
        margin: 0 0 var(--space-2);
        padding: 0 var(--space-3);
    }

    .c-sidenav__separator {
        display: block;
        height: 1px;
        margin: var(--space-3) var(--space-3);
        background: var(--color-line);
        border: 0;
    }

    /* Titled separator → flat-list section heading. Renders via
       AddSeparator("Documents") when the builder passes a label along
       with the separator. Same visual treatment as the nested
       .c-sidenav__group-heading so readers see a consistent section-break
       aesthetic whether a group is flat-with-heading or nested-with-children. */
    .c-sidenav__heading {
        display: block;
        list-style: none;
        margin: var(--space-5) 0 var(--space-2);
        padding: 0 var(--space-3);
        font-family: var(--font-display);
        font-size: var(--fs-caption);
        font-weight: 500;
        letter-spacing: 0.12em;
        text-transform: uppercase;
        color: var(--color-ink-mute);
    }

    /* The first item in the list shouldn't have the section-heading
       top margin that would push everything down. */
    .c-sidenav__list > .c-sidenav__heading:first-child {
        margin-top: 0;
    }


    /* ─── 5. Nav links ────────────────────────────────────────────── */

    /* Links are a flex row so an optional leading icon slot sits in a
       fixed-width column and labels align vertically whether or not an
       individual item has an icon. */
    .c-sidenav__link {
        display: flex;
        align-items: center;
        gap: var(--space-3);
        padding: var(--space-2) var(--space-3);
        font-size: var(--fs-ui);
        line-height: 1.4;
        color: var(--color-ink);
        text-decoration: none;
        border-radius: var(--radius-md);
        transition: background var(--dur-fast) var(--ease),
                    color var(--dur-fast) var(--ease);
    }

    /* Fixed-width icon slot so labels align across items regardless of
       whether they have icons. Muted by default; brightens to the brand
       accent on hover/active alongside the link. */
    .c-sidenav__icon {
        flex: none;
        width: 1.25rem;
        text-align: center;
        font-size: var(--fs-ui);
        color: var(--color-ink-mute);
        transition: color var(--dur-fast) var(--ease);
    }

    .c-sidenav__link:hover .c-sidenav__icon,
    .c-sidenav__link:focus-visible .c-sidenav__icon,
    .c-sidenav__link--active .c-sidenav__icon {
        color: var(--color-accent);
    }

    .c-sidenav__label {
        flex: 1 1 auto;
        min-width: 0;
    }

    .c-sidenav__link:hover,
    .c-sidenav__link:focus-visible {
        background: color-mix(in srgb, var(--color-ink) 6%, transparent);
        color: var(--color-ink);
        outline: none;
    }

    .c-sidenav__link:focus-visible {
        box-shadow: 0 0 0 2px color-mix(in srgb, var(--color-accent) 30%, transparent);
    }

    .c-sidenav__link--active {
        background: color-mix(in srgb, var(--color-accent) 10%, transparent);
        color: var(--color-accent-deep, var(--color-accent));
        font-weight: 500;
    }

    .c-sidenav__link--active:hover {
        background: color-mix(in srgb, var(--color-accent) 14%, transparent);
    }


    /* ─── 6. Hamburger toggle (mobile only) ───────────────────────── */

    /* Mobile-only affordance in the topbar. On desktop the sidenav is
       collapsed via the chevron pair at the top of the sidenav itself
       (.c-sidenav__collapse / .c-sidenav__expand). Hamburger is
       hidden above 900px. */
    .c-sidenav-toggle {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        width: 2.5rem;
        height: 2.5rem;
        padding: 0;
        background: transparent;
        border: 1px solid transparent;
        border-radius: var(--radius-md);
        color: var(--color-ink);
        cursor: pointer;
        transition: background var(--dur-fast) var(--ease),
                    border-color var(--dur-fast) var(--ease);
    }

    @media (min-width: 900px) {
        .c-sidenav-toggle { display: none; }
    }

    .c-sidenav-toggle:hover,
    .c-sidenav-toggle:focus-visible {
        background: color-mix(in srgb, var(--color-ink) 6%, transparent);
        border-color: var(--color-line);
        outline: none;
    }

    .c-sidenav-toggle:focus-visible {
        box-shadow: 0 0 0 2px color-mix(in srgb, var(--color-accent) 30%, transparent);
    }

    /* No-nav pages: hide the topbar hamburger too — without a sidenav
       there's nothing to open. Uses :has() to detect the empty sidenav
       anywhere in the document tree. */
    body:has(.c-sidenav[data-empty="true"]) .c-sidenav-toggle {
        display: none;
    }

    /* Three-bar icon as pure CSS on a single span */
    .c-sidenav-toggle__icon {
        position: relative;
        display: block;
        width: 1.125rem;
        height: 2px;
        background: currentColor;
        border-radius: 1px;
    }

    .c-sidenav-toggle__icon::before,
    .c-sidenav-toggle__icon::after {
        content: "";
        position: absolute;
        left: 0;
        width: 100%;
        height: 2px;
        background: currentColor;
        border-radius: 1px;
    }

    .c-sidenav-toggle__icon::before {
        top: -0.375rem;
    }

    .c-sidenav-toggle__icon::after {
        top: 0.375rem;
    }


    /* ─── 6b. Mobile drawer close button (X) ──────────────────────── */

    /* Visible affordance to close the mobile drawer alongside
       scrim-click and Escape. Lives inside .c-sidenav__chevrons and
       shares that row with the desktop-only chevrons — CSS shows one
       at a time based on viewport. Carries data-sidenav-toggle so the
       existing app-sidenav.js handler closes the drawer on click. */
    .c-sidenav__close {
        display: none;
        align-items: center;
        justify-content: center;
        width: 2.25rem;
        height: 2.25rem;
        padding: 0;
        background: transparent;
        border: 1px solid transparent;
        border-radius: var(--radius-md);
        color: var(--color-ink);
        cursor: pointer;
        font-family: var(--font-display);
        font-size: 1.5rem;
        line-height: 1;
        transition: background var(--dur-fast) var(--ease),
                    border-color var(--dur-fast) var(--ease);
    }

    .c-sidenav__close:hover,
    .c-sidenav__close:focus-visible {
        background: color-mix(in srgb, var(--color-ink) 6%, transparent);
        border-color: var(--color-line);
        outline: none;
    }

    .c-sidenav__close:focus-visible {
        box-shadow: 0 0 0 2px color-mix(in srgb, var(--color-accent) 30%, transparent);
    }

    @media (max-width: 899px) {
        .c-sidenav__close {
            display: inline-flex;
        }
    }


    /* ─── 7. Desktop collapse/expand chevrons ─────────────────────── */

    /* Azure-Portal-pattern chevron pair at the top of the sidenav.
       Both chevrons render as the first row inside the sidenav (see
       AppSidenavTagHelper). On desktop, exactly one is visible based
       on state — they swap in place at the top-right of the rail.
         .c-sidenav__collapse (« ) — visible when open; collapses.
         .c-sidenav__expand   (» ) — visible when closed; expands.
       Both carry data-sidenav-toggle so the existing app-sidenav.js
       handler flips state for free. On mobile both are hidden —
       the topbar hamburger + drawer pattern takes over. */

    .c-sidenav__chevrons {
        display: flex;
        justify-content: flex-end;
        align-items: center;
        margin-bottom: var(--space-2);
    }

    /* When the rail is collapsed, the single visible expand chevron
       centers inside the narrow column rather than hugging the edge. */
    [data-sidenav="closed"] .c-sidenav__chevrons {
        justify-content: center;
    }

    .c-sidenav__collapse,
    .c-sidenav__expand {
        display: none;
        align-items: center;
        justify-content: center;
        width: 1.5rem;
        height: 1.5rem;
        padding: 0;
        background: transparent;
        border: 1px solid transparent;
        border-radius: var(--radius-sm, 4px);
        color: var(--color-ink-mute);
        cursor: pointer;
        font-family: var(--font-display);
        font-size: 1rem;
        line-height: 1;
        transition: background var(--dur-fast) var(--ease),
                    border-color var(--dur-fast) var(--ease),
                    color var(--dur-fast) var(--ease);
    }

    .c-sidenav__collapse:hover,
    .c-sidenav__collapse:focus-visible,
    .c-sidenav__expand:hover,
    .c-sidenav__expand:focus-visible {
        background: color-mix(in srgb, var(--color-ink) 6%, transparent);
        border-color: var(--color-line);
        color: var(--color-ink);
        outline: none;
    }

    .c-sidenav__collapse:focus-visible,
    .c-sidenav__expand:focus-visible {
        box-shadow: 0 0 0 2px color-mix(in srgb, var(--color-accent) 30%, transparent);
    }

    /* Desktop visibility — exactly one chevron shows at a time based on
       [data-sidenav] state. On mobile both stay display: none (handled
       by the base rule above) so only the topbar hamburger is shown. */
    @media (min-width: 900px) {
        .c-sidenav__collapse { display: inline-flex; }
        [data-sidenav="closed"] .c-sidenav__collapse { display: none; }
        [data-sidenav="closed"] .c-sidenav__expand { display: inline-flex; }

        /* Collapsed rail: chevron fills the 1.5rem column edge-to-edge
           (no border-radius chrome), and there's nothing following in
           the flow so the row carries no bottom margin. */
        [data-sidenav="closed"] .c-sidenav__expand {
            border-radius: 0;
        }

        [data-sidenav="closed"] .c-sidenav__chevrons {
            margin-bottom: 0;
        }

        /* Hide nav list on desktop when collapsed; rail shows only the
           expand chevron. On mobile this doesn't apply — the drawer
           shows the full list when open. */
        [data-sidenav="closed"] .c-sidenav__list {
            display: none;
        }
    }


    /* ─── 8. Toolbar container ────────────────────────────────────── */

    /* Horizontal row container used by the <app-toolbar-container>
       tag helper. Flex-wrap so toolbars with many children fold
       gracefully on narrower viewports. */
    .c-toolbar-container {
        box-sizing: border-box;
        display: flex;
        flex-direction: row;
        flex-wrap: wrap;
        align-items: flex-start;
        justify-content: flex-start;
        width: 100%;
    }


    /* ─── 9. User account dropdown ──────────────────────────────────
       Lightweight replacement for the old Syncfusion context-menu.
       Rendered by the UserContextMenu view component; anchored to the
       .c-topbar__user wrapper (position: relative) so no positioning
       math is needed. Toggled by a tiny inline script in the view —
       click-outside and Escape close. */

    .c-user-menu {
        position: absolute;
        top: calc(100% + var(--space-2));
        right: 0;
        min-width: 12rem;
        margin: 0;
        padding: var(--space-2);
        list-style: none;
        background: var(--color-surface);
        color: var(--color-ink);
        border: 1px solid var(--color-line);
        border-radius: var(--radius-md);
        box-shadow: 0 12px 28px -12px rgb(0 0 0 / .18);
        /* Above the sticky topbar's z-index (50) so the dropdown
           doesn't get clipped or covered. */
        z-index: 55;
    }

    /* [hidden] is global in the reset; this keeps the dropdown invisible
       until the trigger's click handler flips menu.hidden. */
    .c-user-menu[hidden] {
        display: none;
    }

    .c-user-menu__header {
        padding: var(--space-2) var(--space-3);
        display: flex;
        flex-direction: column;
        gap: 2px;
    }

    .c-user-menu__greeting {
        font-size: var(--fs-caption);
        letter-spacing: 0.06em;
        text-transform: uppercase;
        color: var(--color-ink-mute);
    }

    .c-user-menu__name {
        font-family: var(--font-display);
        font-size: var(--fs-ui);
        font-weight: 500;
        color: var(--color-ink);
    }

    .c-user-menu__separator {
        height: 1px;
        margin: var(--space-2) 0;
        background: var(--color-line);
    }

    .c-user-menu__link {
        display: block;
        padding: var(--space-2) var(--space-3);
        font-size: var(--fs-ui);
        color: var(--color-ink);
        text-decoration: none;
        border-radius: var(--radius-sm, 4px);
        transition: background var(--dur-fast) var(--ease);
        /* Never wrap menu items — the dropdown grows to fit its widest
           label. Positioned right:0 (see .c-user-menu) so growth
           expands leftward without pushing the rest of the topbar.
           The .c-user-menu min-width stays as a floor for menus with
           short labels. */
        white-space: nowrap;
    }

    .c-user-menu__link:hover,
    .c-user-menu__link:focus-visible {
        background: color-mix(in srgb, var(--color-ink) 6%, transparent);
        outline: none;
    }

    .c-user-menu__link:focus-visible {
        box-shadow: 0 0 0 2px color-mix(in srgb, var(--color-accent) 30%, transparent);
    }


    /* ─── 10. Page wrapper + title ────────────────────────────────── */

    /* Canonical content container emitted by the <app-page> tag
       helper. Constrains width, centers horizontally, fluid side
       padding that scales with viewport:
         phone  (≤767.98px) → 4px  (recovers screen real estate;
                                    a hairline of inset still keeps
                                    content visually distinct from
                                    the full-bleed topbar)
         tablet+            → 16px → 48px via clamp(min, 4vw, max)
       The title ships as an <h1 class="c-page__title"> — one h1 per
       page, outline-correct. Sized modestly at --fs-heading so
       functional pages don't shout; marketing pages style their own
       h1 via a different class (.c-hero__title) for display-scale. */

    .c-page {
        width: 100%;
        margin-inline: auto;
        padding-inline: clamp(var(--space-4), 4vw, var(--space-7));
    }

    @media (max-width: 767.98px) {
        .c-page {
            /* Tight 4px gutter on phones. Hairline inset rather than
               full-bleed so prose / form inputs / labels still get
               a visual frame, but every other pixel goes to content. */
            padding-inline: 0.25rem;
        }
    }

    .c-page__title {
        margin: 0 0 var(--space-5);
        font-family: var(--font-display);
        font-size: var(--fs-heading);
        font-weight: 500;
        line-height: 1.2;
        letter-spacing: -0.01em;
        color: var(--color-ink-h1);
    }

    /* Masthead row — used when the page title shares its row with
       chrome like a Print button. Flex with the title growing and
       the trailing control anchored to the right. */
    .c-page__masthead {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: var(--space-4);
        margin-bottom: var(--space-5);
    }

    .c-page__masthead .c-page__title {
        margin: 0;  /* masthead owns the bottom margin */
    }

    .c-page__print-button {
        display: inline-flex;
        align-items: center;
        gap: var(--space-2);
        padding: var(--space-2) var(--space-4);
        font: inherit;
        font-weight: 500;
        color: var(--color-ink);
        background: transparent;
        border: 1px solid var(--color-line);
        border-radius: var(--radius-md);
        cursor: pointer;
        transition: background var(--dur-fast) var(--ease),
                    border-color var(--dur-fast) var(--ease);
    }

    .c-page__print-button:hover,
    .c-page__print-button:focus-visible {
        background: color-mix(in srgb, var(--color-ink) 6%, transparent);
        border-color: var(--color-ink);
        outline: none;
    }

    .c-page__print-button:focus-visible {
        box-shadow: 0 0 0 2px color-mix(in srgb, var(--color-accent) 30%, transparent);
    }
}
