/*
 * EDOUK — Le socle partagé
 * Polices, variables de thème ( sombre par défaut, clair sur demande ), icônes,
 * champs, boutons, coque de modale et primitives ex-UIkit : tout ce que les deux
 * mondes rendent vraiment. Chargé AVANT `auth.css` et `route.css`, qui ne
 * portent chacun que leurs propres écrans.
*/
@font-face {
    font-family: "Inter";
    font-style: normal;
    font-weight: 100 900;
    font-display: swap;
    src: url("/fonts/inter-latin.woff2") format("woff2");
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329,
        U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
    font-family: "Inter";
    font-style: normal;
    font-weight: 100 900;
    font-display: swap;
    src: url("/fonts/inter-latin-ext.woff2") format("woff2");
    unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0,
        U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
    font-family: "Readex Pro";
    font-style: normal;
    font-weight: 160 700;
    font-display: swap;
    src: url("/fonts/readexpro-latin.woff2") format("woff2");
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329,
        U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
    font-family: "Readex Pro";
    font-style: normal;
    font-weight: 160 700;
    font-display: swap;
    src: url("/fonts/readexpro-latin-ext.woff2") format("woff2");
    unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0,
        U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
    font-family: "Readex Pro";
    font-style: normal;
    font-weight: 160 700;
    font-display: swap;
    src: url("/fonts/readexpro-arabic.woff2") format("woff2");
    unicode-range: U+0600-06FF, U+0750-077F, U+0870-088E, U+0890-0891, U+0898-08E1, U+08E3-08FF, U+200C-200E,
        U+2010-2011, U+204F, U+2E41, U+FB50-FDFF, U+FE70-FE9F, U+10E60-10E7F, U+1EE00-1EEFF;
}
@font-face {
    font-family: "Ubuntu";
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url("/fonts/ubuntu-400-latin.woff2") format("woff2");
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329,
        U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
    font-family: "Ubuntu";
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url("/fonts/ubuntu-400-latin-ext.woff2") format("woff2");
    unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0,
        U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
    font-family: "Ubuntu";
    font-style: normal;
    font-weight: 500;
    font-display: swap;
    src: url("/fonts/ubuntu-500-latin.woff2") format("woff2");
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329,
        U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
    font-family: "Ubuntu";
    font-style: normal;
    font-weight: 500;
    font-display: swap;
    src: url("/fonts/ubuntu-500-latin-ext.woff2") format("woff2");
    unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0,
        U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
    font-family: "Ubuntu";
    font-style: normal;
    font-weight: 700;
    font-display: swap;
    src: url("/fonts/ubuntu-700-latin.woff2") format("woff2");
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329,
        U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
    font-family: "Ubuntu";
    font-style: normal;
    font-weight: 700;
    font-display: swap;
    src: url("/fonts/ubuntu-700-latin-ext.woff2") format("woff2");
    unicode-range: U+0100-02AF, U+0304, U+0308, U+0329, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0,
        U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
    font-family: "Noto Sans Arabic";
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url("/fonts/notosansarabic-400.woff2") format("woff2");
    unicode-range: U+0600-06FF, U+0750-077F, U+0870-088E, U+0890-0891, U+0897-08E1, U+08E3-08FF, U+200C-200E,
        U+2010-2011, U+204F, U+2E41, U+FB50-FDFF, U+FE70-FE74, U+FE76-FEFC;
}
@font-face {
    font-family: "Noto Sans Arabic";
    font-style: normal;
    font-weight: 500;
    font-display: swap;
    src: url("/fonts/notosansarabic-500.woff2") format("woff2");
    unicode-range: U+0600-06FF, U+0750-077F, U+0870-088E, U+0890-0891, U+0897-08E1, U+08E3-08FF, U+200C-200E,
        U+2010-2011, U+204F, U+2E41, U+FB50-FDFF, U+FE70-FE74, U+FE76-FEFC;
}
@font-face {
    font-family: "Cairo";
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url("/fonts/cairo-arabic.woff2") format("woff2");
    unicode-range: U+0600-06FF, U+0750-077F, U+0870-088E, U+0890-0891, U+0897-08E1, U+08E3-08FF, U+200C-200E,
        U+2010-2011, U+204F, U+2E41, U+FB50-FDFF, U+FE70-FE74, U+FE76-FEFC;
}
@font-face {
    font-family: "Cairo";
    font-style: normal;
    font-weight: 500;
    font-display: swap;
    src: url("/fonts/cairo-arabic.woff2") format("woff2");
    unicode-range: U+0600-06FF, U+0750-077F, U+0870-088E, U+0890-0891, U+0897-08E1, U+08E3-08FF, U+200C-200E,
        U+2010-2011, U+204F, U+2E41, U+FB50-FDFF, U+FE70-FE74, U+FE76-FEFC;
}
@font-face {
    font-family: "Cairo";
    font-style: normal;
    font-weight: 700;
    font-display: swap;
    src: url("/fonts/cairo-arabic.woff2") format("woff2");
    unicode-range: U+0600-06FF, U+0750-077F, U+0870-088E, U+0890-0891, U+0897-08E1, U+08E3-08FF, U+200C-200E,
        U+2010-2011, U+204F, U+2E41, U+FB50-FDFF, U+FE70-FE74, U+FE76-FEFC;
}
/* POPPINS — la police de la charte, cinq graisses statiques.
   Inter était variable et tenait en deux fichiers ; Poppins ne l'est pas, chaque
   graisse est un fichier. Les cinq sont celles que la maquette emploie vraiment :
   400 corps, 500 mono-adjacent, 600 libellés et boutons, 700 titres, 800 le H1 et
   les chiffres.

   LE SOUS-ENSEMBLE LATIN SUFFIT. Les accents français vivent dans U+0000-00FF et
   le `œ` dans U+0152-0153, tous deux couverts ici : pas de latin-ext à charger.
   L'arabe ne passe jamais par cette police — voir `[lang="ar"] *` plus bas. */
@font-face {
    font-family: "Poppins";
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url("/fonts/poppins-400-latin.woff2") format("woff2");
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329,
        U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
    font-family: "Poppins";
    font-style: normal;
    font-weight: 500;
    font-display: swap;
    src: url("/fonts/poppins-500-latin.woff2") format("woff2");
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329,
        U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
    font-family: "Poppins";
    font-style: normal;
    font-weight: 600;
    font-display: swap;
    src: url("/fonts/poppins-600-latin.woff2") format("woff2");
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329,
        U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
    font-family: "Poppins";
    font-style: normal;
    font-weight: 700;
    font-display: swap;
    src: url("/fonts/poppins-700-latin.woff2") format("woff2");
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329,
        U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
    font-family: "Poppins";
    font-style: normal;
    font-weight: 800;
    font-display: swap;
    src: url("/fonts/poppins-800-latin.woff2") format("woff2");
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329,
        U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* IBM PLEX MONO — les surtitres et les mentions courtes de la maquette, en
   majuscules espacées. Deux graisses, jamais du corps de texte. */
@font-face {
    font-family: "IBM Plex Mono";
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url("/fonts/ibmplexmono-400-latin.woff2") format("woff2");
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329,
        U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
    font-family: "IBM Plex Mono";
    font-style: normal;
    font-weight: 500;
    font-display: swap;
    src: url("/fonts/ibmplexmono-500-latin.woff2") format("woff2");
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329,
        U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
* {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
    text-decoration: none;
    list-style: none;
    color: var(--accent-color);
    font-size: var(--font-m);
    font-family: "Poppins", "Inter", sans-serif;
}
[lang="ar"] * {
    font-family: "Cairo", "Noto Sans Arabic", "Inter", sans-serif;
}
/* ========================================
   LES ICÔNES — un fichier SVG par icône, dans /public/svg

   LE DESSIN EST DANS LE ::before, PAS SUR LE <i>. C'est la règle qui tient tout
   le reste : le <i> reste une BOÎTE ordinaire, exactement comme du temps des
   glyphes. Donc un `background-color` posé sur lui peint la PASTILLE et pas
   l'icône, un `color` peint l'ICÔNE via `currentColor`, et `width` / `height` /
   `border-radius` / `padding` / `box-shadow` habillent la boîte pendant que le
   dessin se centre dedans. Une quinzaine de règles du tableau de bord sont des
   pastilles teintées bâties comme ça — elles marchent sans rien savoir d'ici.

   Poser le masque sur le <i> lui-même semblait plus court : ça repeignait le
   dessin avec la couleur de fond de la pastille et faisait disparaître celle-ci.

   La TAILLE suit `font-size`, comme avant. Le tracé Lucide n'occupe que ~75 %
   de son carré de 24 là où un glyphe remplissait le sien : le 1.25em rattrape
   cet écart, à ne pas lire comme un agrandissement.

   La classe porte le nom du fichier : `edk-icon-check` lit `/svg/check.svg`.
   Ajouter une icône = déposer le fichier + une ligne ici, rien d'autre.
   ======================================== */
.edk-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    vertical-align: -0.125em;
}
/* Le `display` ci-dessus est une règle auteur : il bat le `[hidden]{display:none}`
   du navigateur, et une icône marquée `hidden` resterait visible. C'est le cas de
   la coche des locales non actives dans la modale des langues, posée par le twig
   et reposée par language_selector_controller.js. */
.edk-icon[hidden] {
    display: none;
}
.edk-icon::before {
    content: "";
    display: block;
    flex: none;
    width: 1.25em;
    height: 1.25em;
    background-color: currentColor;
    -webkit-mask: var(--edk-icon) center / contain no-repeat;
            mask: var(--edk-icon) center / contain no-repeat;
}
/* La rotation du chargement, sur le dessin seul : une pastille autour ne doit
   pas tourner avec lui. `onboardingSpin` est déclarée plus bas dans cette
   feuille — les @keyframes sont globales, l'ordre n'a pas d'importance. */
.edk-icon-spin::before {
    animation: onboardingSpin 1s linear infinite;
}
/* Le doublement de taille de la 404. */
.edk-icon-2x {
    font-size: 2em;
}
.edk-icon-arrow-left { --edk-icon: url("/svg/arrow-left.svg"); }
.edk-icon-arrow-left-from-bracket { --edk-icon: url("/svg/arrow-left-from-bracket.svg"); }
.edk-icon-arrow-right { --edk-icon: url("/svg/arrow-right.svg"); }
.edk-icon-arrow-right-from-bracket { --edk-icon: url("/svg/arrow-right-from-bracket.svg"); }
.edk-icon-arrow-up { --edk-icon: url("/svg/arrow-up.svg"); }
.edk-icon-building { --edk-icon: url("/svg/building.svg"); }
.edk-icon-chart-column { --edk-icon: url("/svg/chart-column.svg"); }
.edk-icon-chart-line { --edk-icon: url("/svg/chart-line.svg"); }
.edk-icon-check { --edk-icon: url("/svg/check.svg"); }
.edk-icon-chevron-down { --edk-icon: url("/svg/chevron-down.svg"); }
.edk-icon-chevron-left { --edk-icon: url("/svg/chevron-left.svg"); }
.edk-icon-chevron-right { --edk-icon: url("/svg/chevron-right.svg"); }
.edk-icon-chevron-up { --edk-icon: url("/svg/chevron-up.svg"); }
.edk-icon-circle { --edk-icon: url("/svg/circle.svg"); }
.edk-icon-circle-check { --edk-icon: url("/svg/circle-check.svg"); }
.edk-icon-circle-info { --edk-icon: url("/svg/circle-info.svg"); }
.edk-icon-circle-xmark { --edk-icon: url("/svg/circle-xmark.svg"); }
.edk-icon-city { --edk-icon: url("/svg/city.svg"); }
.edk-icon-cloud-arrow-up { --edk-icon: url("/svg/cloud-arrow-up.svg"); }
.edk-icon-code { --edk-icon: url("/svg/code.svg"); }
.edk-icon-coins { --edk-icon: url("/svg/coins.svg"); }
.edk-icon-copy { --edk-icon: url("/svg/copy.svg"); }
.edk-icon-earth-africa { --edk-icon: url("/svg/earth-africa.svg"); }
.edk-icon-envelope { --edk-icon: url("/svg/envelope.svg"); }
.edk-icon-eye { --edk-icon: url("/svg/eye.svg"); }
.edk-icon-facebook { --edk-icon: url("/svg/facebook.svg"); }
.edk-icon-file-lines { --edk-icon: url("/svg/file-lines.svg"); }
.edk-icon-fingerprint { --edk-icon: url("/svg/fingerprint.svg"); }
.edk-icon-gear { --edk-icon: url("/svg/gear.svg"); }
.edk-icon-images { --edk-icon: url("/svg/images.svg"); }
.edk-icon-key { --edk-icon: url("/svg/key.svg"); }
.edk-icon-link { --edk-icon: url("/svg/link.svg"); }
.edk-icon-location-dot { --edk-icon: url("/svg/location-dot.svg"); }
.edk-icon-lock { --edk-icon: url("/svg/lock.svg"); }
.edk-icon-lock-keyhole { --edk-icon: url("/svg/lock-keyhole.svg"); }
.edk-icon-map-location-dot { --edk-icon: url("/svg/map-location-dot.svg"); }
.edk-icon-mobile-screen-button { --edk-icon: url("/svg/mobile-screen-button.svg"); }
.edk-icon-phone { --edk-icon: url("/svg/phone.svg"); }
.edk-icon-plus { --edk-icon: url("/svg/plus.svg"); }
.edk-icon-robot { --edk-icon: url("/svg/robot.svg"); }
.edk-icon-shield-check { --edk-icon: url("/svg/shield-check.svg"); }
.edk-icon-sliders { --edk-icon: url("/svg/sliders.svg"); }
.edk-icon-sparkles { --edk-icon: url("/svg/sparkles.svg"); }
.edk-icon-spinner-third { --edk-icon: url("/svg/spinner-third.svg"); }
.edk-icon-star { --edk-icon: url("/svg/star.svg"); }
.edk-icon-star-solid { --edk-icon: url("/svg/star-solid.svg"); }
.edk-icon-tag { --edk-icon: url("/svg/tag.svg"); }
.edk-icon-trash-can { --edk-icon: url("/svg/trash-can.svg"); }
.edk-icon-triangle-exclamation { --edk-icon: url("/svg/triangle-exclamation.svg"); }
.edk-icon-user { --edk-icon: url("/svg/user.svg"); }
.edk-icon-vial { --edk-icon: url("/svg/vial.svg"); }
.edk-icon-whatsapp { --edk-icon: url("/svg/whatsapp.svg"); }
.edk-icon-xmark { --edk-icon: url("/svg/xmark.svg"); }
/* ========================================
   LE THÈME — un seul, le clair

   Toutes les variables vivent dans `:root`. Il n'y a plus d'attribut sur <html>,
   plus de bascule, plus de second jeu de valeurs : la page est servie dans le
   seul thème qui existe, sans script et sans flash.
   ======================================== */
:root {
    /* === COULEURS BASE ===
       LES DIX COULEURS DE LA CHARTE, TELLES QUELLES. Encre #0A1330 pour ce qui
       doit peser, texte #454F6B pour le corps, bleu #316BFF pour le geste, bleu
       profond #1031A9 pour le survol, papier #F5F7FC pour la page, ligne #E3E8F5
       pour les filets, tint #EEF3FF pour les fonds discrets.

       `--default-color` prend l'ENCRE et non le texte : ce token porte les titres
       autant que le corps, et #454F6B sur les deux aurait allégé chaque titre de
       l'application. Le texte de la charte descend sur `--accent-color`, qui est
       exactement le rôle qu'il décrit.

       Les valeurs intermédiaires (les 8 gris, les 12 tintes, les rampes de bouton)
       n'existent pas dans la charte : elles sont interpolées entre ses bornes. */
    --default-color: #0a1330;
    --accent-color: #454f6b;
    --primary-color: #316bff;
    --primary-color-dark: #1031a9;
    --secondary-color: #ff8600;
    --background-color: #f5f7fc;
    --background-grey: #eef3ff;

    /* === BTN PRIMARY (legacy aliases — gardés pour cascade safety) ===
       La rampe du dégradé de marque : accent → bleu → bleu profond. */
    --btn-primary-250: #5f89f7;

    /* === GREYS / SLATE (8 niveaux) ===
       Papier → tint → ligne pour les trois surfaces, puis interpolation jusqu'à
       l'encre. Ce ne sont plus des gris neutres : ils portent la teinte bleutée de
       la charte, comme le papier lui-même. */
    --grey-50:  #f5f7fc;
    --grey-100: #eef3ff;
    --grey-200: #e3e8f5;
    --grey-300: #c9d2e6;
    --grey-400: #98a3bc;
    --grey-500: #6e7a96;
    --grey-600: #454f6b;

    /* === BACKGROUND TINTÉS (mesh / cards) === */
    --bg-page:       #f5f7fc;
    --bg-card:       #ffffff;
    --bg-card-tint:  #fafbfe;
    --bg-modal:      #ffffff;
    --bg-soft:       #eef3ff;

    /* === LE VERRE ===
       Rien à éclaircir sur du blanc : la carte reste la carte, et le survol ne
       change rien.

       LE FILET, LUI, DOIT SE VOIR. `--grey-100` (#eef3ff) posé sur une page
       `--bg-page` (#f5f7fc) donne un contraste de 1,01 : le trait n'existerait
       pas. `--border-color` est le trait de la charte, celui que `--border`
       emploie déjà partout ailleurs ; le survol prend un cran de plus pour rester
       distinct du repos. */
    --glass:              var(--bg-card);
    --glass-hover:        var(--bg-card);
    --glass-border:       var(--border-color);
    --glass-border-hover: var(--grey-300);
    /* Un CONTRÔLE posé sur une carte. Il partage les deux bordures et le fond de
       repos de la carte qui le porte. */
    --glass-hover-strong: var(--bg-card);
    /* Ce qui se pose DANS ce contrôle — le libellé et l'icône, gris ardoise. */

    /* L'onglet courant de la navigation : le bleu pâle et le bleu profond. */

    /* LA NOTIFICATION FLOTTE, DONC ELLE EST OPAQUE.
       Partout ailleurs un fond d'état peut être un voile : il se compose avec la
       surface qui le porte, et on sait laquelle. Une notification, elle, passe
       au-dessus de n'importe quoi — le mesh, une carte, un tableau. */
    --notification-bg:        var(--blue-tint-250);
    --notification-danger-bg: #fce9e7;

    /* === LA ZONE DE DÉPÔT ===
       Pas de mur de vignettes ni de voile : le mur est éteint plus bas, et le
       voile n'aurait donc rien à couvrir. */
    --dropzone-bg:      var(--bg-card);
    --dropzone-border:  var(--primary-color);
    --dropzone-veil:    transparent;
    --dropzone-icon-bg: var(--bg-soft);

    /* === L'ÉTAT D'UNE PAGE ===
       Le libellé et la pastille prennent la même teinte : c'est le contraste du
       papier qui fait déjà le travail. */
    --status-online:      var(--success);
    --status-offline:     var(--error);

    /* Ce qui se pose SUR une surface colorée — le texte d'un bouton primaire, une
       icône dans un en-tête de modale, la pastille d'un interrupteur. */
    --on-accent:     #ffffff;

    /* LE BOUTON D'ACTION GARDE LE BLEU DE LA MARQUE. C'est une surface pleine
       avec du blanc dessus : là où `--primary-color` sert de TEXTE et doit passer
       le contraste, `--cta` n'a que le blanc à porter. */
    --cta:           #316bff;
    --cta-hover:     #1031a9;

    /* LE MINT DE LA CHARTE. Il n'existe que posé sur du bleu ou sur l'encre — le
       hero, le pied de page, la flèche d'un bouton plein. Sur le papier il ne
       passerait pas le contraste : ce n'est pas un token de surface, c'est un
       accent qui vit sur le sombre. */
    --mint:          #7df7c0;
    --mint-veil:     rgba(125, 247, 192, 0.09);
    --mint-line:     rgba(125, 247, 192, 0.28);
    /* Le mint CLAIR de la maquette V2 — l'accent du h1 du hero, et lui seul. */
    --mint-light:    #a8ffd8;
    /* L'or du liseré animé de la carte de capture ( mint → blanc → or → mint ). */
    --edge-gold:     #f5c77a;

    /* LE DÉGRADÉ DU HERO PUBLIC. Bleu profond → bleu de marque → accent : le hero
       est sombre par nature. Le grain casse le banding d'un dégradé plein écran.
       Les trois couches sont aussi disponibles séparément — le liseré de la carte
       de capture ne prend que le dégradé. */
    /* LES VALEURS DE LA MAQUETTE V2 ( export-oultem, 2026-09-06 ) : bleu profond →
       #2E62E8 → #1A3FBF, et quatre halos — deux en haut, deux aux coins bas. */
    --hero-gradient: linear-gradient(120deg, #1031a9 0%, #2e62e8 52%, #1a3fbf 100%);
    --hero-halo:
        radial-gradient(at 50% 0%, rgba(16, 49, 169, 0.55) 0, transparent 58%),
        radial-gradient(at 50% 40%, rgba(255, 255, 255, 0.1) 0, transparent 56%),
        radial-gradient(at 2% 96%, rgba(16, 49, 169, 0.6) 0, transparent 54%),
        radial-gradient(at 98% 96%, rgba(16, 49, 169, 0.6) 0, transparent 54%);
    /* L'opacité est CUITE DANS LE SVG ( `opacity='.07'` sur le rect ) et non posée
       en CSS : un calque de fond ne peut pas porter d'`opacity` à lui seul. */
    --hero-noise: url("data:image/svg+xml,%3Csvg%20xmlns=%27http://www.w3.org/2000/svg%27%3E%3Cfilter%20id=%27n%27%3E%3CfeTurbulence%20type=%27fractalNoise%27%20baseFrequency=%27.8%27%20numOctaves=%273%27/%3E%3C/filter%3E%3Crect%20width=%27100%25%27%20height=%27100%25%27%20filter=%27url%28%23n%29%27%20opacity=%27.07%27/%3E%3C/svg%3E");

    /* LA COMBINAISON, EN UN SEUL TOKEN — grain, halos, dégradé, dans cet ordre de
       calques ( le premier est le plus haut ). C'est elle que le header et le hero
       peignent tous les deux, à l'identique : deux surfaces qui doivent coïncider
       ne peuvent pas être écrites deux fois.

       `background-blend-mode` et non `mix-blend-mode` : le mélange reste ENTRE les
       calques du même élément. Un `mix-blend-mode` se compose avec le fond du plus
       proche contexte d'empilement — c'est ce qui remontait le hero au-dessus de la
       section suivante et faisait ramer le défilement. */
    --hero-mesh: var(--hero-noise), var(--hero-halo), var(--hero-gradient);
    /* Une seule valeur, répétée sur les six calques : la maquette V2 pose son
       grain en `normal` à 7 %, plus rien n'est mélangé. */
    --hero-mesh-blend: normal;

    /* LA PAGE DE CAPTURE ( `/callme`, `/submited` ) EST SUR L'ENCRE : ses trois
       calques — le grain à 16 % en `overlay`, deux halos bleus, les fines rayures
       verticales — sont ceux de `export-oultem/formulaire.html`. */

    /* L'ENCRE, EN APLAT. Le pied de page et les pastilles numérotées de la landing
       sont encre : c'est le contraste voulu par la charte. `--default-color` porte
       la même valeur mais un tout autre rôle — celui-ci est une SURFACE. */
    --ink:           #0a1330;
    /* Le survol d'un bouton encre — le geste de la carte de capture. */

    /* La page du vendeur, telle que son visiteur la voit : le fond de l'iframe de
       preview, la capture de la landing, la page abstraite de la relecture. Blanc
       franc et non le papier de l'interface — c'est une boutique, pas notre outil. */
    --paper:         #ffffff;

    /* === COULEURS SÉMANTIQUES ===
       LES TROIS STATUTS DE LA CHARTE : lead qualifié #10A36E, à relancer #E8A33C,
       hors cible #E04B3F. Chacun décline en un plein pour le texte, un profond
       pour porter du blanc, et un voile pâle pour les pastilles. */
    --success:        #10a36e;
    --success-dark:   #0c8459;
    /* LE FOND PLEIN D'UN RETOUR, sous du texte blanc — le bouton qui vient de dire
       « enregistré », celui qui vient d'échouer. Un vert foncé porte du blanc ET se
       lit sur une pastille pâle : les deux métiers se confondent ici. */
    --success-solid:  #0c8459;
    --success-light:  #e1f5ec;
    --success-text:   #076647;

    --error:          #e04b3f;
    --error-dark:     #b93a30;
    --error-solid:    #b93a30;
    --error-light:    #fce9e7;

    --warning:        #e8a33c;
    --warning-dark:   #c4832a;
    --warning-light:  #fbedd6;
    /* PAS `--warning-dark` : il vaut #ea580c, un orange rouge, et sur un fond
       jaune pâle les deux teintes se battent. On reste dans la teinte du fond en
       assombrissant `--warning`, qui en est la version saturée — le texte devient
       le même ambre, en plus profond, et passe à 5:1 de contraste. */
    --warning-text:   color-mix(in srgb, var(--warning) 65%, black);

    --info:           #1031a9;
    --info-light:     #d7e3ff;
    --info-bg:        #eef3ff;

    /* === TEINTES D'ACCENT ===
       Les familles décoratives : la pastille d'un accordéon, la puce d'un tableau,
       la carte d'un réglage, l'icône d'une fonctionnalité. Même forme que les
       sémantiques ci-dessus — la couleur pleine, sa version claire pour un fond.

       AUCUNE N'EST FUSIONNÉE avec une voisine, même quand deux teintes sont
       proches : ce sont des valeurs en place depuis longtemps, elles ne changent
       pas d'un pixel. Elles n'existent en variables que pour ça. */

    /* Violet — le module de retouche, les cartes lavande, le badge d'inscription */
    /* Les fonds pleins qui portent du blanc : ces deux valeurs le faisaient déjà. */

    /* Pourpre — les accordéons, les puces de tableau, le rappel de rotation */
    --purple:         #7b2cbf;
    --purple-strong:  #7e22ce;
    --purple-solid:   #7e22ce;
    --purple-light:   #e0c9ff;
    --purple-pale:    #f3e8ff;

    /* Orange — la carte « offres », la puce de commande, l'icône ambre */
    --orange-pill-bg:   #fff4e5;
    --orange-pill-text: #b35e00;

    /* Verts — l'interrupteur, la légende des commandes, l'icône de fonctionnalité */
    --green-switch:   #509c2c;
    --green-orders:      #02824a;
    --green-orders-icon: #02b15a;
    --green-orders-bg:   #d1f5e0;

    /* Bleus tintés — les fonds de la liste des pages, les filets de tableau.
       L'échelle court du blanc cassé au « Bleu 200 » #B9CBFF de la charte, en
       passant par le papier, le tint et la ligne. */
    --blue-tint-50:   #fbfcff;
    --blue-tint-100:  #f8faff;
    --blue-tint-200:  #f1f4fc;
    --blue-tint-250:  #eef3ff;
    --blue-tint-300:  #e9eefa;
    --blue-tint-400:  #dce4f7;
    --blue-tint-500:  #cdd9f4;
    --blue-tint-550:  #c3d2f2;
    --blue-tint-600:  #b9cbff;
    /* Le bleu ardoise de la maquette V2 — le texte d'une pastille « À rappeler »
       et du bouton filet « Foire aux questions ». */
    --blue-text-soft: #2e4a9e;
    --blue-visits:      #1031a9;
    --blue-visits-icon: #316bff;
    --blue-visits-bg:   #eef3ff;

    /* Rouges hors sémantique — l'accordéon rouge, le bouton supprimer */
    --red-accordion-icon: #f6ccc8;
    --red-accordion-bg:   #fdf4f3;
    --red-deep:           #8e2b23;

    /* Gris hors échelle — les ascenseurs, deux textes atténués, un pied de page */
    --grey-track:     #e3e8f5;
    --grey-scrollbar: #98a3bc;
    --grey-scrollbar-track: #c9d2e6;
    --grey-text-mid:  #6e7a96;
    --grey-text-soft: #98a3bc;
    /* Le gris secondaire de la maquette V2 ( #8891AD ) : métas des fiches,
       libellés mono, placeholders, horodatages. */
    --grey-text-muted: #8891ad;
    --grey-ink:       #0a1330;

    /* Le voile derrière une modale. Il ne se comporte ni comme une ombre ni comme
       une surface : il assombrit ce qu'il y a dessous. */
    --overlay:        rgba(0, 0, 0, 0.6);

    /* === L'EN-TÊTE DE MODALE ===
       Un bandeau de marque, plein. Pas de filet : l'aplat de couleur marque déjà
       la frontière avec le corps. */
    --modal-head-bg:     var(--primary-color);
    --modal-head-border: transparent;
    --modal-head-sub:    rgba(255, 255, 255, 0.78);

    /* La rangée d'en-tête des tables ( commandes, pages ). Une teinte à elle, et
       non `--bg-card-tint` : ce token sert une douzaine de surfaces ailleurs, et
       la rangée de titres se règle sans les emmener toutes avec elle. */
    --table-head-bg:     #f1f4fc;

    /* === LE MESH DE LA PAGE ===
       Il vit sur le <body> et nulle part ailleurs. Quatre halos aux quatre coins.

       C'est un TOKEN et non une règle : tout ce qui s'en sert suit sans avoir à
       redéclarer quoi que ce soit. */
    --page-mesh:
        radial-gradient(at 12% 20%, rgba(49, 107, 255, .16) 0, transparent 55%),
        radial-gradient(at 88% 15%, rgba(95, 137, 247, .12) 0, transparent 50%),
        radial-gradient(at 95% 95%, rgba(16, 49, 169, .12) 0, transparent 55%),
        radial-gradient(at 5% 95%, rgba(95, 137, 247, .16) 0, transparent 50%);

    /* === LE MESH DE LA LANDING ===
       La page publique est une vitrine, pas un poste de travail : ses halos sont
       plus francs que ceux du tableau de bord.

       DEUX VALEURS ET NON QUATRE. La maquette en dessine une par section, mais elles
       se répètent deux à deux : une pour l'accueil du regard, une pour les sections
       qui suivent.

       LES TROIS TEINTES SONT CELLES DU DÉGRADÉ DE MARQUE et rien d'autre —
       #5F89F7 → #316BFF → #1031A9. Le violet et l'orange qui traînaient dans ces
       halos sont partis avec la charte : « un dégradé, toujours dans la famille
       bleue ». */
    /* Les pages légales se distinguent par la PROFONDEUR du bleu, plus par une
       couleur à elles : le dôme violet et la pointe d'orange sont partis avec la
       charte, le bleu profond #1031A9 prend le dessus du hero. */
    --legal-mesh-hero:
        radial-gradient(at 50% -8%, rgba(16, 49, 169, .12) 0, transparent 52%),
        radial-gradient(at 8% 22%, rgba(95, 137, 247, .14) 0, transparent 48%),
        radial-gradient(at 94% 8%, rgba(49, 107, 255, .12) 0, transparent 46%);

    /* Le document qui s'écrit pendant la génération : une console, pas une surface
       du tableau de bord. Elle est sombre, ses quatre couleurs ne suivent donc pas
       le papier de l'interface. */
    --console-bg:     #0f172a;
    --console-text:   #c8d6f5;
    --console-tag:    #8fb0ff;
    --console-cta:    #ffc27a;

    /* === SHADOWS ===
       Les ombres portent l'ENCRE de la charte et non un noir neutre : sur du papier
       bleuté, une ombre grise tire au vert. */
    --shadow-flat:  0 1px 2px rgba(10, 19, 48, 0.05);
    --shadow:       0 1px 2px rgba(10, 19, 48, 0.04), 0 14px 34px rgba(10, 19, 48, 0.06);
    /* L'OMBRE DE CARTE DE LA MAQUETTE — trois couches et non une. Le liseré blanc
       INTÉRIEUR fait le bord haut ( une carte blanche sur du papier bleuté n'a pas
       d'arête sans lui ), le 1px pose la carte, la retombée longue et très étalée
       (-24px) la décolle sans la border d'un halo. C'est ce que peignent déjà les
       briques et les étapes de l'accueil.

       ELLE PORTE L'ENCRE, comme toutes ses voisines. Le tableau de bord écrivait
       un `rgba(0,0,0,.1)` neutre, hérité d'avant la charte : du noir pur sur du
       papier bleuté tire au vert et salit la carte. */
    --shadow-card:
        inset 0 1px 0 rgba(255, 255, 255, 0.9),
        0 1px 2px rgba(10, 19, 48, 0.06),
        0 16px 32px -24px rgba(10, 19, 48, 0.4);
    /* La retombée bleue du geste principal — le bouton plein ne porte pas une
       ombre grise, il porte la sienne. */
    --shadow-cta:   0 12px 30px -12px rgba(49, 107, 255, 0.7);
    --shadow-soft:  0 1px 2px rgba(10, 19, 48, 0.04), 0 4px 12px rgba(10, 19, 48, 0.05);
    --shadow-lift:  0 4px 12px rgba(10, 19, 48, 0.08), 0 16px 32px rgba(10, 19, 48, 0.10);
    --shadow-focus: 0 0 0 3px rgba(49, 107, 255, 0.35);

    /* === BORDERS === */
    --border-color: #e3e8f5;

    /* === TYPOGRAPHIE === */
    --font-xs: 12.25px;
    --font-s:  13.25px;
    --font-m:  14.25px;
    --font-l:  15.25px;

    /* Les surtitres et les mentions courtes en majuscules espacées — jamais du
       corps de texte. Déclaré une fois ici pour que « Ubuntu » ne revienne pas en
       littéral dans chaque feuille, comme il l'a fait pour les titres. */
    --font-mono: "IBM Plex Mono", ui-monospace, "SFMono-Regular", monospace;

    /* === RADIUS ===
       LES QUATRE VALEURS DE LA CHARTE : 8 les champs, 14 les boutons, 20 les
       cartes, 999 les pastilles. `--radius-s` passe de 7 à 8px — l'écart ne se voit
       pas et aligne tous les champs de l'application sur la maquette. `--radius-l`
       est neuf : seules les pages publiques le consomment pour l'instant, les cartes
       du tableau de bord gardent leurs 14px tant qu'on ne les reprend pas une à une. */
    --radius-sm: 4px;
    --radius-s:  8px;
    --radius:    14px;
    --radius-l:  20px;

    /* === DÉRIVÉES ===
       La couleur de bordure est exposée à part parce que plusieurs règles posent
       leur propre épaisseur ou leur propre côté et ne peuvent pas prendre le
       raccourci complet. */
    --border:       1px solid var(--border-color);
    --border-soft:  1px solid var(--grey-100);

    /* === TRANSITIONS === */
    --transition:      all 200ms ease-out;
    --transition-fast: all 150ms ease-out;
}

/* LE FOND DE LA PAGE VIT ICI, sur le body, et défile avec elle. Avant, chaque
   conteneur repeignait le mesh en `attachment: fixed` — c'est ce qui faisait
   coïncider le header flottant avec la page derrière lui. Une seule surface le
   porte désormais, et le header a son propre traitement ( plus bas ). */
/* `fixed` ET NON `scroll`, PARCE QUE LE HEADER REPEINT LE MÊME MESH.

   L'attachement ne décide pas que du défilement : il décide de la zone sur laquelle
   les pourcentages se calculent. En `scroll` c'est la boîte du body, donc la hauteur
   du document ; en `fixed` c'est le viewport. Le header étant `fixed`, ses halos se
   dimensionnent sur l'écran — si le body se dimensionne sur le document, les deux
   dégradés n'ont ni la même taille ni le même centre, et un trait apparaît là où ils
   se touchent, avant même d'avoir défilé.

   Les deux surfaces doivent donc partager la même zone de référence. Conséquence
   assumée : les halos restent calés sur l'écran et ne défilent pas avec la page. */
.edouk_body {
    background-color: var(--bg-page);
    background-image: var(--page-mesh);
    background-repeat: no-repeat;
    background-attachment: fixed;
}
* {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
    text-decoration: none;
    list-style: none;
    color: var(--accent-color);
    font-size: var(--font-m);
    font-family: "Poppins", "Inter", sans-serif;
}
[lang="ar"] * {
    font-family: "Cairo", "Noto Sans Arabic", "Inter", sans-serif;
}
[lang="ar"] h1,
[lang="ar"] h2,
[lang="ar"] h3,
[lang="ar"] h4,
[lang="ar"] h5,
[lang="ar"] .edouk_label,
[lang="ar"] .edouk_submit,
[lang="ar"] .edouk_btn {
    font-family: "Cairo", "Ubuntu", sans-serif;
}
/* Cairo prioritaire partout en arabe. Les règles de titre en "Poppins" (cette feuille
   et blocs <style> des templates) sont plus spécifiques que [lang="ar"] * et
   gagnaient la cascade : d'où des textes hors Cairo. Le !important tranche sans
   avoir à dupliquer une variante [lang="ar"] par sélecteur.
   Les <i> restent exclus : ils ne portent pas de texte, seulement une icône. */
[lang="ar"] *:not(i) {
    font-family: "Cairo", "Noto Sans Arabic", "Inter", sans-serif !important;
}
/* L'arabe démarre à 500 : Cairo à 400 est trop fin pour être lu confortablement
   à nos tailles. Les poids 600 et 700 déjà posés restent inchangés. */
[lang="ar"] body {
    font-weight: 500;
}
[lang="ar"] .edouk_table tbody td {
    font-weight: 500;
}
[lang="ar"] h1,
[lang="ar"] h2,
[lang="ar"] h3,
[lang="ar"] h4,
[lang="ar"] h5 {
    font-weight: 600;
}
h1,
h2,
h3,
h4,
h5 {
    margin: 0;
    padding: 0;
    color: var(--default-color);
    font-weight: 500;
    font-family: "Poppins";
}
[dir="rtl"] h1,
[dir="rtl"] h2,
[dir="rtl"] h3,
[dir="rtl"] h4,
[dir="rtl"] h5 {
    font-family: "Cairo", "Ubuntu";
}
h1 {
    font-size: 22px;
}
h2 {
    font-size: 20px;
}
h3 {
    font-size: 18px;
}
h4 {
    font-size: 16px;
}
h5 {
    font-size: 14px;
}
@media (min-width: 350px) {
    :root {
        --font-xs: 12.75px;
        --font-s: 13.75px;
        --font-m: 14.75px;
        --font-l: 15.75px;
    }
}
@media (min-width: 768px) {
    :root {
        --font-xs: 13.75px;
        --font-s: 14.25px;
        --font-m: 15.25px;
        --font-l: 16.25px;
    }
    h1 {
        font-size: 24px;
    }
    h2 {
        font-size: 22px;
    }
    h3 {
        font-size: 20px;
    }
    h4 {
        font-size: 18px;
    }
    h5 {
        font-size: 16px;
    }
}
@media (min-width: 992px) {
    :root {
        --font-s: 15.25px;
        --font-m: 16.25px;
        --font-l: 17.25px;
    }
    h1 {
        font-size: 26px;
    }
    h2 {
        font-size: 24px;
    }
    h3 {
        font-size: 22px;
    }
    h4 {
        font-size: 20px;
    }
    h5 {
        font-size: 18px;
    }
}
html {
    width: 100%;
    min-height: 100vh;
    min-height: 100dvh;
    /* La base qu'UIkit posait ici avant son retrait : sans elle, tout ce qui ne
       déclare pas son line-height retombe sur `normal` (~1.2). */
    line-height: 1.5;
}
/* Le défilement doux des ancres de la home (« En savoir plus » → #comment,
   le CTA final → #depot). Posé par une classe et non en global : sur `html`
   partout, Turbo animerait aussi le retour en haut à chaque navigation du
   tableau de bord. */
.edouk_smooth {
    scroll-behavior: smooth;
}
body {
    width: 100%;
    min-height: 100vh;
    min-height: 100dvh;
}
/* PLUS DE FOND ICI. Le mesh et la couleur de page vivent sur le body, et un fond
   opaque à ce niveau les recouvrirait sur toute la hauteur de l'écran. */
.edouk_main {
    width: 100%;
    min-height: 100vh;
    min-height: 100dvh;
    display: flex;
    flex-direction: column;
    background: transparent;
    /* UNE SEULE RANGÉE DE HEADER DEPUIS LA SIDEBAR. La rangée de navigation a
       quitté le header pour la colonne de gauche ( voir `sidebar.html.twig` ),
       il ne reste que la rangée logo : 25 + 41 + 25, plus la respiration. C'est
       la valeur que le visiteur avait déjà, elle vaut maintenant pour tous. */
    padding-top: 96px !important;
    padding-bottom: 30px !important;
}
a {
    text-decoration: none;
}
a:hover {
    text-decoration: none;
}
span,
strong,
ul,
ol,
li,
p,
a,
label,
input,
button,
textarea,
span {
    font-size: var(--font-s);
    margin: 0;
    padding: 0;
}
/* LA MESURE DE TOUTE L'APPLICATION — le header, le pied, les quatre sections de
   la landing, les pages légales et le `<main>` du tableau de bord.

   L'ÉCHELLE EST CELLE D'ORIGINE, MOINS DEUX POINTS À CHAQUE PALIER. Les 5 % du
   mobile ne bougent pas : c'est là que la marge sert vraiment. Au-dessus, chaque
   gouttière rend 2 % à la page, ce qui lui redonne 4 % de largeur — la landing
   était à l'étroit sur grand écran. La progression, elle, ne change pas.

   PUIS L'ÉCHELLE A GLISSÉ D'UN CRAN À PARTIR DE 768px : chaque palier prend la
   valeur de celui d'en dessous, et les deux premiers ne bougent pas. La landing
   respirait encore mal à partir de la tablette. Le palier 768 tombe donc sur la
   même valeur que 576 ; il est gardé tel quel, c'est le barreau qui rend le
   glissement lisible — et le prochain réglage repartira de là. */
.edouk_container {
    padding: 0 5%;
}
@media (min-width: 576px) {
    .edouk_container {
        padding: 0 5.5%;
    }
}
@media (min-width: 768px) {
    .edouk_container {
        padding: 0 5.5%;
    }
}
@media (min-width: 992px) {
    .edouk_container {
        padding: 0 7%;
    }
}
@media (min-width: 1200px) {
    .edouk_container {
        padding: 0 9%;
    }
}
@media (min-width: 1400px) {
    .edouk_container {
        padding: 0 12%;
    }
}
@media (min-width: 1500px) {
    .edouk_container {
        padding: 0 14%;
    }
}
@media (min-width: 1600px) {
    .edouk_container {
        padding: 0 16%;
    }
}
@media (min-width: 1700px) {
    .edouk_container {
        padding: 0 18%;
    }
}
@media (min-width: 1800px) {
    .edouk_container {
        padding: 0 20%;
    }
}
/*
 * iOS UIkit modal backdrop fix (port depuis edouk.css)
 * Quand un .uk-accordion s'ouvre/ferme dans la modal, iOS recompose les couches
 * et le background du .uk-modal flashe. On decouple le backdrop dans un ::before
 * avec sa propre couche compositing (translateZ) immunise aux changements internes.
 */
.uk-modal {
    padding: 30px;
    background: transparent !important;
    background-color: transparent !important;
    -webkit-backdrop-filter: none !important;
    backdrop-filter: none !important;
    isolation: isolate;
}
@media (max-width:355px) {
    .uk-modal {
        padding:30px 11px;
    }
}
.uk-modal::before {
    content: "";
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: var(--overlay);
    z-index: -1;
    pointer-events: none;
    transform: translateZ(0);
    -webkit-transform: translateZ(0);
}
.uk-modal.uk-open {
    transition: none !important;
    background: transparent !important;
    background-color: transparent !important;
    -webkit-backdrop-filter: none !important;
    backdrop-filter: none !important;
}
.uk-modal,
.uk-modal.uk-open,
.uk-modal *,
.uk-modal-dialog * {
    -webkit-tap-highlight-color: transparent;
}

.edouk_modal .uk-modal-dialog {
    width: 100%;
    max-width: 450px !important;
    box-shadow:
        rgba(14, 30, 37, 0.12) 0px 2px 4px 0px,
        rgba(14, 30, 37, 0.32) 0px 2px 16px 0px;
    border-radius: 14px;
    background-color: var(--bg-modal);
    background-image: radial-gradient(at 15% 35%, rgba(49, 107, 255, 0.05) 0px, transparent 50%),
        radial-gradient(at 90% 40%, rgba(255, 134, 0, 0.025) 0px, transparent 45%),
        radial-gradient(at 95% 92%, rgba(0, 55, 214, 0.07) 0px, transparent 50%),
        radial-gradient(at 5% 95%, rgba(92, 138, 255, 0.07) 0px, transparent 45%);
    background-attachment: fixed;
    background-repeat: no-repeat;
}
.uk-modal-body {
    padding: 15px 15px 20px;
}
.edouk_modal .uk-modal-close-default {
    border-radius: 7px;
    margin: 9px;
    display: flex;
    justify-content: center;
    align-items: center;
    background-color: var(--bg-card);
    box-shadow: var(--shadow-lift);
    padding: 7px 7px;
}
html[lang="ar"] .edouk_modal .uk-modal-close-default {
    right: unset;
    left: 6px;
}
.edouk_modal .uk-modal-dialog h2 {
    font-size: calc(var(--font-l) + 3px);
    margin-bottom: 20px;
    padding: 7px;
    border-radius: 7px;
    font-weight: 600;
}
[lang="ar"] .edouk_modal .uk-modal-dialog h2 {
    text-align: right;
    direction: rtl;
}
.edouk_label {
    display: flex;
    align-items: center;
    gap: 5px;
    width: 100%;
    color: var(--accent-color);
    font-size: var(--font-s);
    font-family: "Poppins";
}
.edouk_label i {
    font-size: calc(var(--font-s) - 1px);
    color: var(--primary-color);
}
.edouk_wrapper {
    position: relative;
    border-radius: var(--radius);
    width: 100%;
}
/* AUCUN FOND SOUS L'ICÔNE. Elle est posée en absolu par-dessus le champ et n'a
   rien à masquer. Le fond blanc qui vivait là passait inaperçu tant que tout était
   blanc ; dès que le champ et la carte ont pris deux teintes différentes, il est
   devenu une pastille visible derrière chaque icône ( vu sur la page de connexion ). */
.edouk_wrapper > i {
    position: absolute;
    top: 50%;
    left: 10px;
    transform: translateY(-50%);
    font-size: var(--font-s);
    pointer-events: none;
    line-height: 1;
}
/* Le champ est posé sur du verre, pas sur le fond de carte : en sombre
   `--bg-card` rendait un pavé presque noir dans la carte. En clair `--glass`
   vaut `--bg-card` — le thème clair ne bouge pas d'un pixel. */
.edouk_input {
    width: 100%;
    height: 45px;
    background-color: var(--glass);
    /* Le token et non le 7px écrit à la main : c'est le rayon de champ de la
       charte ( 8px ), et il bouge maintenant d'un seul endroit. */
    border-radius: var(--radius-s);
    padding: 3px 15px 3px 35px;
    font-size: var(--font-m);
    color: var(--default-color);
    border: var(--border);
    box-shadow:
        rgba(0, 0, 0, 0.02) 0px 1px 3px 0px,
        rgba(27, 31, 35, 0.15) 0px 0px 0px 1px;
    box-shadow: var(--shadow-flat);
}
.edouk_input:hover {
    border: 1px solid var(--primary-color);
}
/* UN CHAMP ÉTEINT DOIT SE VOIR. Le verre à nu, en clair, est blanc : le prix
   d'une offre décochée avait exactement l'air d'un champ vide où l'on peut
   écrire. Il prend donc le gris de fond, le gris de texte, et perd son relief
   comme son survol bleu. */
.edouk_input:disabled {
    background-color: var(--grey-100);
    border-color: var(--border-color);
    color: var(--grey-500);
    box-shadow: none;
    cursor: not-allowed;
}
.edouk_input:disabled:hover {
    border: var(--border);
}
/* L'icône du wrapper s'éteint avec lui : posée par-dessus le champ, elle reste
   sinon la seule chose vive d'un champ mort. */
.edouk_wrapper:has(.edouk_input:disabled) > i {
    color: var(--grey-500);
}
.edouk_input:focus {
    outline: 0;
    border: 1px solid var(--primary-color);
    box-shadow: var(--shadow-focus);
    background-color: var(--glass);
}
/* La liste déroulante native hérite du fond du `select` : sur du verre
   semi-transparent le navigateur retombe sur son blanc par défaut. Elle veut une
   couleur opaque — `--bg-card`, le fond que le champ avait avant le verre. */
select.edouk_input option,
select.edouk_input optgroup {
    background-color: var(--bg-card);
    color: var(--default-color);
}
.edouk_input_textarea {
    height: 57px;
    min-height: 57px;
    max-height: 90px;
    padding: 5px 15px!important;
    width: 100%;
    max-width: 100%;
    min-width: 100%;
}
/* Input date natif iOS/Android : le contrôle natif impose sa largeur
   intrinsèque et ignore width:100% (déborde du cadre) — appearance:none
   rend la main au CSS, le picker reste fonctionnel */
input[type="date"].edouk_input {
    -webkit-appearance: none;
    appearance: none;
    display: block;
    min-width: 0;
    max-width: 100%;
    background-color: var(--glass);
}
/* iOS : la valeur est rendue dans un conteneur shadow centré — alignement texte */
input[type="date"].edouk_input::-webkit-date-and-time-value {
    text-align: left;
    margin: 0;
}
html[lang="ar"] input[type="date"].edouk_input::-webkit-date-and-time-value {
    text-align: right;
}
.edouk_input.is_over_limit,
.edouk_input.is_over_limit:hover,
.edouk_input.is_over_limit:focus {
    border: 1px solid var(--error);
    box-shadow: 0 0 0 3px color-mix(in srgb, var(--error) 15%, transparent);
}
html[lang="ar"] .edouk_input {
    text-align: right;
}
html[lang="ar"] .edouk_label {
    text-align: right;
    font-family: "Cairo", "Ubuntu";
}
/* LE BLEU DE LA MARQUE, PAS `--primary-color` : le bouton d'action garde le bleu
   plein de la charte ( voir `--cta` en haut du fichier ). */
.edouk_submit {
    margin-top: 15px;
    width: 100%;
    min-height: 40px;
    border-radius: var(--radius);
    border: solid 1px var(--cta);
    color: var(--on-accent);
    background-color: var(--cta);
    box-shadow: var(--shadow);
    font-size: var(--font-m);
    font-weight: 500;
    cursor: pointer;
    letter-spacing: 0.15px;
    font-family: "Poppins";
    display: flex;
    justify-content: center;
    align-items: center;
    padding: 7px;
    transition: var(--transition);
}
.edouk_submit:hover {
    color: var(--on-accent);
    background-color: var(--cta);
}
.edouk_submit:disabled {
    opacity: 0.75 !important;
}
.edouk_submit_grey {
    color: var(--default-color) !important;
    border-color: var(--default-color) !important;
    background-color: var(--background-grey) !important;
    pointer-events: none !important;
    opacity: 0.65 !important;
    box-shadow: var(--shadow) !important;
}
.edouk_submit_loading {
    opacity: 0.8;
    pointer-events: none;
}
/* Les deux retours du bouton. Fond plein sous du blanc, donc `-solid` et non
   `-dark` : celui-là est une couleur de texte, il est trop clair pour porter du
   blanc. */
.edouk_submit_success {
    background: var(--success-solid) !important;
    border-color: var(--success-solid) !important;
    color: var(--on-accent) !important;
    box-shadow: var(--shadow) !important;
}
.edouk_submit_error {
    background: var(--error-solid) !important;
    border-color: var(--error-solid) !important;
    color: var(--on-accent) !important;
    box-shadow: var(--shadow) !important;
}
.edouk_submit_unchanged {
    background: var(--secondary-color) !important;
    border-color: var(--secondary-color) !important;
    color: var(--on-accent) !important;
    box-shadow: var(--shadow) !important;
}

/* ========================================
   EDOUK BTN (table actions / inline buttons)
   ======================================== */
.edouk_btn {
    border: var(--border);
    border-radius: var(--radius-s);
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
    background-color: var(--bg-card);
    height: 34px;
    padding: 0 12px;
    gap: 6px;
    display: inline-flex;
    justify-content: center;
    align-items: center;
    cursor: pointer;
    font-size: 13.25px;
    font-weight: 600;
    white-space: nowrap;
    color: var(--primary-color);
    transition: all 150ms ease-out;
}
.edouk_btn span,
.edouk_btn i {
    color: inherit;
    font-size: inherit;
}
.edouk_btn i {
    font-size: 15px;
}

/* === EDOUK BTN VARIANTS === */
/* Chaque bouton d'action porte la couleur de la pastille vers laquelle il mène :
   confirmer → vert, annuler → rouge, en livraison → violet, reporter → bleu. */
/* La bordure vient de `.edouk_btn` via `--border`, dont la couleur vaut déjà
   `--glass-border` en sombre : il n'y a que le fond à changer. */
.edouk_btn_primary {
    background-color: var(--glass);
    color: var(--primary-color);
}
.edouk_btn_primary:hover {
    border-color: var(--primary-color);
    background-color: var(--bg-soft);
}
.edouk_btn_secondary {
    background-color: var(--bg-card);
    color: var(--purple-strong);
}
.edouk_btn_secondary:hover {
    border-color: var(--purple-strong);
    background-color: var(--purple-pale);
}
.edouk_btn_confirm {
    background-color: var(--bg-card);
    color: var(--success-text);
}
.edouk_btn_confirm:hover {
    border-color: var(--success-text);
    background-color: var(--success-light);
}
.edouk_btn_danger {
    background-color: var(--bg-card);
    color: var(--error-dark);
}
.edouk_btn_danger:hover {
    border-color: var(--error-dark);
    background-color: var(--error-light);
}
/* LA CORBEILLE DES COMMANDES EST CELLE DE LA TABLE DES PAGES. Elle était grise au
   repos et ne rougissait qu'au survol : sur un écran tactile, où le survol
   n'existe pas, rien ne la distinguait d'un réglage. Le couple `--error-light` /
   `--error` la dit rouge tout de suite, et le survol se contente de resserrer le
   filet — c'est mot pour mot `.edouk_pages_action_delete` de la table des pages.
   Seule la taille reste celle de la famille `.edouk_btn` : 34px, comme les boutons
   d'état de la même rangée. */
.edouk_btn_delete {
    width: 34px;
    padding: 0;
    border-color: var(--error-light);
    background-color: var(--error-light);
    color: var(--error);
}
.edouk_btn_delete:hover {
    border-color: var(--error);
    box-shadow: var(--shadow-soft);
}
.edouk_btn_transparent {
    background-color: var(--bg-card-tint);
    color: var(--accent-color);
    box-shadow: none;
    cursor: default;
}
.edouk_btn_error {
    background: var(--error-solid) !important;
    border-color: var(--error-solid) !important;
    color: var(--on-accent) !important;
}

.ios-switch {
    position: relative;
    min-width: 50px !important;
    width: 50px !important;
    max-width: 50px !important;
    display: flex;
    height: 28px;
    -webkit-appearance: none;
    background: var(--grey-track);
    outline: none;
    border-radius: 50px;
    transition: background 0.3s;
    cursor: pointer;
}
.ios-switch:checked::before {
    transform: translateX(17px);
}
.ios-switch::before {
    content: "";
    position: absolute;
    width: 22px;
    height: 22px;
    border-radius: 50%;
    top: 3px;
    left: 3px;
    background: var(--on-accent);
    transition: transform 0.3s;
}
.ios-switch:checked {
    background: var(--green-switch);
}
/* ---------- La zone de dépôt ----------
   Le composant rend trois enfants : l'input transparent qui couvre tout, le texte
   d'invite, et l'aperçu du fichier choisi. La couche de décor est donc un
   pseudo-élément — il n'y a pas de balise où l'accrocher.

   `overflow: hidden` : sans lui la couche déborde des coins arrondis. */
.dropzone-container {
    position: relative;
    overflow: hidden;
    border: 1px dashed var(--dropzone-border) !important;
    background-color: var(--dropzone-bg) !important;
    border-radius: var(--radius-s) !important;
    transition: border-color 200ms ease-out, background 200ms ease-out;
}
/* Le voile, qui rend le texte lisible par-dessus la carte. */
.dropzone-container::after {
    content: "";
    position: absolute;
    inset: 0;
    z-index: 0;
    pointer-events: none;
    background: var(--dropzone-veil);
}
/* Le contenu repasse au-dessus de la couche de décor — sinon le voile le
   recouvre — mais il reste TRANSPARENT AU CLIC.

   C'est le point délicat : l'input du composant est un calque invisible qui couvre
   toute la zone, et c'est lui qui ouvre le sélecteur de fichier. Il porte
   `z-index: 1`. Tout ce qui monte au même niveau APRÈS lui dans le DOM passe devant
   et lui vole le clic — il ne reste alors que les bordures pour ouvrir la zone. */
.dropzone-placeholder,
.dropzone-preview {
    position: relative;
    z-index: 1;
    pointer-events: none;
}
/* Seul le bouton d'effacement reprend le clic : c'est la seule chose à cliquer
   par-dessus l'input. */
/* Pastille sur carte blanche : la croix prend le texte courant et le fond le gris
   de séparation, sinon elle disparaît. */
.dropzone-preview-button {
    pointer-events: auto;
    color: var(--default-color);
    background-color: var(--grey-200);
    border-radius: var(--radius-sm);
    width: 25px;
    height: 25px;
    display: flex;
    align-items: center;
    justify-content: center;
}
/* La croix du composant arrive par un `::before` paddé — remis à zéro, c'est le
   flex du bouton qui centre le glyphe dans la pastille. */
.dropzone-preview-button::before {
    padding: 0;
}
/* En arabe l'aperçu se lit de droite à gauche : la vignette occupe la droite, la
   pastille bascule à gauche — même geste que le close des modales. */
html[lang="ar"] .dropzone-preview-button {
    right: unset;
    left: 0;
}
/* La pastille d'invite. Elle n'existe pas dans le composant — le bloc d'invite ne
   contient que du texte — donc elle est dessinée ici, flèche comprise.

   C'est un bleu très pâle posé sur du blanc : elle se devine à peine. Le liseré la
   découpe — une ombre portée seule laisse le bord du haut se fondre — et la
   retombée lui donne son relief. Les deux sont bleus : la teinte de la pastille,
   pas un gris. */
.dropzone-placeholder::before {
    content: "";
    display: block;
    width: 42px;
    height: 42px;
    margin: 0 auto 10px;
    border-radius: 12px;
    background-color: var(--dropzone-icon-bg);
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='20' viewBox='0 0 24 24' fill='none' stroke='%23316bff' stroke-width='1.7' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4'/%3E%3Cpath d='M17 8l-5-5-5 5'/%3E%3Cpath d='M12 3v13'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: center;
    box-shadow:
        0 0 0 1px rgba(49, 107, 255, 0.14),
        0 4px 12px -2px rgba(49, 107, 255, 0.30);
}
.dropzone-container:hover {
    border-color: var(--primary-color);
}
.edouk_placeholder {
    display: flex;
    flex-direction: column;
    gap: 7px;
    margin-bottom: 21px;
}
.edouk_placeholder h2,
.edouk_placeholder h1 {
    font-size: 21px;
    font-weight: 700;
    letter-spacing: -0.5px;
}
.edouk_placeholder p {
    font-size: var(--font-s);
    color: var(--accent-color);
    padding: 0 3px;
}

/* Language modal (#edouk-language-modal) */
#edouk-language-form .edouk_language_list {
    display: flex;
    flex-direction: column;
    gap: 6px;
}
#edouk-language-form .edouk_language_item {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 12px 15px;
    border-radius: var(--radius);
    border: solid 1px transparent;
    background-color: var(--bg-card);
    cursor: pointer;
    transition: all 0.2s;
    font-size: var(--font-m);
}
#edouk-language-form .edouk_language_active {
    border-color: var(--primary-color);
    background-color: var(--bg-card);
}
.edouk_modal hr {
    border: none;
    border-top: solid 1px var(--bg-card);
    margin: 19px 0;
}
.edouk_submit_small {
    margin-top: 0;
    color: var(--primary-color);
    background-color: var(--bg-card);
}
html[lang="ar"] .edouk_wrapper > i {
    left: unset;
    right: 10px;
}
html[lang="ar"] .edouk_input {
    padding: 3px 36px 3px 15px;
    text-align: right;
}

/* ---------- Alertes UIkit ----------
   Utilisées dans la modale Telegram pour lister les comptes
   reliés. UIkit les rend en `background: #edfbf6` avec `color: #32d296` : un vert
   clair sur un vert presque blanc, soit 1,9:1. Illisible en clair, et en sombre ce
   fond quasi blanc fait une tache dans la modale.

   Elles reprennent donc la surface de verre du reste du tableau de bord, et la
   couleur ne porte plus que le sens — le texte dit « ce compte est actif », il n'a
   pas à être aussi le fond. */
.uk-alert {
    background: var(--glass);
    border: 1px solid var(--glass-border);
    border-radius: var(--radius);
    color: var(--default-color);
}
.uk-alert-success {
    background: var(--glass);
    color: var(--success-text);
}

/* Fond OPAQUE, et non un voile d'état : voir `--notification-bg`. */
.uk-notification-message {
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    background-color: var(--notification-bg)!important;
    border: 1px solid var(--primary-color);
    color: var(--primary-color)!important;
    font-weight: 600;
}
.uk-notification-message div {
    color: inherit;
}
.uk-notification-message div a {
    text-decoration: underline;
    font-weight: 700;
    margin: 0 6px;
}
.uk-notification-message-danger {
    background-color: var(--notification-danger-bg)!important;
    border-color: var(--error);
    color: var(--error)!important;
}

/* === Universal hover pattern (boutons + zones cliquables) === */
/* Hover : seulement sur devices à vrai pointeur (souris) — évite le hover "collé" sur mobile */
@media (hover: hover) {
    .edouk_submit:hover:not(:disabled),
.edouk_submit_small:hover:not(:disabled),
.edouk_header_tap div button:hover:not(:disabled) {
        transform: translateY(-2px);
        box-shadow: var(--shadow-lift);
    }
    /* Le geste principal suit le pattern universel, mais pose son fond
       explicitement : le bleu ne bouge pas au survol, seule la levée le fait. */
    .edouk_submit:hover:not(:disabled) {
        color: var(--on-accent);
        background-color: var(--cta);
        border-color: var(--cta);
        transform: translateY(-2px);
        box-shadow: var(--shadow-lift);
    }
}
/* Active (tap) : feedback pendant le clic/tap, disparaît au relâchement (mobile + desktop) */
.edouk_submit:active:not(:disabled),
.edouk_submit_small:active:not(:disabled),
.edouk_header_tap div button:active:not(:disabled) {
    transform: translateY(-1px);
    box-shadow: var(--shadow);
}

/* === Accessibility — keyboard focus visible === */
button:focus-visible,
a:focus-visible,
[role="button"]:focus-visible,
.edouk_pay_method_row:focus-within,
.edouk_image_item:focus-visible {
    outline: 2px solid var(--primary-color);
    outline-offset: 2px;
}
/* =========================================================
   MODAL HEAD — bandeau générique (reprend pay / activation)
   Scope: .edouk_modal > .uk-modal-dialog > … .edouk_modal_head
   ========================================================= */

/* Header pleine largeur : on retire le padding du corps de la modale et le
   bouton de fermeture flottant d'UIkit, remplacé par celui du bandeau.

   LA RÈGLE D'ENTRÉE : la modale porte son propre en-tête pleine largeur avec sa
   propre croix — `_head.html.twig` pour presque toutes, `edouk_pay_head` pour le
   renouvellement. Sans ça, masquer la croix d'UIkit laisserait la modale sans
   aucune sortie. Une nouvelle modale à bandeau DOIT être ajoutée aux deux listes,
   sinon elle s'ouvre avec le padding d'UIkit et deux croix superposées. */
#modal-account .uk-modal-body,
#modal-facebook .uk-modal-body,
#modal-formSettings .uk-modal-body,
#modal-generator .uk-modal-body,
#modal-googletag .uk-modal-body,
#modal-lead-action .uk-modal-body,
#modal-lead-delete .uk-modal-body,
#modal-lead-show .uk-modal-body,
#modal-menu .uk-modal-body,
#modal-myaccount .uk-modal-body,
#modal-newUser .uk-modal-body,
#modal-newWebsite .uk-modal-body,
#modal-pay .uk-modal-body,
#modal-telegram .uk-modal-body,
#modal-tiktok .uk-modal-body,
#modal-user-delete .uk-modal-body,
#modal-questions .uk-modal-body,
#modal-websiteDelete .uk-modal-body,
#modal-websiteStats .uk-modal-body,
#modal-whatsapp .uk-modal-body,
#edouk-language-modal .uk-modal-body { padding: 0; }

#modal-account .uk-modal-close-default,
#modal-facebook .uk-modal-close-default,
#modal-formSettings .uk-modal-close-default,
#modal-generator .uk-modal-close-default,
#modal-googletag .uk-modal-close-default,
#modal-lead-action .uk-modal-close-default,
#modal-lead-delete .uk-modal-close-default,
#modal-lead-show .uk-modal-close-default,
#modal-menu .uk-modal-close-default,
#modal-myaccount .uk-modal-close-default,
#modal-newUser .uk-modal-close-default,
#modal-newWebsite .uk-modal-close-default,
#modal-pay .uk-modal-close-default,
#modal-telegram .uk-modal-close-default,
#modal-tiktok .uk-modal-close-default,
#modal-user-delete .uk-modal-close-default,
#modal-questions .uk-modal-close-default,
#modal-websiteDelete .uk-modal-close-default,
#modal-websiteStats .uk-modal-close-default,
#modal-whatsapp .uk-modal-close-default,
#edouk-language-modal .uk-modal-close-default { display: none; }

/* En sombre, le fond est un VOILE de bleu marque posé sur la surface de la modale,
   et c'est le filet du bas qui ferme le bandeau. En clair, l'aplat plein d'avant :
   les deux valeurs vivent dans `--modal-head-bg` et `--modal-head-border`. */
.edouk_modal_head {
    background: var(--modal-head-bg);
    border-bottom: 1px solid var(--modal-head-border);
    border-radius: var(--radius) var(--radius) 0 0;
    padding: 16px 16px 14px;
    display: flex;
    flex-direction: column;
    gap: 10px;
}
/* Variante de couleur optionnelle : le bandeau reprend la couleur de la
   pastille du statut concerné (voir .edouk_table_pill_*).

   Le bleu ne redit rien : c'est déjà la couleur du bandeau par défaut. Il reprend
   donc le même voile que la règle de base — sans ça il réimposait un aplat plein
   par-dessus, et une modale de commande au statut bleu ne ressemblait pas aux
   autres. */
.edouk_modal_head_blue {
    background: var(--modal-head-bg);
}
.edouk_modal_head_green {
    background: var(--success-solid);
}
.edouk_modal_head_red {
    background: var(--error-solid);
}
.edouk_modal_head_purple {
    background: var(--purple-solid);
}
/* LES TROIS VARIANTES SONT DES APLATS, pas le voile du bandeau par défaut. Le
   sous-titre y reprend donc du blanc atténué : `--modal-head-sub` est un bleu pâle
   calibré pour le voile sur fond encre, et sur un aplat de couleur il tombe à 1:1.

   Le token est redéfini pour le sous-arbre, la règle du sous-titre n'a pas à savoir
   dans quelle variante elle se trouve. */
.edouk_modal_head_green,
.edouk_modal_head_red,
.edouk_modal_head_purple {
    --modal-head-sub: rgba(255, 255, 255, 0.78);
}
.edouk_modal_head_top {
    display: flex; align-items: flex-start;
    gap: 12px;
}
.edouk_modal_head_title {
    flex: 1; min-width: 0;
    display: flex; flex-direction: column;
    gap: 3px;
}
.edouk_modal .uk-modal-dialog .edouk_modal_head_title h2 {
    font-family: "Poppins", sans-serif;
    font-weight: 500;
    font-size: calc(var(--font-l) + 1px);
    letter-spacing: -0.1px;
    color: var(--on-accent);
    margin: 0;
    padding: 0;
}
.edouk_modal_head_title p {
    font-size: var(--font-xs);
    color: var(--modal-head-sub);
}
.edouk_modal_head_close {
    width: 30px; height: 30px;
    flex: none;
    display: grid; place-items: center;
    border: 1px solid rgba(255, 255, 255, 0.28);
    border-radius: var(--radius-s);
    background: rgba(255, 255, 255, 0.12);
    cursor: pointer;
    transition: var(--transition-fast);
}
.edouk_modal_head_close:hover { background: rgba(255, 255, 255, 0.22); }
.edouk_modal_head_close i { font-size: 14px; color: var(--on-accent); }

/* Le corps reprend le padding que le dialog vient de perdre. */
.edouk_modal_body {
    padding: 14px 16px 16px;
}

[lang="ar"] .edouk_modal .uk-modal-dialog .edouk_modal_head_title h2 {
    font-family: "Cairo", "Noto Sans Arabic", "Inter", sans-serif;
    font-weight: 600;
}

@media (max-width: 480px) {
    .edouk_modal_head { padding: 14px 14px 12px; }
    .edouk_modal_body { padding: 13px 14px 14px; }
}

/* L'attente d'une turbo-frame : la même dans les modales du compte, la liste des
   commandes, la liste des pages et la retouche. */
.edouk_frame_spinner {
    font-size: 24px;
    color: var(--primary-color);
}

/* =========================================================
   PRIMITIVES UI (ex-UIkit)
   Ce que `uikit.min.css` fournissait et que les règles `uk-*`
   du reste de cette feuille ne posaient pas : la mécanique nue (position,
   affichage, empilement). L'habillage, lui, était déjà ici.
   ========================================================= */

/* Avant que le JS ne pose la classe, la modale est du HTML nu au fil de la
   page : sans ça elle s'afficherait une fraction de seconde au chargement. */
[uk-modal]:not(.uk-modal) { display: none; }

.uk-modal {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    z-index: 1010;
    display: none;
    overflow-y: auto;
}
.uk-modal.uk-open { display: block; }
.uk-modal-dialog {
    position: relative;
    margin: 0 auto;
    box-sizing: border-box;
}
.uk-modal-body { display: flow-root; }
.uk-modal-close-default {
    position: absolute;
    top: 10px;
    right: 10px;
}
.uk-modal-title { font-size: var(--font-l); font-weight: 600; }
.uk-modal-close { cursor: pointer; }
/* La page derrière ne défile plus tant qu'une modale est ouverte. */
body.uk-modal-page { overflow: hidden; }

/* Une transition ne part pas sur un élément qui vient de quitter `display:none` ;
   une animation, si. C'est l'entrée d'UIkit, reproduite sans JS. */
.uk-modal.uk-open .uk-modal-dialog { animation: edk-modal-in 0.3s ease-out; }
@keyframes edk-modal-in {
    from { opacity: 0; transform: translateY(-100px); }
}

ul[uk-accordion] {
    margin: 0;
    padding: 0;
    list-style: none;
}
/* Pas de `display` ici : les trois entêtes d'accordion de l'app posent le leur
   (flex), et cette règle — à une classe, en fin de fichier — le leur volerait
   par simple ordre source. */
.uk-accordion-title {
    text-decoration: none;
    cursor: pointer;
}
/* Le volet replié : `!important` pour ne pas avoir à batailler avec les
   `display: flow-root` / `flex` déjà posés plus haut selon le contexte. */
.uk-accordion-content[hidden] { display: none !important; }
/* Le temps du pli seulement : la boîte est bornée et les marges se replient
   avec la hauteur, sinon le padding laisserait une bande à hauteur nulle. */
.uk-accordion-content.edk-animating {
    overflow: hidden;
    box-sizing: border-box;
    transition:
        height 0.2s ease,
        padding-top 0.2s ease,
        padding-bottom 0.2s ease,
        margin-top 0.2s ease,
        margin-bottom 0.2s ease;
}

.uk-notification {
    position: fixed;
    z-index: 1040;
    box-sizing: border-box;
    width: 350px;
    max-width: calc(100% - 20px);
}
.uk-notification-top-right { top: 10px; right: 10px; }
.uk-notification-top-left { top: 10px; left: 10px; }
.uk-notification-message {
    position: relative;
    padding: 15px;
    margin-bottom: 10px;
    font-size: var(--font-s);
    line-height: 1.4;
    cursor: pointer;
}

/* Utilitaires : les seuls du framework que les templates emploient. */
.uk-text-center { text-align: center; }
.uk-padding { padding: 30px; }
.uk-hidden { display: none !important; }
.uk-flex { display: flex; }
.uk-flex-between { justify-content: space-between; }
.uk-flex-middle { align-items: center; }
.uk-margin-remove { margin: 0 !important; }

