.shell {
    width: 100%;
    max-width: 1440px;
    margin-inline: auto;
    padding-inline: 40px;
}

.grid-law {
    display: grid;
    /* Largeurs partagées avec la bande de bas de page, qui doit dégager
       exactement la photo et refermer exactement la gouttière. */
    --photo-width: clamp(260px, 24vw, 380px);
    --row-gap: 28px;
    /* Pistes fluides : un plancher fixe sur la photo et sur le rail faisait
       déborder la grille entre 1080 et 1440 px, dès que le corps prenait sa
       largeur de contenu. Ici seul le corps encaisse le reste. */
    grid-template-columns: var(--photo-width) minmax(0, 1fr) minmax(220px, 320px);
    grid-template-areas: "photo head head" "photo body meta" "prefooter prefooter prefooter";
    /* Rangée du corps flexible : la photo couvre les deux premières rangées et
       la grille répartirait sa hauteur d'écran sur les deux, gonflant celle du
       titre — corps et rail décrochaient alors vers le bas. Une piste flexible
       absorbe seule ce surplus. */
    grid-template-rows: auto 1fr auto;
    /* Hauteur d'écran garantie : sans elle, `1fr` n'a pas d'espace libre défini
       à consommer, la rangée du corps ne s'agrandit pas et la photo — qui a une
       hauteur d'écran en dur — débordait sous la bande de bas de page puis sous
       le footer, en les recouvrant. */
    min-height: calc(100vh - var(--header-height, 76px));
    column-gap: 40px;
    row-gap: var(--row-gap);
    align-items: start;
}

.grid-law__photo {
    grid-area: photo;
    position: sticky;
    top: var(--header-height, 76px);
    align-self: start;
    height: calc(100vh - var(--header-height, 76px));
    /* Borne dure : la photo s'arrête au bas de sa zone, donc au filet de la
       bande. Elle ne peut plus déborder ni laisser de jour sous elle. */
    max-height: 100%;
    overflow: hidden;
    margin: 0;
}

.grid-law__photo figure {
    border: 0;
}

.grid-law__photo img {
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.grid-law__header {
    grid-area: head;
    padding: 40px 32px 28px 72px;
    border-bottom: 1px solid var(--border);
}

/* Le chapô porte déjà son espacement : le titre ne rajoute rien sous lui. */
.grid-law__header .section-title {
    margin-bottom: 0;
}

.grid-law__header :is(h1, .h1) {
    max-width: 900px;
}

.grid-law__header :is(p, .lead) {
    max-width: 560px;
}

.grid-law__content {
    grid-area: body;
    min-width: 0;
    padding-bottom: 3rem;
}

.grid-law__content > :first-child {
    margin-top: 0;
}

.grid-law__meta {
    grid-area: meta;
    min-width: 0;
    padding-right: 32px;
    padding-bottom: 3rem;
}

/* La bande de bas de page traverse les trois colonnes : ses aplats vont d'un
   bord à l'autre, sans liseré blanc sur les côtés. La photo collante, elle,
   se peint par-dessus son bord gauche — c'est aux contenus de la bande de
   dégager la largeur de la photo, pas aux blocs de se chevaucher. */
.grid-law__prefooter {
    grid-area: prefooter;
    min-width: 0;
    /* La bande colle au bas des rangées de contenu : la gouttière laissait
       filtrer le fond de page entre le bas de la photo et le filet noir. */
    margin-top: calc(var(--row-gap) * -1);
}

/* Sélecteurs de classe explicites : `> *` perdrait contre `.newsletter`, dont
   la feuille est chargée après celle-ci. */
.grid-law__prefooter > .economic-model,
.grid-law__prefooter > .newsletter {
    padding-left: calc(var(--photo-width) + 40px);
    padding-right: clamp(40px, 8vw, 160px);
}

.grid-law__content :is(p, .text) {
    max-width: 720px;
}

.grid-law--no-photo, .grid-law--no-meta {
    grid-template-areas: none;
}

.grid-law--no-photo > *, .grid-law--no-meta > * {
    grid-area: auto;
}

.grid-law--no-photo {
    grid-template-columns: minmax(0, 880px) 280px;
    justify-content: center;
}

.grid-law--no-meta {
    grid-template-columns: 320px minmax(0, 880px);
    justify-content: center;
}

.grid-law--no-photo .grid-law__meta {
    padding-right: 0;
}

.section {
    --section-top: 64px;
    padding-block: var(--section-top) 0;
}

.card-grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: clamp(16px, 2vw, 24px);
}

@media (max-width: 1079px) {
    .grid-law {
        grid-template-columns: minmax(0, 1fr) 240px;
        grid-template-areas: "photo photo" "head head" "body meta" "prefooter prefooter";
        grid-template-rows: auto auto 1fr auto;
        column-gap: 24px;
        padding-inline: 24px;
    }
    /* The rail turns into a scrolling 16:9 banner: sticky belonged to the rail, not the image. */
    .grid-law__photo {
        position: relative;
        top: auto;
        height: auto;
        max-height: none;
        aspect-ratio: 16 / 9;
        margin-inline: -24px;
    }
    /* The portrait photo's face sits in its upper third: a centered 16:9 crop cuts it off. */
    .asso-layout__image {
        object-position: center 20%;
    }
    .grid-law__meta {
        padding-right: 0;
    }
    /* La grille prend une gouttière à ce palier ; la bande de bas de page la
       ressort pour rester bord à bord. La photo est en bandeau : plus rien à
       dégager à gauche. */
    .grid-law__prefooter {
        margin-inline: -24px;
    }
    .grid-law__prefooter > .economic-model {
        padding-left: 0;
        padding-right: 0;
    }
    .grid-law__prefooter > .newsletter {
        padding-left: 24px;
        padding-right: 24px;
    }
    .grid-law--no-photo, .grid-law--no-meta {
        padding-inline: 0;
        grid-template-areas: none;
    }
    .grid-law--no-photo {
        grid-template-columns: minmax(0, 1fr) 280px;
    }
    .grid-law--no-meta {
        grid-template-columns: minmax(0, 1fr);
    }
    .card-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

@media (max-width: 767px) {
    .shell {
        padding-inline: 20px;
    }
    .grid-law {
        --row-gap: 20px;
        grid-template-columns: minmax(0, 1fr);
        grid-template-areas: "photo" "head" "body" "meta" "prefooter";
        gap: 20px;
        padding-inline: 20px;
    }
    .grid-law__photo,
    .grid-law__prefooter {
        margin-inline: -20px;
    }
    .grid-law__prefooter > .newsletter {
        padding-left: 20px;
        padding-right: 20px;
    }
    /* Listings dont le rail (tags, compteur, total) sert à naviguer : il remonte
       au-dessus du contenu (DS CS 8, M3 et M5). */
    .grid-law--meta-first {
        grid-template-areas: "photo" "head" "meta" "body" "prefooter";
    }
    /* Empilé, le rail suit le contenu : la respiration avant la bande de bas de
       page revient au dernier bloc, pas aux deux. */
    .grid-law__content {
        padding-bottom: 0;
    }
    .grid-law--meta-first .grid-law__content,
    .grid-law--no-meta .grid-law__content {
        padding-bottom: 3rem;
    }
    .grid-law__header {
        padding: 24px 0;
    }
    .grid-law--no-photo, .grid-law--no-meta {
        grid-template-columns: minmax(0, 1fr);
    }
    .card-grid {
        grid-template-columns: minmax(0, 1fr);
    }
    .section {
        --section-top: 40px;
    }
}
