/* Folioz — feuille de style commune aux six pages (chemin de fer, panel, profil, annuaire, connexion, démarrage).
   Plan : un poste de travail de secrétariat de rédaction. Papier gris clair, cartes blanches, encre presque noire ;
   le rouge Folioz pour la marque, le bleu repère pour la sélection, vert / orange / rouge pour les contrôles.
   Type : Oxanium (hébergée, celle du logo) pour les titres, la police du système pour le texte, une chasse fixe pour les folios et les heures.
   Chaque page ajoute sa propre feuille (index.css, admin.css, account.css) ; les composants ci-dessous ne s'y redéfinissent pas. */

@font-face{font-family:"Oxanium";src:url(/brand/Oxanium-VF.woff2) format("woff2");font-weight:200 800;font-display:swap}

:root{
  --bg:#f2f3f5; --panel:#ffffff; --panel-2:#f7f8f9; --hover:#eef0f3; --ink:#12161a; --muted:#5d6670; --line:#e1e4e8; --line-2:#c9ced5; --empty:#e6e9ed;
  --brand:#e8472b; --ok:#13803b; --warn:#b36a00; --err:#c8302a; --info:#2462d0; --accent:#12161a; --on-accent:#ffffff; --pubh:#c4cad1;
  --sel:color-mix(in srgb,var(--info) 11%,transparent); --ring:color-mix(in srgb,var(--info) 40%,transparent);
  --sh-1:0 1px 2px rgba(16,24,40,.06); --sh-2:0 1px 3px rgba(16,24,40,.08),0 1px 2px rgba(16,24,40,.04);
  --sh-3:0 16px 40px -12px rgba(16,24,40,.28),0 4px 10px -4px rgba(16,24,40,.10); --scrim:rgba(14,18,22,.5);
  --f-disp:"Oxanium",system-ui,-apple-system,"Segoe UI",sans-serif;
  --f-body:system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif;
  --f-mono:ui-monospace,"SF Mono",SFMono-Regular,"Cascadia Mono","Roboto Mono",Menlo,Consolas,monospace;
  --h:36px; --hs:28px; --r:8px; --r-lg:12px; --r-sm:6px;
  --fs-xs:12px; --fs-s:13px; --fs-m:14px; --fs-l:16px; --fs-xl:20px; /* échelle unique du texte : légendes et pastilles, secondaire, courant, titre de bloc, titre de page */
  --gl:max(16px,env(safe-area-inset-left,0px)); --gr:max(16px,env(safe-area-inset-right,0px));
  color-scheme:light;
}
/* Sombre : choisi à la main (page profil) ou, sans choix, comme l'appareil. Les deux blocs restent identiques. */
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]){
    --bg:#0e1114; --panel:#161a1f; --panel-2:#1b2026; --hover:#20262d; --ink:#e8ebee; --muted:#98a2ac; --line:#262d34; --line-2:#3a434c; --empty:#1f252b;
    --ok:#4cc27c; --warn:#f0aa3c; --err:#ff6b66; --info:#7ba6ff; --accent:#e8ebee; --on-accent:#12161a; --pubh:#343d45;
    --sh-1:0 1px 2px rgba(0,0,0,.4); --sh-2:0 1px 3px rgba(0,0,0,.45); --sh-3:0 18px 44px -12px rgba(0,0,0,.7),0 4px 10px -4px rgba(0,0,0,.5); --scrim:rgba(0,0,0,.62);
    color-scheme:dark;
  }
}
:root[data-theme="dark"]{
  --bg:#0e1114; --panel:#161a1f; --panel-2:#1b2026; --hover:#20262d; --ink:#e8ebee; --muted:#98a2ac; --line:#262d34; --line-2:#3a434c; --empty:#1f252b;
  --ok:#4cc27c; --warn:#f0aa3c; --err:#ff6b66; --info:#7ba6ff; --accent:#e8ebee; --on-accent:#12161a; --pubh:#343d45;
  --sh-1:0 1px 2px rgba(0,0,0,.4); --sh-2:0 1px 3px rgba(0,0,0,.45); --sh-3:0 18px 44px -12px rgba(0,0,0,.7),0 4px 10px -4px rgba(0,0,0,.5); --scrim:rgba(0,0,0,.62);
  color-scheme:dark;
}

/* ---------- socle ---------- */
*,*::before,*::after{box-sizing:border-box}
[hidden]{display:none!important}
html{-webkit-text-size-adjust:100%;text-size-adjust:100%}
html,body{background:var(--bg);color:var(--ink)}
body{margin:0;font:var(--fs-m)/1.45 var(--f-body);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;padding:0 var(--gr) 40px var(--gl)}
body::before{content:"";position:fixed;inset:0 0 auto;height:env(safe-area-inset-top,0px);z-index:10;background:var(--panel)}
h1,h2,h3,h4{font-family:var(--f-disp);letter-spacing:-.01em;margin:0}
h2{font-size:var(--fs-xl);font-weight:600;line-height:1.2;margin:0 0 10px}
h3{font-size:var(--fs-l);font-weight:600;margin:0 0 6px}
h4,.tbl th,.legal .mentions h3{font:600 var(--fs-xs)/1.3 var(--f-body);text-transform:uppercase;letter-spacing:.06em;color:var(--muted)} /* étiquette de section : un seul niveau partout */
h4{margin:16px 0 6px}
a{color:inherit}
p{margin:6px 0}
code,.mono{font-family:var(--f-mono);font-size:.92em;font-variant-numeric:tabular-nums}
.muted{color:var(--muted)}
.sp{flex:1}
:focus-visible{outline:2px solid var(--info);outline-offset:2px}
dialog:focus-visible{outline:none} /* la fenêtre elle-même prend le focus à l'ouverture : pas de cadre bleu autour, seulement sur ses commandes */
::selection{background:color-mix(in srgb,var(--info) 25%,transparent)}

/* ---------- icônes (jeu /assets/icons.svg) ---------- */
.ic{width:16px;height:16px;flex:none;stroke:currentColor;fill:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;vertical-align:-3px}
.sm .ic{width:14px;height:14px}

/* ---------- commandes : un seul gabarit pour button, a.btn, summary.btn, select, input et textarea (hauteur --h) ----------
   .sm = petit bouton (--hs) ; variantes .primary (encre : l'action principale, une seule par écran ou fenêtre), .danger-t (suppression : texte rouge, à la ligne),
   .danger (rouge plein : seulement le bouton de confirmation d'une fenêtre), .ghost (sans cadre), .icon (carré, icône seule). */
button,a.btn,summary.btn,select,input,textarea{font:inherit;color:var(--ink);background:var(--panel);border:1px solid var(--line-2);border-radius:var(--r);padding:0 12px}
button,a.btn,summary.btn{display:inline-flex;align-items:center;justify-content:center;gap:7px;height:var(--h);cursor:pointer;text-decoration:none;white-space:nowrap;user-select:none;-webkit-user-select:none;font-weight:500;box-shadow:var(--sh-1);transition:background-color .12s,border-color .12s,color .12s,box-shadow .12s,filter .12s}
select,input:not([type=radio]):not([type=checkbox]):not([type=color]):not([type=file]){height:var(--h)}
input,textarea{transition:border-color .12s,box-shadow .12s}
input::placeholder,textarea::placeholder{color:color-mix(in srgb,var(--muted) 75%,transparent)}
textarea{padding:8px 11px;line-height:1.45}
input:focus,textarea:focus{outline:0;border-color:var(--info);box-shadow:0 0 0 3px var(--ring)}
input[type=checkbox],input[type=radio]{accent-color:var(--accent);width:16px;height:16px;margin:0;padding:0;cursor:pointer;box-shadow:none}
button:hover:not(:disabled),a.btn:hover,summary.btn:hover,.menu[open]>summary{background:var(--hover);border-color:var(--line-2)}
button:active:not(:disabled){transform:translateY(.5px)}
button:disabled{opacity:.5;cursor:default;box-shadow:none}
[data-perm][aria-disabled="true"]:not(button){opacity:.5;cursor:default} /* lien ou menu grisés par le rôle, comme un bouton (applyPerms) */
button.sm,a.btn.sm,summary.btn.sm{height:var(--hs);padding:0 10px;font-size:var(--fs-s);gap:5px;border-radius:var(--r-sm)}
button.primary,a.btn.primary{background:var(--accent);color:var(--on-accent);border-color:var(--accent);font-weight:600}
button.danger{background:var(--err);color:#fff;border-color:var(--err);font-weight:600}
button.primary:hover:not(:disabled),a.btn.primary:hover{background:var(--accent);border-color:var(--accent);filter:brightness(1.25)}
:root[data-theme="dark"] button.primary:hover:not(:disabled){filter:brightness(.88)}
@media (prefers-color-scheme: dark){ :root:not([data-theme="light"]) button.primary:hover:not(:disabled){filter:brightness(.88)} }
button.danger:hover:not(:disabled){background:var(--err);border-color:var(--err);filter:brightness(.92)}
button.danger-t{color:var(--err)}
button.danger-t:hover:not(:disabled){background:color-mix(in srgb,var(--err) 8%,transparent);border-color:color-mix(in srgb,var(--err) 40%,var(--line))}
button.ghost,a.btn.ghost{background:transparent;border-color:transparent;box-shadow:none}
button.ghost:hover:not(:disabled),a.btn.ghost:hover{background:var(--hover);border-color:transparent}
button.icon{padding:0;width:var(--h)} button.icon.sm{width:var(--hs)}
button.on:disabled{opacity:1}
.on>.ic{color:var(--warn)}
/* groupe de boutons : toujours un conteneur flex (écart et alignement identiques), jamais des boutons collés par des espaces */
.btns{display:flex;flex-wrap:wrap;gap:6px 8px;align-items:center}
.btns+.btns{margin-top:8px}
/* pied d'une fenêtre ou d'un formulaire : actions à droite */
.row{display:flex;gap:8px;justify-content:flex-end;flex-wrap:wrap;margin-top:18px}
/* case à cocher ou bouton radio suivi de son texte : la seule classe pour cela (label.opt) */
label.opt{display:inline-flex;gap:7px;align-items:center;font-weight:400;cursor:pointer}
/* libellé d'un champ, posé au-dessus : fenêtres, connexion, profil, formulaires du panel. Le panel met --lbl-top à 0
   (sa grille et ses colonnes espacent déjà les champs). Une case (.opt) garde sa propre règle. */
dialog.small label:not(.opt),.login-card label,form.stack label,form.create label,.brandform label:not(.opt),#logoLabel{display:block;font-weight:500;margin:var(--lbl-top,14px) 0 5px}
.offscreen{position:fixed;top:0;left:0;opacity:0} /* copy() d'ui.js : le texte à copier, invisible */

/* ---------- liste déroulante (ui.js) : tout <select> devient une face (bouton) et une liste ---------- */
.cs{position:relative;display:inline-flex;vertical-align:middle;max-width:100%}
.cs select{display:none}
.cs-face{flex:1 1 auto;min-width:0;justify-content:space-between;text-align:left;font-weight:400}
.cs-face::after{content:"";flex:none;width:7px;height:7px;margin:-3px 2px 0 4px;border-right:1.5px solid var(--muted);border-bottom:1.5px solid var(--muted);transform:rotate(45deg)}
.cs-txt{display:grid;flex:1 1 auto;min-width:0;text-align:left}
.cs-txt>span{grid-area:1/1;overflow:hidden;text-overflow:ellipsis}
.cs-txt>.sz{visibility:hidden;height:0}
.dot,.cs-dot{display:inline-block;width:10px;height:10px;border-radius:50%;flex:none;background:var(--c,transparent);box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--ink) 30%,transparent)}
.dot.none,.cs-dot.none{background:transparent;box-shadow:none;border:1.5px dashed var(--muted)}
.pop,.cs-list{background:var(--panel);border:1px solid var(--line);border-radius:var(--r-lg);box-shadow:var(--sh-3);padding:5px}
.cs-list{position:fixed;z-index:60;margin:0;list-style:none;max-height:min(340px,60vh);overflow:auto;animation:popin .12s ease-out}
.cs-list li{display:flex;gap:8px;align-items:center;height:var(--h);padding:0 10px;border-radius:var(--r-sm);cursor:pointer;white-space:nowrap}
.cs-list li:hover,.cs-list li.act{background:var(--hover)}
.cs-list li[aria-selected="true"]{font-weight:600}
.cs-list li[aria-disabled="true"]{opacity:.55;cursor:default;font-size:var(--fs-xs);text-transform:uppercase;letter-spacing:.05em}
@keyframes popin{from{opacity:0;transform:translateY(-3px)}}

/* ---------- menu déroulant (<details class="menu">) ---------- */
.menu{position:relative}
.menu>summary{list-style:none}
.menu>summary::-webkit-details-marker{display:none}
.menu>summary::after{content:"";width:6px;height:6px;margin:-3px 0 0 2px;border-right:1.5px solid var(--muted);border-bottom:1.5px solid var(--muted);transform:rotate(45deg)}
.menu .pop{position:absolute;left:0;top:calc(100% + 6px);z-index:40;min-width:200px;display:flex;flex-direction:column;animation:popin .12s ease-out}
.menu.r .pop{left:auto;right:0}
.pop a.btn,.pop button{border:0;justify-content:flex-start;padding:0 10px;background:none;border-radius:var(--r-sm);box-shadow:none;font-weight:400}
.pop a.btn:hover,.pop button:hover:not(:disabled){background:var(--hover)}
.pop hr{border:0;border-top:1px solid var(--line);margin:4px 2px}

/* ---------- en-tête : collé en haut, titre Folioz + magazine, puis les commandes de la page ---------- */
/* Bandeau de maintenance (marqueur NOTICE posé par le serveur ; paintNotice de ui.js le met à jour en direct).
   Dernier enfant de l'en-tête collant : il prend toute la largeur (flex-wrap) et reste visible en faisant défiler. */
.notice{order:99;flex-basis:calc(100% + var(--gl) + var(--gr));margin:4px calc(-1*var(--gr)) -10px calc(-1*var(--gl));padding:7px var(--gr) 7px var(--gl);background:color-mix(in srgb,var(--warn) 14%,var(--panel));color:var(--ink);border-bottom:1px solid color-mix(in srgb,var(--warn) 45%,transparent);font-weight:600;text-align:center;overflow-wrap:anywhere}
.notice:empty{display:none}
header.top{position:sticky;top:env(safe-area-inset-top,0px);z-index:20;margin:0 calc(-1*var(--gr)) 0 calc(-1*var(--gl));padding:10px var(--gr) 10px var(--gl);display:flex;flex-wrap:wrap;gap:8px 12px;align-items:center;
  background:color-mix(in srgb,var(--panel) 88%,transparent);-webkit-backdrop-filter:saturate(1.6) blur(14px);backdrop-filter:saturate(1.6) blur(14px);border-bottom:1px solid var(--line)}
/* flex-wrap : un logo large et un long nom du magazine passent à la ligne sur un téléphone */
h1.brand{display:flex;flex-wrap:wrap;align-items:center;gap:8px;max-width:100%;min-width:0;font:700 22px/1 var(--f-disp);letter-spacing:-.02em;margin:0 6px 0 0}
h1.brand a{display:contents;color:inherit;text-decoration:none}
.mark{height:22px;width:auto;flex:none;aspect-ratio:56/40}
.mark-sm{height:12px;vertical-align:-1px;margin-right:5px}
h1.brand small{font:500 var(--fs-xs) var(--f-body);color:var(--muted);letter-spacing:0}
.mag-brand{flex:0 1 auto;display:inline-flex;align-items:center;gap:8px;height:24px;min-width:0;font:600 var(--fs-m)/1 var(--f-body);letter-spacing:0;color:var(--ink)}
.mag-sep{flex:none;width:1px;height:18px;background:var(--line-2)}
.mag-logo{flex:none;height:24px;width:auto;max-width:96px;object-fit:contain}
.mag-name{min-width:0;max-width:34vw;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* en-tête chargé (chemin de fer) sur téléphone : tout le bloc du magazine (logo et nom) disparaît, Folioz seul */
@media (max-width:600px){ header.top.compact .mag-brand{display:none} }

/* ---------- cartes, tableaux, badges ---------- */
.card{background:var(--panel);border:1px solid var(--line);border-radius:var(--r-lg);padding:18px 20px;margin-bottom:16px;box-shadow:var(--sh-1)}
.card>h2+p.muted{margin-top:-4px}
.scroll{overflow-x:auto}
table.tbl{border-collapse:collapse;width:100%}
.tbl th,.tbl td{text-align:left;padding:9px 10px;border-bottom:1px solid var(--line);vertical-align:middle}
.tbl th{white-space:nowrap}
.tbl tbody tr:last-child td{border-bottom:0}
.tbl tbody tr:hover{background:var(--panel-2)}
.badge{display:inline-flex;align-items:center;min-width:18px;justify-content:center;border-radius:999px;padding:1px 8px;font:600 var(--fs-xs)/1.5 var(--f-body);color:#fff;background:var(--muted)}
.badge.err{background:var(--err)} .badge.warn{background:var(--warn)} .badge.ok{background:var(--ok)} .badge.info{background:var(--info)}

/* ---------- onglets (ui.js tabs) : une page courte par rubrique, défile sur le côté si l'écran est étroit ---------- */
.tabs{display:flex;gap:2px;overflow-x:auto;scrollbar-width:none;margin-bottom:18px;padding:4px;background:var(--panel);border:1px solid var(--line);border-radius:var(--r-lg);box-shadow:var(--sh-1);width:fit-content;max-width:100%}
.tabs::-webkit-scrollbar{display:none}
button.tab{flex:none;border:0;border-radius:var(--r);background:none;color:var(--muted);font-weight:600;padding:0 14px;box-shadow:none}
button.tab:hover:not(:disabled){background:var(--hover);color:var(--ink)}
button.tab[aria-selected=true]{background:var(--accent);color:var(--on-accent)}
.tab .dot{width:8px;height:8px;background:var(--warn);box-shadow:none} .tab .dot.err{background:var(--err)}

/* ---------- messages : sous un formulaire (.msg), en bas de l'écran (.toast), infobulle ([data-tip]) ---------- */
.msg{min-height:1.4em;margin:10px 0 0;white-space:pre-line;overflow-wrap:anywhere}
.msg.err{color:var(--err)} .msg.ok{color:var(--ok)} .msg.warn{color:var(--warn);font-weight:600}
.toast{position:fixed;left:16px;right:16px;margin-inline:auto;width:fit-content;max-width:min(640px,calc(100vw - 32px));bottom:calc(var(--foot,0px) + 16px);z-index:70;
  background:var(--ink);color:var(--panel);border-radius:var(--r-lg);box-shadow:var(--sh-3);padding:10px 16px;font-weight:500;overflow-wrap:anywhere;animation:toastin .18s ease-out}
@keyframes toastin{from{opacity:0;transform:translateY(8px)}}
#tip{position:fixed;z-index:80;width:max-content;max-width:min(320px,90vw);padding:6px 10px;border-radius:var(--r-sm);background:var(--ink);color:var(--panel);font:500 var(--fs-s)/1.35 var(--f-body);box-shadow:var(--sh-3);pointer-events:none;animation:popin .1s ease-out}
[data-tip]:not(button,a,summary,.btn){cursor:help} /* un bouton à infobulle garde la main : le « ? » laisserait croire à une aide */

/* ---------- fenêtres (<dialog>) : .small pour un formulaire court, .wide plus large ---------- */
dialog{border:1px solid var(--line);border-radius:var(--r-lg);padding:0;background:var(--panel);color:var(--ink);box-shadow:var(--sh-3)}
dialog[open]{animation:dlgin .16s ease-out}
dialog::backdrop{background:var(--scrim);-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}
@keyframes dlgin{from{opacity:0;transform:translateY(6px) scale(.985)}}
dialog.small{width:min(420px,94vw);padding:22px 22px 20px}
dialog.small.wide{width:min(660px,94vw)}
dialog.small h2{margin-bottom:6px}
dialog.small input:not([type=radio]):not([type=checkbox]),dialog.small textarea{width:100%}
dialog.small .cs{display:flex}
dialog.small .why{font-size:var(--fs-s);color:var(--muted);margin:8px 0 0}
dialog.ask .why{font-size:var(--fs-m);color:var(--ink);white-space:pre-line} /* ask() : la question elle-même, sur plusieurs lignes si le serveur en envoie */
fieldset.opts{border:0;padding:0;margin:10px 0 0;display:flex;gap:8px 18px;flex-wrap:wrap}
fieldset.opts legend{font-weight:500;padding:0;margin-bottom:6px}

/* ---------- pied de page : Folioz, version, mentions légales ---------- */
.legal{max-width:1100px;margin:40px auto 0;padding:14px 0 8px;border-top:1px solid var(--line);color:var(--muted);font:var(--fs-xs)/1.5 var(--f-body);text-align:center}
.legal b{font:700 var(--fs-s) var(--f-disp);color:var(--ink);letter-spacing:-.01em}
.legal .ver{font:500 var(--fs-xs) var(--f-mono);cursor:help}
.legal details{display:inline}
.legal summary{display:inline;cursor:pointer;text-decoration:underline;text-underline-offset:2px;list-style:none}
.legal summary::-webkit-details-marker{display:none}
.legal .mentions{display:block;max-width:640px;margin:12px auto 0;padding:14px 18px;background:var(--panel);border:1px solid var(--line);border-radius:var(--r-lg);text-align:left;color:var(--ink)}
.legal .mentions h3{margin:12px 0 2px}
.legal .mentions h3:first-child{margin-top:0}
.legal .mentions p{margin:0}

@media (prefers-reduced-motion: reduce){ *,*::before,*::after{animation:none!important;transition:none!important} }
@media (max-width:600px){ header.top{gap:8px 10px} header.top .lbl{display:none} } /* téléphone : boutons de l'en-tête réduits à leur icône (aria-label) */
