/* ==========================================================================
   SHORTCUTLY — LANDING PAGE
   © Shortcutly — Aucune dépendance externe, 100% vanilla.
   Palette et police alignées sur l'application (cohérence de marque).
   ========================================================================== */

/* --- 1. JETONS & THÈMES ------------------------------------------------- */
:root {
    --accent: #e11d48;
    --accent-hover: #be123c;
    --accent-soft: rgba(225, 29, 72, 0.10);
    --accent-ring: rgba(225, 29, 72, 0.22);
    --accent-grad-a: #e11d48;
    --accent-grad-b: #be123c;

    --bg-body: #f7f8fc;
    --bg-surface: #ffffff;
    --bg-surface-2: #f1f3f9;
    --bg-glass: rgba(255, 255, 255, 0.72);
    --bg-inverse: #12121f;

    --text-primary: #0f172a;
    --text-secondary: #475569;
    --text-tertiary: #6b7484;   /* AA sur --bg-surface : 4,71 (etait 3,06) */
    --text-on-accent: #ffffff;

    --border-color: rgba(15, 23, 42, 0.09);
    --border-strong: rgba(15, 23, 42, 0.16);

    --ok: #0e9d68;
    --ok-soft: rgba(14, 157, 104, 0.10);

    --shadow-sm: 0 1px 2px rgba(15, 23, 42, .05), 0 1px 3px rgba(15, 23, 42, .04);
    --shadow-md: 0 4px 16px -4px rgba(15, 23, 42, .10), 0 2px 6px -2px rgba(15, 23, 42, .06);
    --shadow-lg: 0 24px 48px -16px rgba(15, 23, 42, .16), 0 8px 20px -8px rgba(15, 23, 42, .08);
    --shadow-accent: 0 12px 28px -10px rgba(225, 29, 72, .45);

    --radius-sm: 10px;
    --radius: 16px;
    --radius-lg: 22px;

    --maxw: 1180px;
    --nav-h: 66px;
}

[data-theme="dark"] {
    --accent: #fb7185;
    --accent-hover: #f43f5e;
    --accent-soft: rgba(251, 113, 133, 0.12);
    --accent-ring: rgba(251, 113, 133, 0.28);
    --accent-grad-a: #fb7185;
    --accent-grad-b: #e11d48;

    --bg-body: #0d0d1a;
    --bg-surface: #16162a;
    --bg-surface-2: #1c1c33;
    --bg-glass: rgba(22, 22, 42, 0.72);
    --bg-inverse: #06060d;

    --text-primary: #f1f5f9;
    --text-secondary: #a8b3c4;
    --text-tertiary: #8f9ab0;   /* AA sur --bg-surface : 6,27 (etait 4,21) */
    --text-on-accent: #1a0510;

    --border-color: rgba(255, 255, 255, 0.10);
    --border-strong: rgba(255, 255, 255, 0.18);

    --ok: #34d399;
    --ok-soft: rgba(52, 211, 153, 0.12);

    --shadow-sm: 0 1px 2px rgba(0, 0, 0, .4);
    --shadow-md: 0 4px 16px -4px rgba(0, 0, 0, .5);
    --shadow-lg: 0 24px 48px -16px rgba(0, 0, 0, .65);
    --shadow-accent: 0 12px 28px -10px rgba(251, 113, 133, .35);
}

/* --- 2. BASE ------------------------------------------------------------ */
*,
*::before,
*::after {
    box-sizing: border-box;
}

html {
    scroll-behavior: smooth;
    scroll-padding-top: calc(var(--nav-h) + 16px);
    scrollbar-gutter: stable;
    scrollbar-width: thin;
    scrollbar-color: var(--accent) var(--bg-surface-2);
    -webkit-text-size-adjust: 100%;
}

html::-webkit-scrollbar {
    width: 8px;
}

html::-webkit-scrollbar-track {
    background: var(--bg-surface-2);
}

html::-webkit-scrollbar-thumb {
    min-height: 44px;
    border: 2px solid var(--bg-surface-2);
    border-radius: 999px;
    background: linear-gradient(180deg, var(--accent-grad-a), var(--accent-grad-b));
}

html::-webkit-scrollbar-thumb:hover {
    background: var(--accent-hover);
}

body {
    margin: 0;
    background: var(--bg-body);
    color: var(--text-primary);
    font-family: 'Inter', system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
    font-size: 16.5px;
    line-height: 1.65;
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizeLegibility;
    overflow-x: hidden;
}

/* Halo de fond discret, rappel du glassmorphism de l'app */
body::before {
    content: "";
    position: fixed;
    inset: 0;
    z-index: -1;
    pointer-events: none;
    background:
        radial-gradient(720px 420px at 12% -6%, var(--accent-soft), transparent 60%),
        radial-gradient(620px 380px at 92% 4%, rgba(124, 58, 237, .07), transparent 62%);
}

img,
svg {
    max-width: 100%;
}

h1,
h2,
h3,
h4 {
    margin: 0;
    line-height: 1.15;
    letter-spacing: -0.022em;
    text-wrap: balance;
    font-weight: 800;
}

p {
    margin: 0;
}

a {
    color: var(--accent);
    text-decoration: none;
}

a:hover {
    color: var(--accent-hover);
}

ul {
    margin: 0;
    padding: 0;
    list-style: none;
}

button {
    font-family: inherit;
    font-size: inherit;
    cursor: pointer;
}

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

.skip-link {
    position: fixed;
    left: 0;
    top: 0;
    z-index: 200;
    background: var(--accent);
    color: #fff;
    padding: 12px 18px;
    border-radius: 0 0 10px 0;
    font-weight: 600;
    transform: translateY(-150%);
    transition: transform .18s ease;
}

.skip-link:focus {
    transform: none;
    color: #fff;
}

.wrap {
    width: 100%;
    max-width: var(--maxw);
    margin: 0 auto;
    padding: 0 clamp(18px, 4vw, 32px);
}

.visually-hidden {
    position: absolute !important;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
}

/* --- 3. TYPO UTILITAIRE ------------------------------------------------- */
.eyebrow {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-size: .78rem;
    font-weight: 700;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--accent);
    background: var(--accent-soft);
    border: 1px solid var(--accent-ring);
    padding: 6px 14px;
    border-radius: 13px;
}

.section-head {
    max-width: 720px;
    margin: 0 auto clamp(38px, 6vw, 60px);
    text-align: center;
}

.section-head h2 {
    font-size: clamp(1.75rem, 4vw, 2.6rem);
    margin: 18px 0 0;
}

.section-head p {
    color: var(--text-secondary);
    font-size: clamp(1rem, 2vw, 1.12rem);
    margin-top: 14px;
}

.grad-text {
    background: linear-gradient(120deg, var(--accent-grad-a), var(--accent-grad-b));
    -webkit-background-clip: text;
    background-clip: text;
    -webkit-text-fill-color: transparent;
    color: var(--accent);
}

section {
    padding: clamp(64px, 9vw, 112px) 0;
}

/* --- 4. BOUTONS --------------------------------------------------------- */
.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 9px;
    font-weight: 650;
    font-size: .97rem;
    padding: 13px 24px;
    border-radius: 12px;
    border: 1px solid transparent;
    transition: transform .18s ease, box-shadow .18s ease, background .18s ease, border-color .18s ease, color .18s ease;
    white-space: nowrap;
}

.btn:active {
    transform: translateY(1px);
}

.btn-primary {
    background: linear-gradient(135deg, var(--accent-grad-a), var(--accent-grad-b));
    color: #fff;
    box-shadow: var(--shadow-accent);
}

.btn-primary:hover {
    color: #fff;
    transform: translateY(-2px);
    box-shadow: 0 18px 34px -12px rgba(225, 29, 72, .55);
}

.btn-ghost {
    background: var(--bg-surface);
    color: var(--text-primary);
    border-color: var(--border-strong);
    box-shadow: var(--shadow-sm);
}

.btn-ghost:hover {
    color: var(--text-primary);
    border-color: var(--accent);
    transform: translateY(-2px);
}

.btn-lg {
    padding: 16px 30px;
    font-size: 1.03rem;
    border-radius: 14px;
}

.btn-block {
    width: 100%;
}

/* --- 5. NAVBAR ---------------------------------------------------------- */
.nav {
    position: sticky;
    top: 0;
    z-index: 100;
    height: var(--nav-h);
    display: flex;
    align-items: center;
    background: var(--bg-glass);
    backdrop-filter: blur(16px) saturate(180%);
    -webkit-backdrop-filter: blur(16px) saturate(180%);
    border-bottom: 1px solid transparent;
    transition: border-color .25s ease, box-shadow .25s ease;
}

.nav.is-scrolled {
    border-bottom-color: var(--border-color);
    box-shadow: var(--shadow-sm);
}

.nav-inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 20px;
    width: 100%;
    /* Reference de positionnement du menu centre ci-dessous. */
    position: relative;
}

.brand {
    display: inline-flex;
    align-items: center;
    gap: 11px;
    color: var(--text-primary);
    flex: none;
}

.brand:hover {
    color: var(--text-primary);
}

.brand-logo-full {
    display: block;
    width: clamp(132px, 12vw, 158px);
    line-height: 0;
}

.brand-logo-full img {
    display: block;
    width: 100%;
    height: auto;
}

.brand-logo-full .brand-logo-dark {
    display: none;
}

[data-theme="dark"] .brand-logo-full .brand-logo-light {
    display: none;
}

[data-theme="dark"] .brand-logo-full .brand-logo-dark {
    display: block;
}

/* CENTRE SUR LA BARRE, PAS ENTRE SES VOISINS.
   La marque et le bloc de commandes n'ont pas la meme largeur ; un simple
   « flex: 1 » centrerait le menu dans l'espace restant, c'est-a-dire
   legerement decale par rapport a l'ecran. Le positionnement absolu le pose
   au vrai milieu, et l'oeil le lit comme centre.

   « white-space: nowrap » evite qu'un libelle long ne casse sur deux lignes
   maintenant que l'element est sorti du flux. */
.nav-menu {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    display: flex;
    align-items: center;
    gap: 4px;
    white-space: nowrap;
}

.nav-link {
    color: var(--text-secondary);
    font-weight: 550;
    font-size: .93rem;
    padding: 9px 13px;
    border-radius: 9px;
    transition: color .18s ease, background .18s ease;
}

.nav-link:hover,
.nav-link.is-active {
    color: var(--text-primary);
    background: var(--accent-soft);
}

.nav-actions {
    display: flex;
    align-items: center;
    gap: 10px;
    flex: none;
}

.icon-btn {
    width: 40px;
    height: 40px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 11px;
    border: 1px solid var(--border-color);
    background: var(--bg-surface);
    color: var(--text-secondary);
    box-shadow: var(--shadow-sm);
    transition: color .18s ease, border-color .18s ease, transform .18s ease;
}

.icon-btn:hover {
    color: var(--accent);
    border-color: var(--accent);
    transform: translateY(-1px);
}

.icon-btn svg {
    width: 19px;
    height: 19px;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.9;
    stroke-linecap: round;
    stroke-linejoin: round;
}

#themeToggle .icon-sun {
    display: none;
}

[data-theme="dark"] #themeToggle .icon-sun {
    display: block;
}

[data-theme="dark"] #themeToggle .icon-moon {
    display: none;
}

.nav-burger {
    display: none;
}

/* Le bouton « Commencer » du menu ne sert qu'en version mobile :
   sur desktop c'est .nav-cta-desktop qui est affiché (sinon doublon). */
.nav-menu .btn {
    display: none;
}

/* --- 6. HERO ------------------------------------------------------------ */
.hero {
    padding-top: clamp(48px, 7vw, 84px);
    padding-bottom: clamp(56px, 8vw, 96px);
}

.hero-grid {
    display: grid;
    grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
    gap: clamp(32px, 5vw, 64px);
    align-items: center;
}

.hero h1 {
    font-size: clamp(2.15rem, 5.4vw, 3.75rem);
    margin: 22px 0 0;
    letter-spacing: -.03em;
}

.hero-sub {
    color: var(--text-secondary);
    font-size: clamp(1.03rem, 2.1vw, 1.2rem);
    margin-top: 20px;
    max-width: 56ch;
}

.hero-cta {
    display: flex;
    flex-wrap: wrap;
    gap: 13px;
    margin-top: 32px;
}

.hero-note {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px 18px;
    margin-top: 22px;
    color: var(--text-tertiary);
    font-size: .875rem;
}

.hero-note span {
    display: inline-flex;
    align-items: center;
    gap: 7px;
}

.hero-note svg {
    width: 15px;
    height: 15px;
    fill: none;
    stroke: var(--ok);
    stroke-width: 2.4;
    stroke-linecap: round;
    stroke-linejoin: round;
}

/* Clavier illustratif du hero */
.hero-visual {
    position: relative;
}

.kb-mock {
    background: var(--bg-surface);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-lg);
    padding: clamp(16px, 2.4vw, 24px);
}

.kb-mock-bar {
    display: flex;
    align-items: center;
    gap: 7px;
    margin-bottom: 16px;
}

.kb-mock-dot {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    background: var(--border-strong);
}

.kb-mock-title {
    margin-left: 8px;
    font-size: .78rem;
    font-weight: 600;
    color: var(--text-tertiary);
    letter-spacing: .04em;
}

/* Clavier miniature du hero */
.kbm {
    display: flex;
    flex-direction: column;
    gap: clamp(5px, .8vw, 7px);
}

.kbm-row {
    display: flex;
    gap: clamp(5px, .8vw, 7px);
    justify-content: center;
}

.kbm-key {
    flex: 1 1 0;
    min-width: 0;
    height: clamp(30px, 4.6vw, 42px);
    display: flex;
    align-items: center;
    justify-content: center;
    font-size: clamp(.66rem, 1.15vw, .8rem);
    font-weight: 650;
    color: var(--text-secondary);
    background: var(--bg-surface-2);
    border: 1px solid var(--border-color);
    border-bottom: 3px solid var(--border-strong);
    border-radius: 8px;
    transition: transform .2s ease;
}

.kbm-key.kbm-w2 {
    flex: 1.5 1 0;
}

.kbm-key.kbm-space {
    flex: 4 1 0;
}

.kbm-key.is-hot {
    color: #fff;
    background: linear-gradient(135deg, var(--accent-grad-a), var(--accent-grad-b));
    border-color: var(--accent-hover);
    border-bottom-color: var(--accent-hover);
    box-shadow: var(--shadow-accent);
    transform: translateY(-1px);
}

.kb-mock-caption {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    flex-wrap: wrap;
    margin-top: 16px;
    padding-top: 15px;
    border-top: 1px dashed var(--border-color);
}

.kb-mock-caption strong {
    font-size: .95rem;
    font-weight: 700;
}

.kb-mock-caption em {
    font-style: normal;
    font-size: .82rem;
    color: var(--text-tertiary);
}

.kb-combo {
    display: inline-flex;
    align-items: center;
    gap: 6px;
}

.kcap {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 30px;
    height: 30px;
    padding: 0 9px;
    font-size: .8rem;
    font-weight: 700;
    color: var(--text-primary);
    background: var(--bg-surface-2);
    border: 1px solid var(--border-strong);
    border-bottom-width: 3px;
    border-radius: 8px;
}

.kcap.is-hot {
    color: #fff;
    background: linear-gradient(135deg, var(--accent-grad-a), var(--accent-grad-b));
    border-color: var(--accent-hover);
}

.kb-plus {
    color: var(--text-tertiary);
    font-weight: 700;
    font-size: .8rem;
}

/* --- 7. BANDEAU DE CHIFFRES --------------------------------------------- */
.stats {
    padding: 0 0 clamp(52px, 7vw, 84px);
}

#categories {
    padding-top: 0;
    scroll-margin-top: 96px;
}

#categories .section-head h2 {
    margin-top: 0;
}

.stats-grid {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: clamp(12px, 1.4vw, 18px);
}

/* Four quiet proof points. The light comes from layered colors rather than
   backdrop-filter, so the existing scroll reveal stays inexpensive. */
.stat {
    --stat-glow: rgba(225, 29, 72, .15);
    appearance: none;
    position: relative;
    isolation: isolate;
    overflow: hidden;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    width: 100%;
    min-height: 164px;
    padding: 24px 16px 21px;
    border: 1px solid rgba(255, 255, 255, .9);
    border-radius: 22px;
    background: linear-gradient(145deg, rgba(255, 255, 255, .98), rgba(249, 246, 255, .88));
    color: inherit;
    font: inherit;
    text-align: center;
    cursor: pointer;
    touch-action: manipulation;
    box-shadow: 0 18px 42px -28px rgba(49, 34, 93, .28),
                0 3px 12px rgba(49, 34, 93, .05),
                inset 0 1px rgba(255, 255, 255, .9);
    transition: transform .25s cubic-bezier(.2, .8, .3, 1),
                box-shadow .25s ease,
                border-color .25s ease;
}

.stat:focus-visible {
    outline: 3px solid var(--accent);
    outline-offset: 3px;
}

.stat::before {
    content: '';
    position: absolute;
    z-index: -1;
    inset: 0;
    background: radial-gradient(ellipse at 50% -10%, var(--stat-glow), transparent 66%);
    pointer-events: none;
}

.stat::after {
    content: '';
    position: absolute;
    top: 0;
    left: 50%;
    width: 58px;
    height: 2px;
    border-radius: 0 0 2px 2px;
    background: linear-gradient(90deg, transparent, var(--accent), transparent);
    transform: translateX(-50%);
    pointer-events: none;
}

.stat:nth-child(2) { --stat-glow: rgba(125, 88, 208, .16); }
.stat:nth-child(3) { --stat-glow: rgba(87, 139, 217, .15); }
.stat:nth-child(4) {
    --stat-glow: rgba(225, 29, 72, .19);
    border-color: rgba(225, 29, 72, .18);
    background: linear-gradient(145deg, rgba(255, 250, 252, .98), rgba(251, 242, 250, .92));
}

@media (hover: hover) {
    .stat:hover {
        border-color: var(--accent-ring);
        box-shadow: 0 22px 44px -26px rgba(71, 41, 108, .3),
                    0 6px 18px rgba(49, 34, 93, .08),
                    inset 0 1px rgba(255, 255, 255, .9);
    }
}

.stat-num {
    position: relative;
    display: block;
    min-width: 3ch;
    font-size: clamp(2.4rem, 4vw, 3.25rem);
    font-weight: 850;
    letter-spacing: -.035em;
    line-height: 1;
    font-variant-numeric: tabular-nums;
    background: linear-gradient(135deg, var(--accent-grad-a), var(--accent-grad-b));
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
    -webkit-text-fill-color: transparent;
}

@supports not ((-webkit-background-clip: text) or (background-clip: text)) {
    .stat-num {
        color: var(--accent);
        -webkit-text-fill-color: currentColor;
    }
}

.stat-label {
    position: relative;
    margin-top: 12px;
    color: var(--text-secondary);
    font-size: .73rem;
    font-weight: 750;
    letter-spacing: .075em;
    line-height: 1.25;
    text-transform: uppercase;
}

.stat-detail {
    position: relative;
    margin-top: 6px;
    color: var(--text-tertiary);
    font-size: .72rem;
    font-weight: 500;
    line-height: 1.3;
}

[data-theme="dark"] .stat {
    border-color: rgba(255, 255, 255, .13);
    background: linear-gradient(145deg, rgba(35, 33, 61, .98), rgba(21, 23, 45, .96));
    box-shadow: 0 20px 44px -26px rgba(0, 0, 0, .7),
                inset 0 1px rgba(255, 255, 255, .07);
}

[data-theme="dark"] .stat:nth-child(4) {
    border-color: rgba(251, 113, 133, .27);
    background: linear-gradient(145deg, rgba(49, 29, 57, .98), rgba(28, 23, 47, .97));
}

@media (hover: hover) {
    [data-theme="dark"] .stat:hover {
        border-color: var(--accent-ring);
        box-shadow: 0 22px 44px -24px rgba(0, 0, 0, .8),
                    inset 0 1px rgba(255, 255, 255, .1);
    }
}

@media (max-width: 600px) {
    .stat { min-height: 152px; padding: 21px 10px 18px; }
    .stat-num { font-size: clamp(2.25rem, 10vw, 2.8rem); }
    .stat-label { font-size: .67rem; letter-spacing: .055em; }
    .stat-detail { font-size: .68rem; }
}

/* --- 8. FONCTIONNALITÉS -------------------------------------------------- */
/* ==========================================================================
   FONCTIONNALITES — DES CARTES QUI RESPIRENT

   CE QUI N'ALLAIT PAS
     Neuf cartes rigoureusement identiques, alignees trois par trois : un
     tableau, pas une presentation. L'oeil n'avait aucune raison de s'arreter
     quelque part, et l'ensemble se parcourait sans rien retenir.

   CE QUI CHANGE
     • une lueur coloree tres douce apparait au survol, depuis le coin de
       l'icone — la carte devient vivante sans clignoter ;
     • l'icone quitte sa pastille plate pour un degrade et une ombre portee
       de sa propre couleur : elle prend du relief au lieu d'etre posee ;
     • un filet lumineux traverse le haut de la carte au survol, comme un
       reflet sur du verre. C'est ce detail qui donne l'impression de soin ;
     • les deux fonctionnalites Pro portent un accent chaud permanent : on
       repere ce qui est payant sans lire les pastilles.

   Tout est en transitions courtes (.25s) et en deplacements de 2 a 3 px :
   au-dela, une grille de neuf cartes qui bougent devient fatigante.
   ========================================================================== */
.features-grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 20px;
}

.feature {
    position: relative;
    isolation: isolate;
    overflow: hidden;
    background: var(--bg-surface);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-lg);
    padding: 28px 26px 26px;
    box-shadow: var(--shadow-sm);
    transition: transform .25s cubic-bezier(.2, .8, .3, 1),
                box-shadow .25s ease,
                border-color .25s ease;
}

/* La lueur : un cercle diffus place en haut a gauche, la ou se trouve
   l'icone. Invisible au repos, il monte doucement au survol. Pose en
   pseudo-element pour ne rien coder en JavaScript et ne rien repeindre
   d'autre que cette couche. */
.feature::before {
    content: '';
    position: absolute;
    z-index: -1;
    top: -40%;
    left: -20%;
    width: 240px;
    height: 240px;
    border-radius: 50%;
    background: radial-gradient(circle, var(--accent-soft), transparent 68%);
    opacity: 0;
    transition: opacity .3s ease;
}

/* Le filet lumineux en haut de carte. */
.feature::after {
    content: '';
    position: absolute;
    inset: 0 0 auto;
    height: 1px;
    background: linear-gradient(90deg,
            transparent,
            var(--accent-ring) 30%,
            var(--accent-ring) 70%,
            transparent);
    opacity: 0;
    transition: opacity .3s ease;
}

.feature:hover {
    transform: translateY(-3px);
    box-shadow: var(--shadow-lg);
    border-color: var(--accent-ring);
}

.feature:hover::before,
.feature:hover::after {
    opacity: 1;
}

.feature-ico {
    width: 50px;
    height: 50px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 15px;
    background: linear-gradient(145deg, var(--accent-grad-a), var(--accent-grad-b));
    color: #fff;
    margin-bottom: 18px;
    /* L'ombre reprend la couleur de l'icone : elle la fait flotter au lieu de
       la poser sur un fond gris. */
    box-shadow: 0 8px 18px -8px var(--accent-grad-b);
    transition: transform .25s cubic-bezier(.2, .8, .3, 1);
}

.feature:hover .feature-ico {
    transform: translateY(-2px) rotate(-4deg) scale(1.04);
}

.feature-ico svg {
    width: 24px;
    height: 24px;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.9;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.feature h3 {
    font-size: 1.08rem;
    font-weight: 750;
    letter-spacing: -.015em;
    margin-bottom: 9px;
}

.feature p {
    color: var(--text-secondary);
    font-size: .94rem;
    line-height: 1.68;
}

/* --- Les deux fonctionnalites Pro se distinguent en permanence ---------
   Elles portent deja une pastille « Pro », mais une pastille se lit ; un
   fond se voit. Sur une grille de neuf, c'est ce qui permet de comprendre
   l'offre sans la dechiffrer. */
.feature:has(.badge-pro) {
    background: linear-gradient(160deg,
            var(--accent-soft) 0%,
            var(--bg-surface) 42%);
    border-color: var(--accent-ring);
}

.feature:has(.badge-pro) .feature-ico {
    box-shadow: 0 10px 22px -8px var(--accent-grad-b);
}

@media (prefers-reduced-motion: reduce) {

    .feature,
    .feature-ico {
        transition: none;
    }

    .feature:hover {
        transform: none;
    }

    .feature:hover .feature-ico {
        transform: none;
    }
}

.badge-pro {
    position: absolute;
    top: 18px;
    right: 18px;
    font-size: .64rem;
    font-weight: 800;
    letter-spacing: .09em;
    text-transform: uppercase;
    color: #fff;
    background: linear-gradient(135deg, var(--accent-grad-a), var(--accent-grad-b));
    padding: 4px 9px;
    border-radius: 13px;
}

.badge-free {
    position: absolute;
    top: 18px;
    right: 18px;
    font-size: .64rem;
    font-weight: 800;
    letter-spacing: .09em;
    text-transform: uppercase;
    color: var(--ok);
    background: var(--ok-soft);
    border: 1px solid currentColor;
    padding: 3px 9px;
    border-radius: 100px;
}

/* --- 9. COMMENT ÇA MARCHE ----------------------------------------------- */
/* ==========================================================================
   COMMENT CA MARCHE — TROIS ETAPES QUI SE SUIVENT

   Trois cartes cote a cote, identiques, ne disent pas « 1 puis 2 puis 3 » :
   elles disent « voici trois choses ». Le trait qui relie les numeros retablit
   l'enchainement, qui est tout le propos de la section.

   Le trait est purement decoratif et disparait des que les cartes s'empilent
   (il pointerait alors dans le vide, a l'horizontale).
   ========================================================================== */
.steps {
    position: relative;
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 20px;
    counter-reset: step;
}

/* Le fil conducteur, aligne sur le centre des pastilles numerotees
   (30 px de padding haut + 21 px de demi-pastille). */
.steps::before {
    content: '';
    position: absolute;
    left: 12%;
    right: 12%;
    top: 51px;
    height: 2px;
    background: linear-gradient(90deg,
            transparent,
            var(--accent-ring) 12%,
            var(--accent-ring) 88%,
            transparent);
    z-index: 0;
}

.step {
    position: relative;
    /* Au-dessus du fil, sinon celui-ci traverserait les cartes. */
    z-index: 1;
    background: var(--bg-surface);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-lg);
    padding: 30px 26px 28px;
    box-shadow: var(--shadow-sm);
    transition: transform .25s cubic-bezier(.2, .8, .3, 1),
                box-shadow .25s ease,
                border-color .25s ease;
}

.step:hover {
    transform: translateY(-3px);
    box-shadow: var(--shadow-lg);
    border-color: var(--accent-ring);
}

.step h3 {
    font-size: 1.06rem;
    font-weight: 750;
    letter-spacing: -.015em;
    margin-bottom: 9px;
}

.step p {
    color: var(--text-secondary);
    font-size: .94rem;
    line-height: 1.68;
}

/* Pastille ronde plutot que carree : elle se lit comme un jalon sur le fil,
   et non comme une icone de plus. */
.step-num {
    width: 42px;
    height: 42px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    font-weight: 800;
    font-size: 1.05rem;
    color: #fff;
    background: linear-gradient(135deg, var(--accent-grad-a), var(--accent-grad-b));
    box-shadow: var(--shadow-accent);
    margin-bottom: 18px;
    /* Anneau de la couleur du fond : le fil semble passer DERRIERE la
       pastille au lieu de la toucher. */
    outline: 5px solid var(--bg-body);
    transition: transform .25s cubic-bezier(.2, .8, .3, 1);
}

.step:hover .step-num {
    transform: scale(1.07);
}

.step h3 {
    font-size: 1.08rem;
    font-weight: 700;
    margin-bottom: 8px;
}

.step p {
    color: var(--text-secondary);
    font-size: .94rem;
}

/* --- 10. CATÉGORIES ------------------------------------------------------ */
.cats {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 11px;
}

/* ==========================================================================
   CATEGORIES — LA COULEUR DE CHAQUE PASTILLE LUI APPARTIENT

   Chaque categorie porte deja sa couleur dans un point de 10 px, defini en
   attribut « style » dans le HTML. On la recupere ici pour la faire vivre au
   survol : le point grandit, une lueur de SA couleur apparait derriere lui.

   Astuce employee : la couleur n'existe que sur le point (.cat-dot), pas sur
   la pastille. On ne peut donc pas la lire en CSS depuis le parent. Mais un
   « box-shadow: currentColor » applique AU POINT donne exactement l'effet
   recherche, sans une seule ligne de JavaScript et sans dupliquer les
   quatorze couleurs dans la feuille de style — ou elles finiraient par
   diverger de celles du HTML.
   ========================================================================== */
.cat-pill {
    display: inline-flex;
    align-items: center;
    gap: 9px;
    background: var(--bg-surface);
    border: 1px solid var(--border-color);
    border-radius: 100px;
    padding: 9px 17px 9px 13px;
    font-size: .91rem;
    font-weight: 600;
    box-shadow: var(--shadow-sm);
    cursor: default;
    transition: transform .22s cubic-bezier(.2, .8, .3, 1),
                border-color .22s ease,
                box-shadow .22s ease;
}

.cat-pill:hover {
    transform: translateY(-3px);
    border-color: var(--border-strong);
    box-shadow: var(--shadow-md);
}

.cat-dot {
    width: 10px;
    height: 10px;
    border-radius: 50%;
    flex: none;
    /* La couleur de la categorie est posee en « color » dans le HTML ; c'est
       elle qu'on peint ici, et qu'on reutilise pour l'anneau au survol. */
    background: currentColor;
    /* « currentColor » vaut ici la couleur de fond posee en attribut style :
       on la reutilise pour l'anneau, sans la reecrire. */
    transition: transform .22s cubic-bezier(.2, .8, .3, 1),
                box-shadow .22s ease;
}

.cat-pill:hover .cat-dot {
    transform: scale(1.25);
    box-shadow: 0 0 0 4px color-mix(in srgb, currentColor 22%, transparent);
}

/* --- 11. COMPARATIF ------------------------------------------------------ */
.compare-wrap {
    overflow-x: auto;
    border: 1px solid var(--border-color);
    border-radius: var(--radius);
    background: var(--bg-surface);
    box-shadow: var(--shadow-sm);
}

table.compare {
    width: 100%;
    min-width: 560px;
    border-collapse: collapse;
    font-size: .95rem;
}

table.compare th,
table.compare td {
    padding: 15px 20px;
    text-align: left;
    border-bottom: 1px solid var(--border-color);
}

table.compare thead th {
    background: var(--bg-surface-2);
    font-size: .8rem;
    font-weight: 700;
    letter-spacing: .05em;
    text-transform: uppercase;
    color: var(--text-secondary);
}

table.compare thead th:not(:first-child) {
    text-align: center;
    width: 22%;
}

table.compare tbody td:not(:first-child) {
    text-align: center;
}

table.compare tbody tr:last-child td {
    border-bottom: none;
}

table.compare td:first-child {
    font-weight: 600;
}

table.compare td small {
    display: block;
    font-weight: 400;
    color: var(--text-tertiary);
    font-size: .82rem;
    margin-top: 2px;
}

.tick {
    color: var(--ok);
    font-weight: 800;
}

.cross {
    color: var(--text-tertiary);
}

/* --- 12. TARIFS ---------------------------------------------------------- */
.cur-switch {
    display: inline-flex;
    gap: 3px;
    padding: 4px;
    background: var(--bg-surface-2);
    border: 1px solid var(--border-color);
    border-radius: 100px;
    margin: 22px auto 0;
}

.cur-btn {
    border: none;
    background: transparent;
    color: var(--text-secondary);
    font-weight: 650;
    font-size: .86rem;
    padding: 8px 17px;
    border-radius: 100px;
    transition: background .18s ease, color .18s ease;
}

.cur-btn:hover {
    color: var(--text-primary);
}

.cur-btn.is-active {
    background: var(--bg-surface);
    color: var(--accent);
    box-shadow: var(--shadow-sm);
}


/* --- SÉLECTEUR DE LANGUE (barre de navigation) --------------------------

   Un BOUTON, pas une bascule. Deux langues tiendraient dans une bascule
   « FR | EN » ; une troisième n'y tiendrait plus, et il faudrait alors
   redessiner la barre entière. Le bouton porte la langue en cours, la liste
   s'ouvre au clic : la forme ne change pas quand la liste s'allonge.

   Les langues y sont nommées DANS LEUR PROPRE LANGUE — « English », jamais
   « Anglais » : on cherche la sienne, et on la cherche telle qu'on la nomme. */
.lang-menu {
    position: relative;
    display: inline-flex;
}

.lang-current {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    min-height: 38px;
    padding: 5px 9px;
    background: var(--bg-surface-2);
    border: 1px solid var(--border-color);
    border-radius: 999px;
    color: var(--text-secondary);
    font-weight: 700;
    font-size: .78rem;
    letter-spacing: .02em;
    cursor: pointer;
    transition: background .18s ease, color .18s ease, border-color .18s ease;
}

.lang-flag {
    display: block;
    width: 18px;
    height: 12px;
    border-radius: 2px;
    object-fit: cover;
    box-shadow: 0 0 0 1px rgba(15, 23, 42, .12);
    flex: none;
}

.lang-current svg {
    width: 15px;
    height: 15px;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.8;
    stroke-linecap: round;
    stroke-linejoin: round;
    flex: none;
}

.lang-current .lang-chevron {
    width: 12px;
    height: 12px;
    opacity: .7;
    transition: transform .2s ease;
}

.lang-menu.is-open .lang-chevron {
    transform: rotate(180deg);
}

.lang-current:hover,
.lang-menu.is-open .lang-current {
    color: var(--text-primary);
    border-color: var(--border-strong);
}

.lang-list {
    position: absolute;
    top: calc(100% + 8px);
    right: 0;
    z-index: 60;
    min-width: 9.5rem;
    margin: 0;
    padding: 5px;
    list-style: none;
    /* Opaque, et non « en verre » : cette liste s'ouvre par-dessus le
       contenu de la page, qui la traverserait sinon de part en part. */
    background: var(--bg-surface);
    border: 1px solid var(--border-color);
    border-radius: 12px;
    box-shadow: var(--shadow-lg);
    animation: langOuvre .14s ease-out;
}

@keyframes langOuvre {
    from { opacity: 0; transform: translateY(-4px); }
    to   { opacity: 1; transform: none; }
}

.lang-list button {
    display: flex;
    align-items: center;
    justify-content: flex-start;
    gap: 9px;
    width: 100%;
    padding: 9px 11px;
    border: none;
    background: transparent;
    border-radius: 8px;
    color: var(--text-secondary);
    font: inherit;
    font-size: .86rem;
    font-weight: 600;
    text-align: left;
    cursor: pointer;
    transition: background .15s ease, color .15s ease;
}

.lang-list button:hover {
    background: var(--bg-surface-2);
    color: var(--text-primary);
}

/* La langue en cours porte une coche : sans elle, la liste ouverte ne dit
   pas où l'on se trouve — seulement où l'on peut aller. */
/* La langue en cours se distingue par la COULEUR et la GRAISSE, sans
   caractère décoratif : une coche écrite en échappement CSS s'était déjà
   perdue en route et laissait « ¹3 » à côté du libellé. Deux signaux
   typographiques disent la même chose, et rien ne peut se casser. */
.lang-list button.is-active {
    color: var(--accent);
    font-weight: 800;
}

@media (max-width: 560px) {
    .lang-current {
        padding: 5px 8px;
    }
}

.plans {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 20px;
    align-items: start;
}

.plan {
    position: relative;
    display: flex;
    flex-direction: column;
    background: var(--bg-surface);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-lg);
    padding: 30px 26px 28px;
    box-shadow: var(--shadow-sm);
    height: 100%;
}

.plan.is-featured {
    border-color: var(--accent);
    box-shadow: var(--shadow-lg);
}

.plan-flag {
    position: absolute;
    top: -13px;
    left: 50%;
    transform: translateX(-50%);
    font-size: .68rem;
    font-weight: 800;
    letter-spacing: .09em;
    text-transform: uppercase;
    color: #fff;
    background: linear-gradient(135deg, var(--accent-grad-a), var(--accent-grad-b));
    padding: 6px 15px;
    border-radius: 100px;
    box-shadow: var(--shadow-accent);
    white-space: nowrap;
}

/* L'en-tête est centré sur les trois cartes : le regard descend en colonne
   (nom → prix → avantages → bouton) au lieu de zigzaguer entre un titre à
   gauche et un prix à gauche. */
.plan-head {
    text-align: center;
}

.plan-name {
    font-size: 1.16rem;
    font-weight: 800;
}

/* « Pro » ne porte plus sa durée : la bascule au-dessus la dit, et le prix
   la confirme. Répéter « Mensuel » dans le titre obligeait à lire deux
   endroits pour une seule information. Le nom peut donc respirer. */
.plan-name-xl {
    font-size: clamp(1.5rem, 3.2vw, 1.85rem);
    letter-spacing: -.03em;
    line-height: 1.1;
}

.plan-desc {
    color: var(--text-secondary);
    font-size: .9rem;
    margin-top: 6px;
    min-height: 42px;
}

.plan-price {
    display: flex;
    align-items: baseline;
    justify-content: center;
    gap: 7px;
    margin: 18px 0 4px;
    flex-wrap: wrap;
}

.plan-amount {
    font-size: clamp(2rem, 4.2vw, 2.6rem);
    font-weight: 800;
    letter-spacing: -.035em;
    font-variant-numeric: tabular-nums;
}

.plan-period {
    color: var(--text-tertiary);
    font-size: .92rem;
    font-weight: 550;
}

/* Prix barré, affiché seulement quand une promotion est réellement active.
   Sans lui, une remise saisie dans la console ferait simplement baisser le
   chiffre : le visiteur verrait un prix bas, sans jamais savoir qu'il y
   gagne quelque chose — toute la valeur de la promotion serait perdue.
   Le montant reste lu côté serveur ; on n'affiche ici que ce qu'il renvoie. */
.plan-was {
    color: var(--text-tertiary);
    font-size: 1.05rem;
    font-weight: 600;
    text-decoration: line-through;
    text-decoration-thickness: 2px;
    font-variant-numeric: tabular-nums;
    opacity: .75;
}

.plan-alt {
    color: var(--text-tertiary);
    font-size: .84rem;
    min-height: 22px;
}

/* ⚠ L'ORDRE VERTICAL A CHANGÉ, ET C'EST VOULU.

   Le bouton se trouvait AVANT la liste des avantages : on demandait de
   choisir avant d'avoir montré ce qu'on vend. Il est désormais en bas, et
   c'est la liste qui pousse — `flex: 1` sur les avantages, `margin-top:auto`
   sur le bouton. Les trois cartes gardent ainsi leurs boutons alignés même
   quand elles n'ont pas le même nombre de lignes. */
.plan-feats {
    display: flex;
    flex-direction: column;
    gap: 11px;
    font-size: .92rem;
    flex: 1 1 auto;
    margin-top: 4px;
}

.plan-cta {
    margin-top: auto;
    padding-top: 24px;
}

.plan-feats li {
    display: flex;
    gap: 10px;
    align-items: flex-start;
    color: var(--text-secondary);
}

.plan-feats svg {
    width: 17px;
    height: 17px;
    flex: none;
    margin-top: 3px;
    fill: none;
    stroke-width: 2.4;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.plan-feats .yes svg {
    stroke: var(--ok);
}

.plan-feats .no {
    color: var(--text-tertiary);
}

.plan-feats .no svg {
    stroke: var(--text-tertiary);
}

.plan-feats strong {
    color: var(--text-primary);
    font-weight: 650;
}

.pricing-foot {
    text-align: center;
    color: var(--text-tertiary);
    font-size: .88rem;
    margin-top: 28px;
}

/* --- 13. LICENCE --------------------------------------------------------- */
.license-box {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: clamp(26px, 4vw, 50px);
    align-items: center;
    background: var(--bg-surface);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-lg);
    padding: clamp(26px, 4vw, 44px);
    box-shadow: var(--shadow-md);
}

.license-box h3 {
    font-size: clamp(1.3rem, 2.6vw, 1.7rem);
    margin-bottom: 12px;
}

.license-box p {
    color: var(--text-secondary);
    font-size: .97rem;
}

.license-points {
    display: flex;
    flex-direction: column;
    gap: 12px;
    margin-top: 20px;
}

.license-points li {
    display: flex;
    gap: 11px;
    align-items: flex-start;
    color: var(--text-secondary);
    font-size: .93rem;
}

.license-points svg {
    width: 18px;
    height: 18px;
    flex: none;
    margin-top: 3px;
    fill: none;
    stroke: var(--accent);
    stroke-width: 2.1;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.key-demo {
    background: var(--bg-inverse);
    border-radius: var(--radius);
    padding: 26px 22px;
    text-align: center;
    box-shadow: var(--shadow-lg);
}

.key-demo-label {
    font-size: .7rem;
    letter-spacing: .13em;
    text-transform: uppercase;
    color: #7b8598;
    font-weight: 700;
}

.key-demo-code {
    display: block;
    margin-top: 14px;
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: clamp(.92rem, 2.1vw, 1.16rem);
    font-weight: 600;
    letter-spacing: .07em;
    color: #fff;
    word-break: break-all;
}

.key-demo-code .seg-plan {
    color: #fb7185;
}

.key-demo-foot {
    margin-top: 14px;
    font-size: .78rem;
    color: #7b8598;
}

/* --- 14. NOUVEAUTÉS ------------------------------------------------------ */
/* ==========================================================================
   DÉCOR ET PROFONDEUR  (site/js/parallaxe.js)

   Des halos de couleur très diffus, posés derrière le contenu. Leur rôle
   n'est pas d'être remarqués : c'est de donner à la parallaxe quelque chose
   à décaler. Un décalage de profondeur ne se voit que s'il y a un
   arrière-plan par rapport auquel se décaler — sur un aplat uniforme,
   l'effet est rigoureusement invisible.

   ── POURQUOI « pointer-events: none » PARTOUT ────────────────────────────
   Ces éléments couvrent de larges surfaces. Sans cela, ils intercepteraient
   les clics destinés aux boutons et aux liens qu'ils recouvrent — un décor
   ne doit jamais pouvoir empêcher une action.

   ── POURQUOI « will-change » N'EST PAS ICI ───────────────────────────────
   Il est tentant de l'ajouter « pour aider ». En réalité, il force la
   création d'une couche de composition permanente pour chaque halo, occupée
   en mémoire vidéo même immobile. Sur mobile, une demi-douzaine de couches
   de 500 px suffit à faire ramer le reste. Le navigateur promeut de
   lui-même ce qui bouge : translate3d() dans le script y suffit.
   ========================================================================== */

.hero-decor,
.section-decor {
    position: absolute;
    inset: 0;
    overflow: hidden;
    pointer-events: none;
    z-index: 0;
}

/* Le contenu passe devant le décor. Sans cette élévation, la « wrap » et le
   décor se disputeraient l'ordre d'empilement selon leur ordre dans le HTML. */
.hero > .wrap,
#categories > .wrap,
#tarifs > .wrap {
    position: relative;
    z-index: 1;
}

.hero,
#categories,
#tarifs {
    position: relative;
    overflow: hidden;
}

.orbe {
    position: absolute;
    display: block;
    border-radius: 50%;
    /* Le flou fait tout le travail : sans lui, ce sont des ronds de couleur ;
       avec, ce sont des lumières. */
    filter: blur(70px);
    opacity: .55;
    /* Volontairement sans transition : ces éléments sont déplacés à chaque
       image par le script. Une transition les ferait courir après leur
       propre position, et l'effet deviendrait mou. */
}

.orbe-1 {
    top: -140px;
    left: -80px;
    width: 460px;
    height: 460px;
    background: radial-gradient(circle, rgba(244, 63, 94, .42), transparent 68%);
}

.orbe-2 {
    top: 120px;
    right: -120px;
    width: 520px;
    height: 520px;
    background: radial-gradient(circle, rgba(190, 18, 60, .30), transparent 70%);
}

.orbe-3 {
    bottom: -180px;
    left: 38%;
    width: 380px;
    height: 380px;
    background: radial-gradient(circle, rgba(251, 113, 133, .26), transparent 70%);
}

.orbe-cat {
    top: 10%;
    right: -140px;
    width: 440px;
    height: 440px;
    background: radial-gradient(circle, rgba(244, 63, 94, .22), transparent 70%);
}

.orbe-tarifs {
    top: 6%;
    left: -160px;
    width: 480px;
    height: 480px;
    background: radial-gradient(circle, rgba(190, 18, 60, .20), transparent 70%);
}

/* En thème sombre, les halos doivent être plus francs : le fond absorbe
   beaucoup plus de lumière, et à opacité égale ils disparaîtraient. */
[data-theme="dark"] .orbe {
    opacity: .42;
    filter: blur(80px);
}

/* --- La trame de fond ---------------------------------------------------
   Une grille très fine derrière le héros. Elle ne se remarque pas
   consciemment, mais elle donne une texture : c'est ce qui distingue un
   fond « travaillé » d'un fond vide. */
.grille-fond {
    position: absolute;
    inset: -10% -10% 0;
    background-image:
        linear-gradient(to right, currentColor 1px, transparent 1px),
        linear-gradient(to bottom, currentColor 1px, transparent 1px);
    background-size: 58px 58px;
    color: rgba(15, 23, 42, .045);
    /* Estompée sur les bords : une grille qui s'arrête net ressemble à une
       erreur d'affichage. */
    -webkit-mask-image: radial-gradient(ellipse 70% 60% at 50% 35%, #000 35%, transparent 75%);
    mask-image: radial-gradient(ellipse 70% 60% at 50% 35%, #000 35%, transparent 75%);
}

[data-theme="dark"] .grille-fond {
    color: rgba(255, 255, 255, .05);
}

/* --- Le clavier qui s'incline ------------------------------------------
   La transition n'agit QU'AU RETOUR AU REPOS. Pendant que le script écrit
   une nouvelle inclinaison à chaque image, une transition ajouterait un
   retard perceptible : l'objet suivrait le curseur avec un temps de retard
   au lieu de l'accompagner. C'est pourquoi le lissage est fait dans le
   script (approche progressive) et non ici. */
.kb-mock {
    transform-style: preserve-3d;
}

/* --- Mouvement réduit : tout s'arrête ----------------------------------
   Le script ne démarre même pas, mais on neutralise aussi le décor : ces
   halos très contrastés peuvent gêner indépendamment de tout mouvement. */
@media (prefers-reduced-motion: reduce) {

    .orbe {
        opacity: .3;
    }

    .grille-fond {
        display: none;
    }
}

/* ==========================================================================
   TRANSITION VERS L'APPLICATION  (site/js/transition-app.js)

   Une barre fine en haut de l'ecran et un leger estompage de la page. Le but
   n'est pas de decorer : c'est d'accuser reception du clic pendant le temps
   — non maitrise — que met le navigateur a charger la page suivante.

   L'estompage est TRES leger (opacite .82, echelle .995). Au-dela, on donne
   l'impression que la page part, alors qu'elle peut revenir : un retour en
   arriere doit retrouver une page intacte.
   ========================================================================== */
.app-transition {
    position: fixed;
    inset: 0 0 auto;
    height: 3px;
    z-index: 9999;
    opacity: 0;
    pointer-events: none;
    transition: opacity .15s ease;
}

.app-transition.is-on {
    opacity: 1;
}

.app-transition-bar {
    height: 100%;
    width: 0;
    border-radius: 0 3px 3px 0;
    background: linear-gradient(90deg, var(--accent-grad-a), var(--accent-grad-b));
    box-shadow: 0 0 12px -1px var(--accent);
    transition: width .5s cubic-bezier(.15, .85, .35, 1);
}

html.is-leaving body {
    opacity: .82;
    transform: scale(.995);
    transition: opacity .3s ease, transform .3s ease;
}

/* Mouvement reduit : la barre reste — elle informe — mais la page ne bouge
   plus et ne s'estompe plus. */
@media (prefers-reduced-motion: reduce) {
    html.is-leaving body {
        opacity: 1;
        transform: none;
        transition: none;
    }
}

/* ==========================================================================
   NOUVEAUTES — UNE FRISE, PAS UNE PILE DE CARTES

   Trois cartes empilees ne racontent rien : elles se lisent comme trois
   annonces sans rapport. Une frise dit ce que la section promet — une
   progression, un produit qui avance. Le trait vertical et les points
   donnent cette lecture au premier coup d'oeil, avant meme le texte.

   La version la plus recente est marquee (point plein, anneau colore) : sans
   reperage, on ne sait pas ou commence l'actualite.
   ========================================================================== */
.timeline {
    position: relative;
    list-style: none;
    max-width: 760px;
    margin: 0 auto;
    padding: 0 0 0 34px;
    display: flex;
    flex-direction: column;
    gap: 18px;
}

/* Le trait de la frise. Il s'arrete au dernier point plutot que de courir
   jusqu'au bas du conteneur : un trait qui depasse donne l'impression d'un
   element manquant. */
.timeline::before {
    content: '';
    position: absolute;
    left: 7px;
    top: 14px;
    bottom: 14px;
    width: 2px;
    border-radius: 2px;
    background: linear-gradient(to bottom,
            var(--accent-ring),
            var(--border-color) 55%,
            transparent);
}

.rel {
    position: relative;
    display: grid;
    grid-template-columns: 128px minmax(0, 1fr);
    gap: 22px;
    background: var(--bg-surface);
    border: 1px solid var(--border-color);
    border-radius: var(--radius);
    padding: 20px 24px;
    box-shadow: var(--shadow-sm);
    transition: border-color .2s ease, box-shadow .2s ease, transform .2s ease;
}

.rel:hover {
    border-color: var(--border-strong);
    box-shadow: var(--shadow-md);
    transform: translateY(-2px);
}

/* Le point de la frise, aligne sur le trait. */
.rel-dot {
    position: absolute;
    left: -34px;
    top: 26px;
    width: 16px;
    height: 16px;
    border-radius: 50%;
    background: var(--bg-surface);
    border: 2px solid var(--border-strong);
}

.rel.is-latest .rel-dot {
    border-color: var(--accent);
    background: var(--accent);
    box-shadow: 0 0 0 4px var(--accent-soft);
}

.rel.is-next .rel-dot {
    border-style: dashed;
    border-color: var(--text-tertiary);
    background: var(--bg-body);
}

/* Ce qui n'est pas encore livre se lit comme tel, sans crier : fond legerement
   retire, bordure en pointilles. On promet moins fort que ce qui existe. */
.rel.is-next {
    background: transparent;
    border-style: dashed;
}

.rel-tag {
    display: flex;
    flex-direction: column;
    gap: 7px;
}

.rel-ver {
    font-weight: 800;
    font-size: .95rem;
    color: var(--accent);
    letter-spacing: -.01em;
}

.rel.is-next .rel-ver {
    color: var(--text-secondary);
}

.rel-state {
    font-size: .68rem;
    font-weight: 700;
    letter-spacing: .07em;
    text-transform: uppercase;
    padding: 3px 9px;
    border-radius: 100px;
    align-self: flex-start;
}

.rel-state.live {
    color: var(--ok);
    background: var(--ok-soft);
}

.rel-body h3 {
    font-size: 1.02rem;
    margin-bottom: 6px;
    letter-spacing: -.01em;
}

.rel-body p {
    font-size: .93rem;
    line-height: 1.65;
    color: var(--text-secondary);
}

/* Invitation a ecrire, sous la frise. Volontairement discrete : c'est une
   porte ouverte, pas un appel a l'action de plus. */
.timeline-foot {
    max-width: 760px;
    margin: 26px auto 0;
    padding-left: 34px;
    font-size: .92rem;
    color: var(--text-secondary);
}

.timeline-foot a {
    color: var(--accent);
    font-weight: 650;
    text-decoration: underline;
    text-underline-offset: 3px;
    text-decoration-thickness: 1.5px;
}

.timeline-foot a:hover {
    color: var(--accent-hover);
}

@media (max-width: 680px) {
    /* Sur telephone, la colonne de 128 px pour « Version 2.2 » couterait la
       moitie de la largeur utile : l'etiquette repasse au-dessus du texte. */
    .rel {
        grid-template-columns: minmax(0, 1fr);
        gap: 10px;
        padding: 18px 18px;
    }

    .rel-tag {
        flex-direction: row;
        align-items: center;
        gap: 10px;
    }

    .timeline {
        padding-left: 26px;
    }

    .timeline::before {
        left: 5px;
    }

    .rel-dot {
        left: -26px;
        top: 22px;
        width: 13px;
        height: 13px;
    }

    .timeline-foot {
        padding-left: 26px;
    }
}

.rel-state.soon {
    color: var(--text-tertiary);
    background: var(--bg-surface-2);
}

.rel h3 {
    font-size: 1.02rem;
    font-weight: 700;
    margin-bottom: 6px;
}

.rel p {
    color: var(--text-secondary);
    font-size: .93rem;
}

/* --- 15. FAQ ------------------------------------------------------------- */
.faq {
    max-width: 800px;
    margin: 0 auto;
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.faq details {
    background: var(--bg-surface);
    border: 1px solid var(--border-color);
    border-radius: var(--radius);
    box-shadow: var(--shadow-sm);
    overflow: hidden;
}

.faq details[open] {
    border-color: var(--border-strong);
}

.faq summary {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    padding: 19px 22px;
    font-weight: 650;
    font-size: 1rem;
    cursor: pointer;
    list-style: none;
    transition: color .18s ease;
}

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

.faq summary:hover {
    color: var(--accent);
}

.faq summary::after {
    content: "";
    width: 11px;
    height: 11px;
    flex: none;
    border-right: 2.2px solid currentColor;
    border-bottom: 2.2px solid currentColor;
    transform: rotate(45deg) translate(-2px, -2px);
    transition: transform .22s ease;
    opacity: .55;
}

.faq details[open] summary::after {
    transform: rotate(-135deg) translate(-2px, -2px);
}

.faq-body {
    padding: 0 22px 20px;
    color: var(--text-secondary);
    font-size: .95rem;
}

.faq-body p+p {
    margin-top: 10px;
}

/* --- 16. CTA FINAL ------------------------------------------------------- */
/* ==========================================================================
   APPEL FINAL — LE DERNIER ECRAN AVANT LA DECISION

   Un aplat de couleur suffisait, mais restait plat. On ajoute deux halos
   lumineux en diagonale : la surface prend du volume, et le bouton blanc
   au centre s'en detache nettement mieux.

   Les halos sont en pseudo-elements, donc sans un noeud de plus dans le
   HTML, et « overflow: hidden » les taille aux coins arrondis de la carte.
   ========================================================================== */
.cta-final {
    position: relative;
    isolation: isolate;
    overflow: hidden;
    text-align: center;
    background: linear-gradient(135deg, var(--accent-grad-a), var(--accent-grad-b));
    border-radius: var(--radius-lg);
    padding: clamp(40px, 6vw, 68px) clamp(24px, 4vw, 48px);
    box-shadow: var(--shadow-lg);
    color: #fff;
}

.cta-final::before,
.cta-final::after {
    content: '';
    position: absolute;
    z-index: -1;
    border-radius: 50%;
    pointer-events: none;
}

.cta-final::before {
    top: -45%;
    left: -12%;
    width: 420px;
    height: 420px;
    background: radial-gradient(circle, rgba(255, 255, 255, .22), transparent 65%);
}

.cta-final::after {
    right: -14%;
    bottom: -55%;
    width: 380px;
    height: 380px;
    background: radial-gradient(circle, rgba(255, 255, 255, .14), transparent 68%);
}

.cta-final h2 {
    font-size: clamp(1.7rem, 4vw, 2.5rem);
    color: #fff;
}

.cta-final p {
    margin: 16px auto 0;
    max-width: 56ch;
    color: rgba(255, 255, 255, .9);
    font-size: clamp(1rem, 2vw, 1.1rem);
}

.cta-final .btn {
    margin-top: 30px;
    background: #fff;
    color: var(--accent-hover);
    box-shadow: 0 14px 30px -12px rgba(0, 0, 0, .45);
}

.cta-final .btn:hover {
    color: var(--accent-hover);
    transform: translateY(-2px);
}

.cta-final small {
    display: block;
    margin-top: 18px;
    color: rgba(255, 255, 255, .78);
    font-size: .85rem;
}

/* --- 17. PUBLICITÉ ------------------------------------------------------- */
.ad-slot {
    margin: 0 auto;
    max-width: 970px;
    min-height: 0;
}

.ad-slot[hidden] {
    display: none;
}

.ad-label {
    display: block;
    text-align: center;
    font-size: .66rem;
    letter-spacing: .14em;
    text-transform: uppercase;
    color: var(--text-tertiary);
    margin-bottom: 8px;
}

.ad-placeholder {
    display: flex;
    align-items: center;
    justify-content: center;
    flex-direction: column;
    gap: 4px;
    min-height: 108px;
    border: 1.5px dashed var(--border-strong);
    border-radius: var(--radius);
    color: var(--text-tertiary);
    font-size: .84rem;
    background: var(--bg-surface-2);
    padding: 18px;
    text-align: center;
}

.ad-placeholder code {
    font-size: .78rem;
    opacity: .8;
}

/* --- 18. PIED DE PAGE ---------------------------------------------------- */
.footer {
    background: var(--bg-surface);
    border-top: 1px solid var(--border-color);
    padding: clamp(44px, 6vw, 64px) 0 30px;
}

.footer-grid {
    display: grid;
    grid-template-columns: minmax(0, 1.6fr) repeat(3, minmax(0, 1fr));
    gap: 34px;
}

.footer-about p {
    color: var(--text-secondary);
    font-size: .92rem;
    margin-top: 14px;
    max-width: 40ch;
}

.footer h4 {
    font-size: .78rem;
    font-weight: 700;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--text-tertiary);
    margin-bottom: 14px;
}

.footer-links {
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.footer-links a {
    color: var(--text-secondary);
    font-size: .93rem;
}

.footer-links a:hover {
    color: var(--accent);
}

.footer-bottom {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 14px;
    margin-top: 40px;
    padding-top: 24px;
    border-top: 1px solid var(--border-color);
    color: var(--text-tertiary);
    font-size: .86rem;
}

.footer-bottom nav {
    display: flex;
    flex-wrap: wrap;
    gap: 18px;
}

.footer-bottom a {
    color: var(--text-tertiary);
}

.footer-bottom a:hover {
    color: var(--accent);
}

/* --- 19. RÉVÉLATION AU DÉFILEMENT ----------------------------------------
   L'effet n'est actif que si la classe .js-anim est posée sur <html> par le
   script. Sans JavaScript — ou si le script échoue — aucune de ces règles ne
   s'applique et TOUT LE CONTENU RESTE VISIBLE. L'animation est un bonus,
   jamais une condition d'affichage. */
/* RÉVÉLATION AU DÉFILEMENT

   La montée passe de 18 à 26 px et gagne une réduction d'échelle : l'élément
   arrive de plus loin, ce qui rend l'apparition franchement perceptible sans
   la rendre lente. La courbe termine en douceur (pas de rebond) — sur une
   page qui en révèle une trentaine, un rebond deviendrait vite agaçant.

   Le filtre de flou est délibérément ABSENT : il coûte cher à animer, et sur
   une page qui révèle des dizaines de blocs il suffit à faire tomber le
   défilement en dessous de 60 images par seconde. */
.js-anim .reveal {
    opacity: 0;
    transform: translateY(26px) scale(.985);
    transition: opacity .6s cubic-bezier(.2, .7, .3, 1),
                transform .7s cubic-bezier(.2, .7, .3, 1);
}

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

/* --- 20. RESPONSIVE ------------------------------------------------------ */
@media (max-width: 980px) {

    .hero-grid,
    .license-box {
        grid-template-columns: minmax(0, 1fr);
    }

    .hero-visual {
        order: -1;
    }

    .features-grid,
    .steps,
    .plans {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    /* Le fil des etapes ne relie plus rien des que la rangee de trois se
       casse : il pointerait dans le vide, entre deux cartes qui ne se
       suivent plus horizontalement. */
    .steps::before {
        display: none;
    }

    .plan.is-featured {
        grid-column: 1 / -1;
    }

    .footer-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

@media (max-width: 1100px) {
    .nav-menu {
        position: fixed;
        inset: var(--nav-h) 0 auto;
        /* Le centrage absolu du bureau ne s'applique plus ici : « inset » et le
           « transform » d'animation plus bas reprennent la main. On rend en
           revanche le retour a la ligne, inutile a l'horizontale mais utile
           dans une liste verticale. */
        white-space: normal;
        flex-direction: column;
        align-items: stretch;
        gap: 2px;
        padding: 14px clamp(18px, 4vw, 32px) 22px;
        background: var(--bg-surface);
        border-bottom: 1px solid var(--border-color);
        box-shadow: var(--shadow-lg);
        transform: translateY(-12px);
        opacity: 0;
        pointer-events: none;
        transition: opacity .2s ease, transform .2s ease;
        max-height: calc(100vh - var(--nav-h));
        overflow-y: auto;
    }

    .nav-menu.is-open {
        transform: none;
        opacity: 1;
        pointer-events: auto;
    }

    .nav-link {
        padding: 13px 14px;
        font-size: 1rem;
    }

    .nav-burger {
        display: inline-flex;
    }

    .nav-cta-desktop {
        display: none;
    }

    /* Dans le menu déroulant mobile, le bouton reprend sa place */
    .nav-menu .btn {
        display: inline-flex;
        margin-top: 10px;
    }
}

@media (max-width: 680px) {
    /* LA PASTILLE DE VERSION DISPARAIT SUR TELEPHONE.

       Sur un grand ecran elle sert de signal de fraicheur au-dessus du titre.
       Sur un telephone, elle occupe une ligne entiere — parfois deux — juste
       avant le seul message qui compte, et repousse le titre et le bouton
       vers le bas de l'ecran. Le premier coup d'oeil doit tomber sur la
       promesse, pas sur un numero de version. */
    .hero-version {
        display: none;
    }

    .stats-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .features-grid,
    .steps,
    .plans,
    .footer-grid {
        grid-template-columns: minmax(0, 1fr);
    }

    .rel {
        grid-template-columns: minmax(0, 1fr);
        gap: 10px;
    }

    .rel-tag {
        flex-direction: row;
        align-items: center;
        gap: 10px;
    }

    .hero-cta .btn {
        width: 100%;
    }
}

/* --- 21. ACCESSIBILITÉ / IMPRESSION -------------------------------------- */
@media (prefers-reduced-motion: reduce) {

    *,
    *::before,
    *::after {
        animation-duration: .01ms !important;
        transition-duration: .01ms !important;
        scroll-behavior: auto !important;
    }

    .js-anim .reveal {
        opacity: 1;
        transform: none;
    }
}

@media print {

    .nav,
    .ad-slot,
    .cta-final {
        display: none !important;
    }

    body {
        background: #fff;
    }
}

/* ==========================================================================
   BASCULE MENSUEL / ANNUEL, DANS LA CARTE PAYANTE
   Reprend l'aspect du sélecteur de devise, pour que les deux se lisent
   comme un même mécanisme. Placée EN HAUT de la carte : le visiteur doit
   comprendre qu'il choisit une durée avant de lire le prix.
   ========================================================================== */
.plan-switch {
    display: flex;
    gap: 3px;
    padding: 4px;
    margin: 0 0 18px;
    background: var(--bg-surface-2);
    border: 1px solid var(--border-color);
    border-radius: 100px;
}

.dur-btn {
    flex: 1 1 0;
    /* Sans min-width nul, un libellé long élargit la carte au lieu de
       s'adapter — et les trois cartes cessent d'avoir la même largeur. */
    min-width: 0;
    border: none;
    background: transparent;
    color: var(--text-secondary);
    font-family: inherit;
    font-weight: 650;
    font-size: .84rem;
    padding: 8px 12px;
    border-radius: 100px;
    cursor: pointer;
    transition: background .18s ease, color .18s ease;
}

.dur-btn:hover {
    color: var(--text-primary);
}

.dur-btn.is-active {
    background: var(--bg-surface);
    color: var(--accent);
    box-shadow: var(--shadow-sm);
}

.dur-btn:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 2px;
}

/* Le montant est rempli par le script après réponse de l'API : sans hauteur
   réservée, la carte sauterait au moment du remplissage. */
.plan-amount:empty::before {
    content: "—";
}

/* Sur mobile, la bascule se manipule au pouce : 32 px de haut se ratent une
   fois sur deux. On vise la cible tactile recommandée d'environ 44 px. */
@media (max-width: 720px) {
    .dur-btn {
        padding: 12px 12px;
        font-size: .88rem;
    }
}

/* ==========================================================================
   ÉTIQUETTE DE PROMOTION, ET BOUTONS INCITATIFS
   ========================================================================== */

/* --------------------------------------------------------------------------
   « −20 % » — visible au premier coup d'œil

   Une promotion qui ne se voit qu'en comparant deux chiffres barrés n'est pas
   une promotion : c'est une devinette. L'étiquette dit le gain en un mot, et
   un reflet la traverse toutes les quelques secondes pour attirer l'œil sans
   agiter la page.
   -------------------------------------------------------------------------- */
.plan-promo {
    position: absolute;
    top: 14px;
    right: 14px;
    z-index: 2;
    overflow: hidden;
    padding: 5px 12px;
    border-radius: 100px;
    font-size: .74rem;
    font-weight: 800;
    letter-spacing: .04em;
    color: #fff;
    background: linear-gradient(135deg, #f59e0b, #e11d48);
    box-shadow: 0 4px 14px rgba(225, 29, 72, .32);
    white-space: nowrap;
}

/* Le reflet est un pseudo-élément : aucun nœud supplémentaire dans la page,
   et il disparaît tout seul si l'étiquette est masquée. */
.plan-promo::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(110deg,
            transparent 25%,
            rgba(255, 255, 255, .55) 50%,
            transparent 75%);
    transform: translateX(-130%);
    animation: promoShine 3.4s ease-in-out infinite;
}

@keyframes promoShine {
    0%, 62% { transform: translateX(-130%); }
    100%    { transform: translateX(130%); }
}

/* La carte « à vie » porte déjà son fanion centré en haut : on décale
   l'étiquette pour qu'elles ne se chevauchent jamais. */
.plan.is-featured .plan-promo {
    top: 18px;
}

/* --------------------------------------------------------------------------
   BOUTON D'APPEL — attirer sans harceler

   Deux effets, tous deux discrets : une respiration très lente de l'ombre,
   et un reflet qui traverse le bouton. Assez pour que l'œil s'y pose,
   assez lent pour qu'on puisse lire la page sans être distrait.
   -------------------------------------------------------------------------- */
.btn-pulse {
    position: relative;
    overflow: hidden;
    animation: ctaBreath 3.6s ease-in-out infinite;
}

.btn-pulse::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(110deg,
            transparent 30%,
            rgba(255, 255, 255, .38) 50%,
            transparent 70%);
    transform: translateX(-130%);
    animation: ctaShine 4.8s ease-in-out infinite;
    pointer-events: none;
}

@keyframes ctaBreath {
    0%, 100% { box-shadow: 0 6px 18px rgba(225, 29, 72, .28); }
    50%      { box-shadow: 0 8px 26px rgba(225, 29, 72, .46); }
}

@keyframes ctaShine {
    0%, 72% { transform: translateX(-130%); }
    100%    { transform: translateX(130%); }
}

/* Au survol, l'animation cède la place : l'utilisateur a trouvé le bouton,
   il n'a plus besoin qu'on le lui signale. */
.btn-pulse:hover {
    animation: none;
    transform: translateY(-1px);
}

.btn-pulse:hover::after {
    animation: none;
    opacity: 0;
}

/* Précision sous le bouton — « puis choisissez la durée », par exemple. */
.plan-cta-note {
    margin: 9px 0 0;
    font-size: .78rem;
    line-height: 1.4;
    color: var(--text-tertiary);
    text-align: center;
}

/* --------------------------------------------------------------------------
   RESPECT DU RÉGLAGE SYSTÈME

   Un utilisateur qui a demandé moins d'animations le fait souvent pour une
   raison médicale (vertiges, migraines). On coupe tout mouvement, sans rien
   retirer de l'information : l'étiquette et le bouton restent parfaitement
   lisibles, simplement immobiles.
   -------------------------------------------------------------------------- */
@media (prefers-reduced-motion: reduce) {

    .plan-promo::after,
    .btn-pulse,
    .btn-pulse::after {
        animation: none;
    }

    .plan-promo::after,
    .btn-pulse::after {
        display: none;
    }
}

/* ==========================================================================
   CHOIX DE LA DURÉE — mois et années  (js/duree.js)

   Une décision d'achat mérite une page à elle : fond assombri, carte
   centrée, un seul geste à faire. Tout ce qui s'y affiche vient du serveur,
   cette feuille ne fait que le mettre en forme.
   ========================================================================== */

/* Le défilement de la page est bloqué pendant que la modale est ouverte :
   faire défiler l'arrière-plan pendant qu'on règle un curseur donne
   l'impression que la page part en morceaux. */
html.duree-ouvert,
html.duree-ouvert body {
    overflow: hidden;
}

.duree-overlay {
    position: fixed;
    inset: 0;
    z-index: 200;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 20px;
    background: rgba(9, 9, 20, .62);
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
    animation: dureeFondu .18s ease-out;
    overflow-y: auto;
}

@keyframes dureeFondu {
    from { opacity: 0; }
    to   { opacity: 1; }
}

.duree-card {
    position: relative;
    /* Plus large qu'une modale de confirmation ordinaire : on y règle un
       curseur, on y lit un prix, un prix barré et une économie. À 30 rem le
       tout se tassait sur trois lignes serrées. */
    width: min(34rem, 100%);
    background: var(--bg-surface);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-lg);
    padding: 38px 38px 30px;
    box-shadow: var(--shadow-lg);
    text-align: center;
    animation: dureeMonte .22s cubic-bezier(.2, .8, .3, 1);
}

/* ENTRÉE D'UNE FENÊTRE — elle vient de quelque part.

   « translateY + scale » avec un léger dépassement : la carte monte, grandit
   un peu au-delà de sa taille, puis se pose. Ce dépassement dure 60 ms et ne
   se remarque pas consciemment — il se ressent comme de la matière plutôt
   que comme une image qu'on affiche.

   Le fond, lui, se contente d'un fondu : deux animations remarquables en
   même temps se disputent l'attention. */
@keyframes dureeMonte {
    from { opacity: 0; transform: translateY(22px) scale(.965); }
    60%  { opacity: 1; }
    to   { opacity: 1; transform: none; }
}

/* Le contenu de la fenêtre suit sa carte, très légèrement décalé. */
@keyframes contenuMonte {
    from { opacity: 0; transform: translateY(9px); }
    to   { opacity: 1; transform: none; }
}

.duree-card > *,
.entry-card > * {
    animation: contenuMonte .34s cubic-bezier(.2, .8, .3, 1) backwards;
    animation-delay: .08s;
}

/* Les boutons de l'écran d'entrée arrivent l'un après l'autre : trois
   choix qui apparaissent ensemble se lisent comme un bloc ; échelonnés, ils
   se lisent comme trois options. */
.entry-choix > *:nth-child(1) { animation: contenuMonte .34s cubic-bezier(.2,.8,.3,1) backwards; animation-delay: .12s; }
.entry-choix > *:nth-child(2) { animation: contenuMonte .34s cubic-bezier(.2,.8,.3,1) backwards; animation-delay: .18s; }
.entry-choix > *:nth-child(3) { animation: contenuMonte .34s cubic-bezier(.2,.8,.3,1) backwards; animation-delay: .24s; }

/* Le salut de la main : il attire l'oeil vers le haut de la fenêtre. */
@keyframes salut {
    0%, 60%, 100% { transform: rotate(0); }
    15%           { transform: rotate(16deg); }
    30%           { transform: rotate(-9deg); }
    45%           { transform: rotate(11deg); }
}

.entry-wave {
    display: inline-block;
    transform-origin: 70% 75%;
    animation: salut 1.6s ease-in-out .35s 2;
}

/* FERMETURE DES MODALES — contrastée, jamais grise.
   En gris tertiaire la croix se noyait dans la carte ; elle porte donc la
   couleur d'accent dans une pastille légère, qui lui donne à la fois une
   vraie surface et une cible confortable au doigt. Même traitement que dans
   l'application (app/styles/15-modals-…css) : une croix doit se reconnaître
   d'un écran à l'autre. */
.duree-fermer {
    position: absolute;
    top: 12px;
    right: 14px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    padding: 0;
    border: 1px solid rgba(225, 29, 72, .28);
    background: rgba(225, 29, 72, .10);
    color: var(--accent);
    font-size: 1.4rem;
    line-height: 1;
    border-radius: 50%;
    cursor: pointer;
    transition: background .15s ease, color .15s ease, transform .15s ease;
}

.duree-fermer:hover {
    background: var(--accent);
    border-color: var(--accent);
    color: var(--accent-on, #fff);
}

.duree-fermer:active {
    transform: scale(.94);
}

.duree-titre {
    font-size: 1.3rem;
    font-weight: 800;
    letter-spacing: -.02em;
    margin: 0;
}

.duree-sous {
    margin: 8px 0 0;
    font-size: .88rem;
    line-height: 1.5;
    color: var(--text-secondary);
}

/* --- Le nombre, gros et vivant ------------------------------------------ */

.duree-valeur {
    display: flex;
    align-items: baseline;
    justify-content: center;
    gap: 8px;
    margin: 24px 0 2px;
}

.duree-nombre {
    display: inline-block;
    font-size: clamp(3rem, 12vw, 4rem);
    font-weight: 800;
    line-height: 1;
    letter-spacing: -.04em;
    font-variant-numeric: tabular-nums;
    color: var(--accent);
}

/* Pulsation à chaque cran : un repère que la valeur a changé, sans rien
   déplacer autour — le reste de la carte ne bouge pas d'un pixel. */
.duree-nombre.is-pop {
    animation: dureePop .22s cubic-bezier(.34, 1.56, .64, 1);
}

@keyframes dureePop {
    0%   { transform: scale(1); }
    45%  { transform: scale(1.14); }
    100% { transform: scale(1); }
}

.duree-unite {
    font-size: 1.1rem;
    font-weight: 650;
    color: var(--text-secondary);
}

.duree-libelle {
    margin: 0 0 22px;
    min-height: 22px;
    font-size: .92rem;
    font-weight: 550;
    color: var(--text-secondary);
}

/* --- Curseur ------------------------------------------------------------ */

.duree-piste {
    --rempli: 0%;
    margin: 0 4px 22px;
}

.duree-curseur {
    -webkit-appearance: none;
    appearance: none;
    width: 100%;
    height: 8px;
    border-radius: 100px;
    background: linear-gradient(to right,
            var(--accent) 0%,
            var(--accent) var(--rempli),
            var(--bg-surface-2) var(--rempli),
            var(--bg-surface-2) 100%);
    outline: none;
    cursor: pointer;
}

.duree-curseur::-webkit-slider-thumb {
    -webkit-appearance: none;
    appearance: none;
    width: 26px;
    height: 26px;
    border-radius: 50%;
    background: var(--bg-surface);
    border: 3px solid var(--accent);
    box-shadow: 0 2px 10px rgba(225, 29, 72, .35);
    cursor: grab;
    transition: transform .12s ease;
}

.duree-curseur::-webkit-slider-thumb:active {
    transform: scale(1.15);
    cursor: grabbing;
}

.duree-curseur::-moz-range-thumb {
    width: 26px;
    height: 26px;
    border-radius: 50%;
    background: var(--bg-surface);
    border: 3px solid var(--accent);
    box-shadow: 0 2px 10px rgba(225, 29, 72, .35);
    cursor: grab;
}

.duree-curseur:focus-visible {
    outline: 2px solid var(--accent);
    outline-offset: 4px;
}

.duree-bornes {
    display: flex;
    justify-content: space-between;
    margin-top: 8px;
    font-size: .76rem;
    color: var(--text-tertiary);
    font-variant-numeric: tabular-nums;
}

/* --- Ce qui sera débité -------------------------------------------------- */

.duree-facture {
    padding: 18px 16px;
    border-radius: var(--radius-md, 12px);
    background: var(--bg-surface-2);
    border: 1px solid var(--border-color);
}

.duree-prix-ligne {
    display: flex;
    align-items: baseline;
    justify-content: center;
    gap: 10px;
    flex-wrap: wrap;
}

.duree-barre {
    font-size: 1rem;
    font-weight: 600;
    color: var(--text-tertiary);
    text-decoration: line-through;
    text-decoration-thickness: 2px;
    font-variant-numeric: tabular-nums;
}

.duree-prix {
    font-size: clamp(1.5rem, 5vw, 1.9rem);
    font-weight: 800;
    letter-spacing: -.03em;
    font-variant-numeric: tabular-nums;
}

.duree-par-unite {
    margin: 4px 0 0;
    font-size: .85rem;
    color: var(--text-secondary);
    font-variant-numeric: tabular-nums;
}

.duree-gain {
    margin: 12px 0 0;
    font-size: .85rem;
    color: var(--text-secondary);
}

.duree-gain-pct {
    display: inline-block;
    padding: 2px 9px;
    margin-right: 6px;
    border-radius: 100px;
    font-weight: 800;
    font-size: .8rem;
    color: #fff;
    background: linear-gradient(135deg, #f59e0b, #e11d48);
}

/* --- Actions ------------------------------------------------------------- */

.duree-actions {
    margin-top: 22px;
}

.duree-lien {
    display: block;
    width: 100%;
    margin-top: 12px;
    padding: 6px;
    border: none;
    background: transparent;
    color: var(--text-tertiary);
    font-family: inherit;
    font-size: .84rem;
    cursor: pointer;
    text-decoration: underline;
    text-underline-offset: 3px;
}

.duree-lien:hover {
    color: var(--text-primary);
}

@media (max-width: 480px) {
    .duree-card {
        padding: 30px 20px 22px;
    }

    /* Cible tactile confortable : un curseur de 26 px se rate au pouce. */
    .duree-curseur::-webkit-slider-thumb {
        width: 30px;
        height: 30px;
    }

    .duree-curseur::-moz-range-thumb {
        width: 30px;
        height: 30px;
    }
}

@media (prefers-reduced-motion: reduce) {

    .duree-overlay,
    .duree-card,
    .duree-nombre.is-pop {
        animation: none;
    }
}

/* ==========================================================================
   ÉCRAN DE CONNEXION — bouton « Commencer »

   Même famille visuelle que .duree-overlay/.duree-card (fond flouté, carte
   centrée) : deux fenêtres modales dans le même site doivent se ressembler,
   pas se faire concurrence.

   DEUX ÉTATS DANS LA MÊME CARTE, jamais deux fenêtres : le choix (déjà un
   compte ? pas de compte ? gratuit ?) et la saisie de la clé, reliés par un
   simple changement de classe — .entry-step-key affiche l'un ou l'autre.
   ========================================================================== */
.entry-overlay {
    position: fixed;
    inset: 0;
    z-index: 200;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 20px;
    background: rgba(9, 9, 20, .62);
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
    animation: dureeFondu .18s ease-out;
    overflow-y: auto;
}

.entry-card {
    position: relative;
    width: min(26rem, 100%);
    background: var(--bg-surface);
    border: 1px solid var(--border-color);
    border-radius: var(--radius-lg);
    padding: 34px 30px 28px;
    box-shadow: var(--shadow-lg);
    text-align: center;
    animation: dureeMonte .22s cubic-bezier(.2, .8, .3, 1);
}

/* Même croix que partout ailleurs — voir la note de .duree-fermer. */
.entry-fermer {
    position: absolute;
    top: 12px;
    right: 14px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 34px;
    padding: 0;
    border: 1px solid rgba(225, 29, 72, .28);
    background: rgba(225, 29, 72, .10);
    color: var(--accent);
    font-size: 1.4rem;
    line-height: 1;
    border-radius: 50%;
    cursor: pointer;
    transition: background .15s ease, color .15s ease, transform .15s ease;
}

.entry-fermer:hover {
    background: var(--accent);
    border-color: var(--accent);
    color: var(--accent-on, #fff);
}

.entry-fermer:active {
    transform: scale(.94);
}

.entry-wave {
    font-size: 2.1rem;
    line-height: 1;
    margin: 0 0 10px;
}

.entry-titre {
    font-size: 1.25rem;
    font-weight: 800;
    letter-spacing: -.02em;
    margin: 0;
}

.entry-sous {
    margin: 8px 0 24px;
    font-size: .88rem;
    line-height: 1.5;
    color: var(--text-secondary);
}

/* --- Étape 1 : le choix --------------------------------------------------- */
.entry-choix {
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.entry-choix .btn {
    width: 100%;
    justify-content: center;
}

/* --- Étape 2 : la clé ------------------------------------------------------ */
.entry-retour {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    margin: 0 0 14px;
    border: none;
    background: transparent;
    color: var(--text-secondary);
    font-size: .82rem;
    font-weight: 650;
    cursor: pointer;
    padding: 0;
}

.entry-retour:hover {
    color: var(--text-primary);
}

.entry-form {
    text-align: left;
}

.entry-label {
    display: block;
    font-size: .82rem;
    font-weight: 650;
    color: var(--text-secondary);
    margin: 0 0 6px;
}

.entry-input {
    width: 100%;
    padding: 11px 13px;
    font: inherit;
    font-size: .95rem;
    letter-spacing: .02em;
    color: var(--text-primary);
    background: var(--bg-surface-2, rgba(148, 163, 184, .07));
    border: 1px solid var(--border-color);
    border-radius: 10px;
    transition: border-color .15s ease;
}

.entry-input:focus {
    outline: none;
    border-color: var(--accent);
}

.entry-remember {
    display: flex;
    align-items: flex-start;
    gap: 9px;
    margin: 14px 0 18px;
    font-size: .82rem;
    line-height: 1.4;
    color: var(--text-secondary);
    cursor: pointer;
}

.entry-remember input {
    margin-top: 2px;
    flex: none;
}

.entry-error {
    margin: 0 0 14px;
    padding: 9px 12px;
    border-radius: 8px;
    background: rgba(225, 29, 72, .1);
    color: var(--accent);
    font-size: .82rem;
    line-height: 1.4;
    text-align: left;
}

.entry-submit {
    width: 100%;
    justify-content: center;
}

.entry-switch {
    display: block;
    margin: 16px auto 0;
    border: none;
    background: transparent;
    color: var(--text-tertiary);
    font-size: .8rem;
    cursor: pointer;
    text-decoration: underline;
    text-underline-offset: 2px;
}

.entry-switch:hover {
    color: var(--text-primary);
}

@media (max-width: 480px) {
    .entry-card {
        padding: 28px 20px 22px;
    }
}

@media (prefers-reduced-motion: reduce) {
    .entry-overlay,
    .entry-card {
        animation: none;
    }
}
