/* ========================================== PAGE PROJET (case-page) ==========================================
   Gabarit d'etude de cas aligne sur la page About : meme en-tete, meme
   pied de page, meme colonne de lecture (colonne 2 d'une grille de 3), memes
   titres de section "mot.mot", memes listes a filet. Les visuels, eux,
   prennent toute la largeur.

   Pas de GSAP ni de ScrollSmoother : le document defile nativement, le header
   et le footer sont fixes, et le contenu se dissout sous eux grace au meme
   fondu de bord que la page About. */

/* Pas d'overscroll-behavior: none ici : le rebond elastique en haut et en bas
   de page reste, comme sur About. Header, footer et fondus sont fixes, ils ne
   suivent pas le rebond. */
body.case-page {
    overflow: visible;
}

.case-page .main-card {
    display: block;
    width: 100%;
    height: auto;
    min-height: 100vh;
    padding: 0;
}

/* ---------- Header / footer fixes ---------- */

.case-page .content-top-section {
    position: fixed;
    top: var(--space-32);
    left: var(--space-32);
    right: var(--space-32);
    z-index: 50;
}

.case-page .footer-group {
    position: fixed;
    bottom: var(--space-32);
    left: var(--space-32);
    right: var(--space-32);
    z-index: 50;
}

/* Le menu s'ouvre par-dessus l'ecran, pas au milieu d'une page de 5000px. */
.case-page .menu-overlay {
    position: fixed;
    inset: 0;
    z-index: 45;
}

/* ---------- Grille ---------- */

.case {
    --case-gap: var(--space-32);
    --case-pad-top: 224px;
    position: relative;
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    column-gap: var(--case-gap);
    padding: var(--case-pad-top) var(--space-32) 192px;
    color: var(--neutral-dark);
    transition: color 0.8s ease;
}

.case-text {
    grid-column: 2;
    display: flex;
    flex-direction: column;
    gap: var(--space-16);
    padding: 96px 0;
    min-width: 0;
}

.case-intro {
    padding-top: 0;
    /* Le 1er visuel remonte pour depasser en bas d'ecran : on voit qu'il y a
       une suite sous la fiche projet. */
    padding-bottom: 72px;
}

.case-media,
.case-pair {
    grid-column: 1 / -1;
}

/* ---------- Typo (reprend la page About) ---------- */

.case-page .section-title {
    font-family: 'Neue Haas Grotesk Display Pro', sans-serif;
    font-size: 20px;
    font-weight: 600;
    line-height: normal;
    letter-spacing: 0;
    margin: 0;
}

.case-head {
    display: flex;
    flex-direction: column;
    gap: var(--space-8);
}

.case-head .subtitle {
    margin: 0;
    font-weight: 300;
    line-height: 1.3;
}

/* Retour (maquette 2341:5385) : 16px au-dessus du titre. */
.case-actions {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: var(--space-16);
}

/* Retour : la fleche de la page "en cours" (.wip-return-* dans project.css),
   en taille reduite pour ne pas voler la vedette au projet. Masque teinte en
   currentColor pour suivre le theme. */
.case-return-link {
    display: block;
    color: var(--neutral-dark);
    transition: color 0.8s ease;
}

/* Au survol, seule la fleche glisse : le lien (la zone cliquable) reste en
   place, sinon il s'echappe de sous le curseur et le survol clignote. */
.case-return-arrow {
    display: block;
    height: 30px;
    aspect-ratio: 83 / 71;
    background-color: currentColor;
    -webkit-mask: url("fichiers/arrow-left.svg") center / contain no-repeat;
    mask: url("fichiers/arrow-left.svg") center / contain no-repeat;
    transform: scaleX(-1);
    transition: transform 0.2s ease;
}

@media (hover: hover) {
    .case-return-link:hover .case-return-arrow {
        transform: translateX(-4px) scaleX(-1);
    }
}

.case-lead,
.case-body {
    margin: 0;
    font-family: 'DM Mono', monospace;
    font-size: 16px;
    line-height: 1.3;
    text-align: justify;
}

.case-body {
    font-size: 14px;
    line-height: 1.4;
}

.case-tags {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-8);
}

.case-tag {
    display: flex;
    align-items: center;
    height: 22px;
    padding: 4px 12px;
    border-radius: 999px;
    background: var(--neutral-dark-01);
    font-family: 'DM Mono', monospace;
    font-size: 12px;
    font-weight: 500;
    line-height: 14px;
    white-space: nowrap;
    transition: background-color 0.8s ease;
}

/* Lien vers le prototype : meme grammaire que la liste "et.ensuite" (titre,
   sous-titre entre parentheses, fleche au survol), sous un filet qui le
   separe de la fiche projet. */
.case-intro .case-proto {
    margin: var(--space-16) 0 0;
    border-top: 1px solid var(--neutral-dark-01);
    transition: border-color 0.8s ease;
}

/* Sur mobile sans URL dediee, script-core.js desactive le lien. */
.case-proto .is-disabled {
    opacity: 0.55;
    pointer-events: none;
}

/* ---------- Listes a filet (grammaire des listes About) ---------- */

.case-list {
    list-style: none;
    margin: var(--space-16) 0 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: var(--space-8);
}

.case-entry {
    display: flex;
    align-items: flex-end;
    gap: var(--space-8);
    color: inherit;
    text-decoration: none;
    transition: opacity 0.2s ease, transform 0.2s ease;
}

.case-entry-num,
.case-entry-meta {
    font-family: 'DM Mono', monospace;
    font-size: 14px;
    line-height: 1.2;
    opacity: 0.5;
    transition: opacity 0.2s ease;
}

.case-entry-num {
    flex: none;
    width: 24px;
}

.case-entry-title {
    flex: none;
    font-family: 'Neue Haas Grotesk Display Pro', sans-serif;
    font-size: 14px;
    font-weight: 500;
    line-height: normal;
    text-transform: uppercase;
    white-space: nowrap;
}

.case-entry-leader {
    flex: 1 1 0;
    min-width: 16px;
    margin-bottom: 3px;
    border-bottom: 1px solid currentColor;
    opacity: 0.1;
    transition: opacity 0.2s ease;
}

.case-entry-meta {
    min-width: 0;
    text-align: right;
}

/* Survol reserve aux entrees cliquables : les listes d'information (infos
   projet, etapes du parcours) restent statiques. */
@media (hover: hover) {
    a.case-entry:hover {
        transform: translateX(4px);
    }

    a.case-entry:hover .case-entry-num,
    a.case-entry:hover .case-entry-meta,
    a.case-entry:hover .case-entry-leader {
        opacity: 1;
    }

    .case-list:hover li:not(:hover) > a.case-entry {
        opacity: 0.5;
    }
}

/* Le lien "projet suivant" prend l'accent au survol : seul point rouge de la
   section, comme le curseur. */
.case-next .case-entry:hover .case-entry-meta {
    color: var(--primary);
}

/* "et.ensuite" en pleine page : la section occupe tout l'ecran et son contenu
   est centre verticalement, comme la liste de la page Projets. La marge
   negative annule le padding bas de l'article pour qu'en fin de page la
   section corresponde exactement au viewport. */
.case-next--full {
    min-height: 100vh;
    min-height: 100svh;
    justify-content: center;
    padding: 0;
    margin-bottom: -192px;
}

/* ---------- Visuels ---------- */

/* Cadre de la maquette : carte a bord fin et ombre portee, 4px de marge
   autour du visuel, lui-meme arrondi a 8px avec un liseré d'ombre. La
   lightbox reprend le meme cadre. */
.case-media,
.case-lightbox-frame {
    margin: 0;
    padding: 4px;
    overflow: hidden;
    border: 1px solid var(--neutral-dark-01);
    border-radius: 12px;
    background: var(--bg-card);
    box-shadow: 0 7px 11px -2px rgba(0, 0, 0, 0.06);
    transition: background-color 0.8s ease, border-color 0.8s ease;
}

/* Images directes du cadre seulement : une maquette codee (.case-mock) a
   ses propres images, dimensionnees par son CSS. */
.case-media > img,
.case-video,
.case-lightbox-img {
    display: block;
    width: 100%;
    height: auto;
    border-radius: 8px;
    box-shadow:
        0 0 0 1px rgba(0, 0, 0, 0.06),
        0 1px 2px -1px rgba(0, 0, 0, 0.06),
        0 2px 4px 0 rgba(0, 0, 0, 0.04);
}

.case-media > img {
    cursor: zoom-in;
}

/* Bouton son pose sur la video, en bas a droite (la place attendue : le
   centre est celui de lecture/pause). Pastille sombre et floutee, lisible sur
   n'importe quelle image : haut-parleur barre + « Activer le son » tant que
   la video est muette, puis l'icone seule une fois le son mis. Meme effet
   d'aimant que le burger (script-core.js, .is-magnetic). */
.case-media--hero {
    position: relative;
}

.case-video-sound {
    position: absolute;
    right: 24px;
    bottom: 24px;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    height: 36px;
    padding: 0 10px;
    border: 0;
    border-radius: 18px;
    background: rgba(0, 0, 0, 0.45);
    -webkit-backdrop-filter: blur(12px);
    backdrop-filter: blur(12px);
    color: #fff;
    font-family: 'DM Mono', monospace;
    font-size: 12px;
    line-height: 1;
    letter-spacing: 0.02em;
    text-transform: uppercase;
    white-space: nowrap;
    transition: background-color 0.3s cubic-bezier(0.4, 0, 0.2, 1),
        padding 0.4s cubic-bezier(0.4, 0, 0.2, 1), gap 0.4s cubic-bezier(0.4, 0, 0.2, 1);
}

/* Zone de clic un peu plus large que la pastille. */
.case-video-sound::before {
    content: '';
    position: absolute;
    inset: -8px;
}

.case-video-sound:hover,
.case-video-sound:focus-visible {
    background: rgba(0, 0, 0, 0.65);
}

.case-video-sound svg {
    display: block;
    flex: none;
    width: 16px;
    height: 16px;
}

/* Le libelle se replie quand le son est actif : reste une pastille ronde. */
.case-video-sound-label {
    display: block;
    max-width: 10em;
    overflow: hidden;
    transition: max-width 0.4s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.25s ease;
}

.case-video-sound[aria-pressed="true"] {
    gap: 0;
    padding: 0 10px;
}

.case-video-sound[aria-pressed="true"] .case-video-sound-label {
    max-width: 0;
    opacity: 0;
}

.case-video-sound .icon-sound-on,
.case-video-sound[aria-pressed="true"] .icon-sound-off {
    display: none;
}

.case-video-sound[aria-pressed="true"] .icon-sound-on {
    display: block;
}

@media (max-width: 900px) {
    .case-video-sound {
        right: 16px;
        bottom: 16px;
    }
}

/* Le ratio porte sur la video, pas sur le cadre qui ajoute sa marge. */
.case-media--hero .case-video {
    aspect-ratio: 16 / 9;
    object-fit: cover;
}

/* Carre + 16/9 cote a cote, calques sur les 3 colonnes de l'article : le carre
   prend la colonne 1, le 16/9 les colonnes 2-3, qui demarre ainsi a l'aplomb
   du texte au-dessus. Le carre deborde dans la gouttiere de la grille pour
   ne laisser que 16px entre les deux. */
.case-pair {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    column-gap: var(--case-gap);
}

/* Les ratios ne collent plus exactement aux colonnes : on etire les deux
   cadres a la meme hauteur et le visuel couvre (le carre est un peu rogne
   sur les cotes). */
.case-pair {
    align-items: stretch;
}

.case-pair > .case-media {
    grid-column: auto;
    display: flex;
}

.case-pair > .case-media:first-child {
    margin-right: calc(var(--space-16) - var(--case-gap));
}

.case-pair > .case-media:last-child {
    grid-column: 2 / -1;
}

/* Variante a deux visuels de meme format (16/9 + 16/9) : deux colonnes
   egales, sans recadrage. Sur mobile, la regle commune les empile. */
.case-pair--even {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    column-gap: var(--space-16);
}

.case-pair--even > .case-media:first-child {
    margin-right: 0;
}

.case-pair--even > .case-media:last-child {
    grid-column: auto;
}

.case-pair > .case-media > img,
.case-pair > .case-media .case-video {
    height: 100%;
    object-fit: cover;
}

.case > .case-media + .case-media,
.case > .case-pair + .case-media,
.case > .case-media + .case-pair {
    margin-top: var(--space-32);
}

/* ---------- Apparition au defilement ----------
   Seulement si le JS tourne (classe posee dans le <head>) et si le visiteur
   accepte le mouvement. */
@media (prefers-reduced-motion: no-preference) {
    .case-js .case-reveal {
        opacity: 0;
        transform: translateY(24px);
        /* Les couleurs sont repetees ici : sans elles, cette transition
           remplacait celle du cadre (.case-media) et son fond basculait d'un
           coup au changement de theme, pendant que la page fondait. */
        transition:
            opacity 0.8s cubic-bezier(0.22, 1, 0.36, 1),
            transform 0.8s cubic-bezier(0.22, 1, 0.36, 1),
            background-color 0.8s ease,
            border-color 0.8s ease;
    }

    .case-js .case-reveal.is-in {
        opacity: 1;
        transform: none;
    }
}

/* ---------- Lightbox ----------
   Pas de <dialog> : showModal() le place dans la "top layer", au-dessus de tout
   z-index, curseur personnalise compris. Ici c'est une couche fixe glissee
   sous le header et le footer (z-index 50) : le curseur reste visible et le
   burger, passe en croix, sert a fermer. L'image grandit depuis sa place dans
   la page (animation FLIP dans script-case.js). */

.case-lightbox {
    position: fixed;
    inset: 0;
    z-index: 46;
    display: flex;
    align-items: center;
    justify-content: center;
    /* Meme marge de 32px que le reste de l'ecran. Le titre et le footer
       s'effacent le temps de la lightbox, seule la croix reste. */
    padding: var(--lightbox-pad);
    cursor: zoom-out;
    visibility: hidden;
    pointer-events: none;
}

.case-lightbox.is-open,
.case-lightbox.is-closing {
    visibility: visible;
}

.case-lightbox.is-open {
    pointer-events: auto;
}

.case-lightbox-backdrop {
    position: absolute;
    inset: 0;
    background: var(--bg-card);
    opacity: 0;
    transition: opacity 0.45s cubic-bezier(0.22, 1, 0.36, 1), background-color 0.8s ease;
}

.case-lightbox.is-open .case-lightbox-backdrop {
    opacity: 1;
}

.case-page .title-group,
.case-page .footer-group {
    transition: opacity 0.3s ease;
}

.case-page.lightbox-open .title-group,
.case-page.lightbox-open .footer-group {
    opacity: 0;
    pointer-events: none;
}

/* Le cadre (4px de marge + 1px de bord de chaque cote) est retire de la
   place disponible pour que l'ensemble tienne dans la marge d'ecran. */
.case-lightbox {
    --lightbox-pad: var(--space-32);
}

.case-lightbox-frame {
    position: relative;
    transform-origin: 0 0;
    will-change: transform;
}

.case-lightbox .case-lightbox-img {
    width: auto;
    max-width: calc(100vw - 2 * var(--lightbox-pad) - 10px);
    max-height: calc(100vh - 2 * var(--lightbox-pad) - 10px);
    max-height: calc(100dvh - 2 * var(--lightbox-pad) - 10px);
    object-fit: contain;
}

/* Pendant l'agrandissement, le visuel d'origine (cadre compris) s'efface :
   c'est lui qui semble quitter la page. */
.case-media.is-zoom-source {
    visibility: hidden;
}

/* Sur mobile le header defile avec la page : on le fixe le temps de la
   lightbox pour que la croix reste a portee. */
@media (max-width: 900px) {
    .case-lightbox {
        --lightbox-pad: var(--space-24);
    }

    .case-page.lightbox-open .content-top-section {
        position: fixed;
        top: var(--space-24);
    }
}

/* ---------- Fondu de bord ----------
   Meme principe que la page About (4 paliers de flou + voile), mais plus fin :
   - bande basse plus courte (le footer tient sur une ligne), la haute garde de
     quoi passer sous le titre ;
   - le voile suit une courbe ease-in-out au lieu d'un degrade lineaire : un
     degrade lineaire a un debut et une fin de rampe visibles (bandes de Mach),
     ce qui dessinait une ligne laiteuse au-dessus des images ;
   - plateau opaque reduit a ~10% : avant, 30% de la bande etait un aplat franc.
   --fade-scrim est la rampe, du plus opaque (bord d'ecran) au transparent. */

.case-page {
    --fade-h-top: 150px;
    --fade-h-bottom: 112px;
    --fade-scrim:
        #000 0%, #000 10%,
        rgba(0, 0, 0, 0.987) 17.3%, rgba(0, 0, 0, 0.951) 24%,
        rgba(0, 0, 0, 0.896) 30.3%, rgba(0, 0, 0, 0.825) 36.1%,
        rgba(0, 0, 0, 0.741) 41.8%, rgba(0, 0, 0, 0.648) 47.1%,
        rgba(0, 0, 0, 0.55) 52.4%, rgba(0, 0, 0, 0.45) 57.6%,
        rgba(0, 0, 0, 0.352) 62.9%, rgba(0, 0, 0, 0.259) 68.2%,
        rgba(0, 0, 0, 0.175) 73.9%, rgba(0, 0, 0, 0.104) 79.8%,
        rgba(0, 0, 0, 0.049) 86.1%, rgba(0, 0, 0, 0.013) 92.7%,
        transparent 100%;
}

.case-page .edge-fade {
    position: fixed;
    left: 0;
    right: 0;
    z-index: 40;
    pointer-events: none;
}

.case-page .edge-fade-top { top: 0; height: var(--fade-h-top); }
.case-page .edge-fade-bottom { bottom: 0; height: var(--fade-h-bottom); }

.case-page .edge-fade-layer {
    position: absolute;
    left: 0;
    right: 0;
    display: block;
}

/* Chaque palier double le flou et se termine par un fondu doux (masque sur
   ~30% de sa hauteur) pour qu'on ne voie jamais ou l'un relaie l'autre. */
.case-page .edge-fade-1 { -webkit-backdrop-filter: blur(1px); backdrop-filter: blur(1px); }
.case-page .edge-fade-2 { -webkit-backdrop-filter: blur(2px); backdrop-filter: blur(2px); }
.case-page .edge-fade-3 { -webkit-backdrop-filter: blur(4px); backdrop-filter: blur(4px); }
.case-page .edge-fade-4 { -webkit-backdrop-filter: blur(8px); backdrop-filter: blur(8px); }

.case-page .edge-fade-tint {
    top: 0;
    bottom: 0;
    background-color: var(--bg-card);
    transition: background-color 0.8s ease;
}

.case-page .edge-fade-top .edge-fade-1 { top: 0; bottom: 0; -webkit-mask-image: linear-gradient(#000 65%, transparent 100%); mask-image: linear-gradient(#000 65%, transparent 100%); }
.case-page .edge-fade-top .edge-fade-2 { top: 0; bottom: 25%; -webkit-mask-image: linear-gradient(#000 50%, transparent 100%); mask-image: linear-gradient(#000 50%, transparent 100%); }
.case-page .edge-fade-top .edge-fade-3 { top: 0; bottom: 50%; -webkit-mask-image: linear-gradient(#000 35%, transparent 100%); mask-image: linear-gradient(#000 35%, transparent 100%); }
.case-page .edge-fade-top .edge-fade-4 { top: 0; bottom: 75%; -webkit-mask-image: linear-gradient(#000 20%, transparent 100%); mask-image: linear-gradient(#000 20%, transparent 100%); }
.case-page .edge-fade-top .edge-fade-tint { -webkit-mask-image: linear-gradient(to bottom, var(--fade-scrim)); mask-image: linear-gradient(to bottom, var(--fade-scrim)); }

.case-page .edge-fade-bottom .edge-fade-1 { top: 0; bottom: 0; -webkit-mask-image: linear-gradient(to top, #000 65%, transparent 100%); mask-image: linear-gradient(to top, #000 65%, transparent 100%); }
.case-page .edge-fade-bottom .edge-fade-2 { top: 25%; bottom: 0; -webkit-mask-image: linear-gradient(to top, #000 50%, transparent 100%); mask-image: linear-gradient(to top, #000 50%, transparent 100%); }
.case-page .edge-fade-bottom .edge-fade-3 { top: 50%; bottom: 0; -webkit-mask-image: linear-gradient(to top, #000 35%, transparent 100%); mask-image: linear-gradient(to top, #000 35%, transparent 100%); }
.case-page .edge-fade-bottom .edge-fade-4 { top: 75%; bottom: 0; -webkit-mask-image: linear-gradient(to top, #000 20%, transparent 100%); mask-image: linear-gradient(to top, #000 20%, transparent 100%); }
.case-page .edge-fade-bottom .edge-fade-tint { -webkit-mask-image: linear-gradient(to top, var(--fade-scrim)); mask-image: linear-gradient(to top, var(--fade-scrim)); }

/* ---------- Tablette ---------- */

@media (max-width: 1250px) {
    .case {
        --case-gap: var(--space-24);
    }

    /* La colonne du milieu devient trop etroite : le texte prend 2 colonnes. */
    .case-text {
        grid-column: 1 / span 2;
    }
}

/* ---------- Mobile (<= 900px) ----------
   Colonne unique, gouttieres de 24px comme le reste du site. */
@media (max-width: 900px) {
    /* Sur petit ecran le header est trop haut pour la bande de fondu : il
       defile avec la page, comme sur About mobile. */
    .case-page .content-top-section {
        position: absolute;
        top: var(--space-24);
        left: var(--space-24);
        right: var(--space-24);
    }

    .case-page .title-group .site-title {
        font-size: clamp(40px, 6.2vmin, 56px);
        letter-spacing: -0.012em;
    }

    /* Le footer quitte l'ecran : en bas de page, dans le flux. */
    .case-page .footer-group {
        position: static;
        padding: 0 var(--space-24) var(--space-24);
    }

    .case-page .edge-fade {
        display: none;
    }

    .case {
        display: flex;
        flex-direction: column;
        padding: 176px var(--space-24) 96px;
    }

    .case-text {
        padding: 64px 0;
    }

    .case-intro {
        padding-top: 0;
        padding-bottom: 52px;
    }

    .case-next--full {
        padding: 0;
        margin-bottom: -96px;
    }

    .case-pair {
        grid-template-columns: minmax(0, 1fr);
        gap: var(--space-16);
    }

    .case-pair > .case-media:first-child {
        margin-right: 0;
    }

    .case-pair > .case-media:last-child {
        grid-column: auto;
    }

    .case > .case-media + .case-media,
    .case > .case-pair + .case-media,
    .case > .case-media + .case-pair {
        margin-top: var(--space-16);
    }

    /* Sur petit ecran le libelle de droite passe sous l'intitule plutot que
       d'ecraser le filet. */
    .case-list--steps .case-entry {
        flex-wrap: wrap;
        row-gap: 2px;
    }

    .case-list--steps .case-entry-leader {
        display: none;
    }

    .case-list--steps .case-entry-meta {
        flex-basis: 100%;
        padding-left: 32px;
        text-align: left;
    }
}
