/* =========================================================================
   DB Digital — feuille de style unique
   Fond nuit profond, halos violet et corail, dégradé signature comme
   colonne vertébrale visuelle. Deux accents porteurs de sens :
   violet/bleu pour ce qui se pose sur les sites des autres (les scripts),
   corail/ambre pour ce qui vit tout seul (les applications).
   ========================================================================= */

@layer reset, base, layout, components, utilities;

@view-transition { navigation: auto; }

@layer reset {
    *, *::before, *::after { box-sizing: border-box; }
    * { margin: 0; }
    html { -webkit-text-size-adjust: 100%; }
    img, svg { display: block; max-width: 100%; }
    button, input, textarea, select { font: inherit; color: inherit; }
    a { color: inherit; }
}

@layer base {
    :root {
        --nuit: #0a0b14;
        --roche: #12101f;
        --pierre: #171426;
        --trait: rgb(255 255 255 / .1);
        --trait-vive: rgb(255 255 255 / .18);
        --brume: #a9a5c6;
        --brume-sourde: #8b87ab;
        --neige: #f3f1fb;

        --violet: #7c5cff;   /* scripts : ce qui se superpose */
        --violet-clair: #b98bff;
        --bleu: #5c9fff;
        --corail: #ff6f61;   /* applications : ce qui est autonome */
        --ambre: #ffb37a;
        --vert: #5bd6a0;     /* état "en ligne / disponible", jamais décoratif */

        --calque: var(--violet-clair);   /* alias historique, conservé pour les scripts */
        --brique: var(--corail);          /* alias historique, conservé pour les apps */

        --degrade: linear-gradient(90deg, var(--violet-clair), var(--corail));

        --rayon: 20px;
        --gouttiere: clamp(1.25rem, 4vw, 2.5rem);
        --mesure: 62ch;
    }

    html { scroll-behavior: smooth; }
    @media (prefers-reduced-motion: reduce) {
        html { scroll-behavior: auto; }
        *, *::before, *::after {
            animation-duration: .01ms !important;
            animation-iteration-count: 1 !important;
            transition-duration: .01ms !important;
        }
    }

    body {
        background: var(--nuit);
        color: var(--neige);
        font-family: "Instrument Sans", system-ui, -apple-system, sans-serif;
        font-size: clamp(15px, 0.4vw + 14px, 16.5px);
        line-height: 1.6;
        -webkit-font-smoothing: antialiased;
        min-height: 100dvh;
        position: relative;
        overflow-x: clip;
    }

    /* Deux halos colorés diffus, signature du nouveau ton visuel : le fond
       n'est plus un aplat mort, sans devenir un décor envahissant. */
    body::before,
    body::after {
        content: "";
        position: fixed;
        border-radius: 50%;
        filter: blur(90px);
        pointer-events: none;
        z-index: 0;
    }
    body::before {
        width: 620px; height: 620px;
        top: -260px; left: -140px;
        background: radial-gradient(circle, color-mix(in oklab, var(--violet) 55%, transparent), transparent 70%);
    }
    body::after {
        width: 560px; height: 560px;
        top: 120px; right: -220px;
        background: radial-gradient(circle, color-mix(in oklab, var(--corail) 42%, transparent), transparent 70%);
    }

    h1, h2, h3 {
        font-family: "Bricolage Grotesque", "Instrument Sans", sans-serif;
        font-weight: 800;
        line-height: 1.05;
        letter-spacing: -0.03em;
        text-wrap: balance;
    }

    h1 { font-size: clamp(2.3rem, 6vw, 3.8rem); }
    h2 { font-size: clamp(1.5rem, 3.4vw, 2rem); }
    h3 { font-size: 1.125rem; letter-spacing: -0.02em; }

    p { text-wrap: pretty; }

    :focus-visible {
        outline: 2px solid var(--violet-clair);
        outline-offset: 3px;
        border-radius: 3px;
    }

    ::selection { background: var(--violet); color: var(--neige); }
}

@layer layout {
    .shell {
        position: relative;
        z-index: 1;
        max-width: 1180px;
        margin-inline: auto;
        padding: var(--gouttiere);
        display: grid;
        gap: clamp(2rem, 5vw, 3.5rem);
    }

    @media (min-width: 62rem) {
        .shell {
            grid-template-columns: 15rem minmax(0, 1fr);
            align-items: start;
            gap: 4rem;
            padding-block: 3.5rem 5rem;
        }
    }

    .page { display: grid; gap: clamp(3rem, 7vw, 5rem); min-width: 0; }
    .section { display: grid; gap: 1.5rem; }
}

@layer components {

    /* ---------- Rail d'identité ---------- */
    .rail { display: grid; gap: 1.75rem; }

    @media (min-width: 62rem) {
        .rail { position: sticky; top: 3.5rem; }
    }

    /* ---------- Menu mobile : tiroir latéral ----------
       Sous 62rem, le rail complet (logo + nav + pied) mangeait toute la
       hauteur avant le contenu. À la place : une barre sticky en haut
       (logo + bouton) et un vrai tiroir qui glisse depuis la droite,
       par-dessus un voile assombri. L'animation porte sur transform et
       opacity uniquement (pas de display, qui ne s'anime pas), donc le
       panneau existe toujours dans le DOM et sort de l'écran quand il est
       fermé — visibility évite qu'il reste focusable à ce moment-là.
       Au-dessus de 62rem, tout ça est neutralisé : le rail redevient la
       colonne sticky classique et le bouton disparaît. */
    .rail__top {
        position: sticky;
        top: 0;
        z-index: 30;
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 1rem;
        /* Marges négatives = la barre saigne jusqu'aux bords de l'écran
           malgré la gouttière de .shell, et son fond flouté couvre le
           contenu qui défile dessous. */
        margin: calc(var(--gouttiere) * -1) calc(var(--gouttiere) * -1) 0;
        padding: .8rem var(--gouttiere);
        background: color-mix(in oklab, var(--nuit) 82%, transparent);
        backdrop-filter: blur(10px);
        border-bottom: 1px solid var(--trait);
    }
    .rail__toggle {
        display: flex;
        align-items: center;
        justify-content: center;
        width: 2.6rem; height: 2.6rem;
        flex: none;
        border-radius: 12px;
        border: 1px solid var(--trait);
        background: rgb(255 255 255 / .05);
        color: var(--neige);
        cursor: pointer;
        transition: background .18s, border-color .18s, transform .18s;
    }
    .rail__toggle:hover { background: rgb(255 255 255 / .09); border-color: var(--trait-vive); }
    .rail__toggle:active { transform: scale(.94); }
    .rail__toggle i { display: flex !important; align-items: center; justify-content: center; }
    .rail__toggle i::before { display: block; font-size: 1.05rem !important; line-height: 1 !important; width: auto; height: auto; }

    /* Voile : assombrit la page derrière le tiroir et sert de zone de
       fermeture au clic. */
    .rail__voile {
        position: fixed;
        inset: 0;
        z-index: 40;
        background: rgb(6 8 16 / .65);
        backdrop-filter: blur(3px);
        opacity: 0;
        visibility: hidden;
        transition: opacity .3s ease, visibility .3s ease;
    }
    .rail__voile.is-open { opacity: 1; visibility: visible; }

    .rail__panel {
        position: fixed;
        top: 0; right: 0; bottom: 0;
        z-index: 50;
        width: min(19rem, 80vw);
        display: grid;
        align-content: start;
        gap: 1.5rem;
        padding: 1.25rem;
        overflow-y: auto;
        overscroll-behavior: contain;
        background: var(--roche);
        border-left: 1px solid var(--trait-vive);
        box-shadow: -30px 0 60px -20px rgb(0 0 0 / .7);
        transform: translateX(100%);
        visibility: hidden;
        transition: transform .32s cubic-bezier(.2, .8, .2, 1), visibility .32s;
    }
    .rail__panel.is-open { transform: translateX(0); visibility: visible; }

    .rail__panel-tete {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 1rem;
        padding-bottom: 1rem;
        border-bottom: 1px solid var(--trait);
        color: var(--brume-sourde);
        font-size: .72rem;
        font-weight: 700;
        letter-spacing: .12em;
        text-transform: uppercase;
    }
    .rail__fermer {
        display: flex;
        align-items: center;
        justify-content: center;
        width: 2.1rem; height: 2.1rem;
        flex: none;
        border-radius: 50%;
        border: 1px solid var(--trait);
        background: rgb(255 255 255 / .05);
        color: var(--neige);
        cursor: pointer;
        transition: background .18s, border-color .18s;
    }
    .rail__fermer:hover { background: rgb(255 255 255 / .1); border-color: var(--trait-vive); }
    .rail__fermer i { display: flex !important; align-items: center; justify-content: center; }
    .rail__fermer i::before { display: block; font-size: .85rem !important; line-height: 1 !important; width: auto; height: auto; }

    /* Empêche le défilement de la page tant que le tiroir est ouvert. */
    body.menu-ouvert { overflow: hidden; }

    @media (min-width: 62rem) {
        .rail__top {
            position: static;
            margin: 0;
            padding: 0;
            background: none;
            backdrop-filter: none;
            border-bottom: none;
        }
        .rail__toggle,
        .rail__voile,
        .rail__panel-tete { display: none; }

        .rail__panel {
            position: static;
            width: auto;
            gap: 1.75rem;
            padding: 0;
            overflow: visible;
            background: none;
            border-left: none;
            box-shadow: none;
            transform: none;
            visibility: visible;
            transition: none;
        }
        body.menu-ouvert { overflow: visible; }
    }

    .mark {
        display: inline-grid;
        gap: .4rem;
        text-decoration: none;
    }
    .mark b {
        font-family: "Bricolage Grotesque", sans-serif;
        font-size: 1.4rem;
        font-weight: 800;
        letter-spacing: -0.03em;
        background: var(--degrade);
        -webkit-background-clip: text;
        background-clip: text;
        color: transparent;
    }
    .mark span { color: var(--brume-sourde); font-size: .82rem; line-height: 1.4; }

    /* La nav est toujours dans un conteneur qui a déjà sa propre surface
       (le tiroir en mobile, la colonne du rail en grand écran) : lui
       redonner un cadre et un fond faisait un encart dans un encart.
       Une simple colonne de liens, l'état actif se lisant au liseré. */
    .nav {
        display: grid;
        gap: .15rem;
    }

    .nav a {
        position: relative;
        display: flex;
        align-items: center;
        gap: .6rem;
        padding: .65rem .9rem .65rem 1.15rem;
        border-radius: 10px;
        text-decoration: none;
        color: var(--brume);
        font-size: .88rem;
        font-weight: 600;
        transition: color .18s, background .18s;
    }
    .nav a:hover { color: var(--neige); background: rgb(255 255 255 / .06); }
    .nav a[aria-current="page"] {
        color: var(--neige);
        background: rgb(255 255 255 / .07);
    }
    .nav a[aria-current="page"]::before {
        content: "";
        position: absolute;
        left: .35rem;
        top: .4rem;
        bottom: .4rem;
        width: 3px;
        border-radius: 999px;
        background: var(--degrade);
    }
    .nav a[aria-current="page"] i { color: var(--violet-clair); }
    .nav i { width: 1rem; text-align: center; font-size: .85rem; opacity: .85; }

    .rail-foot {
        display: grid;
        gap: .6rem;
        padding-top: 1.25rem;
        border-top: 1px solid var(--trait);
        color: var(--brume-sourde);
        font-size: .82rem;
    }
    .rail-foot p { display: flex; align-items: center; gap: .5rem; }
    .rail-foot a {
        display: flex; align-items: center; gap: .5rem;
        text-decoration: none;
        width: fit-content;
        padding: .5rem .8rem;
        border-radius: 999px;
        background: rgb(255 255 255 / .05);
        border: 1px solid var(--trait);
        color: var(--neige);
        transition: transform .18s, background .18s;
    }
    .rail-foot a:hover { transform: translateY(-2px); background: rgb(255 255 255 / .1); }
    .rail-foot i.fa-circle-check { color: var(--violet-clair); }

    /* ---------- Accroche ---------- */
    .hero { display: grid; gap: 1.75rem; }

    .kicker {
        display: inline-flex;
        align-items: center;
        gap: .5rem;
        width: fit-content;
        padding: .45rem .9rem .45rem .6rem;
        border-radius: 999px;
        background: color-mix(in oklab, var(--violet) 16%, transparent);
        border: 1px solid color-mix(in oklab, var(--violet) 40%, transparent);
        font-size: .82rem;
        font-weight: 600;
        color: var(--violet-clair);
    }
    .kicker .dot {
        width: 7px; height: 7px; border-radius: 50%;
        background: var(--violet-clair);
        animation: pulse 2s ease-in-out infinite;
    }
    @keyframes pulse {
        0% { box-shadow: 0 0 0 0 color-mix(in oklab, var(--violet-clair) 55%, transparent); }
        70% { box-shadow: 0 0 0 8px transparent; }
        100% { box-shadow: 0 0 0 0 transparent; }
    }

    .hero h1 em {
        font-style: normal;
        background: var(--degrade);
        -webkit-background-clip: text;
        background-clip: text;
        color: transparent;
    }

    .hero p.lede {
        max-width: var(--mesure);
        color: var(--brume);
        font-size: clamp(1rem, 1.6vw, 1.15rem);
    }

    /* Une seule animation de fond sur tout le site : la démonstration de
       ce que fait un script. Elle se joue une fois, au chargement. */
    .demo {
        position: relative;
        border-radius: 22px;
        padding: 2px;
        background: linear-gradient(160deg,
            color-mix(in oklab, var(--violet) 40%, transparent),
            color-mix(in oklab, var(--corail) 25%, transparent));
        overflow: hidden;
        max-width: 34rem;
        box-shadow: 0 30px 60px -30px rgb(0 0 0 / .6);
    }
    .demo__bar {
        display: flex;
        align-items: center;
        gap: .5rem;
        padding: .7rem .95rem;
        border-bottom: 1px solid var(--trait);
        background: var(--roche);
        border-radius: 20px 20px 0 0;
    }
    .demo__bar em {
        font-style: normal;
        color: var(--brume-sourde);
        font-size: .78rem;
        letter-spacing: .01em;
        margin-left: .25rem;
    }
    .demo__dot { width: 8px; height: 8px; border-radius: 50%; background: rgb(255 255 255 / .16); }
    .demo__body { padding: 1.4rem 1.15rem 1.6rem; display: grid; gap: .7rem; background: var(--roche); }
    .demo__line { height: 10px; border-radius: 5px; background: rgb(255 255 255 / .09); }
    .demo__line:nth-child(1) { width: 62%; }
    .demo__line:nth-child(2) { width: 88%; }
    .demo__line:nth-child(3) { width: 74%; }

    .demo__tag {
        position: absolute;
        right: .9rem;
        bottom: .9rem;
        display: inline-flex;
        align-items: center;
        gap: .45rem;
        padding: .45rem .75rem;
        border-radius: 9px;
        background: var(--degrade);
        color: var(--nuit);
        font-size: .8rem;
        font-weight: 700;
        opacity: 0;
        transform: translateY(6px);
        animation: pose .5s ease-out 1.1s forwards;
    }
    @keyframes pose { to { opacity: 1; transform: none; } }
    @media (prefers-reduced-motion: reduce) {
        .demo__tag { opacity: 1; transform: none; animation: none; }
    }

    /* ---------- Portes d'entrée des deux catégories ---------- */
    .gates { display: grid; gap: 1.1rem; }
    @media (min-width: 46rem) { .gates { grid-template-columns: 1fr 1fr; } }

    .gate {
        --teinte1: var(--violet);
        --teinte2: var(--violet-clair);
        position: relative;
        border-radius: var(--rayon);
        padding: 2px;
        background: linear-gradient(160deg, color-mix(in oklab, var(--teinte1) 55%, transparent), transparent 60%);
        text-decoration: none;
        overflow: hidden;
    }
    .gate__inner {
        position: relative;
        display: grid;
        gap: .6rem;
        align-content: start;
        padding: 1.7rem 1.5rem 1.5rem;
        border-radius: calc(var(--rayon) - 2px);
        background: var(--roche);
        transition: transform .22s cubic-bezier(.2,.8,.2,1);
    }
    .gate:hover .gate__inner { transform: translateY(-5px); }
    .gate__inner::after {
        content: "";
        position: absolute; inset: 0;
        background: radial-gradient(220px 150px at 85% -10%, color-mix(in oklab, var(--teinte2) 30%, transparent), transparent 70%);
        pointer-events: none;
    }
    .gate--apps { --teinte1: var(--corail); --teinte2: var(--ambre); }

    .gate i {
        position: relative;
        width: 2.4rem; height: 2.4rem;
        flex: none;
        display: flex !important;
        align-items: center;
        justify-content: center;
        border-radius: 12px;
        background: linear-gradient(140deg, var(--teinte1), var(--teinte2));
        color: var(--nuit);
        margin-bottom: .35rem;
    }
    .gate i::before {
        display: block;
        font-size: 1.1rem !important;
        line-height: 1 !important;
        width: auto; height: auto;
    }
    .gate h3 { position: relative; color: var(--neige); }
    .gate p { position: relative; color: var(--brume); font-size: .9rem; }
    .gate b {
        position: relative;
        display: inline-flex;
        align-items: center;
        gap: .4rem;
        margin-top: .5rem;
        color: var(--teinte2);
        font-size: .85rem;
        font-weight: 700;
    }

    /* ---------- Liste des outils ---------- */
    .items {
        display: grid;
        gap: .85rem;
    }

    /* État vide : rien à afficher pour l'instant dans .items (scripts pas
       encore débloqués). Un simple "il n'y a rien" nu aurait l'air cassé,
       donc un encart qui explique que c'est volontaire et à venir. */
    .vide {
        display: grid;
        justify-items: center;
        text-align: center;
        gap: .6rem;
        padding: 2.8rem 1.5rem;
        border-radius: var(--rayon);
        border: 1px dashed var(--trait-vive);
        background: rgb(255 255 255 / .02);
        color: var(--brume);
    }
    .vide i {
        width: 2.6rem; height: 2.6rem;
        display: flex !important;
        align-items: center;
        justify-content: center;
        border-radius: 12px;
        background: linear-gradient(140deg, var(--violet), var(--bleu));
        color: var(--nuit);
        margin-bottom: .2rem;
    }
    .vide i::before { display: block; font-size: 1.1rem !important; line-height: 1 !important; width: auto; height: auto; }
    .vide strong { color: var(--neige); font-size: 1rem; }
    .vide p { max-width: 32rem; font-size: .9rem; line-height: 1.5; margin: 0; }

    .item {
        --teinte1: var(--violet);
        --teinte2: var(--bleu);
        position: relative;
        border-radius: 18px;
        padding: 1.5px;
        background: linear-gradient(150deg, color-mix(in oklab, var(--teinte1) 45%, transparent), transparent 55%);
        transition: transform .2s cubic-bezier(.2,.8,.2,1);
    }
    .item:hover { transform: translateY(-3px); }
    .item--app { --teinte1: var(--corail); --teinte2: var(--ambre); }

    .item::before {
        content: "";
        position: absolute;
        left: 0; top: 0; right: 0; bottom: 0;
        border-radius: 18px;
        background: var(--roche);
        z-index: 0;
        margin: 1.5px;
    }

    @media (min-width: 52rem) {
        .item {
            display: grid;
            grid-template-columns: minmax(0, 1fr) auto;
            align-items: center;
        }
    }

    .item__main {
        position: relative;
        z-index: 1;
        display: grid;
        gap: .5rem;
        min-width: 0;
        padding: 1.3rem 1.4rem .6rem;
    }
    @media (min-width: 52rem) { .item__main { padding: 1.3rem 0 1.3rem 1.4rem; } }

    .item__main h3 { display: flex; align-items: center; gap: .65rem; }
    .item__main p { color: var(--brume); font-size: .92rem; max-width: 52ch; margin: 0; }

    .item__meta {
        display: flex;
        flex-wrap: wrap;
        gap: .4rem;
        list-style: none;
        padding: 0;
        margin-top: .1rem;
    }
    .item__meta li {
        padding: .2rem .55rem;
        border-radius: 999px;
        background: rgb(255 255 255 / .06);
        border: 1px solid var(--trait);
        color: var(--brume);
        font-size: .74rem;
        font-weight: 600;
        font-variant-numeric: tabular-nums;
    }

    .item__actions {
        position: relative;
        z-index: 1;
        display: flex;
        flex-wrap: wrap;
        gap: .5rem;
        align-items: center;
        padding: .6rem 1.4rem 1.4rem;
    }
    @media (min-width: 52rem) { .item__actions { padding: 1.3rem 1.4rem 1.3rem 0; } }

    /* ---------- Boutons ---------- */
    .btn {
        display: inline-flex;
        align-items: center;
        gap: .5rem;
        padding: .7rem 1.15rem;
        border: 1px solid transparent;
        border-radius: 12px;
        font-size: .88rem;
        font-weight: 700;
        text-decoration: none;
        cursor: pointer;
        white-space: nowrap;
        transition: transform .18s cubic-bezier(.2,.8,.2,1), box-shadow .18s, background .18s, border-color .18s, color .18s;
    }
    .btn--solid {
        background: linear-gradient(90deg, var(--teinte1, var(--violet)), var(--teinte2, var(--violet-clair)));
        color: var(--nuit);
        box-shadow: 0 10px 24px -12px color-mix(in oklab, var(--teinte1, var(--violet)) 70%, transparent);
    }
    .btn--solid:hover { transform: translateY(-2px); box-shadow: 0 14px 30px -12px color-mix(in oklab, var(--teinte1, var(--violet)) 80%, transparent); }
    .btn--ghost {
        background: rgb(255 255 255 / .05);
        border-color: var(--trait);
        color: var(--brume);
    }
    .btn--ghost:hover { color: var(--neige); border-color: var(--trait-vive); transform: translateY(-2px); background: rgb(255 255 255 / .09); }
    .btn i { font-size: .82rem; }

    /* ---------- Encart d'aide à l'installation ---------- */
    .primer {
        display: grid;
        gap: .7rem;
        padding: 1.4rem 1.5rem;
        border-radius: var(--rayon);
        background: linear-gradient(140deg, color-mix(in oklab, var(--violet) 14%, transparent), color-mix(in oklab, var(--bleu) 8%, transparent));
        border: 1px solid color-mix(in oklab, var(--violet) 28%, transparent);
    }
    .primer h3 { font-size: 1rem; }
    .primer ol { margin: 0; padding-left: 1.1rem; color: var(--brume); font-size: .9rem; display: grid; gap: .4rem; }
    .primer a { color: var(--violet-clair); font-weight: 600; }
    .kbd {
        display: inline-block;
        padding: .12rem .45rem;
        border-radius: 6px;
        background: rgb(255 255 255 / .1);
        border: 1px solid var(--trait-vive);
        color: var(--neige);
        font-size: .78rem;
        letter-spacing: .03em;
    }

    /* ---------- Formulaires ---------- */
    .form-block {
        position: relative;
        display: grid;
        gap: 1.35rem;
        padding: 2px;
        border-radius: 24px;
        background: linear-gradient(140deg, color-mix(in oklab, var(--violet) 55%, transparent), color-mix(in oklab, var(--corail) 35%, transparent));
    }
    .form-block::before {
        content: "";
        position: absolute; inset: 2px;
        border-radius: 22px;
        background: var(--roche);
        z-index: 0;
    }
    .form-block > * { position: relative; z-index: 1; }
    .form-block { padding: clamp(1.6rem, 3.4vw, 2.4rem); }
    .form-block > header { display: grid; gap: .4rem; }
    .form-block > header p { color: var(--brume); font-size: .92rem; max-width: 48ch; }

    .field { display: grid; gap: .45rem; }
    .field label { font-size: .84rem; color: var(--brume-sourde); font-weight: 600; }
    .field input, .field textarea, .field select {
        width: 100%;
        padding: .75rem .85rem;
        border: 1px solid var(--trait);
        border-radius: 12px;
        background: rgb(255 255 255 / .04);
        color: var(--neige);
        font-size: .95rem;
    }
    .field textarea { resize: vertical; min-height: 7rem; }
    .field input::placeholder, .field textarea::placeholder { color: color-mix(in oklab, var(--brume-sourde) 70%, transparent); }
    .field input:focus, .field textarea:focus, .field select:focus {
        outline: 2px solid var(--violet-clair);
        outline-offset: -1px;
        border-color: transparent;
    }

    .field-row { display: grid; gap: 1rem; }
    @media (min-width: 40rem) { .field-row { grid-template-columns: 1fr 1fr; } }

    .form-grid { display: grid; gap: 1rem; }
    .hp { position: absolute; left: -9999px; }

    /* ---------- Fenêtres modales (signalement, bientôt disponible) ----------
       Le reset (@layer reset, * { margin: 0 }) écrase le centrage par défaut
       du user-agent sur <dialog> une fois ouverte en showModal() : on le
       redéfinit nous-mêmes plutôt que de compter sur le comportement UA. */
    dialog {
        position: fixed;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
        margin: 0;
        width: min(32rem, calc(100vw - 2rem));
        max-height: calc(100vh - 2rem);
        overflow-y: auto;
        padding: 0;
        border: 1px solid var(--trait-vive);
        border-radius: var(--rayon);
        background: var(--roche);
        color: var(--neige);
    }
    dialog::backdrop { background: rgb(6 8 16 / .78); backdrop-filter: blur(4px); }
    .sheet { display: grid; gap: 1.15rem; padding: 1.5rem; }
    .sheet header { display: flex; align-items: start; gap: 1rem; }
    .sheet header div { flex: 1; display: grid; gap: .3rem; }
    .sheet header p { color: var(--brume); font-size: .88rem; }
    .sheet__close {
        border: 0; background: rgb(255 255 255 / .05); color: var(--brume);
        cursor: pointer; padding: .4rem; border-radius: 8px;
        transition: background .15s, color .15s;
    }
    .sheet__close:hover { color: var(--neige); background: rgb(255 255 255 / .1); }

    /* ---------- Pied de page ---------- */
    .foot {
        padding-top: 1.75rem;
        border-top: 1px solid var(--trait);
        color: var(--brume-sourde);
        font-size: .82rem;
        display: grid;
        gap: .4rem;
    }
    .foot a { color: var(--brume); }
    .foot a:hover { color: var(--neige); }

    /* ---------- Page de confirmation ----------
       Sur cette page, .thanks est seul dans .page (colonne large à côté du
       rail de nav) : sans justify-self, un bloc plus étroit que sa colonne
       reste collé à gauche et laisse un grand vide à droite. On le centre
       dans sa colonne, tout en gardant le texte aligné à gauche à
       l'intérieur — un bloc centré, pas un texte centré. */
    .thanks {
        min-height: 70dvh;
        display: grid;
        align-content: center;
        justify-items: start;
        justify-self: center;
        gap: 1.25rem;
        max-width: 34rem;
        text-align: left;
    }
    .thanks i {
        width: 3.2rem; height: 3.2rem;
        flex: none;
        display: flex !important; align-items: center; justify-content: center;
        border-radius: 14px;
        background: var(--degrade);
        color: var(--nuit);
    }
    .thanks i::before {
        display: block;
        font-size: 1.35rem !important;
        line-height: 1 !important;
        width: auto; height: auto;
    }
    .thanks p { color: var(--brume); }

    /* ---------- Bannière d'annonce (sortie d'une app) ----------
       Toute la bannière est un seul <a> : pas de bouton dans un lien
       (imbrication invalide), le .banniere__cta n'est qu'un faux bouton.
       Le fond empile trois couches : un dégradé de lisibilité par-dessus,
       le visuel au milieu, un dégradé de repli en dessous. Si le visuel
       manque dans /assets/img/, il échoue en silence et la bannière reste
       présentable — pas d'image cassée en ligne.

       Le visuel est un paysage 2.4:1 avec les téléphones à droite et du
       vide à gauche. En petit écran le conteneur devient presque carré :
       un cover cadrerait pile sur les téléphones, qui passeraient sous le
       texte. D'où deux mises en page — en bas puis à droite — et un
       dégradé de lisibilité qui pivote avec elles. */
    .banniere {
        position: relative;
        display: block;
        overflow: hidden;
        padding: clamp(1.6rem, 4vw, 2.6rem);
        min-height: 24rem;
        border-radius: var(--rayon);
        border: 1px solid var(--trait-vive);
        text-decoration: none;
        background:
            linear-gradient(180deg,
                var(--roche) 0%,
                color-mix(in oklab, var(--roche) 94%, transparent) 42%,
                color-mix(in oklab, var(--roche) 45%, transparent) 68%,
                color-mix(in oklab, var(--roche) 10%, transparent) 100%),
            url("/assets/img/bobine-banniere.jpg") 72% bottom / cover no-repeat,
            linear-gradient(160deg,
                color-mix(in oklab, var(--violet) 32%, var(--roche)),
                color-mix(in oklab, var(--corail) 24%, var(--roche)));
        transition: transform .25s cubic-bezier(.2,.8,.2,1), border-color .25s;
    }
    /* 75rem et pas le 62rem habituel : à 62rem le rail passe en colonne
       de gauche, donc la zone de contenu reste étroite (~640px) jusque
       vers 1200px de fenêtre. Basculer plus tôt ferait passer le
       paragraphe par-dessus les téléphones. */
    @media (min-width: 75rem) {
        .banniere {
            min-height: clamp(13rem, 26vw, 17rem);
            background:
                linear-gradient(100deg,
                    var(--roche) 0%,
                    color-mix(in oklab, var(--roche) 90%, transparent) 40%,
                    color-mix(in oklab, var(--roche) 35%, transparent) 72%,
                    color-mix(in oklab, var(--roche) 10%, transparent) 100%),
                url("/assets/img/bobine-banniere.jpg") center right / cover no-repeat,
                linear-gradient(120deg,
                    color-mix(in oklab, var(--violet) 32%, var(--roche)),
                    color-mix(in oklab, var(--corail) 24%, var(--roche)));
        }
    }
    .banniere:hover { transform: translateY(-3px); border-color: color-mix(in oklab, var(--corail) 45%, transparent); }

    .banniere__texte { position: relative; max-width: 32rem; display: grid; gap: .7rem; justify-items: start; }
    /* En disposition horizontale, le texte reste dans la moitié sombre :
       sans cette borne, les dernières lignes courent sous les téléphones. */
    @media (min-width: 75rem) { .banniere__texte { max-width: 62%; } }
    .banniere__badge {
        display: inline-flex; align-items: center; gap: .5rem;
        padding: .35rem .75rem;
        border-radius: 999px;
        border: 1px solid color-mix(in oklab, var(--vert) 35%, transparent);
        background: color-mix(in oklab, var(--vert) 12%, transparent);
        color: var(--vert);
        font-size: .72rem; font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
    }
    .banniere__badge .puce {
        width: 6px; height: 6px; border-radius: 50%; flex: none;
        background: var(--vert);
        animation: pulse-dispo 2.2s ease-in-out infinite;
    }
    .banniere h2 {
        font-size: clamp(1.5rem, 4vw, 2.1rem);
        line-height: 1.15;
        color: var(--neige);
    }
    .banniere h2 em {
        font-style: normal;
        background: var(--degrade);
        -webkit-background-clip: text;
        background-clip: text;
        color: transparent;
    }
    .banniere p { color: var(--brume); font-size: .95rem; line-height: 1.6; }
    .banniere__cta {
        display: inline-flex; align-items: center; gap: .5rem;
        margin-top: .4rem;
        padding: .7rem 1.15rem;
        border-radius: 12px;
        background: var(--degrade);
        color: var(--nuit);
        font-size: .9rem; font-weight: 700;
        box-shadow: 0 14px 30px -14px color-mix(in oklab, var(--corail) 70%, transparent);
        transition: transform .2s;
    }
    .banniere:hover .banniere__cta { transform: translateX(3px); }
    .banniere__cta i { display: flex !important; align-items: center; }
    .banniere__cta i::before { display: block; font-size: .8rem !important; line-height: 1 !important; width: auto; height: auto; }

    /* ---------- Projet en vedette (présentation détaillée d'une app) ----------
       Réservé aux applications qu'on veut mettre en avant plutôt que lister
       simplement : logo/nom, texte et points forts d'un côté, visuel de
       l'autre, tech-tag en bas. S'alterne visuellement via .projet--inverse. */
    .projet {
        --teinte1: var(--violet);
        --teinte2: var(--corail);
        position: relative;
        border-radius: 28px;
        padding: 2px;
        background: linear-gradient(150deg, color-mix(in oklab, var(--teinte1) 45%, transparent), color-mix(in oklab, var(--teinte2) 30%, transparent) 70%);
        overflow: hidden;
    }
    .projet__inner {
        position: relative;
        border-radius: 26px;
        background: var(--roche);
        padding: clamp(1.8rem, 4vw, 3rem);
        display: grid;
        gap: clamp(2rem, 5vw, 3rem);
    }
    @media (min-width: 58rem) {
        .projet__inner {
            /* La colonne visuelle est plafonnée à la largeur d'un téléphone :
               un écran de capture est portrait, lui laisser 1fr comme le texte
               ouvrait un grand vide sombre autour de l'image. */
            grid-template-columns: minmax(0, 1fr) minmax(0, 19rem);
            align-items: center;
        }
        .projet--inverse .projet__inner { direction: rtl; }
        .projet--inverse .projet__inner > * { direction: ltr; }
    }

    .projet__tete { display: flex; align-items: center; gap: .85rem; margin-bottom: .4rem; }
    .projet__logo {
        width: 3rem; height: 3rem;
        flex: none;
        display: flex !important; align-items: center; justify-content: center;
        border-radius: 14px;
        background: linear-gradient(140deg, var(--teinte1), var(--teinte2));
        color: var(--nuit);
    }
    .projet__logo::before { display: block; font-size: 1.3rem !important; line-height: 1 !important; width: auto; height: auto; }
    .projet__tete h3 { font-size: 1.5rem; }

    .projet__accroche {
        font-family: "Bricolage Grotesque", sans-serif;
        font-size: 1.2rem;
        font-weight: 700;
        line-height: 1.4;
        color: var(--neige);
        margin-bottom: .7rem;
    }
    .projet__texte { color: var(--brume); font-size: .95rem; line-height: 1.7; margin-bottom: 1.5rem; }
    .projet__texte strong { color: var(--neige); font-weight: 700; }

    .projet__points { display: grid; gap: .65rem; margin-bottom: 1.5rem; }
    .projet__point {
        display: flex; align-items: flex-start; gap: .85rem;
        padding: .85rem 1rem;
        border-radius: 12px;
        border: 1px solid var(--trait);
        background: rgb(255 255 255 / .03);
    }
    .projet__point i {
        flex: none;
        width: 1.9rem; height: 1.9rem;
        display: flex !important; align-items: center; justify-content: center;
        border-radius: 8px;
        background: color-mix(in oklab, var(--teinte1) 20%, transparent);
        color: var(--teinte2);
        margin-top: .1rem;
    }
    .projet__point i::before { display: block; font-size: .85rem !important; line-height: 1 !important; width: auto; height: auto; }
    .projet__point b { display: block; color: var(--neige); font-size: .85rem; font-weight: 700; letter-spacing: .02em; text-transform: uppercase; margin-bottom: .2rem; }
    .projet__point span { color: var(--brume); font-size: .84rem; line-height: 1.5; }

    .projet__tag {
        display: inline-flex; align-items: center; gap: .5rem;
        padding: .45rem .85rem;
        border-radius: 8px;
        border: 1px solid color-mix(in oklab, var(--teinte1) 30%, transparent);
        background: color-mix(in oklab, var(--teinte1) 10%, transparent);
        color: var(--teinte2);
        font-size: .78rem; font-weight: 700; letter-spacing: .03em; text-transform: uppercase;
    }
    .projet__tag .puce { width: 6px; height: 6px; border-radius: 50%; background: var(--teinte2); flex: none; }

    /* "Disponible" doit se lire au premier coup d'œil comme un feu vert,
       pas comme le corail de "bientôt disponible" : même forme, couleur
       différente, avec une pastille qui pulse comme un voyant en ligne. */
    .projet__tag--dispo {
        border-color: color-mix(in oklab, var(--vert) 35%, transparent);
        background: color-mix(in oklab, var(--vert) 12%, transparent);
        color: var(--vert);
    }
    .projet__tag--dispo .puce {
        background: var(--vert);
        animation: pulse-dispo 2.2s ease-in-out infinite;
    }
    @keyframes pulse-dispo {
        0%, 100% { opacity: 1; box-shadow: 0 0 0 0 color-mix(in oklab, var(--vert) 60%, transparent); }
        50% { opacity: .7; box-shadow: 0 0 0 5px transparent; }
    }

    .projet__actions { display: flex; flex-wrap: wrap; gap: .6rem; margin-top: 1.4rem; }

    /* Visuel : véritable capture d'écran de l'application. Pas de cadre
       autour — juste l'écran lui-même, posé sur la carte, avec un léger
       relief (ombre) pour le détacher du fond. */
    .projet__visuel {
        display: flex;
        align-items: center;
        justify-content: center;
        max-width: 15rem;
        margin-inline: auto;
    }

    /* Carrousel : plusieurs captures d'écran défilables au sein du même
       visuel. Les flèches et les points ne s'affichent que s'il y a plus
       d'une image (cf. app.js, qui masque le carrousel à une seule slide). */
    .projet__carousel {
        position: relative;
        width: 100%;
        border-radius: 22px;
        overflow: hidden;
        box-shadow: 0 30px 60px -24px rgb(0 0 0 / .6);
    }
    .projet__carousel-track {
        display: flex;
        transition: transform .4s cubic-bezier(.2,.8,.2,1);
    }
    .projet__carousel-track img {
        display: block;
        width: 100%;
        flex: none;
    }
    .projet__carousel-btn {
        position: absolute;
        top: 50%;
        transform: translateY(-50%);
        width: 2.2rem; height: 2.2rem;
        display: flex !important;
        align-items: center;
        justify-content: center;
        border-radius: 50%;
        border: 1px solid var(--trait-vive);
        background: rgb(10 11 20 / .65);
        color: var(--neige);
        backdrop-filter: blur(6px);
        cursor: pointer;
        transition: background .2s, transform .2s;
    }
    .projet__carousel-btn::before { display: block; font-size: .8rem !important; line-height: 1 !important; width: auto; height: auto; }
    .projet__carousel-btn:hover { background: rgb(10 11 20 / .85); transform: translateY(-50%) scale(1.06); }
    .projet__carousel-btn--prev { left: .6rem; }
    .projet__carousel-btn--next { right: .6rem; }
    .projet__carousel-dots {
        position: absolute;
        left: 0; right: 0; bottom: .7rem;
        display: flex; align-items: center; justify-content: center; gap: .4rem;
    }
    .projet__carousel-dots button {
        width: .45rem; height: .45rem;
        border-radius: 50%;
        border: none;
        padding: 0;
        background: rgb(255 255 255 / .35);
        cursor: pointer;
        transition: background .2s, transform .2s;
    }
    .projet__carousel-dots button.is-active { background: var(--neige); transform: scale(1.25); }
}

@layer utilities {
    .stack { display: grid; gap: 1rem; }
    .muted { color: var(--brume); }
    .lede { font-size: 1.05rem; }
    .visually-hidden {
        position: absolute; width: 1px; height: 1px;
        overflow: hidden; clip-path: inset(50%); white-space: nowrap;
    }
}
