/* =========================================================================
   STUDIO D&T Miniatures Painting · feuille de styles partagée par toutes les pages
   Typographie du site : Grenze Gotisch (titres, écho gothique du logo)
   + Spectral (texte). Chargées via Google Fonts dans le <head> de chaque page.
   Choix assumé : les polices du logo (Rotunda Veneta / Addington CF) restent
   propres au logo, qui est une image ; le site utilise ce duo libre, lisible
   et cohérent avec l'univers médiéval/fantasy.
   Thème piloté par [data-team="dragon"|"poulpe"] sur <html>.
   ========================================================================= */

@property --dim-dragon {
    syntax: '<number>';
    inherits: true;
    initial-value: 0
}

@property --dim-poulpe {
    syntax: '<number>';
    inherits: true;
    initial-value: 0
}

/* --- Tokens --------------------------------------------------------------- */
:root {
    --ink: #170c30;
    --near-black: #1d1d1b;
    --paper: #ffffff;
    --gold: #c9a23b;
    --dragon-1: #3ba3d4;
    --dragon-2: #623885;
    --dragon-3: #41346f;
    --poulpe-1: #fcea10;
    --poulpe-2: #d9435d;
    --poulpe-3: #e71d73;
    --font-display: 'Grenze Gotisch', 'Spectral', serif;
    --font-body: 'Spectral', Georgia, 'Times New Roman', serif;
    --header-h: 88px;
    --container: 1180px;
    --radius: 18px;
    --radius-lg: 28px;
    --ease: cubic-bezier(.22, .61, .36, 1);
}

:root[data-team="dragon"] {
    --primary: #623885;
    --primary-2: #41346f;
    --primary-deep: #2a1c4a;
    --accent: #3ba3d4;
    --primary-soft: #f3eef9;
    --on-primary: #fff;
    --footer-bg: #241740;
    --grad-primary: linear-gradient(135deg, #3ba3d4 0%, #623885 55%, #41346f 100%);
    /* dragon : bleu/violet proches en teinte → on compense avec un tint hero plus marqué */
    --hero-tint-1: 74%;
    --hero-tint-1-size: 66% 82%;
    --hero-tint-1-fade: 92%;
    --hero-tint-2: 62%;
    --hero-tint-2-size: 70% 90%;
    --hero-tint-2-fade: 90%;
    --hero-wash: 78%;
    --hero-disc-tint: 46%;
}

:root[data-team="poulpe"] {
    --primary: #e71d73;
    --primary-2: #d9435d;
    --primary-deep: #9c0f4d;
    --accent: #fcb40f;
    --primary-soft: #fdeef4;
    --on-primary: #fff;
    --footer-bg: #560c31;
    --grad-primary: linear-gradient(135deg, #fcea10 0%, #e71d73 55%, #d9435d 100%);
    /* poulpe : couleurs déjà contrastées → tint un peu plus léger que le dragon */
    --hero-tint-1: 64%;
    --hero-tint-1-size: 60% 76%;
    --hero-tint-1-fade: 86%;
    --hero-tint-2: 52%;
    --hero-tint-2-size: 64% 84%;
    --hero-tint-2-fade: 84%;
    --hero-wash: 70%;
    --hero-disc-tint: 36%;
}

* {
    box-sizing: border-box;
    margin: 0;
    padding: 0
}

html {
    scroll-behavior: smooth;
    /* les tiroirs (menu, filtres) glissent hors écran : on interdit tout
       débordement horizontal du document. clip (contrairement à hidden)
       ne crée pas de conteneur de scroll et préserve les position:sticky.
       overflow-y:auto est indispensable : sans lui, l'appariement CSS
       transforme le visible implicite de l'axe Y en clip et fige tout
       le scroll vertical de la page. */
    overflow-x: hidden;
    overflow-x: clip;
    overflow-y: auto
}

body {
    font-family: var(--font-body);
    color: var(--ink);
    background: var(--paper);
    line-height: 1.6;
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility
}

img {
    max-width: 100%;
    display: block
}

a {
    color: inherit;
    text-decoration: none
}

button {
    font-family: inherit;
    cursor: pointer;
    border: none;
    background: none
}

h1, h2, h3, h4 {
    font-family: var(--font-display);
    font-weight: 500;
    line-height: 1.05;
    letter-spacing: .5px
}

:focus-visible {
    outline: 3px solid var(--accent);
    outline-offset: 3px;
    border-radius: 6px
}

.sr-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    border: 0
}

/* =========================================================================
   1) ÉCRAN DE SÉLECTION "CHOISIS TON CAMP"
   ========================================================================= */
.selector {
    position: fixed;
    inset: 0;
    z-index: 1000;
    display: flex;
    overflow: hidden;
    background: var(--ink);
    --dim-dragon: 0;
    --dim-poulpe: 0
}

.selector[hidden] {
    display: none
}

.selector__head {
    position: absolute;
    top: clamp(18px, 4vh, 40px);
    left: 0;
    right: 0;
    z-index: 40;
    text-align: center;
    pointer-events: none;
    padding: 0 16px;
    animation: dropIn .9s var(--ease) both
}

.selector__kicker {
    font-family: var(--font-body);
    text-transform: uppercase;
    letter-spacing: .42em;
    font-size: clamp(.62rem, 1.5vw, .78rem);
    color: rgba(255, 255, 255, .75);
    margin-bottom: .55rem
}

.selector__title {
    font-family: var(--font-display);
    color: #fff;
    font-size: clamp(1.9rem, 5.2vw, 3.6rem);
    text-shadow: 0 2px 30px rgba(0, 0, 0, .5);
    margin: .67em 0
}

.selector__brush-word {
    white-space: nowrap
}

/* Pinceau image (assets/pinceau.png, 219×859) servant de point d'exclamation
   après « pinceau » : hauteur relative au titre, calée sur la ligne de texte. */
.selector__brush {
    display: inline-block;
    height: 1.15em;
    width: auto;
    vertical-align: -0.14em;
    margin-left: .1em;
    filter: drop-shadow(0 3px 12px rgba(0, 0, 0, .45))
}

.side {
    position: relative;
    flex: 1 1 50%;
    min-width: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    color: #fff;
    text-align: center;
    isolation: isolate;
    transition: flex-grow .55s var(--ease), filter .55s var(--ease)
}

.side--dragon {
    background: radial-gradient(120% 90% at 30% 18%, rgba(59, 163, 212, .55), transparent 60%), radial-gradient(130% 120% at 75% 100%, #2a1c4a 0%, transparent 55%), linear-gradient(160deg, #4a2f7d 0%, #41346f 45%, #241640 100%);
    filter: saturate(calc(1 - var(--dim-dragon) * .55));
    animation: wipeL 1s var(--ease) both
}

.side--poulpe {
    background: radial-gradient(120% 90% at 70% 16%, rgba(252, 234, 16, .55), transparent 58%), radial-gradient(130% 120% at 25% 100%, #8f1147 0%, transparent 55%), linear-gradient(200deg, #f06f3a 0%, #e71d73 42%, #b3134f 100%);
    filter: saturate(calc(1 - var(--dim-poulpe) * .55));
    animation: wipeR 1s var(--ease) both
}

.side::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 5;
    background: #0a0418;
    pointer-events: none
}

.side--dragon::after {
    opacity: calc(var(--dim-dragon) * .62);
    transition: opacity .55s var(--ease)
}

.side--poulpe::after {
    opacity: calc(var(--dim-poulpe) * .62);
    transition: opacity .55s var(--ease)
}

.bubbles {
    position: absolute;
    inset: 0;
    z-index: 1;
    pointer-events: none;
    overflow: hidden
}

.bubbles span {
    position: absolute;
    border-radius: 50%;
    opacity: .5;
    animation: floaty 9s ease-in-out infinite
}

.side--dragon .bubbles span {
    background: radial-gradient(circle at 35% 30%, #7fd0f0, #3ba3d4)
}

.side--poulpe .bubbles span {
    background: radial-gradient(circle at 35% 30%, #ffe14d, #e8a21f)
}

.bubbles span:nth-child(1) {
    width: 14px;
    height: 14px;
    left: 18%;
    top: 24%
}

.bubbles span:nth-child(2) {
    width: 9px;
    height: 9px;
    left: 30%;
    top: 62%;
    animation-delay: 1.2s;
    opacity: .35
}

.bubbles span:nth-child(3) {
    width: 22px;
    height: 22px;
    left: 70%;
    top: 30%;
    animation-delay: .6s
}

.bubbles span:nth-child(4) {
    width: 7px;
    height: 7px;
    left: 62%;
    top: 70%;
    animation-delay: 2s;
    opacity: .3
}

.bubbles span:nth-child(5) {
    width: 12px;
    height: 12px;
    left: 80%;
    top: 58%;
    animation-delay: 1.6s
}

.side__emblem {
    position: absolute;
    z-index: 2;
    width: min(62vh, 640px);
    height: auto;
    color: rgba(255, 255, 255, .07);
    pointer-events: none;
    transition: color .55s var(--ease)
}

.side__btn {
    position: relative;
    z-index: 10;
    width: 100%;
    height: 100%;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: .2rem;
    color: #fff;
    padding: 7vh 4vw
}

.player-tag {
    display: inline-flex;
    align-items: center;
    gap: .5rem;
    font-family: var(--font-body);
    font-size: .72rem;
    letter-spacing: .32em;
    text-transform: uppercase;
    color: rgba(255, 255, 255, .82);
    padding: .34rem .85rem;
    border: 1px solid rgba(255, 255, 255, .32);
    border-radius: 100px;
    backdrop-filter: blur(2px);
    margin-bottom: .4rem
}

.player-tag b {
    color: var(--gold);
    font-weight: 700;
    letter-spacing: .08em
}

.mascot {
    position: relative;
    width: clamp(180px, 26vh, 340px);
    aspect-ratio: 1/1;
    margin: .2rem 0 .4rem;
    margin-top: 80px !important;
    filter: drop-shadow(0 26px 34px rgba(0, 0, 0, .45));
    transition: transform .45s var(--ease)
}

/* Le flottement bob vit sur l'image (son propre transform), le scale de survol
   vit sur le wrapper .mascot : deux transforms indépendants qui se composent,
   sans que l'animation écrase l'agrandissement au hover. */
.mascot__photo {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: contain;
    z-index: 2;
    animation: bob 6s ease-in-out infinite
}

.team-name {
    font-family: var(--font-display);
    font-size: clamp(2.4rem, 6.4vw, 5.2rem);
    line-height: .92;
    text-shadow: 0 3px 26px rgba(0, 0, 0, .45)
}

.team-sub {
    font-family: var(--font-body);
    letter-spacing: .36em;
    text-transform: uppercase;
    font-size: clamp(.66rem, 1.6vw, .82rem);
    color: rgba(255, 255, 255, .78);
    margin-top: .5rem
}

.choose {
    margin-top: 1.5rem;
    display: inline-flex;
    align-items: center;
    gap: .55rem;
    font-family: var(--font-body);
    font-weight: 600;
    letter-spacing: .04em;
    font-size: .95rem;
    padding: .8rem 1.6rem;
    border-radius: 100px;
    color: #fff;
    background: rgba(255, 255, 255, .13);
    border: 1.5px solid rgba(255, 255, 255, .55);
    backdrop-filter: blur(3px);
    opacity: 0;
    transform: translateY(14px);
    transition: opacity .4s var(--ease), transform .4s var(--ease), background .25s, border-color .25s
}

.choose svg {
    width: 18px;
    height: 18px;
    transition: transform .3s var(--ease)
}

.divider {
    position: relative;
    z-index: 30;
    flex: 0 0 0;
    width: 0;
    align-self: stretch;
    display: flex;
    align-items: center;
    justify-content: center;
    pointer-events: none
}

.seam {
    position: absolute;
    top: -2%;
    bottom: -2%;
    left: 50%;
    width: 5px;
    transform: translateX(-50%) skewX(-6deg);
    background: linear-gradient(180deg, transparent, var(--gold) 12%, #fff 50%, var(--gold) 88%, transparent);
    box-shadow: 0 0 18px 3px rgba(255, 255, 255, .55), 0 0 46px 10px rgba(201, 162, 59, .55);
    animation: seamPulse 2.6s ease-in-out infinite
}

.bolt {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%) skewX(-6deg);
    width: 120px;
    height: min(90vh, 860px);
    color: #fff;
    opacity: .95;
    filter: drop-shadow(0 0 10px rgba(255, 255, 255, .7)) drop-shadow(0 0 26px rgba(201, 162, 59, .6))
}

.vs-badge {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    /* Le disque n'est plus dessiné (fond, bordure et ombre retirés ci-dessous) :
       le badge n'est plus qu'un point d'ancrage sur la couture. On le laisse
       donc s'ajuster au glyphe. Avec un carré figé de 86px en mobile, la boîte
       de ligne du « VS » (118px pour un corps de 80px) ne rentrait pas : la
       piste de grille débordait vers le bas au lieu de se centrer, et poussait
       le VS 16px sous la couture. */
    display: block;
    /*background: radial-gradient(circle at 38% 32%, #332455, #150c2c);*/
    /*border: 3px solid var(--gold);*/
    /*box-shadow: 0 0 0 6px rgba(0, 0, 0, .35), 0 14px 40px rgba(0, 0, 0, .55), inset 0 0 22px rgba(201, 162, 59, .35);*/
    animation: vsPop 1.1s var(--ease) .35s both
}

.vs-badge span {
    display: block;
    font-family: var(--font-display);
    font-size: 80px;
    /* Boîte de ligne calée sur le corps : le badge se centre alors sur la
       couture au pixel près, quelle que soit la largeur d'écran. */
    line-height: 1;
    color: #fff;
    text-shadow: 0 0 16px rgba(201, 162, 59, .9);
    letter-spacing: 1px;
    /* Centrage optique. « VS » est tout en capitales, sans jambage : son encre
       occupe 49px au-dessus de la ligne de base sur les 118px de la boîte de
       police (ascendante 88, descendante 30). Son milieu tombe donc 0.06em sous
       le milieu de la boîte. On remonte d'autant pour poser l'encre, et non la
       boîte, sur la couture. Le transform vit ici : celui du badge est réécrit
       par les keyframes vsPop (fill-mode both). */
    transform: translateY(-.061em)
}

.selector__hint {
    position: absolute;
    left: 0;
    right: 0;
    bottom: clamp(14px, 3vh, 30px);
    z-index: 40;
    text-align: center;
    pointer-events: none;
    font-family: var(--font-body);
    font-size: .82rem;
    letter-spacing: .05em;
    color: rgba(255, 255, 255, .62);
    animation: dropIn 1s var(--ease) .3s both
}

.selector__hint kbd {
    font-family: var(--font-body);
    border: 1px solid rgba(255, 255, 255, .3);
    border-radius: 6px;
    padding: .05em .45em;
    font-size: .78em;
    color: #fff
}

.selector:has(.side--dragon .side__btn:hover), .selector:has(.side--dragon .side__btn:focus-visible) {
    --dim-poulpe: 1
}

.selector:has(.side--poulpe .side__btn:hover), .selector:has(.side--poulpe .side__btn:focus-visible) {
    --dim-dragon: 1
}

.selector:has(.side--dragon .side__btn:hover) .side--dragon, .selector:has(.side--dragon .side__btn:focus-visible) .side--dragon {
    flex-grow: 1.45
}

.selector:has(.side--dragon .side__btn:hover) .side--poulpe, .selector:has(.side--dragon .side__btn:focus-visible) .side--poulpe {
    flex-grow: .62
}

.selector:has(.side--poulpe .side__btn:hover) .side--poulpe, .selector:has(.side--poulpe .side__btn:focus-visible) .side--poulpe {
    flex-grow: 1.45
}

.selector:has(.side--poulpe .side__btn:hover) .side--dragon, .selector:has(.side--poulpe .side__btn:focus-visible) .side--dragon {
    flex-grow: .62
}

.side__btn:hover .mascot, .side__btn:focus-visible .mascot {
    transform: scale(1.08) translateY(-6px)
}

.side__btn:hover .choose, .side__btn:focus-visible .choose {
    opacity: 1;
    transform: translateY(0)
}

.side__btn:hover .choose {
    background: rgba(255, 255, 255, .22)
}

.side__btn:hover .choose svg {
    transform: translateX(4px)
}

.side__btn:hover .side__emblem, .side__btn:focus-visible .side__emblem {
    color: rgba(255, 255, 255, .12)
}

.selector.is-leaving {
    transition: opacity .6s ease, transform .6s var(--ease);
    opacity: 0;
    transform: scale(1.04)
}

.selector.is-leaving .side[data-picked] {
    flex-grow: 6
}

/* =========================================================================
   2) STRUCTURE GÉNÉRALE
   ========================================================================= */
.site {
    display: none
}

:root[data-entered] .site {
    display: block
}

:root[data-entered] .selector {
    display: none
}

/* « backwards » et non « both » : avec both, l'état final de l'animation reste
   appliqué, donc un transform (translateY(0)) persiste sur le conteneur. Or un
   ancêtre transformé isole le backdrop et neutralise le backdrop-filter de
   l'en-tête collant, qui laissait alors lire le contenu défilant au travers.
   En backwards, seul l'état de départ est posé avant l'animation ; ensuite
   l'élément retrouve son état naturel, sans transform. */
.page-enter {
    animation: siteIn .7s var(--ease) backwards
}

/* En-tête */
.header {
    position: sticky;
    top: 0;
    z-index: 100;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    padding: .7rem clamp(1rem, 4vw, 2.4rem);
    background: rgba(255, 255, 255, .85);
    backdrop-filter: blur(12px);
    border-bottom: 1px solid #ececf1
}

.brand {
    display: flex;
    align-items: center;
    gap: .7rem;
    line-height: 1;
    flex: 0 0 auto
}

.brand__img {
    height: 65px;
    width: auto;
    display: block
}

.nav {
    display: flex;
    align-items: center;
    gap: .8rem
}

.nav a {
    font-family: var(--font-body);
    font-size: .86rem;
    font-weight: 500;
    padding: .5rem .9rem;
    border-radius: 100px;
    color: #3a3550;
    white-space: nowrap;
    transition: color .2s, background .2s
}

/* éléments propres au menu tiroir (titre, fermeture, réseaux, bloc équipe,
   voile) : inertes en desktop, activés par la media query ci-dessous.
   .nav__soc est un enfant direct de .nav depuis qu'il suit les entrées de menu :
   sans cette ligne il s'afficherait dans la barre de navigation du bureau. */
.nav__head, .nav__soc, .nav__extra, .nav-backdrop {
    display: none
}

/* bouton hamburger : masqué en desktop, révélé par la media query ci-dessous.
   Déclaré AVANT elle pour que son display:flex gagne la cascade. */
.nav-toggle {
    display: none;
    width: 42px;
    height: 42px;
    border-radius: 12px;
    align-items: center;
    justify-content: center;
    color: var(--ink);
    background: var(--primary-soft)
}

.nav-toggle svg {
    width: 24px;
    height: 24px
}

/* bascule sur le menu hamburger un peu avant le vrai point de rupture mobile,
   pour ne jamais faire déborder la barre (nav + switcher d'équipe).
   Le menu devient un tiroir plein écran depuis la droite : liens, choix
   d'équipe (le slider y déménage via app.js) et réseaux sociaux. */
@media (max-width: 1220px) {
    .nav {
        position: fixed;
        top: 0;
        right: 0;
        bottom: 0;
        left: auto;
        width: min(84vw, 360px);
        height: 100vh;
        height: 100dvh;
        flex-direction: column;
        align-items: stretch;
        gap: .15rem;
        background: #fff;
        box-shadow: -24px 0 60px rgba(10, 4, 24, .28);
        padding: 1.1rem 1.15rem calc(1.3rem + env(safe-area-inset-bottom));
        overflow-y: auto;
        overscroll-behavior: contain;
        transform: translateX(calc(100% + 60px));
        visibility: hidden;
        transition: transform .34s var(--ease), visibility .34s;
        z-index: 320
    }

    .nav.open {
        transform: none;
        visibility: visible
    }

    .nav-backdrop {
        display: block;
        position: fixed;
        inset: 0;
        background: rgba(15, 8, 32, .45);
        opacity: 0;
        pointer-events: none;
        transition: opacity .3s;
        z-index: 310
    }

    .nav-backdrop.is-open {
        opacity: 1;
        pointer-events: auto
    }

    .nav__head {
        display: flex;
        align-items: center;
        justify-content: space-between;
        margin-bottom: .9rem
    }

    .nav__title {
        font-family: var(--font-display);
        font-size: 1.55rem;
        color: var(--ink)
    }

    .nav__close {
        display: grid;
        place-items: center;
        width: 38px;
        height: 38px;
        border-radius: 50%;
        background: var(--primary-soft);
        color: var(--primary-deep)
    }

    .nav__close svg {
        width: 20px;
        height: 20px
    }

    .nav a {
        padding: .95rem 1rem;
        border-radius: 14px;
        font-size: 1.02rem;
        white-space: normal
    }

    /* apparition en cascade des liens à l'ouverture */
    .nav.open a {
        animation: navItemIn .4s var(--ease) both
    }

    .nav.open a:nth-of-type(1) { animation-delay: .05s }
    .nav.open a:nth-of-type(2) { animation-delay: .08s }
    .nav.open a:nth-of-type(3) { animation-delay: .11s }
    .nav.open a:nth-of-type(4) { animation-delay: .14s }
    .nav.open a:nth-of-type(5) { animation-delay: .17s }
    .nav.open a:nth-of-type(6) { animation-delay: .2s }

    /* Le selecteur d'equipe reste seul en bas du tiroir, centre avec son
       libelle et sans trait de separation : les reseaux sociaux qui le
       precedaient sont remontes sous les entrees de menu. */
    .nav__extra {
        display: block;
        margin-top: auto;
        padding-top: 1.15rem;
        text-align: center
    }

    .nav__extra-label {
        font-family: var(--font-body);
        font-weight: 700;
        font-size: .72rem;
        letter-spacing: .12em;
        text-transform: uppercase;
        color: var(--primary);
        margin: 0 0 .7rem
    }

    .nav__team {
        display: flex;
        justify-content: center
    }

    /* Retrait a gauche cale sur le texte des entrees de menu : celles-ci portent
       un padding de 1rem, donc leur libelle demarre a 1rem du bord du lien. Les
       pastilles s'alignent dessus. */
    .nav__soc {
        display: flex;
        gap: .6rem;
        margin: .75rem 0 0 1rem
    }

    .nav__soc a {
        display: grid;
        place-items: center;
        width: 44px;
        height: 44px;
        /* Ces liens heritent du padding de .nav a, prevu pour les entrees de
           menu : .95rem 1rem. En box-sizing: border-box il ampute la zone de
           contenu de 32px en largeur et 30,4px en hauteur, soit plus que la
           pastille elle-meme. L'icone, trop grande pour ce qui reste, debordait
           alors vers le coin au lieu de se centrer : sur l'ancienne pastille de
           38px, il restait 6 x 7,6px de contenu et l'icone de 17px se retrouvait
           5,5px trop a droite et 4,7px trop bas. */
        padding: 0;
        border-radius: 50%;
        background: var(--primary-soft);
        color: var(--primary-deep);
        transition: background .2s, color .2s
    }

    .nav__soc a:hover {
        background: var(--primary);
        color: #fff
    }

    .nav__soc svg {
        width: 20px;
        height: 20px
    }

    .nav-toggle {
        display: flex
    }
}

@keyframes navItemIn {
    from {
        opacity: 0;
        transform: translateX(14px)
    }
    to {
        opacity: 1;
        transform: none
    }
}

@media (prefers-reduced-motion: reduce) {
    .nav {
        transition: none
    }

    .nav.open a {
        animation: none
    }
}

.nav a:hover {
    color: var(--primary);
    background: var(--primary-soft)
}

.nav a.is-active {
    color: var(--primary);
    background: var(--primary-soft)
}

.header__right {
    display: flex;
    align-items: center;
    gap: .8rem;
    flex: 0 0 auto
}

/* Slider d'équipe (interrupteur) · dragon | rail coloré | poulpe */
.team-switcher {
    display: inline-flex;
    align-items: center;
    /* 0.8rem au lieu de 0.55rem : ces 4px de plus de chaque côté du rail sont ce
       qui permet aux icônes d'avoir une cible tactile de 44px sans mordre sur
       lui (voir .team-switcher__ico::after). */
    gap: .8rem
}

.team-switcher__ico {
    position: relative;
    width: 23px;
    height: 23px;
    flex: 0 0 auto;
    padding: 0;
    line-height: 0;
    color: #bdb8cc;
    opacity: .7;
    transition: color .35s, transform .35s var(--ease), opacity .35s
}

/* Cible tactile étendue sans toucher au dessin : 23x23 se visait mal au pouce.
   Borne horizontale : l'icône active reçoit un scale(1.16) qui agrandit ce
   pseudo-élément avec elle, donc la demi-largeur finale (23 + 2e) x 0,58 doit
   rester sous la distance du centre au bord du rail, soit 11,5 + 12,8 = 24,3px.
   D'où e <= 9,4px, et 9px retenu. */
.team-switcher__ico::after {
    content: '';
    position: absolute;
    top: -11px;
    bottom: -11px;
    left: -9px;
    right: -9px
}

.team-switcher__ico--poulpe {
    top: -4px;
    position: relative;
}

.team-switcher__ico:hover {
    opacity: 1
}

:root[data-team="dragon"] .team-switcher__ico--dragon, :root[data-team="poulpe"] .team-switcher__ico--poulpe {
    color: var(--primary);
    opacity: 1;
    transform: scale(1.16)
}

.team-switcher__track {
    position: relative;
    flex: 0 0 auto;
    width: 74px;
    height: 38px;
    border-radius: 100px;
    background: var(--grad-primary);
    box-shadow: inset 0 1px 5px rgba(10, 4, 24, .25), 0 5px 14px -5px color-mix(in srgb, var(--primary) 65%, transparent);
    transition: background .45s, box-shadow .45s
}

.team-switcher__knob {
    position: absolute;
    top: 4px;
    left: 4px;
    width: 30px;
    height: 30px;
    border-radius: 50%;
    background: #fff;
    box-shadow: 0 3px 8px rgba(10, 4, 24, .32);
    transition: left .42s var(--ease), transform .2s var(--ease)
}

:root[data-team="poulpe"] .team-switcher__knob {
    left: 40px
}

.team-switcher__track:active .team-switcher__knob {
    transform: scale(.92)
}

/* Focus clavier du sélecteur d'équipe.

   L'anneau global (outline de 3px en var(--accent), décalé de 3px) posait sur
   ce composant un cerne bleu sur l'équipe Kesla et orange sur Diunizel, séparé
   de la pilule par un halo blanc : la couleur d'accentuation ne s'accorde ni
   avec le dégradé de la pilule ni avec le fond clair du tiroir.

   L'indicateur reste, il est indispensable à qui navigue au clavier, mais il
   est redessiné avec la forme et les couleurs du composant : un liseré blanc
   collé à la pilule, puis l'anneau dans la couleur d'équipe. L'ombre portée
   d'origine est reprise, box-shadow ne se cumulant pas d'une règle à l'autre.

   À noter : cet anneau n'apparaît jamais au clic ni au toucher, uniquement à la
   tabulation. */
.team-switcher__track:focus-visible {
    outline: none;
    box-shadow: inset 0 1px 5px rgba(10, 4, 24, .25),
    0 0 0 2px #fff,
    0 0 0 5px var(--primary)
}

.team-switcher__ico:focus-visible {
    outline: 2px solid var(--primary);
    outline-offset: 5px;
    border-radius: 10px
}

/* Boutons */
.btn {
    display: inline-flex;
    align-items: center;
    gap: .55rem;
    font-family: var(--font-body);
    font-weight: 600;
    font-size: 1rem;
    padding: .9rem 1.7rem;
    border-radius: 100px;
    transition: transform .2s var(--ease), box-shadow .25s, background .25s, color .2s
}

.btn svg {
    width: 20px;
    height: 20px;
    flex: 0 0 auto
}

.btn--primary {
    background: var(--grad-primary);
    color: #fff;
    box-shadow: 0 12px 30px -10px color-mix(in srgb, var(--primary) 70%, transparent)
}

.btn--primary:hover {
    transform: translateY(-2px);
    box-shadow: 0 18px 38px -10px color-mix(in srgb, var(--primary) 75%, transparent)
}

.btn--ghost {
    background: #fff;
    color: var(--primary-deep);
    border: 1.5px solid color-mix(in srgb, var(--primary) 32%, transparent)
}

.btn--ghost:hover {
    background: var(--primary-soft);
    border-color: var(--primary)
}

.btn--white {
    background: #fff;
    color: var(--primary-deep)
}

.btn--white:hover {
    transform: translateY(-2px)
}

/* Sections génériques */
.section {
    padding: clamp(3rem, 6vw, 5.5rem) clamp(1rem, 4vw, 2.4rem)
}

.section--tint {
    background: radial-gradient(60% 80% at 100% 0, color-mix(in srgb, var(--accent) 12%, transparent), transparent 60%), radial-gradient(50% 70% at 0 100%, color-mix(in srgb, var(--primary) 10%, transparent), transparent 60%), #faf9fc
}

.section__inner {
    max-width: var(--container);
    margin: 0 auto
}

.section__head {
    text-align: center;
    max-width: 62ch;
    margin: 0 auto 2.6rem
}

.section__head--left {
    text-align: left;
    margin-left: 0
}

.section__kicker {
    font-family: var(--font-body);
    font-weight: 600;
    letter-spacing: .2em;
    text-transform: uppercase;
    font-size: .8rem;
    color: var(--primary);
    margin-bottom: .7rem
}

.section__title {
    font-size: clamp(2rem, 4vw, 3rem);
    color: var(--ink);
    margin-bottom: 30px;
}

.section__title .u {
    background: linear-gradient(transparent 62%, color-mix(in srgb, var(--accent) 55%, transparent) 0)
}

.section__lead {
    margin-top: .9rem;
    font-size: 1.05rem;
    line-height: 1.65;
    color: #4d4763
}

.section__lead a {
    color: var(--primary-deep);
    font-weight: 600;
    text-decoration: underline;
    text-underline-offset: 3px
}

/* =========================================================================
   3) HERO
   ========================================================================= */
.hero {
    min-height: min(92svh, 880px);
    display: grid;
    align-content: center;
    position: relative;
    overflow: hidden;
    padding: clamp(3rem, 7vw, 6rem) clamp(1rem, 4vw, 2.4rem) clamp(3rem, 6vw, 5rem);
    /* Le lavis s'eteint en transparence, non en blanc opaque : sur l'accueil, le
       halo du bas est porte par .hero-zone et doit rester visible au travers. */
    background: radial-gradient(var(--hero-tint-1-size, 48% 60%) at 88% 6%, color-mix(in srgb, var(--accent) var(--hero-tint-1, 45%), transparent), transparent var(--hero-tint-1-fade, 62%)), linear-gradient(180deg, var(--primary-soft) 0%, transparent var(--hero-wash, 42%))
}

/* Zone teintee : le heros et le texte d'introduction qui le suit. Le fond vivait
   sur le seul heros, dont le overflow:hidden tranchait net le halo du bas, d'ou
   une ligne horizontale franche au-dessus du texte. Porte par la zone entiere,
   il se prolonge derriere l'introduction et s'y eteint.
   Les reperes verticaux sont ramenes a l'echelle de la zone (le heros en occupe
   environ les quatre cinquiemes), pour que le heros garde son allure. */
.hero-zone {
    position: relative;
    /* La zone porte le halo du bas, etale sur toute sa hauteur : aucune boite ne
       le decoupe, donc pas d'arete entre le heros et le texte. Les autres
       couches restent sur le heros et s'eteignent en transparence, laissant ce
       halo transparaitre au travers. */
    background: radial-gradient(var(--hero-tint-2-size, 52% 70%) at 4% 90%, color-mix(in srgb, var(--primary) var(--hero-tint-2, 32%), transparent), transparent var(--hero-tint-2-fade, 60%));
    background-color: #fff
}

/* A l'echelle du halo (plusieurs centaines de pixels), le texte d'introduction
   est trop court pour que la couleur s'y eteigne d'elle-meme : elle arriverait
   encore franche au bas de la zone. Ce voile l'amene progressivement au blanc
   sur toute la hauteur du texte. */
.hero-zone::after {
    content: "";
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    height: clamp(220px, 30vh, 420px);
    /* Paliers intermediaires : un fondu long et peu contraste vire aux bandes
       en 8 bits. Une courbe adoucie repartit l'ecart et les efface. */
    background: linear-gradient(180deg,
        rgba(255, 255, 255, 0) 0%,
        rgba(255, 255, 255, .05) 30%,
        rgba(255, 255, 255, .18) 50%,
        rgba(255, 255, 255, .42) 68%,
        rgba(255, 255, 255, .72) 82%,
        rgba(255, 255, 255, .92) 92%,
        #fff 100%);
    pointer-events: none
}

/* Le contenu passe au-dessus du fondu */
.hero-zone > .hero,
.hero-zone > .section--intro {
    position: relative;
    z-index: 1
}

.hero__grid {
    width: 100%;
    max-width: var(--container);
    margin: 0 auto;
    display: grid;
    grid-template-columns:1.15fr .85fr;
    gap: clamp(1.5rem, 4vw, 3rem);
    align-items: center
}

.hero__eyebrow {
    display: inline-flex;
    align-items: center;
    gap: .55rem;
    font-family: var(--font-body);
    font-weight: 600;
    font-size: .8rem;
    letter-spacing: .18em;
    text-transform: uppercase;
    color: var(--primary);
    background: var(--primary-soft);
    padding: .45rem .9rem;
    border-radius: 100px;
    margin-bottom: 1.2rem
}

.hero h1 {
    font-size: clamp(2.6rem, 6vw, 4.6rem);
    color: var(--ink);
    margin-bottom: 1.1rem
}

.hero h1 em {
    font-style: normal;
    color: var(--primary)
}

.hero__lead {
    font-size: clamp(1.05rem, 1.6vw, 1.22rem);
    color: #4a4560;
    max-width: 46ch;
    margin-bottom: 1.8rem
}

.hero__cta {
    display: flex;
    flex-wrap: wrap;
    gap: .8rem;
    margin-bottom: 2rem
}

.hero__stats {
    display: flex;
    gap: 2rem;
    flex-wrap: wrap
}

.hero__stats .num {
    font-family: var(--font-display);
    font-size: 1.9rem;
    color: var(--primary-deep);
    line-height: 1
}

.hero__stats .lbl {
    font-size: .82rem;
    color: #6a6580
}

.hero__art {
    position: relative;
    display: grid;
    place-items: center;
    min-height: 340px
}

.hero__halo {
    position: absolute;
    inset: 2%;
    border-radius: 50%;
    background: var(--grad-primary);
    filter: blur(26px);
    opacity: .45;
    animation: spin 22s linear infinite
}

.hero__disc {
    position: absolute;
    width: 86%;
    aspect-ratio: 1;
    border-radius: 50%;
    background: radial-gradient(circle at 36% 26%, #fff, color-mix(in srgb, var(--primary) var(--hero-disc-tint, 15%), #fff) 80%);
    border: 4px solid rgba(255, 255, 255, .7);
    box-shadow: 0 34px 70px -24px color-mix(in srgb, var(--primary) 55%, transparent), inset 0 2px 22px rgba(255, 255, 255, .6)
}

.hero__mascot {
    position: relative;
    z-index: 2;
    width: 82%;
    aspect-ratio: 1;
    filter: drop-shadow(0 22px 26px rgba(23, 12, 48, .32));
    animation: bob 6s ease-in-out infinite
}

.hero__mascot img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: contain;
    z-index: 2
}

/* hero des pages internes : un cran sous celui de l'accueil */
.hero--inner {
    min-height: min(90svh, 780px);
    padding-bottom: clamp(2rem, 4vw, 3rem)
}

.hero--inner .hero__grid {
    grid-template-columns:1fr;
    text-align: center;
    max-width: 720px
}

.hero--inner .hero__eyebrow {
    margin-inline: auto
}

.hero--inner .hero__lead {
    margin-inline: auto
}

.hero--inner .hero__cta {
    justify-content: center
}

/* grands écrans : le hero respire sur toute la largeur disponible */
@media (min-width: 1440px) {
    .hero__grid {
        max-width: 1280px
    }
}

/* =========================================================================
   4) PRÉSENTATION DU STUDIO
   ========================================================================= */
.about__grid {
    display: grid;
    grid-template-columns:.9fr 1.1fr;
    gap: clamp(1.6rem, 4vw, 3.4rem);
    align-items: center;
    max-width: var(--container);
    margin: 0 auto
}

.about__media {
    position: relative;
    display: grid;
    place-items: center;
    padding: 1.5rem
}

.about__media::before {
    content: "";
    position: absolute;
    inset: 0%;
    border-radius: 50%;
    background: var(--grad-primary);
    opacity: .10;
    filter: blur(48px)
}

.about__logo {
    position: relative;
    width: 100%;
    max-width: 460px;
    height: 500px;
    aspect-ratio: 4/3;
    object-fit: cover;
    border-radius: 22px;
    border: 4px solid #fff;
    box-shadow: 0 0 0 5px color-mix(in srgb, var(--primary) 30%, transparent),
    0 28px 56px -14px rgba(23, 12, 48, .48);
    transition: box-shadow .5s var(--ease);
    display: block
}

.about__photo {
    position: absolute;
    right: 4%;
    bottom: 2%;
    width: 44%;
    border-radius: 18px;
    border: 5px solid #fff;
    box-shadow: 0 18px 36px -14px rgba(23, 12, 48, .45);
    object-fit: cover;
    aspect-ratio: 4/3
}

/* Presentation du studio : le texte passe au-dessus, sur deux colonnes, et la
   photo vient dessous. Les deux paragraphes fournis par le studio sont longs :
   cote a cote avec la photo, la colonne de texte devenait un ruban vertical. */
.about__grid--stack {
    grid-template-columns: 1fr;
    align-items: start;
    gap: clamp(1.8rem, 4vw, 2.8rem)
}

.about__grid--stack .about {
    text-align: center
}

/* .about p est borne a 54ch, heritage de la mise en page en deux colonnes ou le
   texte occupait une colonne etroite. Ici le bloc est pleine largeur : sans ce
   retrait, le sur-titre formait une boite de 490px calee a gauche (donc decalee
   par rapport au titre centre) et les paragraphes n'occupaient pas leur colonne. */
.about__grid--stack .about > .section__kicker,
.about__grid--stack .about__text p {
    max-width: none
}

.about__text {
    columns: 2;
    column-gap: clamp(2rem, 4.5vw, 4rem);
    margin-top: 1.3rem;
    text-align: left
}

.about__grid--stack .about__media {
    padding: 0;
    /* sous 980px, .about__media passe en order:-1 pour remonter la photo ;
       ici elle doit rester sous le texte. */
    order: 0
}

.about__grid--stack .about__logo {
    max-width: 820px;
    height: auto;
    aspect-ratio: 4/3;
    margin: 0 auto
}

/* Sous 900px la double colonne casse la lecture : une seule colonne. */
@media (max-width: 900px) {
    .about__text {
        columns: 1
    }
}

.about p {
    color: #4a4560;
    font-size: 1.06rem;
    margin-bottom: 1rem;
    max-width: 54ch
}

.about__values {
    display: grid;
    grid-template-columns:repeat(3, 1fr);
    gap: 1rem;
    margin-top: 1.8rem
}

.about__value {
    background: #fff;
    border: 1px solid #ececf1;
    border-radius: var(--radius);
    padding: 1.1rem
}

.about__value .vi {
    width: 42px;
    height: 42px;
    border-radius: 12px;
    display: grid;
    place-items: center;
    background: var(--primary-soft);
    color: var(--primary);
    margin-bottom: .6rem
}

.about__value .vi svg {
    width: 22px;
    height: 22px
}

.about__value h4 {
    font-size: 1.1rem;
    color: var(--ink);
    margin-bottom: .2rem
}

.about__value p {
    font-size: .9rem;
    margin: 0;
    color: #5a5570
}

/* =========================================================================
   5) PRESTATIONS (cartes égales · aucune mise en avant)
   ========================================================================= */
.cards {
    display: grid;
    grid-template-columns:repeat(3, 1fr);
    gap: 1.4rem
}

.card {
    position: relative;
    display: flex;
    flex-direction: column;
    background: #fff;
    border: 1px solid #ececf1;
    border-radius: var(--radius-lg);
    padding: 2rem 1.7rem;
    cursor: pointer;
    transition: transform .25s var(--ease), box-shadow .3s, border-color .25s
}

.card:hover {
    transform: translateY(-6px);
    box-shadow: 0 24px 50px -24px rgba(23, 12, 48, .4);
    border-color: color-mix(in srgb, var(--primary) 35%, transparent)
}

.card__icon {
    width: 54px;
    height: 54px;
    border-radius: 15px;
    display: grid;
    place-items: center;
    margin-bottom: 1.1rem;
    background: var(--primary-soft);
    color: var(--primary)
}

.card__icon svg {
    width: 28px;
    height: 28px
}

.card h3 {
    font-size: 1.4rem;
    color: var(--ink);
    margin-bottom: .5rem
}

.card p {
    color: #56506a;
    font-size: .98rem;
    margin-bottom: 1.1rem
}

.card .price {
    font-family: var(--font-body);
    font-weight: 600;
    color: var(--primary-deep);
    font-size: .92rem
}

.card ul {
    list-style: none;
    margin-top: 1rem;
    display: grid;
    gap: .5rem
}

.card li {
    display: flex;
    gap: .55rem;
    align-items: flex-start;
    font-size: .92rem;
    color: #46415c
}

.card li svg {
    width: 18px;
    height: 18px;
    color: var(--primary);
    flex: 0 0 auto;
    margin-top: .18rem
}

.card__link {
    margin-top: auto;
    align-self: flex-start;
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    color: var(--primary-deep);
    font-weight: 600;
    font-size: .92rem;
    /* Le lien n'apparaît qu'au survol (ou au focus clavier) de sa carte ;
       l'espace reste réservé pour éviter tout saut de mise en page. */
    opacity: 0;
    transform: translateY(4px);
    transition: opacity .22s var(--ease), transform .22s var(--ease)
}

/* Lien étendu : toute la carte devient cliquable via ce pseudo-élément */
.card__link::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 1
}

.card:hover .card__link,
.card:focus-within .card__link {
    opacity: 1;
    transform: none
}

.card__link svg {
    width: 16px;
    height: 16px;
    transition: transform .2s
}

.card:hover .card__link svg {
    transform: translate(2px, -2px)
}

/* =========================================================================
   6) GALERIE CATÉGORISÉE
   ========================================================================= */
/* Barre du nombre de photos affichees (galerie) : selecteur aligne a droite. */
.gallery-bar {
    display: flex;
    justify-content: flex-end;
    margin: 0 0 1.3rem
}

/* Barre de filtres collee sous le header pendant le defilement de la grille,
   a toutes les largeurs (elle ne l'etait que sous 520px). Fond transparent au
   repos pour ne pas trancher dans la section ; le fond givre n'apparait qu'une
   fois la barre reellement plaquee (.is-stuck, posee par site.js). */
/* Le coeur et son libelle sur une meme ligne. Regle nommee plutot qu'un style
   inline, qui passerait au-dessus de toute media query. */
.filter--fav {
    display: inline-flex;
    align-items: center;
    gap: .35rem
}

.gallery-filters {
    position: sticky;
    top: var(--header-h);
    z-index: 40;
    display: flex;
    flex-wrap: wrap;
    gap: .6rem;
    justify-content: center;
    padding: .7rem 0;
    margin-bottom: 1.8rem;
    background: transparent
}

.gallery-filters.is-stuck {
    background: color-mix(in srgb, #faf9fc 82%, transparent);
    backdrop-filter: blur(12px) saturate(1.3);
    box-shadow: 0 8px 18px -14px rgba(23, 12, 48, .5)
}

.filter {
    font-family: var(--font-body);
    font-weight: 600;
    font-size: .9rem;
    color: #5a5570;
    padding: .5rem 1.1rem;
    border-radius: 100px;
    border: 1.5px solid #e6e3ee;
    background: #fff;
    transition: color .2s, background .2s, border-color .2s
}

.filter:hover {
    border-color: color-mix(in srgb, var(--primary) 40%, transparent);
    color: var(--primary-deep)
}

.filter.is-active {
    color: #fff;
    background: var(--grad-primary);
    border-color: transparent
}

.gallery {
    display: grid;
    grid-template-columns:repeat(4, 1fr);
    gap: 1rem
}

.tile {
    position: relative;
    border-radius: var(--radius);
    overflow: hidden;
    aspect-ratio: 1;
    display: flex;
    align-items: flex-end;
    color: #fff;
    padding: 1rem;
    background: var(--grad-primary);
    isolation: isolate;
    cursor: pointer;
    transition: transform .3s var(--ease), box-shadow .3s, opacity .35s
}

.tile img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    z-index: 0;
    transition: transform .55s var(--ease)
}

.tile::before {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(180deg, transparent 42%, rgba(10, 4, 24, .72));
    z-index: 1;
    opacity: .85;
    transition: opacity .3s
}

.tile__cap {
    position: relative;
    z-index: 2;
    font-family: var(--font-body);
    font-weight: 600;
    font-size: .95rem;
    letter-spacing: .02em;
    text-shadow: 0 1px 8px rgba(0, 0, 0, .55)
}

.tile__tag {
    position: absolute;
    top: 12px;
    left: 12px;
    z-index: 2;
    font-family: var(--font-body);
    /* 0.66rem donnait 10,56px, sous le plancher de 12px : c'est la valeur que
       voyaient la tablette et le bureau. */
    font-size: .75rem;
    font-weight: 600;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: #fff;
    background: color-mix(in srgb, var(--primary) 75%, rgba(10, 4, 24, .4));
    padding: .2rem .55rem;
    border-radius: 100px
}

.tile:hover {
    transform: translateY(-4px);
    box-shadow: 0 24px 46px -20px rgba(23, 12, 48, .55)
}

.tile:hover img {
    transform: scale(1.07)
}

.tile__like {
    position: absolute;
    top: 12px;
    right: 12px;
    z-index: 2;
    width: 34px;
    height: 34px;
    border-radius: 50%;
    background: rgba(10, 4, 24, .32);
    display: grid;
    place-items: center;
    border: 1px solid rgba(255, 255, 255, .45);
    backdrop-filter: blur(3px);
    color: #fff;
    opacity: 0;
    transform: scale(.8);
    transition: opacity .25s, transform .25s, background .2s, color .2s
}

.tile__like svg {
    width: 17px;
    height: 17px;
    fill: none
}

.tile:hover .tile__like, .tile__like.is-liked {
    opacity: 1;
    transform: scale(1)
}

.tile__like.is-liked {
    background: #fff;
    color: #e0245e
}

.tile__like.is-liked svg {
    fill: currentColor
}

/* Animation du like : le cœur « pop » (rebond élastique) pendant qu'un
   anneau éclate autour du bouton. Déclenchée par la classe is-pop, posée
   par site.js au clic seulement, jamais au chargement de la page. */
.tile__like::after {
    content: '';
    position: absolute;
    inset: -1px;
    border-radius: 50%;
    border: 2px solid #e0245e;
    opacity: 0;
    pointer-events: none;
}

.tile__like.is-pop svg {
    animation: like-pop .5s cubic-bezier(.34, 1.56, .64, 1);
}

.tile__like.is-pop::after {
    animation: like-burst .5s ease-out;
}

@keyframes like-pop {
    0% { transform: scale(1); }
    35% { transform: scale(1.4); }
    60% { transform: scale(.85); }
    100% { transform: scale(1); }
}

@keyframes like-burst {
    0% { transform: scale(.4); opacity: .55; }
    100% { transform: scale(1.75); opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
    .tile__like.is-pop svg,
    .tile__like.is-pop::after {
        animation: none;
    }
}

/* révèle le cœur au focus clavier (sinon invisible hors survol) */
.tile__like:focus-visible {
    opacity: 1;
    transform: scale(1);
    outline: 2px solid #fff;
    outline-offset: 2px
}

/* ---- Lightbox galerie ---- */
.lightbox {
    width: 100vw;
    max-width: 100vw;
    height: 100vh;
    max-height: 100vh;
    margin: 0;
    padding: 0;
    border: none;
    background: transparent;
    overflow: hidden
}

.lightbox[open] {
    display: grid;
    place-items: center;
    animation: lightboxIn .25s var(--ease)
}

/* Sur mobile, la barre d'adresse qui se retracte agrandit la zone visible sans
   que le voile, dimensionne sur la zone de mise en page, ne suive : une bande
   non assombrie restait en bas de l'ecran. « lvh » est la hauteur barre
   retractee, donc la plus grande : le voile couvre toujours, quitte a deborder
   sous la barre quand elle est affichee, ce qui ne se voit pas. Les navigateurs
   qui ignorent l'unite retombent sur le « inset: 0 » par defaut. */
.lightbox::backdrop {
    background: rgba(8, 3, 20, .86);
    backdrop-filter: blur(4px);
    bottom: auto;
    height: 100lvh
}

.lightbox__figure {
    margin: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: .9rem;
    padding: 1rem
}

.lightbox__img {
    max-width: 92vw;
    max-height: 80vh;
    width: auto;
    height: auto;
    border-radius: var(--radius);
    box-shadow: 0 30px 90px -20px rgba(0, 0, 0, .8);
    display: block
}

.lightbox__img.is-swap {
    animation: lightboxSwap .3s var(--ease)
}

.lightbox__cap {
    color: rgba(255, 255, 255, .92);
    font-family: var(--font-display);
    font-size: 1.15rem;
    text-align: center
}

/* Surtitre de la visionneuse. Le gabarit etant partage, le span existe partout,
   mais il ne parait qu'a l'endroit precis ou la vignette perd son texte : la
   page galerie sur telephone, plus bas dans la media query. Partout ailleurs il
   reste muet, et rien ne change. */
.lightbox__tag {
    display: none
}

.lightbox__count {
    font-family: var(--font-body);
    font-size: .85rem;
    color: rgba(255, 255, 255, .5);
    margin-left: .7rem
}

.lightbox__ctrl {
    position: fixed;
    z-index: 2;
    display: grid;
    place-items: center;
    width: 48px;
    height: 48px;
    border-radius: 50%;
    color: #fff;
    background: rgba(255, 255, 255, .12);
    backdrop-filter: blur(4px);
    transition: background .2s, transform .2s
}

.lightbox__ctrl:hover {
    background: rgba(255, 255, 255, .24)
}

.lightbox__ctrl:focus-visible {
    outline: 2px solid #fff;
    outline-offset: 3px
}

.lightbox__ctrl svg {
    width: 22px;
    height: 22px
}

.lightbox__close {
    top: clamp(1rem, 3vw, 1.6rem);
    right: clamp(1rem, 3vw, 1.6rem)
}

.lightbox__nav {
    top: 50%;
    transform: translateY(-50%)
}

.lightbox__nav:hover {
    transform: translateY(-50%) scale(1.08)
}

.lightbox__prev {
    left: clamp(.6rem, 3vw, 2rem)
}

.lightbox__next {
    right: clamp(.6rem, 3vw, 2rem)
}

.lightbox__nav[hidden] {
    display: none
}

@keyframes lightboxIn {
    from {
        opacity: 0
    }
}

@keyframes lightboxSwap {
    from {
        opacity: .35;
        transform: scale(.985)
    }
}

@media (prefers-reduced-motion: reduce) {
    .lightbox[open], .lightbox__img.is-swap {
        animation: none
    }

    .lightbox__ctrl, .lightbox__nav:hover {
        transition: none
    }
}

.tile.is-hidden {
    display: none
}

.gallery__more {
    text-align: center;
    margin-top: 2rem
}

.gallery-empty {
    text-align: center;
    color: #7a7590;
    padding: 2.4rem 1rem;
    font-size: .98rem
}

.gallery-empty[hidden] {
    display: none
}

/* Catalogue sans aucun produit publie : etat franc, centre, sans filtres. */
.catalog-empty {
    text-align: center;
    max-width: 34rem;
    margin: 0 auto;
    padding: clamp(2.5rem, 8vw, 6rem) 1rem
}

.catalog-empty__icon {
    width: 54px;
    height: 54px;
    color: var(--primary);
    opacity: .5;
    margin-bottom: 1.1rem
}

.catalog-empty__title {
    font-family: var(--font-display);
    font-size: clamp(1.4rem, 3vw, 1.9rem);
    color: var(--ink);
    margin: 0 0 .6rem
}

.catalog-empty__text {
    color: var(--primary-2);
    line-height: 1.65;
    margin: 0 0 1.7rem
}

/* =========================================================================
   7) SALONS / ÉVÉNEMENTS
   ========================================================================= */
.salons {
    display: grid;
    grid-template-columns:repeat(auto-fill, minmax(240px, 1fr));
    gap: 1.1rem
}

.salon {
    position: relative;
    display: flex;
    gap: 1rem;
    background: #fff;
    border: 1px solid #ececf1;
    border-radius: var(--radius);
    padding: 1.2rem;
    transition: transform .25s var(--ease), box-shadow .3s, border-color .25s
}

.salon:hover {
    transform: translateY(-4px);
    box-shadow: 0 22px 44px -24px rgba(23, 12, 48, .38);
    border-color: color-mix(in srgb, var(--primary) 30%, transparent)
}

.salon__date {
    flex: 0 0 auto;
    width: 62px;
    height: 62px;
    border-radius: 14px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    background: var(--grad-primary);
    color: #fff;
    line-height: 1
}

.salon__date .d {
    font-family: var(--font-display);
    font-size: 1.5rem
}

.salon__date .m {
    font-size: .66rem;
    letter-spacing: .12em;
    text-transform: uppercase;
    margin-top: .15rem
}

.salon__body h4 {
    font-size: 1.16rem;
    color: var(--ink);
    margin-bottom: .2rem
}

.salon__loc {
    display: flex;
    align-items: center;
    gap: .35rem;
    font-size: .9rem;
    color: #6a6580
}

.salon__loc svg {
    width: 15px;
    height: 15px;
    color: var(--primary)
}

.salon__note {
    margin-top: .4rem;
    font-size: .82rem;
    color: var(--primary-deep);
    font-weight: 600
}

.salons-cta {
    margin-top: 1.8rem;
    text-align: center;
    color: #55506a
}

/* =========================================================================
   8) AVIS CLIENTS
   ========================================================================= */
.reviews {
    display: grid;
    grid-template-columns:repeat(3, 1fr);
    gap: 1.3rem
}

.review {
    position: relative;
    background: #fff;
    border: 1px solid #ececf1;
    border-radius: var(--radius-lg);
    padding: 1.8rem;
    display: flex;
    flex-direction: column;
    gap: .9rem
}

.review__stars {
    display: flex;
    gap: .15rem;
    color: var(--accent)
}

.review__stars svg {
    width: 18px;
    height: 18px
}

.review__quote {
    color: #403b56;
    font-size: 1.02rem;
    flex: 1
}

.review__author {
    display: flex;
    align-items: center;
    gap: .7rem
}

.review__avatar {
    width: 42px;
    height: 42px;
    border-radius: 50%;
    display: grid;
    place-items: center;
    font-family: var(--font-display);
    color: #fff;
    background: var(--grad-primary);
    font-size: 1.1rem
}

.review__name {
    font-weight: 600;
    color: var(--ink);
    font-size: .95rem;
    line-height: 1.2
}

.review__meta {
    font-size: .82rem;
    color: #7a7590
}

.review__mark {
    position: absolute;
    top: 1rem;
    right: 1.4rem;
    font-family: var(--font-display);
    font-size: 3.4rem;
    color: var(--primary-soft);
    line-height: 1
}

/* =========================================================================
   9) CONTACT + ENVOI DE PHOTOS
   ========================================================================= */
.contact {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: clamp(1.3rem, 3vw, 2rem);
    max-width: var(--container);
    margin: 0 auto
}

.contact > .form,
.contact__aside {
    width: 100%;
    max-width: 680px
}

.form {
    background: #fff;
    border: 1px solid #ececf1;
    border-radius: var(--radius-lg);
    padding: clamp(1.4rem, 3vw, 2.2rem);
    box-shadow: 0 24px 60px -40px rgba(23, 12, 48, .4)
}

.form__row {
    display: grid;
    grid-template-columns:1fr 1fr;
    gap: 1rem
}

.field {
    margin-bottom: 1.1rem;
    display: flex;
    flex-direction: column;
    gap: .4rem
}

.field label {
    font-family: var(--font-body);
    font-weight: 600;
    font-size: .86rem;
    color: var(--ink)
}

.field input, .field textarea {
    font-family: var(--font-body);
    font-size: 1rem;
    color: var(--ink);
    padding: .8rem .95rem;
    border: 1.5px solid #e3e0ec;
    border-radius: 12px;
    background: #fbfafd;
    transition: border-color .2s, box-shadow .2s
}

.field textarea {
    resize: vertical;
    min-height: 120px
}

.field input:focus, .field textarea:focus {
    outline: none;
    border-color: var(--primary);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--primary) 18%, transparent)
}

/* zone d'upload photos */
.dropzone {
    position: relative;
    border: 2px dashed color-mix(in srgb, var(--primary) 35%, #d9d5e4);
    border-radius: 16px;
    background: var(--primary-soft);
    padding: 1.5rem;
    text-align: center;
    cursor: pointer;
    transition: border-color .2s, background .2s
}

.dropzone:hover, .dropzone.is-drag {
    border-color: var(--primary);
    background: color-mix(in srgb, var(--primary) 12%, #fff)
}

.dropzone input {
    position: absolute;
    inset: 0;
    opacity: 0;
    cursor: pointer
}

.dropzone__ico {
    width: 46px;
    height: 46px;
    border-radius: 50%;
    display: grid;
    place-items: center;
    margin: 0 auto .6rem;
    background: #fff;
    color: var(--primary);
    box-shadow: 0 6px 16px -8px color-mix(in srgb, var(--primary) 60%, transparent)
}

.dropzone__ico svg {
    width: 24px;
    height: 24px
}

.dropzone strong {
    color: var(--primary-deep)
}

.dropzone small {
    display: block;
    color: #7a7590;
    margin-top: .25rem;
    font-size: .82rem
}

.field__hint {
    margin-top: .6rem;
    font-size: .84rem;
    color: #c2410c
}

.field__hint[hidden] {
    display: none
}

.previews {
    display: grid;
    grid-template-columns:repeat(auto-fill, minmax(82px, 1fr));
    gap: .6rem;
    margin-top: 1rem
}

.preview {
    position: relative;
    aspect-ratio: 1;
    border-radius: 12px;
    overflow: hidden;
    border: 1px solid #e3e0ec;
    background: #f3f1f7
}

.preview img {
    width: 100%;
    height: 100%;
    object-fit: cover
}

.preview button {
    position: absolute;
    top: 4px;
    right: 4px;
    width: 22px;
    height: 22px;
    border-radius: 50%;
    background: rgba(10, 4, 24, .6);
    color: #fff;
    display: grid;
    place-items: center;
    font-size: 13px;
    line-height: 1
}

.preview button:hover {
    background: var(--primary)
}

.form__submit {
    display: flex;
    align-items: center;
    justify-content: flex-end;
    gap: 1rem;
    flex-wrap: wrap;
    margin-top: .4rem
}

.form__ok {
    display: none;
    align-items: center;
    gap: .5rem;
    color: #1f8a4c;
    font-weight: 600;
    font-size: .92rem
}

.form__ok.show {
    display: inline-flex
}

.form__ok svg {
    width: 18px;
    height: 18px
}

.contact__aside {
    display: flex;
    flex-direction: column;
    gap: 1rem
}

.contact__card {
    background: radial-gradient(120% 130% at 100% 0, color-mix(in srgb, var(--primary) 42%, transparent), transparent 62%), var(--ink);
    color: #fff;
    border-radius: var(--radius-lg);
    padding: clamp(1.4rem, 3vw, 1.9rem) clamp(1.4rem, 4vw, 2.4rem);
    position: relative;
    overflow: hidden;
    text-align: center;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1.1rem
}

.contact__card h3 {
    font-size: 1.35rem;
    position: relative
}

/* coordonnées alignées en ligne (la card passe en pleine largeur sous le formulaire) */
.contact__grid {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: .7rem 1.8rem;
    position: relative
}

.contact__line {
    display: inline-flex;
    align-items: center;
    gap: .55rem;
    position: relative;
    font-size: .95rem;
    color: rgba(255, 255, 255, .88);
    text-decoration: none;
    transition: color .2s
}

/* Au survol d'un lien de contact, la couleur d'equipe parcourt le texte de
   gauche a droite. Le degrade (accent a gauche, teinte de repos a droite) est
   plus large que le texte ; on le fait glisser en animant sa position, ce qui
   pousse la couleur a travers les lettres sans les redessiner. Les paliers
   (accent jusqu'a 45 %, repos a partir de 55 %) sont cales pour que la fenetre
   visible ne montre que du repos au demarrage et que de l'accent une fois
   survole : la transition ne se voit qu'en cours de balayage. Effet discret
   mais net, et qui suit l'equipe choisie via var(--accent). */
.contact__line-text {
    background-image: linear-gradient(
        90deg,
        var(--accent) 0,
        var(--accent) 45%,
        rgba(255, 255, 255, .88) 55%,
        rgba(255, 255, 255, .88) 100%
    );
    background-size: 240% 100%;
    background-position: 100% 0;
    background-repeat: no-repeat;
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    color: transparent;
    transition: background-position .6s var(--ease, ease)
}

a.contact__line:hover .contact__line-text {
    background-position: 0 0
}

a.contact__line:hover svg {
    color: var(--accent)
}

.contact__line svg {
    width: 18px;
    height: 18px;
    color: var(--accent);
    flex: 0 0 auto;
    transition: transform .25s var(--ease, ease)
}

a.contact__line:hover svg {
    transform: translateX(1px) scale(1.08)
}

/* Sans animation demandee : simple bascule vers la couleur d'equipe, sans
   balayage ni deplacement d'icone. */
@media (prefers-reduced-motion: reduce) {
    .contact__line-text {
        transition: none;
        background: none;
        -webkit-text-fill-color: currentColor;
        color: rgba(255, 255, 255, .88)
    }

    a.contact__line:hover .contact__line-text {
        color: var(--accent)
    }

    .contact__line svg,
    a.contact__line:hover svg {
        transition: none;
        transform: none
    }
}

.contact__socials {
    display: flex;
    justify-content: center;
    gap: .6rem;
    position: relative
}

.contact__socials a {
    width: 40px;
    height: 40px;
    border-radius: 50%;
    display: grid;
    place-items: center;
    background: rgba(255, 255, 255, .1);
    transition: background .2s
}

.contact__socials a:hover {
    background: var(--primary)
}

.contact__socials svg {
    width: 19px;
    height: 19px;
    color: #fff
}

.contact__map {
    flex: 1;
    border-radius: var(--radius-lg);
    overflow: hidden;
    min-height: 160px;
    background: linear-gradient(135deg, var(--primary-soft), #fff);
    border: 1px solid #ececf1;
    display: grid;
    place-items: center;
    color: #9a95ad;
    font-size: .9rem;
    text-align: center;
    padding: 1rem
}

/* =========================================================================
   10) BANDEAU CTA
   ========================================================================= */
.cta-band {
    max-width: var(--container);
    margin: 0 auto;
    border-radius: var(--radius-lg);
    padding: clamp(2.2rem, 5vw, 3.6rem);
    background: var(--grad-primary);
    color: #fff;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 2rem;
    flex-wrap: wrap;
    position: relative;
    overflow: hidden
}

.cta-band::after {
    content: "";
    position: absolute;
    right: -40px;
    top: -60px;
    width: 280px;
    height: 280px;
    border-radius: 50%;
    background: rgba(255, 255, 255, .12)
}

.cta-band h2 {
    font-size: clamp(1.8rem, 3.5vw, 2.7rem);
    position: relative;
    z-index: 2;
    max-width: 18ch
}

.cta-band p {
    position: relative;
    z-index: 2;
    opacity: .92;
    margin-top: .5rem
}

.cta-band .btn--white {
    position: relative;
    z-index: 2
}

/* =========================================================================
   11) PAGE PRESTATIONS · détails
   ========================================================================= */
/* Vue d'ensemble des 3 prestations (sert aussi de navigation par ancre) */
.presta-overview {
    display: grid;
    grid-template-columns:repeat(3, 1fr);
    gap: 1rem;
    max-width: var(--container);
    margin: 0 auto
}

.presta-overview__item {
    display: flex;
    align-items: center;
    gap: .85rem;
    padding: 1rem 1.1rem;
    background: #fff;
    border: 1px solid #e6e3ee;
    border-radius: var(--radius);
    color: inherit;
    text-decoration: none;
    transition: transform .25s var(--ease), box-shadow .3s, border-color .25s
}

.presta-overview__item:hover {
    transform: translateY(-3px);
    border-color: color-mix(in srgb, var(--primary) 35%, transparent);
    box-shadow: 0 18px 38px -24px rgba(23, 12, 48, .4)
}

.presta-overview__ico {
    width: 46px;
    height: 46px;
    flex: none;
    border-radius: 14px;
    display: grid;
    place-items: center;
    color: var(--primary-deep);
    background: var(--primary-soft)
}

.presta-overview__ico svg {
    width: 24px;
    height: 24px
}

.presta-overview__main {
    flex: 1;
    min-width: 0
}

.presta-overview__name {
    font-family: var(--font-display);
    font-size: 1.15rem;
    color: var(--ink);
    line-height: 1.1
}

.presta-overview__desc {
    font-size: .84rem;
    color: #5a5570;
    margin-top: .15rem
}

.presta-overview__arrow {
    flex: none;
    color: var(--primary);
    transition: transform .2s
}

.presta-overview__arrow svg {
    width: 20px;
    height: 20px
}

.presta-overview__item:hover .presta-overview__arrow {
    transform: translateX(3px)
}

/* En-tête d'une prestation : icône identifiante + descripteur distinct */
/* En-tete d'une prestation. Le texte du studio y est long : borne a 84 signes,
   il etirait la page sur plusieurs ecrans. Il prend toute la largeur. */
.presta-header {
    display: flex;
    align-items: flex-start;
    gap: 1.1rem;
    margin-bottom: 2.2rem
}

.presta-header__ico {
    width: 58px;
    height: 58px;
    flex: none;
    border-radius: 16px;
    display: grid;
    place-items: center;
    color: #fff;
    background: var(--grad-primary);
    box-shadow: 0 14px 30px -12px color-mix(in srgb, var(--primary) 60%, transparent)
}

.presta-header__ico svg {
    width: 30px;
    height: 30px
}

.presta-header__tag {
    display: block;
    font-family: var(--font-body);
    font-weight: 700;
    font-size: .74rem;
    letter-spacing: .16em;
    text-transform: uppercase;
    color: var(--primary);
    margin-bottom: .35rem
}

.presta-header h2 {
    font-size: clamp(1.9rem, 3.6vw, 2.6rem);
    color: var(--ink);
    line-height: 1.08;
    margin-bottom: .5rem
}

.presta-header h2 .u {
    background: linear-gradient(transparent 62%, color-mix(in srgb, var(--accent) 55%, transparent) 0)
}

.presta-header p {
    color: #453f5c;
    font-size: 1.05rem;
    line-height: 1.6
}

.presta {
    display: flex;
    flex-direction: column;
    gap: clamp(1.4rem, 3vw, 2.2rem);
    max-width: var(--container);
    margin: 0 auto
}

/* La colonne de texte est la plus chargee (presentations longues du studio) :
   elle prend environ 70 % de la rangee, l'image le reste. */
.presta-row {
    display: grid;
    grid-template-columns:.75fr 1.25fr;
    gap: clamp(1.4rem, 4vw, 3rem);
    align-items: stretch;
    background: #fff;
    border: 1px solid #ececf1;
    border-radius: var(--radius-lg);
    overflow: hidden
}

.presta-row:nth-child(even) {
    grid-template-columns:1.25fr .75fr
}

.presta-row:nth-child(even) .presta-row__media {
    order: 2
}

/* Le panneau epouse le format carre des photos et ne s'etire plus sur toute la
   hauteur de la rangee : etire, il rognait largement une image carree dans une
   colonne etroite et haute. « contain » garantit qu'aucun sujet n'est coupe,
   meme si une photo arrivait avec un autre format. */
/* Cadre au format carre des photos, centre dans la rangee : la photo le remplit
   exactement, donc ni rognage ni bande de remplissage, et l'espace restant se
   repartit egalement au-dessus et en dessous. */
.presta-row__media {
    position: relative;
    aspect-ratio: 1 / 1;
    align-self: center;
    overflow: hidden;
    /* Centre dans la rangee, le cadre ne rejoint plus les angles arrondis de la
       carte : ses coins cote texte sont arrondis a leur tour, le bord exterieur
       restant aligne sur celui de la carte. */
    border-radius: 0 var(--radius) var(--radius) 0
}

.presta-row--reverse .presta-row__media {
    border-radius: var(--radius) 0 0 var(--radius)
}

/* La photo entre par le bord exterieur de la carte quand la rangee apparait au
   defilement. Le cadre etant en overflow:hidden et colle a ce bord, l'image
   glisse depuis l'exterieur et se devoile en entrant. */
@media (prefers-reduced-motion: no-preference) {
    .presta-row.reveal .presta-row__media img {
        opacity: 0;
        transform: translateX(-102%);
        transition: transform .8s var(--ease) .1s, opacity .45s ease .1s
    }

    .presta-row--reverse.reveal .presta-row__media img {
        transform: translateX(102%)
    }

    .presta-row.reveal.in .presta-row__media img {
        opacity: 1;
        transform: none
    }
}

.presta-row__media img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover
}

/* Média du côté droit (différencie la section 3D de la section Socle) */
.presta-row--reverse {
    grid-template-columns:1.25fr .75fr
}

.presta-row--reverse .presta-row__media {
    order: 2
}

.presta-row__body {
    padding: clamp(1.4rem, 3vw, 2.4rem)
}

.presta-row__num {
    font-family: var(--font-display);
    font-size: .95rem;
    letter-spacing: .1em;
    color: var(--primary);
    text-transform: uppercase;
    margin-bottom: .4rem
}

.presta-row__body h3 {
    font-size: clamp(1.5rem, 3vw, 2rem);
    color: var(--ink);
    margin-bottom: .6rem
}

/* Pas de bornage a 52ch : la colonne de texte est deja dimensionnee par la
   grille de la rangee, le plafond ne faisait qu'y creuser une bande vide. */
.presta-row__body p {
    color: #4a4462;
    font-size: 1.05rem;
    line-height: 1.65;
    margin-bottom: 1rem
}

.presta-row__list {
    list-style: none;
    display: grid;
    grid-template-columns:1fr 1fr;
    gap: .5rem .9rem;
    margin-bottom: 1.2rem
}

.presta-row__list li {
    display: flex;
    gap: .55rem;
    align-items: flex-start;
    font-size: 1rem;
    color: #3f3a55
}

.presta-row__list svg {
    width: 18px;
    height: 18px;
    color: var(--primary);
    flex: 0 0 auto;
    margin-top: .18rem
}

.presta-row__price {
    display: inline-flex;
    align-items: center;
    gap: .5rem;
    font-family: var(--font-body);
    font-weight: 600;
    color: var(--primary-deep);
    background: var(--primary-soft);
    padding: .5rem 1rem;
    border-radius: 100px;
    font-size: .92rem;
    white-space: nowrap
}

.presta-row__price svg {
    width: 17px;
    height: 17px;
    flex: 0 0 auto
}

/* Peinture : échelle de niveaux ascendante (niveau + jauge de finition) */
.levels {
    display: grid;
    grid-template-columns:repeat(3, 1fr);
    gap: 1.4rem;
    align-items: stretch
}

.level {
    position: relative;
    display: flex;
    flex-direction: column;
    background: #fff;
    border: 1px solid #e6e3ee;
    border-radius: var(--radius-lg);
    overflow: hidden;
    transition: transform .3s var(--ease), box-shadow .3s, border-color .3s
}

.level:hover {
    transform: translateY(-5px);
    box-shadow: 0 26px 50px -30px rgba(23, 12, 48, .45);
    border-color: color-mix(in srgb, var(--primary) 30%, transparent)
}

/* Cadre 4/3 commun aux trois vignettes, quel que soit le format de la photo :
   les cartes restent alignees. */
.level__media {
    position: relative;
    aspect-ratio: 4 / 3;
    background: var(--grad-primary)
}




/* Position absolue : sans elle, « height:100% » ne se resout pas contre un
   parent dont la hauteur vient d'un aspect-ratio, et l'image imposait sa
   hauteur naturelle, desalignant les trois cartes. */
.level__media img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    /* La photo remplit le cadre : les bandes de remplissage d'un « contain »
       trahissaient l'ecart entre le fond du cliche et celui du cadre. Les
       sujets sont centres avec de la marge, le rognage ne les entame pas. */
    object-fit: cover
}

/* pastille de niveau : numéro + jauge de finition (pips remplis selon le niveau) */
.level__tier {
    position: absolute;
    left: .9rem;
    bottom: .9rem;
    display: inline-flex;
    align-items: center;
    gap: .45rem;
    padding: .3rem .8rem;
    background: rgba(255, 255, 255, .96);
    border-radius: 100px;
    box-shadow: 0 8px 20px -8px rgba(23, 12, 48, .38)
}

.level__num {
    width: 26px;
    height: 26px;
    flex: none;
    border-radius: 50%;
    display: grid;
    place-items: center;
    font-family: var(--font-display);
    font-size: 1rem;
    line-height: 1;
    color: #fff;
    background: var(--grad-primary)
}

.level__tier-label {
    font-family: var(--font-body);
    font-weight: 700;
    font-size: .74rem;
    letter-spacing: .05em;
    text-transform: uppercase;
    color: var(--primary-deep)
}

.level__meter {
    display: inline-flex;
    gap: 3px;
    margin-left: .05rem
}

.level__meter span {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: color-mix(in srgb, var(--primary) 20%, #fff);
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--primary) 30%, transparent)
}

.level__meter span.on {
    background: var(--primary);
    box-shadow: none
}

.level__body {
    display: flex;
    flex-direction: column;
    flex: 1;
    padding: 1.4rem 1.4rem 1.6rem
}

.level__body h3 {
    font-size: 1.4rem;
    color: var(--ink);
    margin-bottom: .45rem
}

.level__body > p {
    color: #453f5c;
    line-height: 1.6;
    margin-bottom: 1.1rem
}

/* micro-label "Ce qui est inclus", partagé avec les presta-rows.
   p.incl-label : spécificité suffisante pour l'emporter sur .level__body > p
   et .presta-row__body p (sinon la couleur accent est écrasée par le gris du corps). */
p.incl-label {
    font-family: var(--font-body);
    font-weight: 700;
    font-size: .72rem;
    letter-spacing: .12em;
    text-transform: uppercase;
    color: var(--primary);
    margin-bottom: .6rem;
    max-width: none
}

/* Mention "sur devis" sous la liste d'un niveau de peinture.
   p.incl-note pour la meme raison de specificite que p.incl-label. */
p.incl-note {
    margin: .7rem 0 0;
    font-size: .86rem;
    font-style: italic;
    line-height: 1.55;
    color: #6a6580;
    max-width: none
}

/* Texte d'introduction place sous le heros d'une page.
   Les paragraphes fournis par le studio font 120 a 250 mots : dans la colonne
   centree et etroite d'une tete de section, ils tombaient comme un bloc isole.
   Ils occupent donc toute la largeur, sur deux colonnes : la ligne reste a une
   longueur lisible (~60 signes) et le pave remplit enfin la page. */
.section--intro {
    padding-top: clamp(1.6rem, 3.5vw, 2.8rem);
    padding-bottom: 0
}

.intro__text {
    margin: 0;
    text-align: center;
    text-wrap: pretty;
    font-size: clamp(1rem, .96rem + .25vw, 1.1rem);
    line-height: 1.78;
    color: #4d4763
}

/* Post-scriptum du catalogue : en retrait sous le texte, jamais en colonnes. */
.intro__ps {
    margin: 1.6rem 0 0;
    padding-top: 1.1rem;
    border-top: 1px solid #ececf1;
    font-size: .9rem;
    line-height: 1.7;
    color: #6a6580
}

/* Accroches de section portant un paragraphe long : la tete de section est
   bornee a 62 signes, trop etroit pour ces textes. Le titre reste centre, le
   texte prend toute la largeur. */
.section__head--wide {
    max-width: none
}

.level .presta-row__list {
    grid-template-columns:1fr;
    gap: .42rem;
    margin-bottom: 1.3rem
}

.level .presta-row__price {
    margin-top: auto;
    align-self: flex-start
}

/* process */
.steps {
    display: grid;
    grid-template-columns:repeat(4, 1fr);
    gap: 1.2rem;
    counter-reset: step
}

.step {
    position: relative;
    background: #fff;
    border: 1px solid #ececf1;
    border-radius: var(--radius);
    padding: 1.6rem 1.3rem
}

.step__num {
    width: 46px;
    height: 46px;
    border-radius: 50%;
    display: grid;
    place-items: center;
    font-family: var(--font-display);
    font-size: 1.3rem;
    color: #fff;
    background: var(--grad-primary);
    margin-bottom: .9rem
}

.step h4 {
    font-size: 1.15rem;
    color: var(--ink);
    margin-bottom: .3rem
}

.step p {
    font-size: .92rem;
    color: #5a5570
}

/* faq */
.faq {
    max-width: 820px;
    margin: 0 auto;
    display: flex;
    flex-direction: column;
    gap: .7rem
}

.faq details {
    background: #fff;
    border: 1px solid #ececf1;
    border-radius: 14px;
    padding: .4rem .4rem;
    transition: border-color .2s
}

.faq details[open] {
    border-color: color-mix(in srgb, var(--primary) 35%, transparent)
}

.faq summary {
    list-style: none;
    cursor: pointer;
    padding: .9rem 1.1rem;
    font-family: var(--font-body);
    font-weight: 600;
    font-size: 1.02rem;
    color: var(--ink);
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 1rem
}

.faq summary::-webkit-details-marker {
    display: none
}

.faq summary .chev {
    width: 22px;
    height: 22px;
    color: var(--primary);
    transition: transform .25s;
    flex: 0 0 auto
}

.faq details[open] summary .chev {
    transform: rotate(180deg)
}

.faq p {
    padding: 0 1.1rem 1rem;
    color: #4a4462;
    line-height: 1.65
}

/* =========================================================================
   12) PAGE PARTENAIRES
   ========================================================================= */
.partners {
    display: grid;
    grid-template-columns:repeat(3, 1fr);
    gap: 1.3rem
}

.partner {
    background: #fff;
    border: 1px solid #ececf1;
    border-radius: var(--radius-lg);
    padding: 1.8rem;
    display: flex;
    flex-direction: column;
    gap: .8rem;
    transition: transform .25s var(--ease), box-shadow .3s, border-color .25s
}

/* Apparition en cascade au défilement (site.js), même logique que la galerie
   et le catalogue : masquées jusqu'à .is-revealing, fill « backwards » pour
   que le soulèvement au survol reste actif après l'animation. */
.partners--cascade .partner:not(.is-revealing) {
    opacity: 0
}

.partner.is-revealing {
    animation: productReveal .5s var(--ease) backwards
}

.partner:hover {
    transform: translateY(-6px);
    box-shadow: 0 24px 50px -24px rgba(23, 12, 48, .4);
    border-color: color-mix(in srgb, var(--primary) 35%, transparent)
}

.partner__logo {
    width: 100%;
    height: 165px;
    border-radius: 16px;
    background: var(--primary-soft);
    /* Centrage en flex et non en grid : sur un item de grille dont la piste est
       en « auto », le max-height: 100% de l'image ne se résolvait pas et valait
       none. Le logo s'affichait donc à sa taille intrinsèque, 240x240 pour
       88px de zone utile, et l'overflow: hidden en rognait 152px, en haut comme
       en bas. Cela touchait toutes les largeurs, le bureau compris. */
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
    /* Cadre plus haut et retrait reduit : le logo disposait de 88 px utiles sur
       une carte de 320, il s'y perdait. */
    padding: .85rem
}

.partner__logo img {
    max-width: 100%;
    max-height: 100%;
    object-fit: contain
}

.partner__logo .ph {
    font-family: var(--font-display);
    font-size: 1.6rem;
    color: var(--primary)
}

.partner h3 {
    font-size: 1.3rem;
    color: var(--ink)
}

.partner .role {
    font-size: .78rem;
    font-weight: 600;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--primary)
}

.partner p {
    color: #56506a;
    font-size: .95rem;
    flex: 1
}

/* Cibles tactiles : au doigt, le coeur des favoris (34 px) et le lien de
   presentation (24 px de haut) restent sous le seuil confortable. On elargit la
   zone sensible sans toucher a l'apparence, et seulement sur ecran tactile. */
@media (pointer: coarse) {
    .tile__like::after {
        content: "";
        position: absolute;
        inset: -8px
    }

    .partner__more {
        padding: .6rem 0
    }
}

/* Bouton d'ouverture de la presentation, en pied de carte. */
.partner__more {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    margin-top: auto;
    padding: 0;
    background: none;
    border: 0;
    font: inherit;
    font-weight: 600;
    font-size: .95rem;
    color: var(--primary);
    cursor: pointer;
    transition: gap .2s var(--ease), color .2s
}

.partner__more svg {
    width: 17px;
    height: 17px
}

.partner--openable {
    cursor: pointer
}

.partner--openable:hover .partner__more,
.partner__more:hover {
    gap: .7rem;
    color: var(--primary-deep)
}

.partner__more:focus-visible {
    outline: 2px solid var(--primary);
    outline-offset: 3px;
    border-radius: 6px
}

/* Panneau de lecture d'une presentation : meme dialogue natif que la selection,
   en plus large car il accueille plusieurs paragraphes. */
.partner-modal {
    border: none;
    padding: 0;
    margin: auto;
    width: min(92vw, 660px);
    border-radius: var(--radius-lg);
    box-shadow: 0 40px 90px -30px rgba(10, 4, 24, .5)
}

.partner-modal::backdrop {
    background: rgba(10, 4, 24, .55);
    bottom: auto;
    height: 100lvh
}

.partner-modal[open] {
    animation: cartIn .3s var(--ease)
}

.partner-modal__inner {
    display: flex;
    flex-direction: column;
    max-height: min(84vh, 700px);
    padding: clamp(1.3rem, 3vw, 1.9rem)
}

.partner-modal__head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: .8rem;
    margin-bottom: 1rem
}

.partner-modal__role {
    font-size: .78rem;
    font-weight: 600;
    letter-spacing: .08em;
    text-transform: uppercase;
    color: var(--primary);
    /* La marge passe au-dessus : le role suit desormais le titre. */
    margin: .35rem 0 0
}

.partner-modal__title {
    font-family: var(--font-display);
    font-weight: 500;
    font-size: clamp(1.5rem, 3vw, 1.9rem);
    color: var(--ink);
    margin: 0
}

.partner-modal__close {
    width: 38px;
    height: 38px;
    flex: none;
    border-radius: 50%;
    display: grid;
    place-items: center;
    background: var(--primary-soft);
    color: var(--primary-deep);
    border: 0;
    cursor: pointer;
    transition: background .2s, color .2s
}

.partner-modal__close:hover {
    background: var(--primary);
    color: #fff
}

.partner-modal__close svg {
    width: 18px;
    height: 18px
}

.partner-modal__body {
    flex: 1 1 auto;
    /* Sans min-height:0, un element flex garde min-height:auto et refuse de
       retrecir sous la hauteur de son contenu : un texte long repousserait le
       pied hors du cadre au lieu de faire defiler le corps. */
    min-height: 0;
    overflow-y: auto;
    color: #4a4560;
    font-size: 1rem;
    line-height: 1.72
}

.partner-modal__body p {
    margin: 0 0 1rem
}

.partner-modal__body p:last-child {
    margin-bottom: 0
}

.partner-modal__foot {
    flex: none;
    margin-top: 1.3rem;
    padding-top: 1.1rem;
    border-top: 1px solid #ececf1
}

/* Lien pose au fil d'un texte : souligne, sans icone, contrairement a .link
   qui est un lien d'action inline-flex avec sa fleche. */
.link-inline {
    color: var(--primary-deep);
    font-weight: 600;
    text-decoration: underline;
    text-underline-offset: 3px;
    text-decoration-thickness: 1px
}

.link-inline:hover {
    color: var(--primary);
    text-decoration-thickness: 2px
}

/* Lien texte + icône (flèche), composant partagé */
.link {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    color: var(--primary-deep);
    font-weight: 600;
    font-size: .92rem
}

.link svg {
    width: 16px;
    height: 16px;
    flex: none;
    transition: transform .2s
}

.link:hover svg {
    transform: translate(2px, -2px)
}

.partner a.link {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    color: var(--primary-deep);
    font-weight: 600;
    font-size: .92rem
}

.partner a.link svg {
    width: 16px;
    height: 16px;
    transition: transform .2s
}

.partner a.link:hover svg {
    transform: translate(2px, -2px)
}

/* =========================================================================
   12bis) PAGE PRODUITS
   ========================================================================= */
.product-layout {
    display: grid;
    grid-template-columns: 260px 1fr;
    gap: 2rem;
    align-items: start
}

/* Colonne de filtres collante sous le header (69px) avec une marge de 15px.
   Si elle dépasse la hauteur dispo, elle défile en interne ; pas de
   overscroll-behavior:contain pour que le scroll enchaîne sur la page une
   fois arrivé en bout (le bas des filtres reste toujours atteignable). */
.product-sidebar {
    position: sticky;
    top: 100px;
    align-self: start;
    max-height: calc(100vh - 116px);
    overflow-y: auto;
    padding-right: .5rem;
    scrollbar-width: thin;
    scrollbar-gutter: stable
}

.product-cat__subs {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: .4rem;
    padding: 0 1.1rem 1rem
}

.product-note {
    color: #7a7590;
    font-size: .9rem;
    margin-bottom: 1.2rem
}

.product-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 1.2rem
}

.product-card {
    position: relative;
    display: flex;
    flex-direction: column;
    background: #fff;
    border: 1px solid #ececf1;
    border-radius: var(--radius-lg);
    overflow: hidden;
    cursor: pointer;
    transition: transform .25s var(--ease), box-shadow .3s, border-color .25s
}

/* Carte produit entièrement cliquable (même logique que les Hauts Faits) :
   le lien « Voir la fiche » n'apparaît qu'au survol et son pseudo-élément
   étendu rend toute la carte cliquable vers la fiche. */
.product-card .link {
    opacity: 0;
    transform: translateY(4px);
    transition: opacity .22s var(--ease), transform .22s var(--ease)
}

.product-card .link::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 1
}

.product-card:hover .link,
.product-card:focus-within .link {
    opacity: 1;
    transform: none
}

/* Écrans tactiles (sans survol) : les liens révélés au survol des cartes
   (Hauts Faits, catalogue) resteraient invisibles ; on les affiche d'office
   pour que l'appel à l'action soit visible sur mobile et tablette. */
@media (hover: none) {
    /* Sur tactile, pas de survol : les éléments révélés au hover restent visibles.
       Le cœur de like doit toujours être accessible en galerie (mobile/tablette). */
    .card__link,
    .product-card .link,
    .tile__like {
        opacity: 1;
        transform: none
    }
}

.product-card.is-hidden {
    display: none
}

/* Apparition en cascade au défilement (site.js) : les cartes sont masquées
   jusqu'à ce qu'elles reçoivent .is-revealing (délai croissant). Le fill
   « backwards » n'affecte que la période de délai : après l'animation la carte
   reprend ses valeurs de base (donc le soulèvement au survol reste actif). */
.product-grid--cascade .product-card:not(.is-revealing) {
    opacity: 0
}

@keyframes productReveal {
    from {
        opacity: 0;
        transform: translateY(14px)
    }
    to {
        opacity: 1;
        transform: none
    }
}

.product-card.is-revealing {
    animation: productReveal .5s var(--ease) backwards
}

.product-card:hover {
    transform: translateY(-6px);
    box-shadow: 0 24px 50px -24px rgba(23, 12, 48, .4);
    border-color: color-mix(in srgb, var(--primary) 35%, transparent)
}

/* Les visuels fournis vont du carre (720x720, soixante-dix sur quatre-vingt-
   quinze) au portrait etroit (267x613) : la hauteur du cadre suivait celle de
   la photo et les cartes d'une meme rangee se decalaient d'autant. Le format
   pose ici ne s'appliquait pas, la hauteur en pourcentage de l'image rendant
   celle du cadre indefinie ; l'image est donc detachee du flux plus bas, et le
   carre tient en toute circonstance. */
.product-card__media {
    position: relative;
    aspect-ratio: 1 / 1;
    overflow: hidden;
    /* Safari sur iOS ne rogne pas un calque filtre au border-radius d'un
       ancetre : le fond floute ci-dessous debordait donc les coins arrondis de
       la carte, et le visuel s'affichait dans un rectangle. Le cadre porte donc
       son propre arrondi haut, au lieu de compter sur le rognage de la carte.
       Moins l'epaisseur de sa bordure, sans quoi un liseré reste visible. */
    border-radius: calc(var(--radius-lg) - 1px) calc(var(--radius-lg) - 1px) 0 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: .4rem;
    background: var(--primary-soft);
    color: var(--primary)
}

/* Les photos non carrees laissent deux bandes. Une teinte fixe ne peut pas
   leur convenir : les fonds incrustes vont du charbon au blanc casse. La
   bande reprend donc la photo elle-meme, agrandie et floutee, et prend sa
   couleur quelle qu'elle soit. */
.product-card__media::before {
    content: "";
    position: absolute;
    inset: -14%;
    background-image: var(--visuel, none);
    background-position: center;
    background-size: cover;
    filter: blur(26px) saturate(.65);
    opacity: .5
}

.product-card__media svg {
    width: 34%;
    height: 34%
}

.product-card__media span {
    font-size: .78rem;
    color: #9a95ad
}

.product-card__media img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: contain
}

.product-card__body {
    padding: 1.3rem;
    display: flex;
    flex-direction: column;
    flex: 1
}

.product-card__tag {
    font-family: var(--font-body);
    font-size: .72rem;
    font-weight: 600;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--primary);
    margin-bottom: .4rem
}

.product-card__body h3 {
    font-size: 1.18rem;
    color: var(--ink);
    margin-bottom: .35rem
}

.product-card__body p {
    color: #56506a;
    font-size: .92rem;
    flex: 1
}

.product-card__foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .6rem;
    flex-wrap: wrap;
    margin-top: 1.1rem
}

.product-card__price {
    font-family: var(--font-body);
    font-weight: 600;
    color: var(--primary-deep);
    font-size: .9rem
}

.product-card__add {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    font-family: var(--font-body);
    font-weight: 600;
    font-size: .84rem;
    padding: .55rem 1rem;
    border-radius: 100px;
    background: var(--primary-soft);
    color: var(--primary-deep);
    transition: background .2s, color .2s
}

.product-card__add svg {
    width: 15px;
    height: 15px
}

.product-card__add:hover {
    background: var(--grad-primary);
    color: #fff
}

.product-card__add.is-added {
    background: var(--grad-primary);
    color: #fff
}

/* panier de sélection : bouton flottant + modale */
.cart-fab {
    position: fixed;
    right: clamp(1rem, 3vw, 2rem);
    bottom: clamp(1rem, 3vw, 2rem);
    z-index: 90;
    width: 62px;
    height: 62px;
    border-radius: 50%;
    display: grid;
    place-items: center;
    background: var(--grad-primary);
    color: #fff;
    box-shadow: 0 12px 30px -10px color-mix(in srgb, var(--primary) 70%, transparent);
    transition: transform .2s var(--ease), box-shadow .25s
}

/* A l'arrivee sur une page, le bouton recouvrait un appel a l'action du heros,
   « Voir nos realisations » sur l'accueil. Il ne se montre donc qu'une fois le
   premier ecran depasse, et se retire quand on y revient. La classe est posee
   par le script, avec une marge entre les deux seuils pour qu'il ne clignote
   pas a la frontiere. */
.cart-fab {
    opacity: 0;
    visibility: hidden;
    transform: translateY(14px) scale(.85);
    transition: transform .28s var(--ease), opacity .22s var(--ease), visibility .22s, box-shadow .25s
}

.cart-fab.is-visible {
    opacity: 1;
    visibility: visible;
    transform: none
}

.cart-fab.is-visible:hover {
    transform: translateY(-2px);
    box-shadow: 0 18px 38px -10px color-mix(in srgb, var(--primary) 75%, transparent)
}

.cart-fab[hidden] {
    display: none
}

.cart-fab svg {
    width: 26px;
    height: 26px
}

.cart-fab__badge[hidden] {
    display: none
}

.cart-fab__badge {
    position: absolute;
    top: -4px;
    right: -4px;
    min-width: 24px;
    height: 24px;
    padding: 0 .35rem;
    border-radius: 100px;
    display: grid;
    place-items: center;
    background: #fff;
    color: var(--primary-deep);
    font-family: var(--font-body);
    font-size: .78rem;
    font-weight: 700;
    box-shadow: 0 4px 12px -4px rgba(23, 12, 48, .35)
}

.cart-fab.pop {
    animation: cartPop .4s var(--ease)
}

@keyframes cartPop {
    0% {
        transform: scale(1)
    }
    40% {
        transform: scale(1.14)
    }
    100% {
        transform: scale(1)
    }
}

.cart-modal {
    border: none;
    padding: 0;
    margin: auto;
    width: min(92vw, 500px);
    border-radius: var(--radius-lg);
    box-shadow: 0 40px 90px -30px rgba(10, 4, 24, .5)
}

.cart-modal::backdrop {
    background: rgba(10, 4, 24, .55);
    bottom: auto;
    height: 100lvh
}

.cart-modal[open] {
    animation: cartIn .3s var(--ease)
}

@keyframes cartIn {
    from {
        opacity: 0;
        transform: translateY(14px)
    }
}

.cart-modal__inner {
    display: flex;
    flex-direction: column;
    max-height: min(80vh, 640px);
    padding: clamp(1.3rem, 3vw, 1.8rem)
}

.cart-modal__head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .8rem;
    margin-bottom: .3rem
}

.cart-modal__title {
    font-family: var(--font-display);
    font-weight: 500;
    font-size: 1.7rem;
    color: var(--ink)
}

.cart-modal__close {
    width: 38px;
    height: 38px;
    flex: none;
    border-radius: 50%;
    display: grid;
    place-items: center;
    background: var(--primary-soft);
    color: var(--primary-deep);
    transition: background .2s, color .2s
}

.cart-modal__close:hover {
    background: var(--primary);
    color: #fff
}

.cart-modal__close svg {
    width: 18px;
    height: 18px
}

.cart-modal__hint {
    font-size: .86rem;
    color: #6a6580;
    margin-bottom: 1rem
}

.cart-list {
    list-style: none;
    flex: 1;
    overflow-y: auto;
    overscroll-behavior: contain;
    display: flex;
    flex-direction: column;
    gap: .6rem;
    padding: .2rem 0;
    margin: 0
}

.cart-item {
    display: flex;
    align-items: center;
    gap: .8rem;
    border: 1px solid #ececf1;
    border-radius: 18px;
    padding: .55rem .7rem;
    transition: border-color .2s, background .2s
}

.cart-item:has(a.cart-item__link:hover) {
    border-color: color-mix(in srgb, var(--primary) 35%, transparent);
    background: color-mix(in srgb, var(--primary-soft) 45%, #fff)
}

.cart-item__link {
    display: flex;
    align-items: center;
    gap: .8rem;
    flex: 1;
    min-width: 0;
    color: inherit;
    text-decoration: none;
    border-radius: 12px
}

.cart-item__link:focus-visible {
    outline: 2px solid var(--primary);
    outline-offset: 3px
}

a.cart-item__link:hover .cart-item__name {
    text-decoration: underline;
    text-underline-offset: 2px
}

.cart-item__thumb {
    width: 54px;
    height: 54px;
    flex: none;
    border-radius: 12px;
    object-fit: cover;
    background: var(--primary-soft)
}

.cart-item__thumb--ph {
    display: grid;
    place-items: center;
    color: var(--primary)
}

.cart-item__thumb--ph svg {
    width: 24px;
    height: 24px
}

.cart-item__main {
    flex: 1;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: .1rem
}

.cart-item__name {
    font-weight: 600;
    font-size: .95rem;
    color: var(--ink)
}

.cart-item__count {
    color: var(--primary);
    font-weight: 700
}

.cart-item__price {
    font-size: .84rem;
    color: #6a6580
}

.cart-item__remove {
    width: 26px;
    height: 26px;
    flex: none;
    border-radius: 50%;
    display: grid;
    place-items: center;
    background: var(--primary-soft);
    color: var(--primary-deep);
    font-size: 1rem;
    line-height: 1;
    transition: background .15s, color .15s
}

.cart-item__remove:hover {
    background: var(--primary);
    color: #fff
}

.cart-modal__empty {
    text-align: center;
    color: #6a6580;
    padding: 1.4rem 0 1.8rem
}

.cart-modal__foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .8rem;
    flex-wrap: wrap;
    padding-top: 1.1rem;
    margin-top: .4rem;
    border-top: 1px solid #ececf1
}

.cart-modal__foot[hidden] {
    display: none
}

.cart-modal__clear {
    font-family: var(--font-body);
    font-weight: 600;
    font-size: .88rem;
    color: #6a6580;
    text-decoration: underline;
    text-underline-offset: 2px;
    cursor: pointer
}

.cart-modal__clear:hover {
    color: var(--primary)
}

@media (prefers-reduced-motion: reduce) {
    .cart-fab.pop, .cart-modal[open] {
        animation: none
    }

    .cart-fab {
        transition: none
    }
}

@media (max-width: 980px) {
    .product-layout {
        grid-template-columns: 1fr
    }

    .product-sidebar {
        position: static
    }

    .product-grid {
        grid-template-columns: repeat(2, 1fr)
    }
}

/* mobile : 2 colonnes compactes pour raccourcir la page catalogue */
@media (max-width: 520px) {
    .product-grid {
        grid-template-columns: repeat(2, 1fr);
        gap: .7rem
    }

    .product-card__body {
        padding: .8rem .75rem .85rem
    }

    .product-card__tag {
        font-size: .62rem;
        margin-bottom: .25rem
    }

    .product-card__body h3 {
        font-size: .95rem;
        margin-bottom: .2rem
    }

    .product-card__meta {
        font-size: .74rem
    }

    .product-card .link {
        font-size: .78rem
    }

    .product-card__foot {
        margin-top: .6rem;
        gap: .4rem
    }

    .product-card__price {
        font-size: .8rem
    }

    /* Ce bouton ne vit plus que sur la fiche produit : le commit c6566de l'a
       retiré des cartes du catalogue, or c'est pour elles que le libellé était
       masqué ici. Sur la fiche c'est l'action principale, donc il garde son
       texte et une cible tactile de 44px au lieu de se réduire à un « + » nu
       de 33x31. */
    .product-card__add {
        padding: .6rem 1.1rem;
        font-size: .84rem;
        min-height: 44px
    }
}

/* =========================================================================
   12ter) PAGES LÉGALES
   ========================================================================= */
.legal {
    max-width: 760px;
    margin: 0 auto
}

.legal h2 {
    font-size: 1.3rem;
    color: var(--ink);
    margin: 2.2rem 0 .7rem
}

.legal h2:first-child {
    margin-top: 0
}

.legal p, .legal li {
    color: #46415c;
    font-size: .98rem;
    margin-bottom: .8rem
}

.legal ul {
    padding-left: 1.2rem
}

.legal a {
    color: var(--primary-deep);
    font-weight: 600;
    text-decoration: underline;
    text-underline-offset: 2px
}

/* =========================================================================
   13) FOOTER
   ========================================================================= */
.footer {
    background: var(--footer-bg, var(--ink));
    color: rgba(255, 255, 255, .72);
    padding: 1.9rem clamp(1rem, 4vw, 2.4rem);
    margin-top: clamp(3rem, 6vw, 5rem)
}

/* footer sur une bande fine : liens légaux (2 lignes, à gauche) ·
   réseaux (centre) · crédit (2 lignes, à droite).
   Grille 1fr auto 1fr : réseaux parfaitement centrés, liens et crédit
   ancrés aux deux bords pour un rendu symétrique. */
.footer__bar {
    max-width: var(--container);
    margin: 0 auto;
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    align-items: center;
    gap: .7rem 2rem;
    font-size: .84rem
}

/* les 2 réseaux côte à côte, centrés */
.footer__brandcol {
    justify-self: center;
    display: flex;
    align-items: center;
    gap: .55rem
}

.footer__legal {
    justify-self: start
}

.footer__credit {
    justify-self: end;
    text-align: right
}

@media (max-width: 820px) {
    .footer__bar {
        grid-template-columns: 1fr;
        justify-items: center;
        text-align: center;
        gap: .9rem 1.4rem
    }

    .footer__brandcol,
    .footer__legal,
    .footer__credit {
        justify-self: center;
        text-align: center
    }

    .footer__bar .footer__legal {
        align-items: center
    }
}

.footer__brand {
    display: inline-flex;
    flex: none
}

.footer__credit {
    color: rgba(255, 255, 255, .55)
}

.footer__credit-link {
    color: rgba(255, 255, 255, .8);
    text-underline-offset: 2px;
    text-decoration-color: rgba(255, 255, 255, .35);
    transition: color .2s, text-decoration-color .2s
}

.footer__credit-link:hover {
    color: #fff;
    text-decoration-color: #fff
}


.footer__logo {
    height: 46px;
    width: auto;
    display: block
}

.footer__soc {
    display: flex;
    gap: .5rem
}

.footer__soc a {
    width: 34px;
    height: 34px;
    border-radius: 50%;
    display: grid;
    place-items: center;
    background: rgba(255, 255, 255, .08);
    transition: background .2s
}

.footer__soc a:hover {
    background: var(--primary)
}

.footer__soc svg {
    width: 16px;
    height: 16px;
    color: #fff
}

/* liens légaux empilés sur 2 lignes */
.footer__legal {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: .5rem
}

.footer__legal a {
    color: rgba(255, 255, 255, .7);
    transition: color .2s
}

.footer__legal a:hover {
    color: #fff
}

/* =========================================================================
   Animations
   ========================================================================= */
@keyframes wipeL {
    from {
        transform: translateX(-100%);
        opacity: 0
    }
    to {
        transform: translateX(0);
        opacity: 1
    }
}

@keyframes wipeR {
    from {
        transform: translateX(100%);
        opacity: 0
    }
    to {
        transform: translateX(0);
        opacity: 1
    }
}

@keyframes dropIn {
    from {
        opacity: 0;
        transform: translateY(-16px)
    }
    to {
        opacity: 1;
        transform: translateY(0)
    }
}

@keyframes vsPop {
    0% {
        opacity: 0;
        transform: translate(-50%, -50%) scale(.3) rotate(-30deg)
    }
    60% {
        transform: translate(-50%, -50%) scale(1.15) rotate(6deg)
    }
    100% {
        opacity: 1;
        transform: translate(-50%, -50%) scale(1) rotate(0)
    }
}

@keyframes seamPulse {
    0%, 100% {
        opacity: .8
    }
    50% {
        opacity: 1
    }
}

@keyframes bob {
    0%, 100% {
        transform: translateY(0)
    }
    50% {
        transform: translateY(-10px)
    }
}

@keyframes floaty {
    0%, 100% {
        transform: translateY(0) scale(1)
    }
    50% {
        transform: translateY(-22px) scale(1.12)
    }
}

@keyframes siteIn {
    from {
        opacity: 0;
        transform: translateY(10px)
    }
    to {
        opacity: 1;
        transform: translateY(0)
    }
}

@keyframes spin {
    to {
        transform: rotate(360deg)
    }
}

@keyframes riseIn {
    from {
        opacity: 0;
        transform: translateY(18px)
    }
    to {
        opacity: 1;
        transform: translateY(0)
    }
}

@keyframes swapPop {
    0% {
        opacity: 0;
        transform: scale(.8) rotate(-6deg)
    }
    55% {
        opacity: 1;
        transform: scale(1.07) rotate(2deg)
    }
    100% {
        opacity: 1;
        transform: scale(1) rotate(0)
    }
}

.hero.is-theming .hero__eyebrow {
    animation: riseIn .55s var(--ease) .04s both
}

.hero.is-theming h1 {
    animation: riseIn .55s var(--ease) .10s both
}

.hero.is-theming .hero__lead {
    animation: riseIn .55s var(--ease) .16s both
}

.hero.is-theming .hero__cta {
    animation: riseIn .55s var(--ease) .22s both
}

.hero.is-theming .hero__stats {
    animation: riseIn .55s var(--ease) .28s both
}

.hero__mascot.is-swapping img {
    animation: swapPop .6s var(--ease) both
}

/* révélation au scroll */
.reveal {
    opacity: 0;
    transform: translateY(26px);
    transition: opacity .7s var(--ease), transform .7s var(--ease)
}

.reveal.in {
    opacity: 1;
    transform: none
}

/* =========================================================================
   Responsive
   ========================================================================= */
@media (max-width: 980px) {
    .about__grid {
        grid-template-columns:1fr;
        text-align: center
    }

    .about p {
        margin-inline: auto
    }

    .about__media {
        order: -1
    }

    .contact {
        grid-template-columns:1fr
    }

    .reviews {
        grid-template-columns:1fr 1fr
    }

    .partners {
        grid-template-columns:1fr 1fr
    }

    .steps {
        grid-template-columns:1fr 1fr
    }

    .presta-row, .presta-row:nth-child(even) {
        grid-template-columns:1fr
    }

    .presta-row:nth-child(even) .presta-row__media, .presta-row--reverse .presta-row__media {
        order: 0
    }

    /* Empilee, l'image coiffe la carte sur toute sa largeur. Aucun arrondi
       propre : la carte etant en overflow:hidden, elle arrondit d'elle-meme les
       deux angles du haut et laisse le bas droit, la ou l'image se poursuit dans
       le texte. Format 4/3 comme les vignettes de niveau, plutot que le carre
       qui occupait tout un ecran de haut. */
    .presta-row__media,
    .presta-row--reverse .presta-row__media {
        min-height: 0;
        width: auto;
        max-width: none;
        margin: 0;
        aspect-ratio: 4 / 3;
        border-radius: 0
    }

    .presta-row__media img {
        object-fit: cover
    }

    /* Coiffant la carte, l'image se devoile par le haut et non plus par le cote.
       Sous la meme garde que sur grand ecran : sans elle, un visiteur ayant
       demande a limiter les animations verrait l'image decalee hors cadre, le
       fondu qui l'accompagne ne s'appliquant pas. */
    @media (prefers-reduced-motion: no-preference) {
        .presta-row.reveal .presta-row__media img,
        .presta-row--reverse.reveal .presta-row__media img {
            transform: translateY(-102%)
        }

        .presta-row.reveal.in .presta-row__media img {
            transform: none
        }
    }

    .levels {
        grid-template-columns:1fr
    }

    .presta-overview {
        grid-template-columns:1fr
    }
}

@media (max-width: 880px) {
    /* sélecteur empilé */
    .selector {
        flex-direction: column
    }

    /* Le titre quitte son calque flottant et prend sa place en haut, au-dessus
       des deux cartes. Superposé, il ne recouvrait que la carte du haut : celle
       du bas n'en portait rien, et c'est ce déséquilibre qui se voyait. */
    .selector__head {
        position: static;
        flex: 0 0 auto;
        padding: clamp(18px, 3.4vh, 34px) 16px clamp(8px, 1.6vh, 18px)
    }

    /* Titre resserré : en flux il ajoute sa hauteur à celle des cartes, alors
       qu'en superposition il ne coûtait rien. */
    .selector__title {
        margin: .3em 0 0
    }

    /* Les deux cartes se partagent à égalité ce qui reste sous le titre, au
       lieu de réclamer 50% chacune de toute la hauteur. */
    .side {
        flex: 1 1 0;
        min-height: 0
    }

    .selector:has(.side--dragon .side__btn:hover) .side--dragon, .selector:has(.side--poulpe .side__btn:hover) .side--poulpe {
        flex-grow: 1.25
    }

    .selector:has(.side--dragon .side__btn:hover) .side--poulpe, .selector:has(.side--poulpe .side__btn:hover) .side--dragon {
        flex-grow: .85
    }

    .divider {
        width: auto
    }

    .seam {
        top: 50%;
        left: -2%;
        right: -2%;
        bottom: auto;
        width: auto;
        height: 5px;
        transform: translateY(-50%) skewY(-4deg);
        background: linear-gradient(90deg, transparent, var(--gold) 12%, #fff 50%, var(--gold) 88%, transparent)
    }

    .bolt {
        display: none
    }

    .mascot {
        width: clamp(120px, 19vh, 190px);
        /* La marge haute de 80px du cas général dégageait le titre au-dessus de
           la pile verticale : en vis-à-vis elle désalignerait la mascotte du
           hashtag. Le couple se centre maintenant de lui-même dans la bande. */
        margin: 0 !important;
        /* Filet de sécurité : sur un écran très étroit et très haut, la mascotte
           cède de la place au hashtag plutôt que de faire déborder la rangée. */
        min-width: 0;
        flex: 0 1 auto
    }

    .player-tag {
        display: none
    }

    .selector__kicker {
        letter-spacing: .22em
    }

    /* Logo et hashtag en vis-à-vis. Empilés, ils déséquilibraient la bande :
       large et courte, elle laissait 143px de vide au-dessus de la mascotte
       contre 63px sous le nom, et le hashtag du camp du bas frôlait le bord de
       l'écran. En rangée, le couple se lit comme un bloc unique et se centre. */
    .side__btn {
        flex-direction: row;
        gap: clamp(.5rem, 3.2vw, 1.1rem);
        padding: 5vh 6vw
    }

    /* Camp du bas inversé : les deux cartes se répondent en miroir de part et
       d'autre de la couture, mascottes en diagonale. L'ordre du DOM ne change
       pas ; la lecture par un lecteur d'écran non plus, l'aria-label du bouton
       portant l'intitulé. */
    .side--poulpe .side__btn {
        flex-direction: row-reverse
    }

    /* Le hashtag ne cède jamais : c'est la mascotte qui rend de la place. Sans
       ce flex-shrink à 0, la boîte du nom passait sous la largeur de son texte
       et « #Diunizel » débordait de 16px sur un écran étroit et haut. */
    .team-name {
        flex: 0 0 auto
    }

    .hero__grid {
        grid-template-columns:1fr;
        text-align: center
    }

    .hero__eyebrow, .hero__cta {
        justify-content: center
    }

    .hero__lead {
        margin-inline: auto
    }

    .hero__stats {
        justify-content: center
    }

    .hero__art {
        order: -1;
        min-height: 240px;
        /* Le hero passe en colonne unique dès 880px, mais le plafond de la
           mascotte n'existait que sous 520px : entre les deux elle prenait 82%
           de toute la largeur, soit 579px à 768px de large (57% de la hauteur
           d'écran), et les CTA du hero tombaient sous la ligne de flottaison en
           tablette portrait. Largeur explicite obligatoire : le disque à 86% et
           la mascotte à 82% en dépendent, et l'item de grille en margin auto
           s'effondrerait à 0 sans elle. */
        width: clamp(236px, 46vw, 320px);
        max-width: 100%;
        margin-inline: auto
    }

    .cards {
        grid-template-columns:1fr
    }

    .gallery {
        grid-template-columns:repeat(2, 1fr)
    }

    .reviews {
        grid-template-columns:1fr
    }

    .about__values {
        grid-template-columns:1fr
    }

    .form__row {
        grid-template-columns:1fr
    }
}

@media (max-width: 520px) {
    .gallery {
        grid-template-columns:repeat(2, 1fr)
    }

    /* Bandeau CTA empilé : le bouton passe seul sur sa ligne et restait collé à
       gauche, à 25 ou 40px du centre de l'encadré selon la page. Les marges
       automatiques absorbent l'espace libre de part et d'autre, donc le bouton
       se centre sur sa ligne sans que le texte au-dessus perde son alignement à
       gauche. Vaut pour les cinq bandeaux du site, qui partagent cette classe. */
    .cta-band .btn {
        margin-inline: auto
    }

    /* les cards partenaires restent sur 2 colonnes jusqu'au vrai mobile */
    .partners {
        grid-template-columns:1fr
    }

    /* Carte partenaire en vis-à-vis : logo carré à gauche, texte à droite.
       Empilée, la boîte du logo faisait 283 x 120 pour un logo carré de 88px,
       soit deux tiers de fond rose vide, et la carte montait à 283px de haut
       pour 66px de texte. Le logo étant carré et le texte court, la rangée les
       met à leur échelle et divise la hauteur par deux. */
    .partner {
        display: grid;
        grid-template-columns: auto 1fr;
        align-items: center;
        column-gap: 1rem;
        row-gap: .12rem;
        padding: 1.1rem
    }

    /* Le logo occupe toute la hauteur de la colonne de texte, quel que soit le
       nombre de lignes réellement présentes (le rôle et le lien sont facultatifs
       en base). */
    .partner__logo {
        grid-column: 1;
        grid-row: 1 / -1;
        align-self: center;
        /* Cadre au format des logos, larges et bas, plutot que carre : carre, il
           laissait le logo a 102 px de large pour beaucoup de vide au-dessus et
           en dessous. Largeur calee sur celle de la colonne, que le lien
           « Lire la presentation » occupe deja. */
        width: 152px;
        height: 96px;
        border-radius: 14px;
        padding: .45rem
    }

    .partner .role,
    .partner h3,
    .partner p,
    .partner a.link {
        grid-column: 2
    }

    /* Titre resserré : en rangée il n'a plus toute la largeur de la carte. */
    .partner h3 {
        font-size: 1.15rem;
        line-height: 1.2
    }

    .steps {
        grid-template-columns:1fr
    }

    .hero__stats {
        gap: 1.2rem
    }

    .presta-row__list {
        grid-template-columns:1fr
    }

    .about__photo {
        position: relative;
        right: auto;
        bottom: auto;
        width: 60%;
        margin: 1rem auto 0
    }
}

@media (prefers-reduced-motion: reduce) {
    * {
        animation-duration: .001ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .05ms !important
    }

    html {
        scroll-behavior: auto
    }

    .reveal {
        opacity: 1;
        transform: none
    }
}

/* =========================================================================
   Transition douce des couleurs sur TOUTE la page lors d'un changement
   d'équipe (classe .theming posée brièvement par le JS). Hors hero, ça
   évite l'effet "on/off". Respecte prefers-reduced-motion.
   ========================================================================= */
@media (prefers-reduced-motion: no-preference) {
    :root.theming, :root.theming * {
        transition: color .5s var(--ease), background-color .5s var(--ease),
        border-color .5s var(--ease), fill .5s var(--ease), stroke .5s var(--ease),
        box-shadow .5s var(--ease), opacity .5s var(--ease),
        left .42s var(--ease), transform .42s var(--ease) !important;
    }
}

/* =========================================================================
   Salons · cards façon affiches
   ========================================================================= */
.salons {
    grid-template-columns: repeat(auto-fill, minmax(212px, 1fr));
    gap: 1.4rem;
}

.salon {
    display: flex;
    flex-direction: column;
    background: #fff;
    border: 1px solid #ececf1;
    border-radius: var(--radius-lg);
    overflow: hidden;
    /* Pas de retrait : l'affiche va d'un bord a l'autre et prend directement
       les angles arrondis de la carte, au lieu de flotter dans un encadrement
       blanc. Le retrait vient de la regle generique .salon, plus haut, dont la
       carte « a venir » n'a pas besoin non plus (son contenu a le sien). */
    padding: 0;
    box-shadow: 0 16px 36px -24px rgba(23, 12, 48, .42);
    transition: transform .35s var(--ease), box-shadow .35s var(--ease);
}

/* L'affiche remplissant la carte, la bordure laisserait un liseré blanc d'un
   pixel tout autour : elle est retiree, pas seulement rendue transparente. */
.salon:not(.salon--soon) {
    border: 0
}

.salon:hover {
    transform: translateY(-6px);
    box-shadow: 0 30px 56px -26px rgba(23, 12, 48, .5);
}

/* Format A4, celui des affiches de salon : l'affiche remplit le cadre sans
   bande laterale. « contain » reste la garantie qu'une affiche d'un autre
   format serait montree en entier plutot que rognee. */
.salon__poster {
    position: relative;
    aspect-ratio: 1 / 1.414;
    overflow: hidden;
    background: #efedf4;
}

.salon__poster img {
    width: 100%;
    height: 100%;
    object-fit: contain;
    display: block;
    transition: transform .55s var(--ease);
}

.salon:hover .salon__poster img {
    transform: scale(1.05);
}

.salon__info {
    padding: .85rem 1rem 1.05rem;
    display: flex;
    flex-direction: column;
    gap: .12rem;
}

.salon__when {
    font-family: var(--font-body);
    font-weight: 600;
    font-size: .8rem;
    color: var(--primary);
}

.salon__name {
    font-size: 1.18rem;
    color: var(--ink);
}

.salon__loc {
    display: flex;
    align-items: center;
    gap: .32rem;
    font-size: .86rem;
    color: #6a6580;
    margin-top: .1rem;
}

.salon__loc svg {
    width: 14px;
    height: 14px;
    flex: 0 0 auto;
    color: var(--primary);
}

/* Pas de format impose : la carte s'aligne sur la hauteur des cartes d'affiche
   de la rangee, quel que soit le format de celles-ci. Le minimum la garde
   presentable si elle se retrouve seule. */
.salon--soon {
    min-height: 240px;
    border-style: dashed;
    border-color: color-mix(in srgb, var(--primary) 38%, #dcd8e6);
    background: var(--primary-soft);
    box-shadow: none;
}

/* Carte « D'autres à venir… » : purement informative, aucun clic possible,
   donc on neutralise l'effet de survol hérité de .salon */
.salon--soon:hover {
    transform: none;
    box-shadow: none;
}

.salon__soon {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    text-align: center;
    padding: 1.6rem 1.2rem;
    gap: .35rem;
}

.salon__soon-ico {
    width: 56px;
    height: 56px;
    border-radius: 50%;
    display: grid;
    place-items: center;
    background: #fff;
    color: var(--primary);
    box-shadow: 0 10px 22px -10px color-mix(in srgb, var(--primary) 55%, transparent);
    margin-bottom: .3rem;
}

.salon__soon-ico svg {
    width: 27px;
    height: 27px;
}

.salon__soon h4 {
    font-size: 1.22rem;
    color: var(--ink);
}

.salon__soon p {
    font-size: .88rem;
    color: #56506a;
}

/* mobile : affiches sur 2 colonnes pour raccourcir la page
   (déclaré après les règles .salons ci-dessus pour gagner la cascade) */
@media (max-width: 520px) {
    .salons {
        grid-template-columns: repeat(2, 1fr);
        gap: .8rem
    }

    /* Sous 430px, deux colonnes ramenent l'affiche a 165px de large : au format
       A4 elle n'est plus lisible. Une seule colonne lui rend sa taille. */
    @media (max-width: 430px) {
        .salons {
            grid-template-columns: 1fr
        }
    }

    .salon__soon {
        padding: 1rem .7rem
    }

    .salon__soon-ico {
        width: 44px;
        height: 44px
    }

    .salon__soon-ico svg {
        width: 21px;
        height: 21px
    }

    .salon__soon h4 {
        font-size: 1rem
    }
}

/* CTAs réseaux sous les salons */
.salons-social {
    display: flex;
    gap: .9rem;
    justify-content: center;
    flex-wrap: wrap;
    margin-top: 1.5rem;
}

.btn-soc {
    display: inline-flex;
    align-items: center;
    gap: .6rem;
    font-family: var(--font-body);
    font-weight: 600;
    font-size: 1rem;
    color: #fff;
    padding: .85rem 1.7rem;
    border-radius: 100px;
    transition: transform .2s var(--ease), box-shadow .25s, filter .2s;
}

.btn-soc svg {
    width: 21px;
    height: 21px;
    flex: 0 0 auto;
}

/* Libellé court réservé au mobile (voir bloc @media 520px en fin de fichier) */
.btn-soc__short {
    display: none;
}

.btn-soc:hover {
    transform: translateY(-3px);
    filter: brightness(1.06);
}

.btn-soc--fb {
    background: #1877f2;
    box-shadow: 0 14px 28px -12px rgba(24, 119, 242, .75);
}

.btn-soc--ig {
    background: linear-gradient(45deg, #feda75, #fa7e1e 22%, #d62976 50%, #962fbf 74%, #4f5bd5);
    box-shadow: 0 14px 28px -12px rgba(214, 41, 118, .7);
}

/* Contact · carte "100% à distance" (remplace l'ancienne carte atelier) */
.contact__remote {
    display: flex;
    gap: .95rem;
    align-items: flex-start;
    background: var(--primary-soft);
    border: 1px solid color-mix(in srgb, var(--primary) 18%, transparent);
    border-radius: var(--radius-lg);
    padding: 1.3rem;
    flex: 1;
}

.contact__remote .ico {
    flex: 0 0 auto;
    width: 46px;
    height: 46px;
    border-radius: 13px;
    display: grid;
    place-items: center;
    background: #fff;
    color: var(--primary);
    box-shadow: 0 8px 18px -10px color-mix(in srgb, var(--primary) 60%, transparent);
}

.contact__remote .ico svg {
    width: 24px;
    height: 24px;
}

.contact__remote h4 {
    font-size: 1.12rem;
    color: var(--ink);
    margin-bottom: .25rem;
}

.contact__remote p {
    font-size: .92rem;
    color: #56506a;
}

/* =========================================================================
   Galerie · animation organique du filtre
   ========================================================================= */
.tile {
    transition: transform .32s var(--ease), box-shadow .32s var(--ease), opacity .3s var(--ease);
}

.tile.leaving {
    opacity: 0;
    transform: scale(.86) translateY(8px);
    pointer-events: none;
}

@keyframes tilePop {
    0% {
        opacity: 0;
        transform: scale(.84) translateY(16px);
    }
    60% {
        opacity: 1;
    }
    100% {
        opacity: 1;
        transform: none;
    }
}

.tile.pop {
    /* « backwards » : la tuile prend l'état initial (invisible) pendant son
       délai, puis après l'animation reprend ses valeurs de base (le soulèvement
       au survol reste donc actif, contrairement à « forwards »/« both »). */
    animation: tilePop 1s var(--ease) backwards;
}

/* Galerie en cascade : les tuiles sont masquées jusqu'à recevoir .pop, où
   site.js les révèle une par une (délai croissant) à l'entrée dans le viewport. */
.gallery--cascade .tile:not(.pop) {
    opacity: 0;
}

/* =========================================================================
   Séparateur "foudre" (image foudre.png) entre les deux camps
   ========================================================================= */
.divider img {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    height: 104%;
    width: auto;
    max-width: none;
    pointer-events: none;
    user-select: none;
    z-index: 1;
    filter: drop-shadow(0 0 12px rgba(160, 215, 255, .65)) drop-shadow(0 0 40px rgba(120, 180, 255, .45));
    animation: foudreFlicker 3.8s ease-in-out infinite;
}

@keyframes foudreFlicker {
    0%, 100% {
        opacity: .95
    }
    43% {
        opacity: .8
    }
    48% {
        opacity: 1
    }
    52% {
        opacity: .86
    }
    70% {
        opacity: .97
    }
}

@media (max-width: 880px) {
    /* la foudre bascule à l'horizontale, le long de la couture */
    .divider img {
        height: 96vw;
        width: auto;
        transform: translate(-50%, -50%) rotate(90deg);
    }
}

/* =========================================================================
   12quater) CATALOGUE : FACETTES, BARRE D'OUTILS, PAGINATION
   ========================================================================= */
.product-note {
    max-width: 70ch
}

/* --- Facettes (colonne de filtres) --- */
.facets {
    display: flex;
    flex-direction: column
}

.facet {
    border-top: 1px solid #ececf1
}

.facet:first-child {
    border-top: none
}

.facet summary {
    list-style: none;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .5rem;
    padding: .9rem .2rem;
    font-family: var(--font-body);
    font-weight: 600;
    font-size: .96rem;
    color: var(--ink)
}

.facet summary::-webkit-details-marker {
    display: none
}

.facet summary:focus-visible {
    outline: 2px solid var(--primary);
    outline-offset: 2px;
    border-radius: 6px
}

.facet .chev {
    width: 16px;
    height: 16px;
    flex: none;
    color: var(--primary);
    transition: transform .25s var(--ease)
}

.facet details[open] > summary .chev {
    transform: rotate(180deg)
}

.facet__opts {
    display: flex;
    flex-direction: column;
    gap: .05rem;
    padding-bottom: .7rem
}

.facet__opt {
    display: flex;
    align-items: center;
    cursor: pointer;
    padding: .38rem .4rem;
    border-radius: 12px;
    transition: background .15s
}

.facet__opt:hover {
    background: var(--primary-soft)
}

.facet__opt input {
    position: absolute;
    opacity: 0;
    width: 1px;
    height: 1px
}

.facet__opt span {
    position: relative;
    padding-left: 1.75rem;
    font-size: .9rem;
    line-height: 1.3;
    color: #4d4763
}

.facet__opt span::before {
    content: "";
    position: absolute;
    left: 0;
    top: 50%;
    transform: translateY(-50%);
    width: 18px;
    height: 18px;
    border-radius: 6px;
    border: 1.5px solid #cfc9dd;
    background: #fff;
    transition: background .15s, border-color .15s
}

.facet__opt span::after {
    content: "";
    position: absolute;
    left: 6px;
    top: 50%;
    width: 5px;
    height: 9px;
    border: solid #fff;
    border-width: 0 2px 2px 0;
    transform: translateY(-62%) rotate(45deg) scale(0);
    transition: transform .16s var(--ease)
}

.facet__opt input:checked + span::before {
    background: var(--primary);
    border-color: var(--primary)
}

.facet__opt input:checked + span::after {
    transform: translateY(-62%) rotate(45deg) scale(1)
}

.facet__opt input:focus-visible + span::before {
    outline: 2px solid var(--primary);
    outline-offset: 2px
}

/* --- Barre d'outils résultats --- */
.catalog-bar {
    display: flex;
    align-items: center;
    gap: 1rem;
    flex-wrap: wrap;
    padding-bottom: 1rem;
    margin-bottom: 1.1rem;
    border-bottom: 1px solid #ececf1
}

.catalog-count {
    font-size: .95rem;
    color: #4d4763
}

.catalog-count strong {
    color: var(--ink);
    font-weight: 700
}

.catalog-controls {
    margin-left: auto;
    display: flex;
    gap: .8rem;
    flex-wrap: wrap
}

.ctrl {
    display: inline-flex;
    align-items: center;
    gap: .45rem;
    font-size: .84rem;
    color: #6a6580
}

/* « Trier : » / « Afficher : » : garder le libellé (et son deux-points) d'un bloc */
.ctrl__label {
    white-space: nowrap
}

.ctrl select {
    font-family: var(--font-body);
    font-size: .88rem;
    font-weight: 600;
    color: var(--ink);
    padding: .5rem 2.1rem .5rem .85rem;
    border: 1.5px solid #e3e0ec;
    border-radius: 100px;
    background-color: #fff;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%234d4763' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right .75rem center;
    cursor: pointer;
    appearance: none;
    -webkit-appearance: none;
    transition: border-color .2s
}

/* Le tri porte des libelles longs (« Prix croissant ») quand le nombre par page
   n'affiche que deux chiffres : sans largeur minimale, le premier se comprimait
   et son texte etait tronque. */
#sortSelect {
    min-width: 11.5rem
}

#perPageSelect {
    min-width: 4.6rem
}

.ctrl select:hover {
    border-color: var(--primary)
}

.ctrl select:focus-visible {
    outline: none;
    border-color: var(--primary);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--primary) 18%, transparent)
}

/* --- Bouton Filtres (mobile) --- */
.filters-toggle {
    display: none;
    align-items: center;
    gap: .5rem;
    font-family: var(--font-body);
    font-weight: 600;
    font-size: .9rem;
    color: var(--primary-deep);
    padding: .55rem 1rem;
    border: 1.5px solid color-mix(in srgb, var(--primary) 30%, transparent);
    border-radius: 100px;
    background: #fff;
    transition: background .2s, border-color .2s
}

.filters-toggle:hover {
    background: var(--primary-soft);
    border-color: var(--primary)
}

.filters-toggle svg {
    width: 18px;
    height: 18px
}

.filters-toggle__badge[hidden] {
    display: none
}

.filters-toggle__badge {
    display: inline-grid;
    place-items: center;
    min-width: 20px;
    height: 20px;
    padding: 0 .32rem;
    border-radius: 100px;
    background: var(--primary);
    color: #fff;
    font-size: .72rem;
    font-weight: 700
}

/* --- Chips de filtres actifs --- */
.active-chips {
    display: flex;
    flex-wrap: wrap;
    gap: .5rem;
    align-items: center;
    margin-bottom: 1.2rem
}

.active-chips[hidden] {
    display: none
}

.chip {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    font-size: .82rem;
    font-weight: 600;
    color: var(--primary-deep);
    background: var(--primary-soft);
    border: 1px solid color-mix(in srgb, var(--primary) 22%, transparent);
    border-radius: 100px;
    padding: .3rem .4rem .3rem .85rem
}

.chip button {
    display: inline-grid;
    place-items: center;
    width: 18px;
    height: 18px;
    border-radius: 50%;
    background: color-mix(in srgb, var(--primary) 14%, #fff);
    color: var(--primary-deep);
    font-size: .9rem;
    line-height: 1;
    transition: background .15s, color .15s
}

.chip button:hover {
    background: var(--primary);
    color: #fff
}

.chip__clear {
    border: none;
    background: none;
    color: #6a6580;
    font-family: var(--font-body);
    font-size: .82rem;
    font-weight: 600;
    text-decoration: underline;
    text-underline-offset: 2px;
    cursor: pointer;
    padding: .3rem .4rem
}

.chip__clear:hover {
    color: var(--primary)
}

.link-btn {
    border: none;
    background: none;
    color: var(--primary);
    font: inherit;
    font-weight: 600;
    text-decoration: underline;
    text-underline-offset: 2px;
    cursor: pointer
}

/* --- Carte : métadonnée partenaire + pied ancré en bas --- */
.product-card__meta {
    font-size: .82rem;
    color: #6a6580;
    margin-bottom: .2rem
}

/* --- Pagination --- */
.pagination {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    align-items: center;
    gap: .35rem;
    margin-top: 2.4rem
}

.pagination:empty {
    display: none
}

.pagination button, .pagination .page-ellipsis {
    min-width: 40px;
    height: 40px;
    display: inline-grid;
    place-items: center;
    padding: 0 .55rem;
    border-radius: 12px;
    border: 1.5px solid #e3e0ec;
    background: #fff;
    font-family: var(--font-body);
    font-weight: 600;
    font-size: .9rem;
    color: var(--ink);
    cursor: pointer;
    transition: border-color .2s, background .2s, color .2s
}

.pagination button:hover:not([disabled]):not(.is-current) {
    border-color: var(--primary);
    color: var(--primary-deep)
}

.pagination button.is-current {
    background: var(--primary);
    border-color: var(--primary);
    color: #fff;
    cursor: default
}

.pagination button[disabled] {
    opacity: .4;
    cursor: not-allowed
}

.pagination .page-nav {
    display: inline-flex;
    align-items: center;
    gap: .35rem;
    padding: 0 .95rem
}

.pagination .page-nav svg {
    width: 15px;
    height: 15px
}

.pagination .page-ellipsis {
    border: none;
    background: none;
    cursor: default;
    color: #6a6580
}

/* --- Drawer mobile (par défaut masqué) --- */
.product-sidebar__head, .product-sidebar__foot {
    display: none
}

.filters-backdrop {
    display: none
}

@media (max-width: 980px) {
    .filters-toggle {
        display: inline-flex
    }

    .catalog-bar {
        justify-content: space-between
    }

    .catalog-controls {
        margin-left: 0;
        width: 100%
    }

    .catalog-controls .ctrl {
        flex: 1
    }

    .catalog-controls select {
        width: 100%;
        /* Safari iOS zoome d'office sur un champ dont le corps est sous 16px, et
           ne dézoome pas en sortant. Les 0.88rem du cas général valaient
           14,08px : c'était le seul endroit du site qui déclenchait ce zoom, les
           champs texte étant déjà à 16px. */
        font-size: 1rem
    }

    .product-sidebar {
        position: fixed;
        top: 0;
        left: 0;
        bottom: 0;
        /* align-self:start (hérité du mode sticky desktop) fausse le calcul
           top/bottom d'un enfant de grille en fixed : hauteur explicite pour
           que le pied sticky (« Voir les résultats ») reste toujours visible */
        align-self: auto;
        height: 100vh;
        height: 100dvh;
        z-index: 200;
        width: min(87vw, 350px);
        max-height: none;
        margin: 0;
        background: #fff;
        box-shadow: 0 0 60px rgba(10, 4, 24, .32);
        padding: 1.2rem 1.2rem 0;
        overflow-y: auto;
        display: flex;
        flex-direction: column;
        transform: translateX(-100%);
        visibility: hidden;
        transition: transform .32s var(--ease), visibility .32s
    }

    .product-sidebar.is-open {
        transform: none;
        visibility: visible
    }

    .product-sidebar__head {
        display: flex;
        align-items: center;
        justify-content: space-between;
        margin-bottom: .4rem
    }

    .product-sidebar__head h2 {
        font-family: var(--font-display);
        font-weight: 500;
        font-size: 1.5rem;
        color: var(--ink)
    }

    .product-sidebar__close {
        display: grid;
        place-items: center;
        width: 38px;
        height: 38px;
        border-radius: 50%;
        background: var(--primary-soft);
        color: var(--primary-deep)
    }

    .product-sidebar__close svg {
        width: 20px;
        height: 20px
    }

    .facets {
        flex: 1
    }

    .product-sidebar__foot {
        display: flex;
        gap: .6rem;
        position: sticky;
        bottom: 0;
        background: #fff;
        padding: .9rem 0;
        margin-top: .4rem;
        border-top: 1px solid #ececf1
    }

    .product-sidebar__foot .btn {
        flex: 1;
        justify-content: center;
        padding: .8rem 1rem
    }

    .filters-backdrop {
        display: block;
        position: fixed;
        inset: 0;
        z-index: 190;
        background: rgba(10, 4, 24, .5);
        opacity: 0;
        visibility: hidden;
        transition: opacity .32s, visibility .32s
    }

    .filters-backdrop.is-open {
        opacity: 1;
        visibility: visible
    }
}

@media (prefers-reduced-motion: reduce) {
    .product-sidebar, .filters-backdrop, .facet .chev, .facet__opt span::after {
        transition: none
    }
}

/* =========================================================================
   AFFINAGES MOBILE (≤ 520px), demande cliente du 24/07/2026
   Placé en fin de fichier pour l'emporter sur les règles mobiles antérieures.
   Le header est sticky (top:0) et mesure 88px : les barres fixées se calent
   juste dessous via --header-h.
   ========================================================================= */
@media (max-width: 520px) {
    :root {
        --header-h: 88px;
    }

    /* #1 · Mascotte du hero d'accueil moins imposante : on donne au bloc
       .hero__art une largeur explicite (le disque 86% et la mascotte 82% en
       dépendent) ; largeur définie obligatoire, sinon l'item de grille en
       margin auto s'effondre à 0 (l'enfant % n'a pas de largeur intrinsèque). */
    .hero__art {
        width: 236px;
        max-width: 100%;
        min-height: 200px;
        margin-inline: auto;
    }

    /* #2 · Filtres galerie : rangée unique défilable horizontalement (au lieu
       d'un pavé qui s'enroule sur 3 lignes), et fixée sous le header pour rester
       à portée de pouce pendant le défilement de la grille. */
    .gallery-filters {
        position: sticky;
        top: var(--header-h);
        z-index: 40;
        flex-wrap: nowrap;
        justify-content: flex-start;
        overflow-x: auto;
        overflow-y: hidden;
        -webkit-overflow-scrolling: touch;
        scrollbar-width: none;
        gap: .5rem;
        /* La rangee defile : elle file jusqu'aux bords de l'ecran, sinon la
           derniere pastille visible est tranchee net a 16 px du bord et le fond
           givre, une fois la barre plaquee, forme un bandeau flottant au lieu
           de couvrir toute la largeur. */
        margin: 0 calc(clamp(1rem, 4vw, 2.4rem) * -1) 1rem;
        padding: .7rem clamp(1rem, 4vw, 2.4rem);
        scroll-padding-inline: clamp(1rem, 4vw, 2.4rem);
        /* Transparent au repos : la barre se fond dans la section. Le fond
           givré n'apparaît QUE lorsqu'elle est réellement collée en défilant
           (classe .is-stuck posée par site.js → plus de bande blanche au repos). */
        background: transparent;
    }

    .gallery-filters.is-stuck {
        background: color-mix(in srgb, #faf9fc 82%, transparent);
        backdrop-filter: blur(12px) saturate(1.3);
        box-shadow: 0 8px 18px -14px rgba(23, 12, 48, .5);
    }

    .gallery-filters::-webkit-scrollbar {
        display: none;
    }

    /* les puces gardent leur taille (pas de compression) et défilent */
    .gallery-filters .filter {
        flex: 0 0 auto;
        white-space: nowrap;
    }

    /* #2 (suite) · Tuiles galerie repensées : la pastille de tag quittait le coin
       haut-gauche (où elle s'enroulait sur 2 lignes et frôlait le cœur). Elle
       devient un KICKER doré au bas de la tuile, au-dessus de la légende ; le
       cœur de like reste le seul élément en haut. On empile le contenu du bas
       (colonne), sans toucher au HTML de la tuile. */
    .tile {
        flex-direction: column;
        justify-content: flex-end;
        align-items: flex-start;
        gap: .12rem;
    }

    .tile__tag {
        position: relative;      /* dans le flux, mais au-dessus du voile (::before) */
        z-index: 2;
        top: auto;
        left: auto;
        max-width: 100%;
        background: none;        /* fini la pastille pleine */
        padding: 0;
        /* blanc atténué : lisible sur le voile sombre de toutes les tuiles, et
           en retrait sous le titre (blanc plein) pour la hiérarchie */
        color: rgba(255, 255, 255, .78);
        font-weight: 700;
        /* 0.6rem donnait 9,6px, sous le plancher de lisibilité. Remonté à 12px :
           l'interlettrage large de ce libellé le rendait d'autant plus dur à
           lire en capitales. */
        font-size: .75rem;
        letter-spacing: .1em;
        text-shadow: 0 1px 6px rgba(0, 0, 0, .6);
    }

    /* #1 · Sur un écran de téléphone, une tuile fait moins de 170 px de large :
       un titre de trois lignes et son surtitre finissent par recouvrir la
       figurine qu'ils annoncent. Le texte part entièrement dans la visionneuse,
       qui s'ouvre au premier appui, et la vignette ne montre plus que la photo.
       Le voile sombre s'en va avec lui : il n'avait d'autre rôle que de rendre
       ce texte lisible. La légende reste dans le HTML, d'où la visionneuse la
       lit, et l'attribut alt de l'image la porte pour les lecteurs d'écran.

       La page seule, et non la classe : la même tuile sert la section galerie
       de l'accueil, qui garde ses légendes. */
    body.p-app_galerie .tile__tag,
    body.p-app_galerie .tile__cap {
        display: none;
    }

    body.p-app_galerie .tile::before {
        opacity: 0;
    }

    /* Le texte retire de la vignette se lit ici. */
    body.p-app_galerie .lightbox__tag {
        display: block;
        font-family: var(--font-body);
        font-size: .72rem;
        font-weight: 700;
        letter-spacing: .1em;
        text-transform: uppercase;
        color: rgba(255, 255, 255, .58);
        margin-bottom: .3rem;
    }

    /* Sans categorie, pas de ligne blanche au-dessus de la legende. Selecteur
       plus fort que celui ci-dessus, sans quoi le span vide garderait sa
       hauteur. */
    body.p-app_galerie .lightbox__tag:empty {
        display: none;
    }

    .tile__like {
        z-index: 3;
    }

    /* #2 (suite) · La page /galerie était sur blanc franc. Teinte douce MAIS
       clairement visible (le #faf9fc précédent était quasi-blanc, imperceptible) :
       la variante « soft » de la couleur d'équipe, posée sur tout le <body>.
       Uniforme → aucune couture ni liseré, et couvre la marge du footer.
       Mobile uniquement (desktop /galerie reste blanc). */
    body.p-app_galerie {
        background: var(--primary-soft);
    }

    /* Le fondu du heros s'acheve en blanc pur, ce qui convient partout ailleurs :
       le fond du site l'est aussi. Sur la galerie en telephone il tombe sur la
       teinte ci-dessus, et le raccord se lisait comme un trait tire a la regle
       juste au-dessus des filtres. La zone reprend donc le blanc la ou le heros
       le laisse et rejoint la teinte en une centaine de pixels, le temps que les
       filtres respirent. */
    body.p-app_galerie .gallery-page {
        background: linear-gradient(180deg, #fff 0, var(--primary-soft) 104px);
        padding-top: 1.5rem;
    }

    /* #3 · Facebook / Instagram côte à côte (libellé court réservé au mobile). */
    .salons-social {
        flex-wrap: nowrap;
        gap: .6rem;
    }

    .btn-soc {
        flex: 1 1 0;
        min-width: 0;
        justify-content: center;
        padding: .8rem .5rem;
        font-size: .92rem;
    }

    .btn-soc__full {
        display: none;
    }

    .btn-soc__short {
        display: inline;
    }

    /* #5 · Héros (accueil ET pages annexes) : les deux CTA côte à côte et de
       taille égale (flex:1). L'icône flèche du bouton primaire est masquée pour
       un rendu équilibré et un texte qui tient sans rétrécir. */
    .hero__cta {
        flex-wrap: nowrap;
        gap: .6rem;
        width: 100%;
    }

    .hero__cta .btn {
        flex: 1 1 0;
        min-width: 0;
        justify-content: center;
        text-align: center;
        padding: .85rem .5rem;
        font-size: .82rem;
        line-height: 1.2;
    }

    .hero__cta .btn svg {
        display: none;
    }

    /* #6 · Cartes de niveaux de finition (page Prestations) : carrousel
       horizontal à glisser (scroll-snap), avec aperçu de la carte suivante. */
    .levels {
        display: flex;
        grid-template-columns: none;
        gap: 1rem;
        overflow-x: auto;
        overflow-y: hidden;
        scroll-snap-type: x mandatory;
        -webkit-overflow-scrolling: touch;
        scrollbar-width: none;
        margin-bottom: .5rem;
        padding-bottom: .5rem;
    }

    .levels::-webkit-scrollbar {
        display: none;
    }

    .level {
        flex: 0 0 82%;
        scroll-snap-align: start;
    }

    /* #7 · Barre d'outils du catalogue (Filtres / Trier / Afficher) fixée sous
       le header : les filtres restent à portée de pouce après un long scroll. */
    .catalog-bar {
        position: sticky;
        top: var(--header-h);
        z-index: 40;
        gap: .6rem .9rem;
        padding: .7rem 0;
        margin-bottom: 1rem;
        /* transparent au repos ; givré seulement quand collée (comme les filtres galerie) */
        background: transparent;
    }

    .catalog-bar.is-stuck {
        background: color-mix(in srgb, #faf9fc 90%, transparent);
        backdrop-filter: blur(12px) saturate(1.3);
        box-shadow: 0 8px 18px -14px rgba(23, 12, 48, .5);
    }
}

/* =========================================================================
   Cartes faisables au doigt (hauts faits, salons) sur petit écran
   ========================================================================= */
/* Empilées, cinq hauts faits ou plusieurs affiches font une colonne
   interminable. Sur mobile elles défilent horizontalement, avec accrochage
   natif : pas de script, le geste du doigt suffit et le clavier reste
   opérant. Placé en fin de feuille pour l'emporter sur les grilles définies
   plus haut aux mêmes largeurs. */
@media (max-width: 880px) {
    .cards,
    .salons {
        display: grid;
        grid-auto-flow: column;
        grid-template-columns: none;
        overflow-x: auto;
        overscroll-behavior-x: contain;
        scroll-snap-type: x mandatory;
        /* Les tuiles filent jusqu'aux bords de l'écran : marge négative égale
           au retrait de la section, rendue en rembourrage interne. */
        margin-inline: calc(clamp(1rem, 4vw, 2.4rem) * -1);
        padding-inline: clamp(1rem, 4vw, 2.4rem);
        scroll-padding-inline: clamp(1rem, 4vw, 2.4rem);
        padding-bottom: .4rem;
        scrollbar-width: none;
    }

    .cards::-webkit-scrollbar,
    .salons::-webkit-scrollbar {
        display: none;
    }

    /* La tuile suivante dépasse volontairement : elle signale qu'on peut faire
       défiler, sans avoir à ajouter une flèche ou une consigne. */
    .cards {
        /* Bornee : a 82 % la tuile atteignait 660 px sur tablette. */
        grid-auto-columns: clamp(240px, 82%, 390px);
        gap: 1rem;
    }

    .salons {
        grid-auto-columns: clamp(150px, 56%, 240px);
        gap: .9rem;
    }

    .card,
    .salon {
        scroll-snap-align: start;
    }

    /* La carte « d'autres à venir » n'a plus de hauteur propre à tenir : elle
       s'aligne sur les affiches de la rangée. */
    .salon--soon {
        min-height: 0;
    }
}

/* Au doigt, on ne survole pas : le soulèvement au survol n'a pas lieu d'être
   et gênerait le défilement. */
@media (max-width: 880px) and (pointer: coarse) {
    .salon:hover,
    .card:hover {
        transform: none;
    }
}

/* Cartes de niveau resserrées sur mobile : à 1.6 d'interligne et 16 px de
   texte, une carte atteignait 925 px de haut pour un écran de 812. On resserre
   l'interligne et les espacements plutôt que de réduire le corps du texte, qui
   doit rester confortable à lire. */
@media (max-width: 700px) {
    /* Sur petit ecran, la pastille degradee en tete de prestation prend une
       place que le titre et le texte valorisent mieux. Elle est purement
       decorative, la retirer ne coute aucune information. */
    .presta-header__ico {
        display: none;
    }

    .level__body {
        padding: 1.15rem 1.15rem 1.3rem;
    }

    .level__body p,
    .level .presta-row__list li {
        line-height: 1.42;
    }

    .level .presta-row__list {
        gap: .38rem .9rem;
        margin-bottom: .9rem;
    }

    .level p.incl-label {
        margin-bottom: .45rem;
    }

    .level p.incl-note {
        margin-top: .5rem;
    }
}
