/* ============================================================================
   OKTO UI : feuille de style partagee d'okto-auth
   Systeme de design d'OKTO RMM (jumeau d'OKTO PSA), porte en CSS pur.
   Jetons repris de /srv/okto-rmm/apps/web/src/styles/globals.css (l. 2150-2364).
   Aucun build, aucun import, aucune ressource distante. Poppins auto-hebergee.

   THEME  : sombre par defaut. La classe .dark sur <html> donne le sombre, son
            absence donne le clair. Aucun script ici, un autre agent s'en charge.
   MARQUE : le corail (--primary) sert aux ACTIONS et a l'ETAT ACTIF, jamais a
            un statut. Les statuts prennent success / warning / destructive / info.
   PERF   : transitions de 150 ms sur transform/opacity/color/background-color
            seulement, jamais sur width/height/top/left. Aucune ombre par rangee
            de tableau. Rien ici qui ne serve a une page reelle d'okto-auth.

   CONTRAT DE CLASSES : les pages s'y tiennent, rien d'autre n'est stylise.
   COQUE    okto-shell, okto-sidebar(__brand __toggle __nav __footer __scrim),
            okto-version, okto-brand(__logo __name), okto-main,
            okto-header(__left __right __title __burger), okto-content(__inner)
            etats : .okto-sidebar[data-collapsed="true"] (rail de 64 px) ;
                    .okto-shell[data-menu="ouvert"] (tiroir mobile, sous 900 px)
   MENU     okto-nav-item(__icone __label), okto-count (masquee si vide),
            okto-nav-section(__titre __chevron __contenu)
            etats : .okto-nav-item[aria-current="page"] ou .est-actif ;
                    .okto-nav-section[data-ouvert="true|false"] ;
                    replie : infobulle = attribut title natif, aucune classe.
            C'est okto-nav.js qui ECRIT ces attributs. Il tient aussi a jour le
            <h1 id="okto-titre-section"> de l'en-tete depuis le data-label.
   CARTES   okto-card(--compacte --sans-marge __header __titre __desc __body
            __footer), okto-grid
   TITRES   okto-section-header(__texte __titre __sous-titre __actions),
            okto-separateur
   TABLEAUX okto-table-wrap, okto-table, okto-num, okto-col-actions
   BADGES   okto-badge(--success --warning --destructive --info __point)
   BOUTONS  okto-btn(--primaire --secondaire --discret --destructif
            --destructif-discret --sm --icone --pleine-largeur --repliable
            __label), etat : [data-chargement="true"]
            --repliable + __label : sous 900 px dans .okto-header__right, le
            libelle disparait et le bouton se reduit a son icone de 32 px.
   FORMS    okto-form, okto-field, okto-field-row, okto-label(--requis),
            okto-input, okto-select, okto-select-wrap, okto-textarea,
            okto-checkbox, okto-check-row(__texte), okto-help, okto-erreur
   MODALE   okto-overlay, okto-modal(--sm --lg __header __titre __desc __fermer
            __body __footer), body.okto-scroll-bloque
   AVIS     okto-alerte(--success --warning --destructive --info), okto-vide,
            okto-toasts, okto-toast(--ok --err)
            toast() d'admin.html doit emettre okto-toast okto-toast--ok|--err
   AUTH     okto-auth(__card __logo __titre __sous-titre __foot __pied)
   DIVERS   okto-visually-hidden ; ico-clair / ico-sombre (bascule de theme) ;
            transition partagee var(--okto-tr)
   ========================================================================== */

/* POPPINS AUTO-HEBERGEE : latin + latin-ext, graisses 400/500/600/700, 8 fichiers,
   52 Ko. Le devanagari de Google est ecarte : poids mort en francais. Bijection
   verifiee dans les deux sens avec /fonts/. Jamais le CDN, la CSP le refuse. */
@font-face{font-family:'Poppins';font-style:normal;font-weight:400;font-display:swap;src:url(/fonts/poppins-pxiEyp8kv8JHgFVrJJfecg.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:400;font-display:swap;src:url(/fonts/poppins-pxiEyp8kv8JHgFVrJJnecmNE.woff2) format('woff2');unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,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:'Poppins';font-style:normal;font-weight:500;font-display:swap;src:url(/fonts/poppins-pxiByp8kv8JHgFVrLGT9Z1xlFQ.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-pxiByp8kv8JHgFVrLGT9Z1JlFc-K.woff2) format('woff2');unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,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:'Poppins';font-style:normal;font-weight:600;font-display:swap;src:url(/fonts/poppins-pxiByp8kv8JHgFVrLEj6Z1xlFQ.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-pxiByp8kv8JHgFVrLEj6Z1JlFc-K.woff2) format('woff2');unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,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:'Poppins';font-style:normal;font-weight:700;font-display:swap;src:url(/fonts/poppins-pxiByp8kv8JHgFVrLCz7Z1xlFQ.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-pxiByp8kv8JHgFVrLCz7Z1JlFc-K.woff2) format('woff2');unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}

/* ===== JETONS COMMUNS AUX DEUX THEMES ===== */
:root {
  --font-sans: 'Poppins', system-ui, -apple-system, 'Segoe UI', sans-serif;
  --radius: 0.5rem;                        /* cartes, modales, tableaux */
  --radius-md: calc(var(--radius) - 2px);  /* boutons, champs, nav */
  --radius-sm: calc(var(--radius) - 4px);  /* cases a cocher */
  --radius-full: 9999px;
  --okto-tr: 150ms cubic-bezier(0.4, 0, 0.2, 1);   /* duree + courbe partagees */
  --okto-shadow-xs: 0 1px 2px 0 rgb(0 0 0 / 0.05);
  --okto-shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
  --okto-shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
  --okto-shadow-xl: 0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1);
  --okto-sidebar-w: 208px;                 /* valeur eprouvee, ne pas reduire */
  --okto-sidebar-w-collapsed: 64px;
  --okto-header-h: 64px;
  --okto-content-pad: 24px;
  --okto-content-max: 1600px;
}

/* ===== SOMBRE (defaut) ===== */
.dark {
  color-scheme: dark;
  --background: 225 17% 9%;      --foreground: 225 21% 93%;
  --card: 220 17% 14%;           --card-foreground: 225 21% 93%;
  --popover: 220 17% 14%;        --popover-foreground: 225 21% 93%;
  --primary: 13 83% 63%;         --primary-foreground: 0 0% 100%;   /* corail #ef7350 */
  --secondary: 221 17% 18%;      --secondary-foreground: 225 21% 93%;
  --muted: 221 17% 18%;          --muted-foreground: 219 11% 64%;
  --accent: 221 17% 22%;         --accent-foreground: 225 21% 93%;
  --destructive: 7 79% 68%;      --destructive-foreground: 8 47% 15%;
  --success: 159 50% 53%;        --warning: 37 70% 59%;        --info: 216 100% 72%;
  --border: 221 17% 22%;         --input: 221 17% 22%;         --ring: 13 83% 63%;
  --info-bg: 219 42% 18%;        --warning-bg: 43 55% 13%;     --success-bg: 154 39% 12%;
  --destructive-bg: 8 47% 15%;   --neutral-bg: 221 17% 18%;
}

/* ===== CLAIR ===== */
:root:not(.dark) {
  color-scheme: light;
  --background: 220 23% 97%;     --foreground: 222 22% 15%;
  --card: 0 0% 100%;             --card-foreground: 222 22% 15%;
  --popover: 0 0% 100%;          --popover-foreground: 222 22% 15%;
  --primary: 13 83% 63%;         --primary-foreground: 0 0% 100%;  /* le corail ne derive pas */
  --secondary: 220 21% 95%;      --secondary-foreground: 222 22% 15%;
  --muted: 220 21% 95%;          --muted-foreground: 220 9% 46%;
  --accent: 220 14% 91%;         --accent-foreground: 222 22% 15%;
  --destructive: 6 63% 46%;      --destructive-foreground: 0 0% 100%;
  --success: 160 75% 29%;        --warning: 36 71% 42%;        --info: 220 84% 56%;
  --border: 220 14% 91%;         --input: 220 14% 91%;         --ring: 13 83% 63%;
  --info-bg: 219 91% 96%;        --warning-bg: 38 87% 94%;     --success-bg: 157 37% 93%;
  --destructive-bg: 6 83% 95%;   --neutral-bg: 220 21% 95%;
}

/* ===== BASE ===== */
*, *::before, *::after { box-sizing: border-box; }
* { scrollbar-width: thin; scrollbar-color: hsl(var(--muted-foreground) / 0.4) transparent; }
html { -webkit-text-size-adjust: 100%; }
body { margin: 0; font-family: var(--font-sans); font-size: 0.875rem; line-height: 1.25rem; background-color: hsl(var(--background)); color: hsl(var(--foreground)); -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; }
h1, h2, h3, h4 { margin: 0; font-weight: 600; letter-spacing: -0.01em; }
h1 { font-size: 1.5rem; line-height: 2rem; }
h2 { font-size: 1.25rem; line-height: 1.75rem; }
h3 { font-size: 1.125rem; line-height: 1.75rem; }
h4 { font-size: 1rem; line-height: 1.5rem; }
p { margin: 0; }
img { max-width: 100%; }
a { color: hsl(var(--primary)); text-decoration: none; }
a:hover { text-decoration: underline; }
code { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 0.8125rem; }
::selection { background-color: hsl(var(--primary) / 0.28); }
:focus-visible { outline: 2px solid hsl(var(--ring)); outline-offset: 2px; }
.okto-visually-hidden { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }

/* ===== COQUE : barre 208 px (rail 64 px), en-tete 64 px, contenu defilant.
   La largeur n'est JAMAIS animee : une transition sur width force un recalcul
   de mise en page a chaque image. Le repli est instantane. ===== */
.okto-shell { display: flex; height: 100vh; height: 100dvh; overflow: hidden; }
.okto-sidebar { display: flex; flex-direction: column; flex-shrink: 0; width: var(--okto-sidebar-w); height: 100%; background-color: hsl(var(--card)); border-right: 1px solid hsl(var(--border)); }
.okto-sidebar[data-collapsed="true"] { width: var(--okto-sidebar-w-collapsed); }
/* Meme hauteur que l'en-tete : les deux bords inferieurs s'alignent au pixel. */
.okto-sidebar__brand { display: flex; align-items: center; justify-content: space-between; gap: 4px; height: var(--okto-header-h); padding: 0 12px; border-bottom: 1px solid hsl(var(--border)); }
/* Replie : aucun rembourrage lateral, sinon logo + bouton + 24 px debordent des
   64 px et le logo se fait couper (piege deja paye dans OKTO RMM). */
.okto-sidebar[data-collapsed="true"] .okto-sidebar__brand { justify-content: center; gap: 2px; padding: 0; }
.okto-brand { display: flex; align-items: center; gap: 8px; min-width: 0; flex: 1 1 auto; overflow: hidden; }
.okto-sidebar[data-collapsed="true"] .okto-brand { flex: 0 0 auto; }
.okto-brand__logo { width: 22px; height: 22px; flex-shrink: 0; object-fit: contain; }
.okto-brand__name { font-size: 1.125rem; font-weight: 700; letter-spacing: -0.025em; color: hsl(var(--foreground)); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.okto-sidebar[data-collapsed="true"] .okto-brand__name { display: none; }
.okto-sidebar__toggle { flex-shrink: 0; display: inline-flex; align-items: center; justify-content: center; padding: 6px; border: 0; background: transparent; border-radius: var(--radius-md); color: hsl(var(--muted-foreground)); cursor: pointer; transition: background-color var(--okto-tr), color var(--okto-tr); }
.okto-sidebar__toggle:hover { background-color: hsl(var(--muted)); color: hsl(var(--foreground)); }
.okto-sidebar__toggle svg { width: 16px; height: 16px; display: block; }
.okto-sidebar[data-collapsed="true"] .okto-sidebar__toggle { padding: 4px; }
.okto-sidebar[data-collapsed="true"] .okto-sidebar__toggle svg { transform: rotate(180deg); }
.okto-sidebar__nav { display: flex; flex-direction: column; gap: 4px; flex: 1 1 auto; min-height: 0; overflow-y: auto; padding: 8px; }
/* Pied : le numero de version, comme dans OKTO RMM. Disparait au repli. */
.okto-sidebar__footer { border-top: 1px solid hsl(var(--border)); padding: 8px 16px; }
.okto-version { font-size: 11px; line-height: 14px; color: hsl(var(--muted-foreground) / 0.65); }
.okto-sidebar[data-collapsed="true"] .okto-sidebar__footer { display: none; }
.okto-main { display: flex; flex-direction: column; flex: 1 1 auto; min-width: 0; overflow: hidden; }
.okto-header { display: flex; align-items: center; justify-content: space-between; gap: 8px; flex-shrink: 0; height: var(--okto-header-h); padding: 0 24px; background-color: hsl(var(--card)); border-bottom: 1px solid hsl(var(--border)); }
.okto-header__left, .okto-header__right { display: flex; align-items: center; gap: 12px; min-width: 0; }
.okto-header__left { flex: 1 1 auto; }
.okto-header__right { flex-shrink: 0; }
.okto-header__title { font-size: 0.9375rem; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* .okto-brand pousse en flex:1 dans la barre laterale ; dans l'en-tete elle
   doit rester collee a gauche, sinon le titre part au milieu. */
.okto-header .okto-brand { flex: 0 0 auto; }
.okto-sep { width: 1px; height: 20px; flex: 0 0 auto; background-color: hsl(var(--border)); }
/* Selecteur descendant volontaire : le burger porte aussi .okto-btn, qui est
   declaree plus bas avec display:inline-flex et la meme specificite. Sans le
   .okto-header devant, le bouton reste visible sur grand ecran. */
.okto-header .okto-header__burger { display: none; }
/* Conteneur de defilement de la page : c'est lui qui sert de reference au thead
   collant du tableau. Ne jamais lui remettre overflow visible. */
.okto-content { flex: 1 1 auto; min-width: 0; overflow-x: hidden; overflow-y: auto; padding: var(--okto-content-pad); }
.okto-content__inner { width: 100%; max-width: var(--okto-content-max); margin-inline: auto; }
/* Respiration verticale entre les blocs de premier niveau. Sans elle, le
   panneau actif colle au bas des cartes d'introduction : zero pixel d'ecart,
   mesure a 1440 comme a 390. Une marge, pas un gap : elle se fond avec la
   marge basse du bloc precedent au lieu de s'y ajouter, et un bloc en
   display:none n'ouvre aucun trou. */
.okto-content__inner > * + * { margin-top: 24px; }
.okto-sidebar__scrim { display: none; }

/* ===== MENU : les entrees sont des <button data-tab="...">, il faut donc
   neutraliser le style natif du bouton. ===== */
.okto-nav-item { display: flex; align-items: center; gap: 12px; width: 100%; padding: 8px 12px; border: 0; background: transparent; border-radius: var(--radius-md); font-family: inherit; font-size: 0.875rem; line-height: 1.25rem; font-weight: 500; text-align: left; text-decoration: none; color: hsl(var(--muted-foreground)); cursor: pointer; transition: background-color var(--okto-tr), color var(--okto-tr); }
.okto-nav-item:hover { background-color: hsl(var(--muted)); color: hsl(var(--foreground)); text-decoration: none; }
.okto-nav-item__icone { width: 16px; height: 16px; flex-shrink: 0; }
.okto-nav-item__label { flex: 1 1 auto; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* Actif : corail translucide. C'est un ETAT ACTIF, pas un statut. */
.okto-nav-item[aria-current="page"], .okto-nav-item.est-actif { background-color: hsl(var(--primary) / 0.14); color: hsl(var(--primary)); font-weight: 600; }
.okto-nav-item[aria-current="page"]:hover, .okto-nav-item.est-actif:hover { background-color: hsl(var(--primary) / 0.2); color: hsl(var(--primary)); }
.okto-count { display: inline-flex; align-items: center; justify-content: center; min-width: 20px; height: 18px; padding: 0 6px; border-radius: var(--radius-full); background-color: hsl(var(--muted-foreground) / 0.18); color: hsl(var(--muted-foreground)); font-size: 11px; font-weight: 600; font-variant-numeric: tabular-nums; }
/* Une pastille sans chiffre est une pastille grise vide : on ne l'affiche pas.
   La regle couvre aussi le temps d'attente, avant que le compteur ne reponde. */
.okto-count:empty { display: none; }
.okto-nav-item[aria-current="page"] .okto-count, .okto-nav-item.est-actif .okto-count { background-color: hsl(var(--primary) / 0.18); color: hsl(var(--primary)); }
/* Sections repliables. Le repli est un display:none, pas une animation de
   hauteur : rien a recalculer, rien qui saccade. */
.okto-nav-section { margin-top: 8px; }
.okto-nav-section::before { content: ""; display: block; border-top: 1px solid hsl(var(--border)); margin: 8px 0; }
.okto-nav-section__titre { display: flex; align-items: center; justify-content: space-between; gap: 8px; width: 100%; padding: 6px 8px; border: 0; background: transparent; font-family: inherit; font-size: 11px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.06em; color: hsl(var(--muted-foreground) / 0.75); cursor: pointer; transition: color var(--okto-tr); }
.okto-nav-section__titre:hover { color: hsl(var(--muted-foreground)); }
.okto-nav-section__titre svg { width: 14px; height: 14px; flex-shrink: 0; }
.okto-nav-section__chevron { transition: transform var(--okto-tr); }
.okto-nav-section[data-ouvert="false"] .okto-nav-section__chevron { transform: rotate(-90deg); }
.okto-nav-section__contenu { display: flex; flex-direction: column; gap: 4px; }
.okto-nav-section[data-ouvert="false"] .okto-nav-section__contenu { display: none; }
/* Rail de 64 px : icones seules, infobulle = attribut title natif. Les en-tetes
   de section disparaissent, les items restent TOUS visibles, meme ceux d'une
   section fermee. */
.okto-sidebar[data-collapsed="true"] .okto-nav-item { justify-content: center; gap: 0; padding: 8px; }
.okto-sidebar[data-collapsed="true"] .okto-nav-item__label,
.okto-sidebar[data-collapsed="true"] .okto-count,
.okto-sidebar[data-collapsed="true"] .okto-nav-section__titre { display: none; }
.okto-sidebar[data-collapsed="true"] .okto-nav-section__contenu { display: flex; }

/* ===== TIROIR MOBILE (sous 900 px) ===== */
@media (max-width: 899px) {
  .okto-header { padding: 0 12px; }
  .okto-content { padding: 16px; }
  .okto-header .okto-header__burger { display: inline-flex; }
  .okto-sidebar { position: fixed; inset: 0 auto 0 0; z-index: 50; width: 256px; box-shadow: var(--okto-shadow-lg); transform: translateX(-100%); transition: transform var(--okto-tr); }
  .okto-shell[data-menu="ouvert"] .okto-sidebar { transform: translateX(0); }
  .okto-shell[data-menu="ouvert"] .okto-sidebar__scrim { display: block; position: fixed; inset: 0; z-index: 40; background-color: hsl(var(--background) / 0.8); }
  /* Les actions de l'en-tete se replient sur leur icone. Sans cela elles sont
     incompressibles (370 px a elles seules) et le titre de section est reduit
     a son ellipse des 390 px, puis le dernier bouton sort de l'ecran a 320 px.
     Le nom accessible reste porte par l'aria-label du bouton. */
  .okto-header__right .okto-btn__label { display: none; }
  .okto-header__right .okto-btn--repliable { width: 32px; padding: 0; }
}

/* ===== CARTES ===== */
.okto-card { background-color: hsl(var(--card)); color: hsl(var(--card-foreground)); border: 1px solid hsl(var(--border)); border-radius: var(--radius); padding: 24px; box-shadow: var(--okto-shadow-xs); }
.okto-card--compacte { padding: 16px; }
.okto-card--sans-marge { padding: 0; overflow: hidden; }   /* tableau bord a bord */
.okto-card__header { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; margin-bottom: 16px; }
.okto-card__titre { font-size: 1rem; line-height: 1.5rem; font-weight: 600; color: hsl(var(--card-foreground)); }
.okto-card__desc { margin-top: 4px; font-size: 0.875rem; color: hsl(var(--muted-foreground)); }
.okto-card__body > * + * { margin-top: 16px; }
/* flex-wrap comme sur .okto-modal__footer : le pied du gabarit de courriel
   porte cinq boutons simultanement, soit environ 790 px incompressibles dans
   une colonne de 556 px. Sans le repli, deux d'entre eux sortaient de l'ecran
   et l'overflow-x:hidden de .okto-content les rendait inatteignables. */
.okto-card__footer { display: flex; align-items: center; justify-content: flex-end; gap: 8px; flex-wrap: wrap; margin-top: 24px; padding-top: 16px; border-top: 1px solid hsl(var(--border)); }
.okto-grid { display: grid; gap: 16px; grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }

/* ===== EN-TETE DE SECTION ===== */
.okto-section-header { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; flex-wrap: wrap; margin-bottom: 24px; }
.okto-section-header__texte { min-width: 0; }
.okto-section-header__titre { display: flex; align-items: center; gap: 12px; font-size: 1.5rem; line-height: 2rem; font-weight: 600; letter-spacing: -0.015em; color: hsl(var(--foreground)); }
.okto-section-header__sous-titre { margin-top: 4px; font-size: 0.875rem; color: hsl(var(--muted-foreground)); max-width: 70ch; }
.okto-section-header__actions { display: flex; align-items: center; gap: 8px; flex-shrink: 0; }
.okto-separateur, hr { border: 0; border-top: 1px solid hsl(var(--border)); margin: 24px 0; }

/* ===== TABLEAUX : le tableau defile DANS sa carte.
   Piege : des qu'on met overflow sur l'enveloppe, elle devient le conteneur de
   defilement du thead collant ; sans hauteur maximale elle ne defile jamais et
   l'en-tete ne colle a rien. ===== */
.okto-table-wrap { --okto-table-max-h: calc(100vh - 16rem); max-height: var(--okto-table-max-h); overflow: auto; border: 1px solid hsl(var(--border)); border-radius: var(--radius); background-color: hsl(var(--card)); }
.okto-table { width: 100%; border-collapse: separate; border-spacing: 0; font-size: 0.875rem; color: hsl(var(--card-foreground)); }
/* En-tete collant OPAQUE : un fond translucide laisse passer les rangees sous
   l'en-tete pendant le defilement. Repli opaque juste avant le color-mix. */
.okto-table thead th { position: sticky; top: 0; z-index: 2; background-color: hsl(var(--muted)); background-color: color-mix(in srgb, hsl(var(--muted)) 40%, hsl(var(--card))); box-shadow: inset 0 -1px 0 hsl(var(--border)); padding: 12px 16px; text-align: left; font-size: 0.75rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; color: hsl(var(--muted-foreground)); white-space: nowrap; }
.okto-table tbody td { padding: 12px 16px; border-top: 1px solid hsl(var(--border)); vertical-align: middle; }
.okto-table tbody tr:first-child td { border-top: 0; }
/* Aucune ombre par rangee : repetee sur des centaines de lignes, elle coute une
   passe de peinture a chaque image de defilement. */
.okto-table tbody tr { transition: background-color var(--okto-tr); }
.okto-table tbody tr:hover { background-color: hsl(var(--muted) / 0.5); }
.okto-table .okto-num { text-align: right; font-variant-numeric: tabular-nums; }
.okto-table .okto-col-actions { width: 1%; white-space: nowrap; text-align: right; }
/* La colonne des actions est TOUJOURS la derniere. Le width:1% de l'en-tete ne
   suffit pas : c'est la cellule du corps qui decide de la largeur reelle en
   mise en page automatique. Sans cette regle, la colonne riche (Acces) prenait
   874 px sur 1920 pendant que les quatre boutons s'empilaient un par ligne
   dans 143 px, portant la rangee a 154 px de haut. */
.okto-table tbody td:last-child { width: 1%; }

/* ===== BADGES DE STATUT : aucune variante corail : le corail dit action ou etat
   actif, jamais l'etat d'une chose. Le neutre est la forme de base. ===== */
.okto-badge { display: inline-flex; align-items: center; gap: 6px; padding: 2px 10px; border: 1px solid hsl(var(--border)); border-radius: var(--radius-full); background-color: hsl(var(--neutral-bg)); color: hsl(var(--muted-foreground)); font-size: 0.75rem; line-height: 1rem; font-weight: 500; white-space: nowrap; vertical-align: middle; }
.okto-badge--success { background-color: hsl(var(--success-bg)); color: hsl(var(--success)); border-color: hsl(var(--success) / 0.3); }
.okto-badge--warning { background-color: hsl(var(--warning-bg)); color: hsl(var(--warning)); border-color: hsl(var(--warning) / 0.3); }
.okto-badge--destructive { background-color: hsl(var(--destructive-bg)); color: hsl(var(--destructive)); border-color: hsl(var(--destructive) / 0.3); }
.okto-badge--info { background-color: hsl(var(--info-bg)); color: hsl(var(--info)); border-color: hsl(var(--info) / 0.3); }
/* La couleur seule ne porte jamais l'information : le texte la porte aussi. */
.okto-badge__point { width: 6px; height: 6px; flex-shrink: 0; border-radius: var(--radius-full); background-color: currentColor; }

/* ===== BOUTONS : un seul primaire par zone de decision. ===== */
.okto-btn { display: inline-flex; align-items: center; justify-content: center; gap: 8px; height: 36px; padding: 0 16px; border: 1px solid transparent; border-radius: var(--radius-md); font-family: inherit; font-size: 0.875rem; font-weight: 500; white-space: nowrap; text-decoration: none; cursor: pointer; user-select: none; transition: background-color var(--okto-tr), border-color var(--okto-tr), color var(--okto-tr), opacity var(--okto-tr), transform var(--okto-tr); }
.okto-btn:hover { text-decoration: none; }
.okto-btn:active:not(:disabled) { transform: translateY(1px); }
.okto-btn:disabled, .okto-btn[aria-disabled="true"] { cursor: not-allowed; pointer-events: none; opacity: 0.55; }
.okto-btn svg { width: 16px; height: 16px; flex-shrink: 0; }
.okto-btn--primaire { background-color: hsl(var(--primary)); color: hsl(var(--primary-foreground)); }
.okto-btn--primaire:hover { background-color: hsl(var(--primary) / 0.9); }
.okto-btn--secondaire { background-color: hsl(var(--secondary)); color: hsl(var(--secondary-foreground)); border-color: hsl(var(--border)); }
.okto-btn--secondaire:hover { background-color: hsl(var(--accent)); }
.okto-btn--discret { background-color: transparent; color: hsl(var(--muted-foreground)); }
.okto-btn--discret:hover { background-color: hsl(var(--muted)); color: hsl(var(--foreground)); }
.okto-btn--destructif { background-color: hsl(var(--destructive)); color: hsl(var(--destructive-foreground)); }
.okto-btn--destructif:hover { background-color: hsl(var(--destructive) / 0.9); }
.okto-btn--destructif-discret { background-color: transparent; color: hsl(var(--destructive)); }
.okto-btn--destructif-discret:hover { background-color: hsl(var(--destructive-bg)); }
.okto-btn--sm { height: 32px; padding: 0 12px; font-size: 0.8125rem; }
.okto-btn--sm svg { width: 14px; height: 14px; }
.okto-btn--icone { width: 36px; padding: 0; }
.okto-btn--icone.okto-btn--sm { width: 32px; }
.okto-btn--pleine-largeur { width: 100%; }
.okto-btn[data-chargement="true"] { pointer-events: none; opacity: 0.75; }
.okto-btn[data-chargement="true"]::before { content: ""; width: 14px; height: 14px; border-radius: var(--radius-full); border: 2px solid currentColor; border-right-color: transparent; animation: okto-spin 700ms linear infinite; }
@keyframes okto-spin { to { transform: rotate(360deg); } }

/* ===== FORMULAIRES : les champs prennent --background : sur une carte, ils se
   lisent comme un creux. C'est le rendu d'OKTO RMM. ===== */
.okto-form > * + * { margin-top: 16px; }
.okto-field { display: flex; flex-direction: column; gap: 6px; }
.okto-field-row { display: grid; gap: 16px; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); }
.okto-label { font-size: 0.875rem; font-weight: 500; color: hsl(var(--foreground)); }
.okto-label--requis::after { content: "*"; margin-left: 3px; color: hsl(var(--destructive)); }
.okto-input, .okto-select, .okto-textarea { width: 100%; height: 36px; padding: 0 12px; border: 1px solid hsl(var(--input)); border-radius: var(--radius-md); background-color: hsl(var(--background)); color: hsl(var(--foreground)); font-family: inherit; font-size: 0.875rem; transition: border-color var(--okto-tr), background-color var(--okto-tr); }
.okto-textarea { height: auto; min-height: 88px; padding: 8px 12px; resize: vertical; line-height: 1.4; }
.okto-input::placeholder, .okto-textarea::placeholder { color: hsl(var(--muted-foreground)); }
.okto-input:hover:not(:disabled), .okto-select:hover:not(:disabled), .okto-textarea:hover:not(:disabled) { border-color: hsl(var(--muted-foreground) / 0.5); }
.okto-input:focus-visible, .okto-select:focus-visible, .okto-textarea:focus-visible { outline: none; border-color: hsl(var(--ring)); box-shadow: 0 0 0 3px hsl(var(--ring) / 0.3); }
.okto-input:disabled, .okto-select:disabled, .okto-textarea:disabled { background-color: hsl(var(--muted)); color: hsl(var(--muted-foreground)); cursor: not-allowed; }
.okto-input[readonly] { background-color: hsl(var(--muted) / 0.6); }
/* Le rouge ne suffit jamais : le texte d'erreur l'accompagne toujours. */
.okto-input[aria-invalid="true"], .okto-textarea[aria-invalid="true"] { border-color: hsl(var(--destructive)); }
.okto-input[type="color"] { width: 44px; padding: 3px; cursor: pointer; }
.okto-input[type="file"] { height: auto; padding: 7px 12px; cursor: pointer; }
/* Select : chevron dessine en CSS, donc aucun data: URI et aucun souci de CSP. */
.okto-select-wrap { position: relative; display: block; }
.okto-select { appearance: none; -webkit-appearance: none; padding-right: 32px; cursor: pointer; }
.okto-select-wrap::after { content: ""; position: absolute; right: 13px; top: 50%; width: 7px; height: 7px; margin-top: -6px; border-right: 1.5px solid hsl(var(--muted-foreground)); border-bottom: 1.5px solid hsl(var(--muted-foreground)); transform: rotate(45deg); pointer-events: none; }
.okto-checkbox { appearance: none; -webkit-appearance: none; display: inline-flex; align-items: center; justify-content: center; width: 16px; height: 16px; flex-shrink: 0; margin: 0; border: 1px solid hsl(var(--input)); border-radius: var(--radius-sm); background-color: hsl(var(--background)); cursor: pointer; transition: background-color var(--okto-tr), border-color var(--okto-tr); }
.okto-checkbox:hover:not(:disabled) { border-color: hsl(var(--primary) / 0.6); }
/* Coche : etat actif d'une commande, le corail est a sa place. */
.okto-checkbox:checked { background-color: hsl(var(--primary)); border-color: hsl(var(--primary)); }
.okto-checkbox::after { content: ""; width: 4px; height: 8px; margin-top: -2px; border: solid hsl(var(--primary-foreground)); border-width: 0 2px 2px 0; transform: rotate(45deg) scale(0.6); opacity: 0; transition: opacity var(--okto-tr), transform var(--okto-tr); }
.okto-checkbox:checked::after { opacity: 1; transform: rotate(45deg) scale(1); }
.okto-checkbox:disabled { opacity: 0.5; cursor: not-allowed; }
.okto-check-row { display: flex; align-items: flex-start; gap: 10px; cursor: pointer; }
.okto-check-row .okto-checkbox { margin-top: 2px; }
.okto-check-row__texte { font-size: 0.875rem; line-height: 1.25rem; }
.okto-help { font-size: 0.75rem; line-height: 1rem; color: hsl(var(--muted-foreground)); }
.okto-erreur { display: flex; align-items: flex-start; gap: 5px; font-size: 0.75rem; line-height: 1rem; color: hsl(var(--destructive)); }
.okto-erreur svg { width: 12px; height: 12px; margin-top: 2px; flex-shrink: 0; }

/* ===== MODALE ===== */
.okto-overlay { position: fixed; inset: 0; z-index: 50; display: flex; align-items: center; justify-content: center; padding: 16px; overflow-y: auto; background-color: hsl(var(--background) / 0.8); animation: okto-fade-in var(--okto-tr); }
/* display:flex ecrase [hidden] : il faut le reimposer, sinon la modale reste
   visible en permanence. Piege classique. */
.okto-overlay[hidden] { display: none !important; }
.okto-modal { display: flex; flex-direction: column; width: 100%; max-width: 32rem; max-height: 90vh; overflow: hidden; background-color: hsl(var(--card)); color: hsl(var(--card-foreground)); border: 1px solid hsl(var(--border)); border-radius: var(--radius); box-shadow: var(--okto-shadow-xl); animation: okto-modal-in 200ms cubic-bezier(0.4, 0, 0.2, 1); }
.okto-modal--sm { max-width: 24rem; }   /* confirmation */
.okto-modal--lg { max-width: 48rem; }   /* formulaire long */
.okto-modal__header { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; flex-shrink: 0; padding: 16px 24px; border-bottom: 1px solid hsl(var(--border)); }
.okto-modal__titre { font-size: 1.125rem; line-height: 1.75rem; font-weight: 600; }
.okto-modal__desc { margin-top: 4px; font-size: 0.875rem; color: hsl(var(--muted-foreground)); }
.okto-modal__fermer { flex-shrink: 0; display: inline-flex; align-items: center; justify-content: center; width: 28px; height: 28px; margin: -2px -6px 0 0; border: 0; background: transparent; border-radius: var(--radius-md); color: hsl(var(--muted-foreground)); cursor: pointer; transition: background-color var(--okto-tr), color var(--okto-tr); }
.okto-modal__fermer:hover { background-color: hsl(var(--muted)); color: hsl(var(--foreground)); }
.okto-modal__fermer svg { width: 16px; height: 16px; }
.okto-modal__body { flex: 1 1 auto; min-height: 0; overflow-y: auto; padding: 24px; }
.okto-modal__body > * + * { margin-top: 16px; }
.okto-modal__footer { display: flex; align-items: center; justify-content: flex-end; gap: 8px; flex-shrink: 0; flex-wrap: wrap; padding: 16px 24px; border-top: 1px solid hsl(var(--border)); background-color: hsl(var(--muted) / 0.3); }
body.okto-scroll-bloque { overflow: hidden; }
@keyframes okto-fade-in { from { opacity: 0; } }
@keyframes okto-modal-in { from { opacity: 0; transform: scale(0.96); } }

/* ===== AVIS, ETAT VIDE, TOASTS ===== */
.okto-alerte { display: flex; align-items: flex-start; gap: 10px; padding: 12px 14px; border: 1px solid hsl(var(--border)); border-radius: var(--radius-md); background-color: hsl(var(--neutral-bg)); color: hsl(var(--foreground)); font-size: 0.8125rem; line-height: 1.15rem; }
.okto-alerte svg { width: 16px; height: 16px; flex-shrink: 0; margin-top: 1px; }
.okto-alerte--success { background-color: hsl(var(--success-bg)); border-color: hsl(var(--success) / 0.3); color: hsl(var(--success)); }
.okto-alerte--warning { background-color: hsl(var(--warning-bg)); border-color: hsl(var(--warning) / 0.3); color: hsl(var(--warning)); }
.okto-alerte--destructive { background-color: hsl(var(--destructive-bg)); border-color: hsl(var(--destructive) / 0.3); color: hsl(var(--destructive)); }
.okto-alerte--info { background-color: hsl(var(--info-bg)); border-color: hsl(var(--info) / 0.3); color: hsl(var(--info)); }
.okto-vide { padding: 40px 24px; text-align: center; color: hsl(var(--muted-foreground)); font-size: 0.875rem; }
.okto-vide svg { width: 28px; height: 28px; margin-bottom: 10px; opacity: 0.5; }
.okto-toasts { position: fixed; right: 16px; bottom: 16px; z-index: 60; display: flex; flex-direction: column; gap: 8px; pointer-events: none; }
.okto-toast { max-width: 22rem; padding: 10px 14px; border: 1px solid hsl(var(--border)); border-radius: var(--radius-md); background-color: hsl(var(--card)); color: hsl(var(--card-foreground)); box-shadow: var(--okto-shadow-lg); font-size: 0.8125rem; line-height: 1.15rem; animation: okto-fade-in var(--okto-tr); }
.okto-toast--ok { background-color: hsl(var(--success-bg)); border-color: hsl(var(--success) / 0.4); color: hsl(var(--success)); }
.okto-toast--err { background-color: hsl(var(--destructive-bg)); border-color: hsl(var(--destructive) / 0.4); color: hsl(var(--destructive)); }

/* ===== PAGES D'AUTHENTIFICATION (carte centree) ===== */
.okto-auth { display: flex; align-items: center; justify-content: center; min-height: 100vh; min-height: 100dvh; padding: 24px; }
.okto-auth__card { width: 100%; max-width: 400px; padding: 32px; border: 1px solid hsl(var(--border)); border-radius: var(--radius); background-color: hsl(var(--card)); color: hsl(var(--card-foreground)); box-shadow: var(--okto-shadow-md); }
.okto-auth__logo { display: block; width: 56px; height: 56px; margin: 0 auto 16px; object-fit: contain; }
.okto-auth__titre { font-size: 1.25rem; line-height: 1.75rem; font-weight: 600; text-align: center; }
.okto-auth__sous-titre { margin-top: 6px; text-align: center; font-size: 0.875rem; color: hsl(var(--muted-foreground)); }
.okto-auth__foot { margin-top: 24px; text-align: center; font-size: 0.75rem; color: hsl(var(--muted-foreground)); }
/* Pied de carte : version a gauche, bascule de theme a droite. Les cinq pages
   portent la meme commande au meme endroit ; sans elle, un usager qui arrive
   d'abord sur la connexion subit le theme du systeme sans recours. */
.okto-auth__pied { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-top: 20px; padding-top: 16px; border-top: 1px solid hsl(var(--border)); }

/* ===== BASCULE DE THEME : l'icone annonce ce que le clic va faire, jamais
   l'etat courant : en sombre on montre le soleil, en clair on montre la lune.
   Definie ici une seule fois pour les cinq pages. ===== */
.ico-clair { display: none; }
:root.dark .ico-clair { display: block; }
:root.dark .ico-sombre { display: none; }

/* ===== MOUVEMENT REDUIT ===== */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; }
}
