/*
 * Frame of a portal page: header, content column, footer.
 *
 * The header takes part in the flow and scrolls away with the page; only its compact variant is
 * `fixed`, and the slot it sits in keeps its room so the content needs no compensating padding.
 * See components/header.css for the two states and the `sticky-header` controller for the switch.
 */

.mo-website {
    background-color: var(--mo-surface-default);
}

/*
 * Width of the portal's single centred content column — a detail page's panel, and a
 * `.mo-page__body` (`pages/section.css`, the legal and search pages). Measured on "Laboratoire"
 * (4418:3830). Lives here, loaded on every page, rather than in `pages/detail.css`, which only the
 * detail templates link.
 */
:root {
    --mo-detail-column: 1112px;
}

/*
 * The flex column lives on a wrapper rather than on the body: the wrapper is also the scope of the
 * `drawer` controller, which needs the button in the header and the panel after the footer inside
 * one element.
 */
.mo-website__frame {
    display: flex;
    min-height: 100vh;
    flex-direction: column;
}

/*
 * Vertical rhythm of the page frame, measured on "Laboratoires" (4418:605) and "Boîte à outils"
 * (4418:1952), which agree everywhere they overlap:
 *
 *   haut de page → fil d'Ariane   40
 *   fil d'Ariane → contenu        24
 *   contenu → raccourcis          40
 *   raccourcis → pied de page     40
 *
 * The gap is the smaller of the two, and the shortcut row adds what it needs — writing it the other
 * way round would take a negative margin under the breadcrumb.
 */
.mo-website__main {
    display: flex;
    width: 100%;
    max-width: 1920px;
    flex: 1 0 auto;
    flex-direction: column;
    gap: var(--mo-spacing-sm);
    margin-inline: auto;
    padding-block: var(--mo-spacing-md);
    padding-inline: var(--mo-margin-body-lr);
}

.mo-website__main > .mo-shortcuts {
    margin-top: calc(var(--mo-spacing-md) - var(--mo-spacing-sm));
}

/*
 * On a detail page the breadcrumb joins the centred column instead of running to the page margin —
 * the maquette aligns it with the panel below it (4418:3831 and 4418:3968 both at x=404). `:has()`
 * keeps that here rather than making every detail template pass a modifier; where it is not
 * supported the breadcrumb stays full width, which is only the previous behaviour.
 */
.mo-website__main:has(.mo-detail) > .mo-breadcrumb {
    width: 100%;
    max-width: var(--mo-detail-column);
    margin-inline: auto;
}

/*
 * Section title of a page block: an icon and a heading, on one line.
 *
 * Measured on the home page panels (Figma "Frame 10", 4402:1333): a 28px icon, 8px of gap, and the
 * heading set in H3 semibold — not the H4 bold it carried, which read a step too small.
 */
.mo-section-title {
    display: flex;
    align-items: center;
    gap: var(--mo-spacing-xxs);
    margin: 0;
    color: var(--mo-text-default-dark);
    font-size: var(--mo-font-size-h3);
    font-weight: var(--mo-font-weight-h3);
    line-height: var(--mo-line-height-h3);
}

.mo-section-title__icon {
    width: var(--mo-scale-350);
    height: var(--mo-scale-350);
    flex: none;
    color: var(--mo-icon-action);
}

/*
 * The "Prochains événements" heading is the one section title whose icon carries the
 * "Icon/secondary" Figma variable instead of "Icon/action" (4402:1344 vs. 4402:1333 on the home
 * page) — the calendar icon is yellow where every other section title icon is pink.
 */
.mo-section-title__icon--secondary {
    color: var(--mo-icon-secondary);
}

/*
 * "Apparition au scroll du bas vers le haut", the annotation carried by the home page cards, the
 * shortcut row, and every block below a page's `<h1>` elsewhere in the portal.
 *
 * The hidden state is scoped to `[data-reveal-armed]`, an attribute the controller sets on itself
 * when it connects. A decoration must never be able to hide content: should the JavaScript fail to
 * load or throw, the attribute is absent and every block simply renders, unanimated. The controller
 * also reveals everything at once under reduced motion or without IntersectionObserver.
 *
 * The `transition` lives on `.is-revealed` alone, not on the hidden state: a block still has to
 * *reach* `translateY(sm)` the moment it gets armed, and that move must be instantaneous. Declaring
 * the transition on the hidden rule too would animate that first drop — invisibly for a block
 * discovered later by scroll, since it has long finished by the time it enters the viewport, but not
 * for a block already on screen at load, revealed a frame or two after being armed: it would start
 * climbing back up before ever reaching the bottom, out of a partial drop instead of the full one, so
 * the apparition read as shorter and hastier than the one played out on scroll.
 */
@media (prefers-reduced-motion: no-preference) {
    [data-reveal-armed] .mo-reveal {
        opacity: 0;
        transform: translateY(var(--mo-spacing-sm));
    }

    [data-reveal-armed] .mo-reveal.is-revealed {
        opacity: 1;
        transform: none;
        transition: opacity 400ms ease-out, transform 400ms ease-out;
    }
}
