/* =========================================================
   NEXUS DESIGN SYSTEM — "Liquid Glass" (ex "Mission Control")
   Refonte visuelle uniquement (aucune logique/comportement touche) : dark
   teal + verre sobre + profondeur, en conservant integralement l'API de
   tokens precedente (memes noms --bg/--surface/--border/--success/...) afin
   que tout le CSS/HTML existant (y compris les correctifs des Groupes 1-10)
   continue de fonctionner sans modification. Le glass (translucidite +
   blur) est reserve aux GRANDES SURFACES (topbar, sidebar, cards, dialogs) ;
   tableaux, formulaires et champs de saisie restent des fonds opaques pour
   la lisibilite (cf. regles plus bas). */
:root {
  /* --bg/--surface*/--card-bg et tout le sous-bloc Glass (--glass-*) ont ete
     retires d'ici : redefinis (valeurs differentes) par le bloc "NEXUS —
     LIQUID GLASS / VISUAL POLISH" plus bas dans ce fichier, qui les emporte
     de toute facon en cascade (regle plus tardive). Les garder ici en double
     etait mort et trompeur. --border/--border-strong restent : non
     redefinis plus bas, toujours utilises tels quels dans tout le fichier. */
  --border: #1E4A56;
  --border-strong: #2C6373;

  /* Texte — hierarchie a 4 niveaux */
  --text: #EDF3F5;
  --text-secondary: #A9BAC0;
  --text-tertiary: #7B8F96;
  --text-disabled: #51656C;
  --muted: var(--text-secondary);

  /* Accent NEXUS (bleu) — dominant. Accent secondaire (violet) — rare,
     jamais utilise comme couleur principale d'une page ou d'une action.
     Valeurs inchangees (identite fonctionnelle preservee). */
  --primary: #4C9FFF;
  /* Derive de --primary (meme logique que --danger-solid/--success-solid) :
     l'ancienne valeur fixe (#3E82D1) etait pensee pour du texte blanc et
     cassait le contraste une fois le bouton primaire passe en texte fonce
     (Groupe 11) — 87% garde un ecart visible avec --primary (etat hover)
     tout en restant assez clair pour ce meme texte fonce (mesure : 4.66:1). */
  --primary-dark: color-mix(in srgb, var(--primary) 87%, black);
  --primary-bg: rgba(76, 159, 255, .14);
  /* --primary-bg reste translucide (halos de hover/focus : hub-tile, input,
     recherche...) ou aucun texte critique ne repose dessus. Pour les badges/
     libelles ou du texte var(--primary) est pose SUR ce fond (chip "today",
     badge-commande, lien actif sidebar...), meme probleme que les tokens
     -bg semantiques plus haut : opaque et fige sur --surface a la place,
     donc un contraste stable quel que soit ce sur quoi il est pose.
     Mesure reelle : 4.68:1. */
  --primary-tint: color-mix(in srgb, var(--primary) 6%, var(--surface));
  --accent-2: #7B61FF;
  --accent-2-bg: rgba(123, 97, 255, .14);
  --accent: var(--primary);
  --accent-soft: var(--primary-bg);

  /* Etats semantiques (une fonction chacun, jamais decoratifs) — valeurs
     inchangees : le theme s'adapte a ces couleurs, pas l'inverse. */
  --success: #22C55E;
  /* Etait rgba(couleur, .14) — une teinte VRAIMENT translucide qui reprenait
     la couleur de ce qu'il y a derriere. Sur les surfaces glass (carte, table,
     select...), une fois --glass-bg eclairci, ce fond derriere devient trop
     clair et fait chuter le contraste texte-sur-badge. Ces tokens servent a
     du texte-sur-teinte (badges, voyants, cellules de statut, selects) : ce
     sont des indicateurs de donnee, pas des surfaces decoratives — ils
     restent donc opaques (color-mix fige sur --surface) et gardent un
     contraste stable et connu quel que soit ce sur quoi le badge est pose
     (carte glass, table, sidebar) — mais toujours DEPENDANT de la valeur de
     --surface elle-meme (fige dessus, pas dessus + transparence) : ratio
     revu a la baisse (13%->6%) quand --surface a legerement eclairci (bloc
     "VISUAL POLISH" plus bas), pour garder la meme marge. Mesure reelle
     (navigateur, texte = couleur pleine) : success 5.53:1, warning 5.97:1,
     danger 4.74:1. */
  --success-bg: color-mix(in srgb, var(--success) 6%, var(--surface));
  --success-soft: var(--success-bg);
  /* Meme constat que --danger-solid ci-dessous, cote vert : le blanc sur
     --success plein (barre de progression) ne mesure que 2.28:1 — --success
     reste inchange pour tous les usages texte-sur-teinte (badges, voyants). */
  --success-solid: color-mix(in srgb, var(--success) 65%, black);
  --warning: #F59E0B;
  --warning-bg: color-mix(in srgb, var(--warning) 6%, var(--surface));
  --warning-soft: var(--warning-bg);
  /* --danger volontairement plus clair que le rouge "identite" habituel :
     #EF4444 ne passait qu'a 3.71:1 (texte de badge) — sous le seuil AA 4.5:1.
     #F87171 retablit une marge suffisante. Les fonds pleins + texte blanc
     (bouton, segment de barre) utilisent --danger-solid, plus fonce, car un
     ton clair suffisant pour du texte-sur-teinte est trop clair pour du
     blanc-sur-aplat — meme rouge, deux usages contradictoires. */
  --danger: #F87171;
  --danger-bg: color-mix(in srgb, var(--danger) 6%, var(--surface));
  --danger-soft: var(--danger-bg);
  --danger-solid: color-mix(in srgb, var(--danger) 70%, black);
  --info: #3B82F6;
  --info-bg: color-mix(in srgb, var(--info) 6%, var(--surface));
  --info-soft: var(--info-bg);

  /* Alias retro-compatibles (references existantes dans le CSS/templates) */
  --vert: var(--success); --vert-bg: var(--success-bg);
  --orange: var(--warning); --orange-bg: var(--warning-bg);
  --rouge: var(--danger); --rouge-bg: var(--danger-bg);

  /* -bg ici aussi opaques (color-mix sur --surface, cf. justification au-
     dessus des tokens success/warning/danger/info) : memes badges de donnee
     (categorie produit), meme risque de contraste sous surface glass
     eclaircie, meme dependance a la valeur de --surface elle-meme (ratio
     revu 8%->4% quand --surface a legerement eclairci, bloc "VISUAL POLISH"
     plus bas). cat-eliquide (le plus sombre en luminance) mesurait encore
     trop juste (4.50:1) a 4% une fois --surface reajuste — ratio propre et
     plus bas (1.5%) pour cette seule couleur ; les 7 autres restent a 4%,
     nettement au-dessus. */
  --cat-concentres: #B39CFF; --cat-concentres-bg: color-mix(in srgb, var(--cat-concentres) 4%, var(--surface));
  --cat-cbd: #52C98A; --cat-cbd-bg: color-mix(in srgb, var(--cat-cbd) 4%, var(--surface));
  --cat-eliquide: #E36FA6; --cat-eliquide-bg: color-mix(in srgb, var(--cat-eliquide) 1.5%, var(--surface));
  --cat-materiel: #4FB4DE; --cat-materiel-bg: color-mix(in srgb, var(--cat-materiel) 4%, var(--surface));
  --cat-puff: #D4B94A; --cat-puff-bg: color-mix(in srgb, var(--cat-puff) 4%, var(--surface));
  --cat-fleur: #7BC45C; --cat-fleur-bg: color-mix(in srgb, var(--cat-fleur) 4%, var(--surface));
  --cat-resine: #D2924E; --cat-resine-bg: color-mix(in srgb, var(--cat-resine) 4%, var(--surface));
  --cat-accessoire: #8C9EFF; --cat-accessoire-bg: color-mix(in srgb, var(--cat-accessoire) 4%, var(--surface));

  /* Tableau New : couleurs fixes (identiques quel que soit le theme) — OUI
     cyan, COMMANDE vert pomme, RECU bleu, NON rouge. Retunees pour rester
     lisibles sur fond sombre. */
  --status-voulu: #062329;
  --status-voulu-bg: #17c3d6;
  --status-commande: #0e1a05;
  --status-commande-bg: #6fae3a;
  --status-refuse: #ffffff;
  --status-refuse-bg: #d43a4a;
  --status-recu: #ffffff;
  --status-recu-bg: #3562c9;

  /* Echelle — coins nets et techniques, jamais "bubble". --radius-lg
     (dialogs, dropdowns) reste distinct de --radius-sm (boutons/inputs/
     badges). --radius-md a existe ici pour .card mais son unique
     consommateur (border-radius de .card) est desormais fixe en dur par le
     bloc "VISUAL POLISH" plus bas (16px) — token retire, plus aucun usage. */
  --radius-sm: 7px;
  --radius-lg: 16px;
  --shadow-sm: 0 1px 3px rgba(0, 0, 0, .24);
  --shadow-md: 0 8px 24px rgba(0, 0, 0, .32);
  --font: "Inter", -apple-system, "Segoe UI", ui-sans-serif, system-ui, Arial, sans-serif;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  font-family: var(--font);
  /* Le fond (couleur/image/halos) est defini plus bas par le bloc "NEXUS —
     LIQUID GLASS / VISUAL POLISH" (regle body{} plus tardive = qui gagne) :
     ancien jeu de halos radiaux retire d'ici, il ne s'affichait plus. */
  color: var(--text);
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3 { letter-spacing: -0.01em; }

.topbar {
  display: flex;
  align-items: center;
  gap: 20px;
  height: 58px;
  padding: 0 20px;
  /* background/backdrop-filter/box-shadow redefinis (valeurs differentes)
     par le bloc "VISUAL POLISH" plus bas, qui les emporte — retires d'ici.
     border-bottom garde son epaisseur/style ici (la regle plus bas ne fixe
     que border-bottom-color). */
  border-bottom: 1px solid var(--glass-border-top);
  position: sticky;
  top: 0;
  z-index: 100;
}
.topbar .brand { display: flex; align-items: center; text-decoration: none; flex: none; }
/* Bouton hamburger : n'existe que sous 720px (cf. media query plus bas),
   masque en desktop/tablette ou le comportement actuel de la sidebar est
   conserve tel quel. */
.sidebar-toggle {
  display: none; flex: none; width: 34px; height: 34px; margin-right: 2px;
  align-items: center; justify-content: center; border: 1px solid var(--border);
  border-radius: var(--radius-sm); background: var(--surface); color: var(--text); cursor: pointer;
}
.sidebar-toggle:hover { border-color: var(--border-strong); }
.sidebar-toggle svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; }
.sidebar-backdrop { display: none; }
.brand-logo { height: 30px; width: auto; display: block; }
.topbar .user-info a { color: var(--muted); text-decoration: none; padding-left: 12px; margin-left: 2px; border-left: 1px solid var(--border); }
.topbar .user-info a:hover { color: var(--primary); }
.user-info { display: flex; gap: 10px; align-items: center; color: var(--muted); font-size: 0.85em; }
.topbar-spacer { flex: 1; }
.topbar-actions { display: flex; align-items: center; }

.topbar-search { position: relative; flex: 1; max-width: 420px; margin-left: 12px; }
.topbar-search-icon { position: absolute; left: 10px; top: 50%; transform: translateY(-50%); width: 15px; height: 15px; fill: none; stroke: var(--muted); stroke-width: 2; pointer-events: none; }
.topbar-search input {
  /* Composant interne (capsule de recherche) : fond opaque, pas de glass —
     priorite a la lisibilite du texte tape par-dessus la topbar translucide. */
  width: 100%; padding: 7px 12px 7px 32px; border-radius: var(--radius-sm);
  background: var(--surface); border: 1px solid var(--border); color: var(--text); font-size: 0.87em;
  transition: border-color .12s, box-shadow .12s;
}
.topbar-search input:focus { outline: none; border-color: var(--primary); box-shadow: 0 0 0 3px var(--primary-bg); }
.topbar-search input::placeholder { color: var(--muted); }
.topbar-search-results {
  position: absolute; top: calc(100% + 6px); left: 0; right: 0; z-index: 200;
  background: var(--glass-sheen), var(--glass-bg-elevated);
  backdrop-filter: var(--glass-blur);
  -webkit-backdrop-filter: var(--glass-blur);
  border: 1px solid var(--glass-border-strong); border-top-color: var(--glass-border-top); border-radius: var(--radius-lg);
  box-shadow: var(--glass-shadow), var(--glass-highlight); overflow: hidden; padding: 4px;
}
.topbar-search-result { display: block; padding: 7px 10px; border-radius: var(--radius-sm); color: var(--text); text-decoration: none; font-size: 0.87em; }
.topbar-search-result:hover, .topbar-search-result.is-active { background: var(--primary-tint); color: var(--primary); }

.user-avatar {
  width: 30px; height: 30px; border-radius: var(--radius-sm); background: var(--surface-2);
  border: 1px solid var(--border); color: var(--text); display: flex; align-items: center;
  justify-content: center; font-weight: 700; font-size: 0.8em; flex: none;
}
.user-avatar.mini { width: 28px; height: 28px; }
.user-copy { display: flex; flex-direction: column; line-height: 1.2; min-width: 100px; }
.user-copy strong { font-size: 0.85em; }
.user-copy span { font-size: 0.72em; color: var(--muted); margin-top: 1px; }

.app-shell { display: flex; align-items: stretch; min-height: calc(100vh - 58px); }

.sidebar {
  flex: none;
  width: 232px;
  display: flex;
  flex-direction: column;
  gap: 1px;
  padding: 12px 8px;
  /* background/backdrop-filter/box-shadow redefinis par le bloc "VISUAL
     POLISH" plus bas — retires d'ici. border-right garde son epaisseur/
     style ici (la regle plus bas ne fixe que border-right-color). */
  border-right: 1px solid var(--glass-border-top);
  position: sticky;
  top: 58px;
  height: calc(100vh - 58px);
  max-height: calc(100vh - 58px);
  overflow-y: auto;
  scrollbar-width: thin;
}
.sidebar-caption {
  font-size: 0.66em; font-weight: 700; letter-spacing: 0.09em; color: var(--muted);
  padding: 16px 12px 6px; text-transform: uppercase;
}
.sidebar-caption:first-child { padding-top: 6px; }
.sidebar-link {
  min-height: 36px; padding: 7px 10px; color: var(--text); text-decoration: none;
  font-size: 0.85em; font-weight: 500; border: 0; border-left: 2px solid transparent;
  border-radius: var(--radius-sm); display: flex; align-items: center; gap: 10px;
  transition: background .12s, color .12s, border-color .12s;
}
.sidebar-link:hover { background: var(--surface-hover); color: var(--text); }
/* background/border-left-color/box-shadow redefinis (valeurs differentes)
   par le bloc "VISUAL POLISH" plus bas — retires d'ici. */
.sidebar-link.active {
  color: var(--primary);
  font-weight: 600;
}
.sidebar-link.active .nav-icon { color: var(--primary); }
.sidebar-home { margin-bottom: 4px; }
.sidebar-link-disabled { color: var(--muted); cursor: not-allowed; }
.sidebar-link-disabled:hover { background: transparent; color: var(--muted); }

.sidebar-group summary.sidebar-link { cursor: pointer; list-style: none; }
.sidebar-group summary.sidebar-link::-webkit-details-marker { display: none; }
.sidebar-label { flex: 1; line-height: 1.2; }
.sidebar-chevron { color: var(--muted); font-size: 1.1em; line-height: 1; margin-left: auto; transition: transform .15s; }
.sidebar-group[open] .sidebar-chevron { transform: rotate(90deg); }
.sidebar-subnav { display: flex; flex-direction: column; gap: 1px; padding: 2px 0 4px 34px; }
.sidebar-sublink { min-height: 30px; padding: 6px 10px; font-size: 0.82em; color: var(--muted); }
.sidebar-sublink:hover { color: var(--text); }
.sidebar-sublink.active { color: var(--primary); background: var(--primary-tint); }

.nav-icon {
  width: 26px; height: 26px; border-radius: var(--radius-sm); display: inline-flex;
  align-items: center; justify-content: center; flex: none; color: var(--muted);
}
.nav-icon svg { width: 17px; height: 17px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }

.sidebar-bottom { margin-top: auto; padding: 10px 4px 0; border-top: 1px solid var(--border); }
.sidebar-user-mini { display: flex; align-items: center; gap: 9px; padding: 8px; border-radius: var(--radius-sm); }
.sidebar-user-mini > div:last-child { display: flex; flex-direction: column; min-width: 0; }
.sidebar-user-mini strong { font-size: 0.78em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.sidebar-user-mini span { font-size: 0.68em; color: var(--muted); margin-top: 1px; }

.container { flex: 1; min-width: 0; max-width: none; margin: 0; padding: 28px 32px; }

@media (max-width: 900px) {
  .container { padding: 20px; }
  .sidebar { width: 200px; }
  .topbar-search { max-width: 220px; }
}
/* Palier propre a la recherche rapide (721-900px, la sidebar/hamburger du
   Groupe 3 ne commence qu'a 720px — ne pas chevaucher cette plage) : mesure
   reelle a 768px, la recherche ne mesurait que 94px (illisible) car
   .topbar-spacer (flex:1, purement decoratif) se partageait a egalite le peu
   d'espace restant avec elle. Le nom/role (.user-copy, texte informatif, pas
   un controle) est masque pour liberer de la place ; "Mon profil"/
   "Déconnexion" restent des liens texte cliquables, contrairement au palier
   <=720px qui les masque totalement (la sidebar mobile n'offre pas
   d'equivalent). Resultat mesure : recherche remonte a 220px (son plafond). */
@media (min-width: 721px) and (max-width: 900px) {
  .user-copy { display: none; }
  .topbar-spacer { flex-grow: 0; }
}
@media (max-width: 720px) {
  .topbar { height: 52px; padding: 0 12px; gap: 10px; }
  .brand-logo { height: 24px; }
  .topbar-search { display: none; }
  .user-copy, .topbar .user-info > a { display: none; }
  .sidebar-toggle { display: inline-flex; }

  /* Repliee par defaut : la sidebar ne reserve plus aucun espace, le
     contenu principal commence immediatement sous le bandeau. Ouverte via
     le bouton hamburger (sidebar_toggle.js), elle redevient un panneau
     deroulant qui reutilise tel quel le style vertical de la sidebar
     desktop (categories, sous-groupes, mini-profil, scroll interne) au
     lieu de l'ancienne bande horizontale repliee au-dessus du contenu. */
  .sidebar {
    display: none;
    position: fixed; top: 52px; left: 0; right: 0; z-index: 200;
    width: auto; max-height: calc(100vh - 52px);
    border-right: 0; border-bottom: 1px solid var(--border);
    box-shadow: var(--shadow-md);
  }
  body.sidebar-open .sidebar { display: flex; }
  body.sidebar-open .sidebar-backdrop {
    display: block; position: fixed; inset: 52px 0 0 0; z-index: 150;
    background: rgba(0, 0, 0, .45);
  }
  .container { padding: 16px; }
}

.card {
  /* background/backdrop-filter/border-top-color/border-radius/box-shadow
     redefinis (valeurs differentes, ex. border-radius 16px) par le bloc
     "VISUAL POLISH" plus bas — retires d'ici. border reste ici pour son
     epaisseur/style (la regle plus bas ne fixe que border-color). */
  border: 1px solid var(--glass-border);
  padding: 18px 20px;
  margin-bottom: 20px;
}
.card h2 { margin-top: 0; font-size: 1.05em; font-weight: 600; }

.pc-collapsible { margin-bottom: 14px; }
.pc-collapsible summary {
  cursor: pointer;
  font-weight: 600;
  padding: 8px 10px;
  border-radius: 8px;
  background: var(--bg);
  list-style: none;
  user-select: none;
}
.pc-collapsible summary::-webkit-details-marker { display: none; }
.pc-collapsible summary::before {
  content: "▶";
  display: inline-block;
  margin-right: 8px;
  font-size: 0.8em;
  transition: transform 0.15s;
}
.pc-collapsible[open] summary::before { transform: rotate(90deg); }
.pc-collapsible summary:hover { background: var(--border); }
.pc-collapsible table { margin-top: 10px; }

.hub-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 18px;
  margin-top: 20px;
}
.hub-tile {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 6px;
  aspect-ratio: 4 / 3;
  /* border-radius/background/backdrop-filter/border-top-color/box-shadow
     redefinis par le bloc "VISUAL POLISH" plus bas — retires d'ici. border
     reste ici pour son epaisseur/style (la regle plus bas ne fixe que
     border-color). */
  border: 1px solid var(--glass-border);
  color: var(--text);
  text-decoration: none;
  text-align: center;
  padding: 20px;
  font-weight: 700;
  letter-spacing: 0.02em;
  transition: border-color 0.15s, transform 0.1s, background 0.15s;
}
.hub-tile:hover { border-color: var(--primary); transform: translateY(-2px); background: var(--primary-bg); }
.hub-tile-label { font-size: 1.05em; }
.hub-tile-disabled {
  cursor: not-allowed;
  color: var(--muted);
  background: transparent;
  border-style: dashed;
}
.hub-tile-disabled:hover { border-color: var(--border); transform: none; background: transparent; }
.hub-tile-soon { font-size: 0.7em; font-weight: 500; color: var(--muted); text-transform: uppercase; letter-spacing: 0.05em; }
.hub-tile-count {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 26px; height: 26px; padding: 0 8px; border-radius: 999px;
  background: var(--primary-tint); color: var(--primary); font-size: 0.85em; font-weight: 700;
}

.admin-columns { display: flex; gap: 16px; flex-wrap: wrap; align-items: flex-start; margin-top: 14px; }
.admin-column { flex: 1 1 240px; min-width: 220px; }
.admin-column h3 { margin: 0 0 8px; font-size: 0.95em; }
.admin-inline-input {
  width: 100%; border: 1px solid transparent; background: transparent;
  padding: 3px 4px; font-size: 0.95em; color: var(--text); font-family: inherit;
}
.admin-inline-input:hover, .admin-inline-input:focus { border-color: var(--border); background: var(--bg); }
.admin-inline-select { border: 1px solid var(--border); background: var(--bg); color: var(--text); font-size: 0.85em; padding: 3px 4px; }

.page-head {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  margin-bottom: 16px;
  gap: 16px;
}
/* Breakpoint propre a ce composant (6 pages : incident_detail, cycle_detail,
   section_grid, cycle_indispo, passage_commande_bucket/session) — mesure
   reelle : a 720px/768px les deux blocs tiennent encore cote a cote sans
   degradation visible, mais des 500px le titre passe a 3 lignes et le bouton
   d'action se met lui-meme sur 2 lignes (compression que 600px evite encore). */
@media (max-width: 600px) {
  .page-head { flex-direction: column; align-items: stretch; }
}

.hint { color: var(--muted); font-size: 0.9em; }
.locked-notice { padding: 10px 14px; background: var(--card-bg); border: 1px dashed var(--border); border-radius: 8px; }
.breadcrumb { margin-bottom: 4px; }
.breadcrumb a { color: var(--muted); text-decoration: none; }

.section-nav { display: flex; gap: 8px; flex-wrap: wrap; }
.section-nav-btn {
  display: inline-block; padding: 6px 12px; border-radius: 6px; border: 1px solid var(--border);
  background: var(--surface-2);
  color: var(--text); text-decoration: none; font-size: 0.88em; white-space: nowrap;
}
.section-nav-btn:hover { background: var(--surface-hover); border-color: var(--primary); color: var(--primary); }

.inline-form { display: flex; gap: 14px; flex-wrap: wrap; align-items: flex-end; }
.inline-form label { display: flex; flex-direction: column; gap: 4px; font-size: 0.85em; color: var(--muted); }

.dropzones { display: flex; gap: 16px; margin: 12px 0 16px; flex-wrap: wrap; }
.dropzone {
  flex: 1 1 260px;
  border: 2px dashed var(--border);
  border-radius: 10px;
  padding: 20px;
  text-align: center;
  cursor: pointer;
  transition: border-color 0.15s, background 0.15s;
}
.dropzone:hover { border-color: var(--primary); }
.dropzone.dropzone-active { border-color: var(--primary); background: var(--vert-bg); }
.dropzone-label { font-weight: 600; margin: 0 0 6px; }
.dropzone-filename { color: var(--muted); font-size: 0.85em; margin: 0; word-break: break-all; }

/* Composants internes (niveau 3) : fond opaque plein, jamais de glass —
   la lisibilite des formulaires prime sur l'effet visuel (ajustement
   explicite de la DA validee). Seul le focus gagne un halo discret. */
input[type=text], input[type=password], input[type=number], input[type=date], select, textarea {
  font-family: inherit;
  font-size: 0.9em;
  padding: 7px 10px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface-2);
  color: var(--text);
  transition: border-color .12s, box-shadow .12s;
}
/* border-color/box-shadow ici redefinis par le bloc "VISUAL POLISH" plus
   bas (memes selecteurs, meme specificite, regle plus tardive) — retires. */
input:focus, select:focus, textarea:focus { outline: none; }
textarea { width: 100%; font-family: ui-monospace, monospace; }

/* Groupe 11 : #fff sur --primary ne mesurait que 2.72:1 (sous l'AA). --primary
   reste la couleur d'identite bleue de NEXUS (inchangee) ; c'est le TEXTE qui
   passe en fonce (#1c1f26, deja la convention NEXUS pour texte-sur-fond-vif
   ailleurs dans ce fichier — categories, statuts peints...), mesure a 6.05:1
   sur --primary et 4.66:1 sur --primary-dark (etat hover, cf. token ci-dessus). */
button, .button {
  font-family: inherit;
  font-size: 0.86em;
  font-weight: 600;
  padding: 7px 14px;
  border-radius: var(--radius-sm);
  border: 1px solid transparent;
  background: var(--primary);
  color: #1c1f26;
  cursor: pointer;
  transition: background .15s, border-color .15s, color .15s, box-shadow .15s, transform .15s;
}
button:hover, .button:hover { background: var(--primary-dark); color: #1c1f26; box-shadow: 0 4px 14px -4px var(--primary-bg); transform: translateY(-1px); }
button:active, .button:active { transform: translateY(0); }
button.secondary, .button.secondary { background: var(--surface-2); border-color: var(--border); color: var(--text); }
button.secondary:hover, .button.secondary:hover { border-color: var(--border-strong); color: var(--text); box-shadow: none; }
button.ghost, .button.ghost { background: transparent; border-color: transparent; color: var(--muted); }
button.ghost:hover, .button.ghost:hover { background: var(--surface-hover); color: var(--text); box-shadow: none; transform: none; }
button.danger, .button.danger { background: var(--danger-solid); color: #fff; }
button.danger:hover, .button.danger:hover { background: #c94449; }
/* a.link-btn ajoute : le selecteur ne visait que <button class="link-btn">,
   or de nombreux templates posent aussi cette classe sur des <a> (aucune
   regle "a {}" generique dans ce fichier) — ces liens tombaient donc sur la
   couleur de lien par defaut du navigateur (bleu/violet visite), quasi
   invisible sur le nouveau fond sombre. */
button.link-btn, a.link-btn { background: none; border: none; color: var(--primary); padding: 2px 6px; font-size: 0.85em; font-weight: 500; text-decoration: none; }
/* color explicite necessaire : .link-btn n'a pas de fond (texte seul) — sans
   ce rappel, l'etat hover heriterait du color:#1c1f26 de la regle generique
   button:hover ci-dessus (Groupe 11), quasi invisible sur un fond sombre. */
button.link-btn:hover, a.link-btn:hover { text-decoration: underline; background: none; box-shadow: none; transform: none; color: var(--primary); }

/* Lien <a> stylise comme un vrai bouton (memes regles que button ci-dessus) —
   pour une navigation cliquable clairement visible, pas un simple lien texte. */
.button { display: inline-flex; align-items: center; gap: 6px; text-decoration: none; }

/* Tableaux (niveau 3) : fond opaque, jamais de glass — priorite absolue a la
   lisibilite des donnees. Header legerement plus lumineux que le corps pour
   marquer une separation claire (cf. section 9 de la DA), lignes toujours
   transparentes par defaut (le fond de card/dialogue transparait), hover
   discret. Les surcharges de statut (Groupes 4/5/7) restent plus specifiques
   et l'emportent normalement. */
.data-table { width: 100%; border-collapse: collapse; font-size: 0.88em; }
.data-table th, .data-table td { padding: 9px 12px; border-bottom: 1px solid var(--border); text-align: left; }
/* .data-table th: background redefini par le bloc "VISUAL POLISH" plus bas
   — retire d'ici. .data-table tbody tr:hover: entierement redefini plus bas
   (meme selecteur, meme specificite) — supprime, la regle Groupes 4/5/7
   plus specifique continue de l'emporter normalement dans les deux cas. */
.data-table th { color: var(--text-secondary); font-weight: 600; font-size: 0.78em; text-transform: uppercase; letter-spacing: 0.04em; }

/* table-layout:fixed + colonnes en % + aucune largeur minimale = sur petit
   ecran le tableau se contracte a 100% du conteneur au lieu de deborder,
   et chaque colonne (Reference, Designation...) devient illisible. Le
   min-width force le tableau a garder sa largeur naturelle ; c'est le
   wrapper .table-scroll (deja en place autour) qui absorbe le depassement
   en scroll horizontal plutot que le reste de la page. */
.grid-table { table-layout: fixed; min-width: 900px; }
.grid-table input { width: 100%; min-width: 0; box-sizing: border-box; }
.grid-table input:disabled { background: transparent; border-color: transparent; color: var(--text); opacity: 0.85; }
.grid-table td { vertical-align: middle; overflow: hidden; }
.grid-table th { vertical-align: middle; white-space: normal; line-height: 1.25; }
.grid-table td:nth-child(1) input, .grid-table td:nth-child(2) input { font-size: 0.95em; }

/* Pas de fleches +/- sur les champs numeriques saisis manuellement */
.grid-table input::-webkit-outer-spin-button,
.grid-table input::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}
.grid-table input[type=number] { -moz-appearance: textfield; }
.qte-finale { font-weight: 700; }
.row-actions { white-space: nowrap; }

/* Colonnes Qte/Modif/Motif colorees pour reperage visuel rapide dans la
   grille de proposition de commande — entete + champ de saisie, y compris
   desactive (identite de colonne, pas juste affordance d'edition). */
/* !important necessaire : la feuille V2 impose `th { background:...!important; }`
   plus bas dans ce fichier (cf. commentaire pres de .tableau-new-matrix). */
.grid-table th.col-qte { background: #C8E6C9 !important; color: #1c1f26; }
.grid-table th.col-modif { background: #BBDEFB !important; color: #1c1f26; }
.grid-table th.col-motif { background: #FFF59D !important; color: #1c1f26; }
.grid-table input[data-field="qte"] { background: #E8F5E9; color: #1c1f26; }
.grid-table input[data-field="modif"] { background: #E3F2FD; color: #1c1f26; }
.grid-table input[data-field="motif"] { background: #FFFDE7; color: #1c1f26; }

.add-line-preview { display: inline-block; min-width: 3em; font-weight: 600; }

/* Retour visuel bref quand une Qte/Modif est auto-arrondie au colisage (COEF COM) */
.qty-rounded-flash { animation: qtyRoundedFlash 0.9s ease-out; }
@keyframes qtyRoundedFlash {
  0% { background-color: #FFF176; }
  100% { background-color: transparent; }
}

/* Bordure fine et discrete commune a tous les badges, via currentColor : le
   `color` de chaque .badge-* etant deja la teinte semantique, une seule
   ligne suffit a border tous les badges existants sans toucher chacun
   individuellement (aucune classe .badge-* modifiee ci-dessous). */
.badge {
  display: inline-block;
  padding: 2px 9px;
  border-radius: 999px;
  font-size: 0.8em;
  font-weight: 600;
  border: 1px solid color-mix(in srgb, currentColor 35%, transparent);
}
.badge-draft { background: var(--orange-bg); color: var(--orange); }
.badge-sent { background: var(--vert-bg); color: var(--vert); }
.badge-ready { background: var(--accent-2-bg); color: var(--accent-2); }
.badge-commande { background: var(--primary-tint); color: var(--primary); }
.badge-closed { background: var(--border); color: var(--muted); }
.badge-pending { background: var(--rouge-bg); color: var(--rouge); }
.badge-franco-ok { background: var(--vert-bg); color: var(--vert); }
.badge-franco-ko { background: var(--rouge-bg); color: var(--rouge); }
.badge-non-traitee { background: var(--rouge-bg); color: var(--rouge); }
.badge-frs-contact { background: var(--orange-bg); color: var(--orange); }
.badge-traitee { background: var(--vert-bg); color: var(--vert); }
.badge-dem { background: var(--orange-bg); color: var(--orange); }
.badge-recu { background: var(--vert-bg); color: var(--vert); }

/* Reclamation (role bureau) : le select de statut reprend les memes tokens que
   le badge qu'il remplace en mode edition, pour ne pas perdre le repere couleur. */
.recla-statut-select.status-non-traitee { background: var(--rouge-bg); color: var(--rouge); border-color: var(--rouge); }
.recla-statut-select.status-frs-contact { background: var(--orange-bg); color: var(--orange); border-color: var(--orange); }
.recla-statut-select.status-traitee { background: var(--vert-bg); color: var(--vert); border-color: var(--vert); }
/* Le focus global (select:focus { border-color: var(--primary) }) perd face a
   la specificite de la regle de couleur ci-dessus : sans cette regle, le focus
   resterait visuellement identique a l'etat repos. */
.recla-statut-select.status-non-traitee:focus,
.recla-statut-select.status-frs-contact:focus,
.recla-statut-select.status-traitee:focus {
  outline: none; box-shadow: inset 0 0 0 1px currentColor;
}

.absence-cell-wrap {
  display: flex; flex-direction: column; gap: 3px; min-width: 132px; padding: 2px;
}
.absence-cell-wrap.absence-cell-repos { background: var(--orange-bg); border-radius: 4px; }
.absence-mini-toggle {
  display: flex; align-items: center; gap: 4px; font-size: 0.75em; color: var(--muted);
  white-space: nowrap; cursor: pointer;
}
.absence-cell-wrap.absence-cell-repos .absence-mini-toggle { color: var(--orange); font-weight: 600; }
.absence-mini-toggle input[type="checkbox"] { margin: 0; }
.absence-time-block { display: flex; flex-direction: column; gap: 3px; }
.absence-shift { display: flex; gap: 3px; }
.absence-time-input {
  width: 100%; min-width: 0; border: 1px solid var(--border); background: var(--bg);
  color: var(--text); font-size: 0.8em; padding: 2px; font-family: inherit;
}
.absence-cell-comment { font-size: 0.7em; word-break: break-word; }

.rh-coverage-alert { border-radius: 4px; padding: 8px 10px; font-size: 0.9em; display: flex; flex-wrap: wrap; gap: 4px 6px; align-items: center; }
.rh-coverage-alert-trou { background: var(--rouge-bg); color: var(--rouge); }
.rh-coverage-alert-ok { background: var(--vert-bg); color: var(--vert); }
.rh-coverage-alert-info { background: var(--orange-bg); color: var(--orange); }
.rh-coverage-day { font-weight: 600; }

.rh-gap-row { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; padding: 4px 0; border-top: 1px solid var(--border); }
.rh-gap-row:first-of-type { border-top: none; }

.rh-weekly-hours-total { font-size: 0.6em; font-weight: 600; color: var(--muted); background: var(--panel-alt, rgba(127,127,127,0.08)); border-radius: 4px; padding: 3px 8px; margin-left: 10px; vertical-align: middle; }
.rh-colleague-schedule-row { background: var(--panel-alt, rgba(127,127,127,0.05)); font-size: 0.9em; }
.rh-colleague-schedule-row td { padding-top: 6px; padding-bottom: 6px; }

.rh-gantt2-title { font-weight: 700; font-size: 1em; margin-bottom: 2px; }
.rh-gantt2-legend { display: flex; flex-wrap: wrap; gap: 14px; align-items: center; margin: 10px 0 14px; font-size: 0.85em; }
.rh-gantt2-legend-item { display: inline-flex; align-items: center; gap: 6px; }
.rh-gantt2-swatch { width: 16px; height: 16px; border-radius: 3px; display: inline-block; flex-shrink: 0; }
.rh-gantt2-swatch-repos { background: var(--panel-alt, #e2e5eb); border: 1px solid var(--border); }
.rh-gantt2-swatch-leave { background: var(--rouge-bg); border: 1px solid var(--rouge); }

.rh-gantt2-header { display: flex; }
.rh-gantt2-header-spacer { width: 238px; flex-shrink: 0; }
.rh-gantt2-hours { position: relative; flex: 1; height: 24px; border-bottom: 2px solid var(--border); font-size: 0.78em; font-weight: 600; color: var(--muted); }
.rh-gantt2-hours span { position: absolute; transform: translateX(-50%); }

.rh-gantt2-wrap { position: relative; margin-top: 6px; }
.rh-gantt2-gridlines { position: absolute; top: 0; bottom: 0; left: 238px; right: 0; pointer-events: none; }
.rh-gantt2-gridlines span { position: absolute; top: 0; bottom: 0; width: 1px; background: var(--border); opacity: 0.6; }

.rh-gantt2-day-block { display: flex; border: 1px solid var(--border); border-radius: 6px; overflow: hidden; margin-top: 10px; background: var(--card-bg, transparent); }
.rh-gantt2-day-label { width: 88px; flex-shrink: 0; background: var(--panel-alt, rgba(127,127,127,0.08)); display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; font-weight: 700; font-size: 0.78em; text-transform: uppercase; letter-spacing: 0.03em; padding: 6px 4px; border-right: 1px solid var(--border); }
.rh-gantt2-day-label .hint { text-transform: none; font-weight: 400; font-size: 0.85em; }
.rh-gantt2-day-rows { flex: 1; display: flex; flex-direction: column; min-width: 0; }
.rh-gantt2-day-row { display: flex; align-items: stretch; }
.rh-gantt2-day-row + .rh-gantt2-day-row { border-top: 1px solid var(--border); }
.rh-gantt2-day-name { width: 150px; flex-shrink: 0; display: flex; align-items: center; padding: 5px 8px; font-size: 0.85em; border-right: 1px solid var(--border); }
.rh-gantt2-day-name.is-selected { font-weight: 700; }
.rh-gantt2-day-timeline { position: relative; flex: 1; min-height: 32px; }
.rh-gantt2-bar { position: absolute; top: 3px; bottom: 3px; border-radius: 3px; }
.rh-gantt2-bar-pause { position: absolute; top: 3px; bottom: 3px; background-image: repeating-linear-gradient(45deg, rgba(255,255,255,0.75) 0, rgba(255,255,255,0.75) 3px, transparent 3px, transparent 7px); }
.rh-gantt2-full-status { position: absolute; top: 3px; bottom: 3px; left: 0; right: 0; border-radius: 3px; display: flex; align-items: center; justify-content: center; font-size: 0.78em; font-weight: 700; letter-spacing: 0.03em; text-transform: uppercase; }
.rh-gantt2-full-status.is-repos { background: var(--panel-alt, #e2e5eb); color: var(--muted); }
.rh-gantt2-full-status.is-leave { background: var(--rouge-bg); color: var(--rouge); }
.rh-repos-replacement-badge { margin-top: 6px; display: flex; flex-direction: column; gap: 4px; }
.rh-repos-replacement-item { background: var(--vert-bg); color: var(--vert); border-radius: 4px; padding: 4px 6px; font-size: 0.8em; font-weight: 600; }
.rh-repos-replacement-item .hint { font-weight: 400; }

.recla-lines-table input, .recla-lines-table select { width: 100%; }
.recla-lines-table td { vertical-align: middle; }
.recla-remove-line-btn { white-space: nowrap; }

.planning-commande-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
/* Un item de grille a par defaut min-width:auto (= la largeur min-content de
   son contenu) : si ce contenu est plus large que la piste 1fr qui lui est
   assignee, la piste (et donc la grille entiere) s'agrandit pour l'accueillir
   — c'est ce qui provoquait le depassement de +15px a 390px (confirme : le
   forcer a 0 fait retomber scrollWidth a 390px pile) et probablement le
   retour a la ligne asymetrique de la nav semaine a 1280px (2 colonnes). */
.planning-commande-grid > .card { min-width: 0; }
/* Nav semaine : le "(semaine de commande ...)" concatene sur la meme ligne
   que le libelle rendait le bloc <strong> ~600px de large a 1280px, ne
   laissant plus assez de place a "Semaine suivante ->" qui se retrouvait
   seul sur sa propre ligne (retour a la ligne asymetrique). Passer ce
   sous-texte sur sa propre ligne raccourcit la largeur du bloc et suffit a
   tout faire tenir sur une seule ligne. */
.pc-week-sub { display: block; }
@media (max-width: 900px) {
  .planning-commande-grid { grid-template-columns: 1fr; }
}
.planning-commande-envoi-row td { background: var(--rouge-bg); }
/* Le badge ENVOI a deja sa propre teinte rouge : sur une ligne deja teintee,
   les deux fonds translucides s'additionnent et le texte tombe sous le
   seuil de contraste. Le badge redevient transparent, la ligne porte seule
   la couleur. */
.planning-commande-envoi-row .badge-pending { background: transparent; }
.planning-commande-done-row td { background: var(--vert-bg); }
/* Meme residu que ci-dessus, cote "Terminee" : le badge (deja vert) empile sa
   propre teinte translucide sur la ligne, deja teintee de la meme couleur.
   Mesure : le contraste passe de 6.48:1 (ligne seule) a 4.99:1 (empilement) —
   toujours au-dessus du seuil AA mais degrade sans raison, la ligne portant
   deja seule l'information de statut. */
.planning-commande-done-row .badge-traitee { background: transparent; }
.planning-commande-status-inner { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }

.home-dashboard-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; align-items: start; }
@media (max-width: 1100px) {
  .home-dashboard-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 700px) {
  .home-dashboard-grid { grid-template-columns: 1fr; }
}
.home-dashboard-block { display: flex; flex-direction: column; height: 303px; }
.home-dashboard-scroll { overflow-y: auto; flex: 1; min-height: 0; }
/* Encart unique Bertrand/Marceau/Daniel (pas de grille 3 colonnes, une seule
   carte pleine largeur regroupant tout : passage, fournitures, incidents). */
.home-tournee-wrap { margin-bottom: 20px; }
.home-tournee-card .home-dashboard-scroll { max-height: 70vh; }
.home-tournee-shop-block { padding: 10px 0; border-bottom: 1px solid var(--border); }
.home-tournee-shop-block:last-child { border-bottom: none; }
.home-tournee-shop-name { margin: 0 0 6px; }
.home-tournee-subsection { margin: 8px 0 0 4px; }
.home-tournee-subtitle { display: block; font-size: 0.8em; color: var(--muted); font-weight: 600; margin-bottom: 4px; }
.home-mini-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; font-size: 0.92em; }
.home-passage-row { margin-bottom: 12px; }
.home-passage-row:last-child { margin-bottom: 0; }
.home-passage-tag {
  display: inline-block; margin-left: 6px; padding: 1px 7px; border-radius: 999px;
  font-size: 0.68em; font-weight: 700; letter-spacing: 0.02em; color: #1c1f26;
  vertical-align: middle; text-decoration: none;
}
/* Blanc sur ce bleu ne mesure que 3.98:1 (sous l'AA). Meme bleu que la palette
   Passage Boutique/Planning Travaux (#2979FF) : le noir pur y donne 5.27:1,
   deja verifie au Groupe 6 (le #1c1f26 "par defaut" des autres tags ne
   suffirait pas non plus sur cette teinte precise, 4.14:1). */
.home-passage-tag-avis { background: #2979FF; color: #000; }
.home-passage-tag-avis:hover { text-decoration: underline; }
.home-fourn-shop-group { margin-bottom: 10px; }
.home-fourn-shop-group:last-child { margin-bottom: 0; }
.home-fourn-shop-name { display: block; text-decoration: none; }
.home-fourn-shop-name:hover { text-decoration: underline; }
.home-fourn-product-list { list-style: none; margin: 4px 0 0; padding: 0; display: flex; flex-direction: column; gap: 4px; }
.home-fourn-product-row { display: flex; align-items: center; justify-content: space-between; gap: 8px; flex-wrap: wrap; padding-left: 14px; }
.home-fourn-product-text { overflow-wrap: anywhere; min-width: 0; flex: 1 1 auto; }
.home-fourn-field { flex: 0 0 auto; max-width: 100%; }
.home-passage-tag-interro { background: #FFEE00; }
.home-passage-tag-remplacement { background: #FF9500; }
.home-passage-tag-mat-aprem { background: #D9D9D9; }
.home-passage-tag-retro-ok { background: #00E676; }
.home-passage-tag-retro-pending { background: #FF5252; color: white; }
.home-buyer-progress { margin-bottom: 16px; }
.home-buyer-progress:last-child { margin-bottom: 0; }
.home-product-progress { margin-bottom: 12px; }
.home-progress-label { display: flex; justify-content: space-between; gap: 8px; font-size: 0.9em; margin-bottom: 4px; }

.progress-bar { position: relative; width: 100%; height: 20px; border-radius: 10px; background: var(--panel-alt, rgba(127,127,127,0.15)); overflow: hidden; }
/* --success-solid (pas --vert) : le label blanc de la barre est centre sur
   toute la largeur du conteneur, donc des que le remplissage atteint ~50%
   il se retrouve sur le vert plein — mesure : 2.28:1 avec --vert, 5.01:1
   avec --success-solid. */
/* --glass-sheen en 1er calque : le label (centre verticalement, cf. plus
   bas) tombe toujours dans la partie DEJA transparente du degrade (des 42%
   de hauteur) — le contraste mesure ci-dessus reste donc identique, seul le
   haut du segment gagne un reflet, pour integrer ces barres au reste du
   systeme glass plutot que des aplats "flat design" isoles. */
.progress-bar-fill { height: 100%; background: var(--glass-sheen), var(--success-solid); border-radius: 10px; }
.progress-bar-segmented { display: flex; }
.progress-bar-segment { height: 100%; position: relative; }
.progress-bar-segment-rouge { background: var(--glass-sheen), var(--danger-solid); }
/* Meme resultat que ci-dessus : le label du segment vert est toujours pose
   sur son propre segment, jamais sur la piste neutre. */
.progress-bar-segment-vert { background: var(--glass-sheen), var(--success-solid); }
.progress-bar-segment-bleu { background: var(--glass-sheen), #1f4e9d; }
.progress-bar-label {
    position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
    font-size: 0.72em; font-weight: 600; color: #fff; text-shadow: 0 1px 2px rgba(0,0,0,0.6);
    pointer-events: none;
}
.progress-bar-segment-label {
    position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
    font-size: 0.68em; font-weight: 600; color: #fff; text-shadow: 0 1px 2px rgba(0,0,0,0.6);
    white-space: nowrap; pointer-events: none; overflow: hidden;
}

.voyant { display: inline-block; width: 14px; height: 14px; border-radius: 50%; }
.voyant-vert { background: var(--vert); }
.voyant-orange { background: var(--orange); }
.voyant-rouge { background: var(--rouge); }

tr.indicateur-vert td.qte-finale { color: var(--vert); }
tr.indicateur-orange td.qte-finale { color: var(--orange); }
tr.indicateur-rouge td.qte-finale { color: var(--rouge); }
tr.row-pending { background: var(--orange-bg); }

.login-body {
  position: relative;
  min-height: 100vh;
  background: var(--bg);
}
.login-banner { position: absolute; top: 0; left: 0; width: 100%; height: auto; display: block; }
.login-card {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 32px;
  display: flex;
  flex-direction: column;
  gap: 14px;
  width: 320px;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.15);
}
.login-card h1 { font-size: 1.2em; margin: 0 0 6px; }
.login-card label { display: flex; flex-direction: column; gap: 6px; font-size: 0.9em; color: var(--muted); }
.login-card .error { color: var(--rouge); font-size: 0.9em; margin: 0; }

/* ---- Tableau New ---- */
.np-legend { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 8px; }
.np-legend-title { font-size: 0.85em; color: var(--muted); margin-right: 4px; }
.np-badge {
  display: inline-block;
  padding: 3px 10px;
  border-radius: 999px;
  font-size: 0.78em;
  font-weight: 600;
  border: 1px solid transparent;
}
/* Le fond teinte seul se distingue trop peu des nouvelles surfaces (moins
   sombres qu'avant) : une barre d'accent a gauche redonne un repere net,
   sans encadrer chaque cellule (on reste sur des lignes de tableau denses,
   pas un quadrillage façon Excel). */
td.cat-concentres { color: var(--cat-concentres); background: var(--cat-concentres-bg); border-left: 3px solid var(--cat-concentres); }
td.cat-cbd { color: var(--cat-cbd); background: var(--cat-cbd-bg); border-left: 3px solid var(--cat-cbd); }
td.cat-eliquide { color: var(--cat-eliquide); background: var(--cat-eliquide-bg); border-left: 3px solid var(--cat-eliquide); }
td.cat-materiel { color: var(--cat-materiel); background: var(--cat-materiel-bg); border-left: 3px solid var(--cat-materiel); }
td.cat-puff { color: var(--cat-puff); background: var(--cat-puff-bg); border-left: 3px solid var(--cat-puff); }
td.cat-fleur { color: var(--cat-fleur); background: var(--cat-fleur-bg); border-left: 3px solid var(--cat-fleur); }
td.cat-resine { color: var(--cat-resine); background: var(--cat-resine-bg); border-left: 3px solid var(--cat-resine); }
td.cat-accessoire { color: var(--cat-accessoire); background: var(--cat-accessoire-bg); border-left: 3px solid var(--cat-accessoire); }
.np-badge.cat-concentres { color: var(--cat-concentres); background: var(--cat-concentres-bg); border-color: color-mix(in srgb, var(--cat-concentres) 55%, transparent); }
.np-badge.cat-cbd { color: var(--cat-cbd); background: var(--cat-cbd-bg); border-color: color-mix(in srgb, var(--cat-cbd) 55%, transparent); }
.np-badge.cat-eliquide { color: var(--cat-eliquide); background: var(--cat-eliquide-bg); border-color: color-mix(in srgb, var(--cat-eliquide) 55%, transparent); }
.np-badge.cat-materiel { color: var(--cat-materiel); background: var(--cat-materiel-bg); border-color: color-mix(in srgb, var(--cat-materiel) 55%, transparent); }
.np-badge.cat-puff { color: var(--cat-puff); background: var(--cat-puff-bg); border-color: color-mix(in srgb, var(--cat-puff) 55%, transparent); }
.np-badge.cat-fleur { color: var(--cat-fleur); background: var(--cat-fleur-bg); border-color: color-mix(in srgb, var(--cat-fleur) 55%, transparent); }
.np-badge.cat-resine { color: var(--cat-resine); background: var(--cat-resine-bg); border-color: color-mix(in srgb, var(--cat-resine) 55%, transparent); }
.np-badge.cat-accessoire { color: var(--cat-accessoire); background: var(--cat-accessoire-bg); border-color: color-mix(in srgb, var(--cat-accessoire) 55%, transparent); }
td.cat-concentres, td.cat-cbd, td.cat-eliquide, td.cat-materiel, td.cat-puff,
td.cat-fleur, td.cat-resine, td.cat-accessoire { font-weight: 600; }
/* Vue boutique (gerant/vendeur) de Tableau New : des qu'un statut est fixe
   (voulu/commande/refuse/recu, cf. tr.status-* plus bas), la ligne entiere
   porte deja un fond plein et vif. La teinte de categorie (fond translucide
   a 22%) se superposait a ce fond et l'assombrissait de facon variable
   (ex. categorie + Recu/Refuse -> 3.2-3.6:1, sous le seuil AA), et un texte
   fonce fixe unique ne convenait pas aux 4 statuts (Recu/Refuse sont
   penses pour du texte clair). Hierarchie retenue : le STATUT reste
   l'information prioritaire (fond + texte, memes tokens --status-* que la
   ligne), la CATEGORIE redescend en indicateur secondaire (uniquement la
   bordure gauche deja posee par la regle generale td.cat-*, fond neutralise
   ici pour ne pas se recombiner avec le fond de statut). Une ligne
   "status-none" n'est pas concernee, son texte de categorie reste normal. */
.np-shop-table tr.status-voulu td[class*="cat-"] { background: transparent; color: var(--status-voulu); }
.np-shop-table tr.status-commande td[class*="cat-"] { background: transparent; color: var(--status-commande); }
.np-shop-table tr.status-refuse td[class*="cat-"] { background: transparent; color: var(--status-refuse); }
.np-shop-table tr.status-recu td[class*="cat-"] { background: transparent; color: var(--status-recu); }

.np-badge.status-voulu { color: var(--status-voulu); background: var(--status-voulu-bg); }
.np-badge.status-commande { color: var(--status-commande); background: var(--status-commande-bg); }
.np-badge.status-refuse { color: var(--status-refuse); background: var(--status-refuse-bg); }
.np-badge.status-recu { color: var(--status-recu); background: var(--status-recu-bg); }

/* min-width:0 + max-width:100% : sans ca, un .table-scroll place dans un
   parent flex/grid (ex. .admin-columns) hérite du min-width:auto par
   defaut des items flex et se laisse pousser par la largeur intrinseque du
   tableau au lieu de la contenir — le scroll se retrouve alors sur la page
   entiere plutot que sur ce conteneur. Aucun effet sur les usages actuels
   en flux normal (deja a 100% par defaut). */
.table-scroll { overflow-x: auto; margin-bottom: 20px; min-width: 0; max-width: 100%; }
.tableau-new-matrix { border-collapse: collapse; }
.tableau-new-matrix th, .tableau-new-matrix td { white-space: nowrap; }
.np-shop-header { font-size: 0.72em; line-height: 1.3; text-align: center; }
.np-week-header, .np-buyer-header { text-align: center; font-size: 0.75em; }
.np-week-header { font-weight: 700; text-transform: uppercase; letter-spacing: 0.03em; }
.np-buyer-header { font-weight: 600; }
/* La feuille de style V2 impose `th { background:...!important; }` et
   `.data-table th { color: var(--muted); }` (specificite superieure a une
   simple classe) — sans !important + selecteur plus specifique ici, ces
   couleurs de bandeau/semaine en cours restent invisibles. */
.tableau-new-matrix th.np-week-header { background: var(--bg) !important; color: var(--text) !important; }
.tableau-new-matrix th.np-buyer-header { background: var(--card-bg) !important; color: var(--muted) !important; }
.tableau-new-matrix th.np-week-header-current { background: #8bc34a !important; color: #000000 !important; }
.tableau-new-matrix th.np-shop-header-current { background: var(--primary-bg) !important; }
.tableau-new-matrix th.np-shop-brand-bv { color: #29b6f6 !important; }
.tableau-new-matrix th.np-shop-brand-nfc { color: var(--rouge) !important; }
.tableau-new-matrix th.np-shop-brand-nlcorp { color: #c9a300 !important; }
details.card summary { cursor: pointer; font-size: 1em; }
details.card[open] summary { margin-bottom: 12px; }
.np-cell {
  min-width: 78px;
  text-align: center;
  border-left: 1px solid var(--border);
}
.np-cell select, .np-cell .np-qty { display: block; width: 100%; font-size: 0.72em; padding: 2px 3px; margin-bottom: 2px; }
.np-cell.status-voulu, tr.status-voulu { background: var(--status-voulu-bg); color: var(--status-voulu); }
.np-cell.status-commande, tr.status-commande { background: var(--status-commande-bg); color: var(--status-commande); }
.np-cell.status-refuse, tr.status-refuse { background: var(--status-refuse-bg); color: var(--status-refuse); }
.np-cell.status-recu, tr.status-recu { background: var(--status-recu-bg); color: var(--status-recu); }
/* Vue office (.np-cell) : select/input opaques recouvraient presque toute la
   couleur de statut portee par la cellule (meme defaut que .inc-cell, corrige
   au Groupe 5) — transparent + heritage de la couleur deja posee sur .np-cell.
   :not(.status-none) exclut les cellules sans statut (pas de couleur a preserver). */
.np-cell[class*="status-"]:not(.status-none) .np-status,
.np-cell[class*="status-"]:not(.status-none) .np-qty {
  background: transparent; color: inherit; border-color: currentColor;
}
.np-cell[class*="status-"]:not(.status-none) .np-qty::placeholder { color: currentColor; opacity: .55; }
.np-cell[class*="status-"]:not(.status-none) .np-status:focus,
.np-cell[class*="status-"]:not(.status-none) .np-qty:focus {
  outline: none; border-color: currentColor; box-shadow: inset 0 0 0 1px currentColor;
}
/* Vue boutique (tr.status-*, une seule couleur pour toute la ligne) : le
   survol generique (.data-table tbody tr:hover) remplace le fond par un
   gris neutre sans toucher au texte, qui reste alors la couleur pensee
   pour l'ancien fond vif (ex. texte fonce voulu/commande sur gris ->
   1.15:1 / 1.26:1). Le survol assombrit desormais le fond DE STATUT
   lui-meme (color-mix, -15%) au lieu de le remplacer : le statut reste
   identifiable et le texte associe garde un contraste correct (>=4.4:1
   sur les 4 statuts) sans jamais retoucher les tokens --status-*. */
.np-shop-table tr.status-voulu:hover { background: color-mix(in srgb, var(--status-voulu-bg) 85%, black); }
.np-shop-table tr.status-commande:hover { background: color-mix(in srgb, var(--status-commande-bg) 85%, black); }
.np-shop-table tr.status-refuse:hover { background: color-mix(in srgb, var(--status-refuse-bg) 85%, black); }
.np-shop-table tr.status-recu:hover { background: color-mix(in srgb, var(--status-recu-bg) 85%, black); }

.np-product-cat { min-width: 220px; }
.np-product-cat .np-field { display: block; width: 100%; margin-bottom: 3px; }
.np-product-cat select.np-field { font-size: 0.78em; }
.tableau-new-matrix .np-field { font-size: 0.85em; padding: 4px 6px; }
.np-price-field { width: 70px; }

/* ---- Incidents ---- */
.incident-matrix { border-collapse: collapse; }
.incident-matrix th, .incident-matrix td { white-space: nowrap; }
.inc-cell { min-width: 78px; text-align: center; border-left: 1px solid var(--border); }
.inc-cell .inc-qty, .inc-cell .inc-status { display: block; width: 100%; font-size: 0.72em; padding: 2px 3px; margin-bottom: 2px; }
/* Couleurs fixes (comme .np-week-header-current) : NON RECUP = bleu ciel,
   RECUP = vert fluo, NON CONCERNE = gris (+ info/reel non modifiables),
   memes sur les 3 champs (info/reel/statut) de la case. */
.inc-cell.status-non_recup { background: #87cefa !important; color: #002233 !important; }
.inc-cell.status-recup { background: #39ff14 !important; color: #003300 !important; }
.inc-cell.status-non_concerne { background: #9e9e9e !important; color: #1a1a1a !important; }
/* Les 2 inputs + le select empilent chacun leur propre fond opaque
   (regle globale input/select, .container:371) sur ~78px de large : ca
   recouvrait quasiment toute la case, ne laissant voir la couleur de
   reperage qu'en un mince lisere. Ici seulement (pas la regle globale,
   partagee par tous les formulaires NEXUS) : fond transparent, texte
   herite de la case (deja adapte par statut ci-dessus), bordure/anneau de
   focus recycles depuis la meme couleur (currentColor) plutot qu'un bleu
   --primary qui tombe a ~1-2:1 sur ces 3 fonds clairs. */
.inc-cell .inc-qty, .inc-cell .inc-status {
  background: transparent; color: inherit; border-color: currentColor;
}
.inc-cell .inc-qty::placeholder { color: currentColor; opacity: .55; }
.inc-cell .inc-qty:disabled { opacity: 0.7; }
.inc-cell .inc-qty:focus, .inc-cell .inc-status:focus {
  outline: none; border-color: currentColor; box-shadow: inset 0 0 0 1px currentColor;
}

/* ---- Passage Boutique ---- */
.pb-block { padding-top: 0; }
.pb-month-banner {
  text-align: center;
  font-size: 1.2em;
  font-weight: 700;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  padding: 12px 16px;
  margin: -18px -20px 16px;
  background: var(--primary-bg);
  color: var(--primary);
  border-radius: 9px 9px 0 0;
}
.pb-matrix { table-layout: fixed; width: 100%; }
.pb-matrix th, .pb-matrix td { text-align: center; overflow: hidden; }
.pb-matrix thead th { text-align: center; }
.pb-shop-colgroup { width: 12%; }
.pb-shop-col { position: sticky; left: 0; background: var(--card-bg); z-index: 1; text-align: left; overflow: hidden; text-overflow: ellipsis; }
.pb-person-header { font-size: 0.68em; padding: 4px 2px; }
.pb-matrix thead th { padding: 4px 2px; font-size: 0.72em; line-height: 1.2; white-space: normal; }

/* Pas de hauteur max ni de defilement vertical interne : le bloc s'agrandit avec
   son contenu et c'est la page qui defile ; le bandeau reste fige via la fenetre. */

/* Bandeau d'entetes fige a l'ecran pendant le defilement de la page */
.pb-matrix thead th {
  position: sticky;
  background: var(--card-bg);
  color: var(--text);
  box-shadow: 0 1px 0 0 var(--border);
}
.pb-matrix thead tr:first-child th { top: 0; z-index: 4; }
.pb-matrix thead tr:last-child th { top: var(--pb-row1-h, 32px); z-index: 3; }
.pb-matrix thead .pb-shop-col { z-index: 5; }

/* Bandeau fige en haut de fenetre pendant le defilement de la page (clone JS
   du bandeau mois + entetes, car le vrai thead ne peut plus etre sticky une
   fois le defilement interne du bloc supprime — cf. .pb-table-scroll). */
.pb-sticky-header {
  position: fixed;
  top: 0;
  z-index: 500;
  display: none;
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-top: none;
  box-shadow: 0 4px 10px rgba(0, 0, 0, 0.3);
}
.pb-sticky-header .pb-month-banner { margin: 0; border-radius: 0; }
.pb-sticky-header-scroll { overflow: hidden; }
.pb-sticky-header-scroll table.pb-matrix { margin: 0; }

.pb-cell { border-left: 1px solid var(--border); padding: 2px 2px; cursor: pointer; }
.pb-tool-group { display:flex; align-items:center; gap:8px; flex-wrap:wrap; }
.pb-tool-separator { width:1px; height:34px; background:var(--border); margin:0 6px; }
.pb-marker-tool { display:inline-flex; align-items:center; gap:7px; min-height:42px; padding:5px 10px; border:1px solid var(--border); border-radius:10px; background:var(--card-bg); color:var(--text); cursor:pointer; font-weight:650; }
.pb-marker-tool img { width:30px; height:30px; display:block; }
.pb-marker-tool:hover, .pb-marker-tool.is-active { border-color:var(--primary); box-shadow:0 0 0 2px color-mix(in srgb, var(--primary) 18%, transparent); background:var(--primary-bg); }
.pb-marker-clear { color:var(--muted); }
.pb-color-group { padding-top:2px; }
.pb-marker-stack { display:flex; justify-content:center; align-items:center; gap:3px; flex-wrap:wrap; min-height:30px; margin-bottom:2px; }
.pb-cell-marker { width:27px; height:27px; object-fit:contain; display:block; flex:0 0 auto; }
.pb-cell.has-markers { outline:1px solid rgba(239,51,64,.18); }
/* Separation plus marquee entre les blocs de semaine (4 colonnes Bertrand/Marceau/Dan/Divers) */
.pb-cell.pb-week-start { border-left: 2px solid var(--primary); }
.pb-matrix thead th.pb-week-start { border-left: 2px solid var(--primary); }

/* Mise en avant du bloc de la semaine en cours */
.pb-cell.pb-current-week { background: var(--primary-bg); }
.pb-matrix thead th.pb-current-week { background: var(--primary-tint); color: var(--primary); }
.pb-current-week-badge {
  display: block; font-size: 0.6em; font-weight: 700; letter-spacing: 0.03em;
  text-transform: uppercase; color: var(--primary); margin-top: 2px;
}
.pb-cell .pb-day, .pb-cell .pb-comment {
  display: block; width: 100%; text-align: center; margin-bottom: 2px;
  padding: 2px 1px; box-sizing: border-box; min-width: 0;
  background: transparent;
}
.pb-cell .pb-day { font-size: 0.85em; font-weight: 700; }
.pb-cell .pb-comment { font-size: 0.62em; }
.pb-day-display { font-weight: 700; font-size: 0.85em; }
.pb-comment-display { font-size: 0.65em; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Case peinte (fond vif) : texte fonce pour rester lisible sur les couleurs claires */
.pb-cell[style] .pb-day, .pb-cell[style] .pb-comment,
.pb-cell[style] .pb-day-display, .pb-cell[style] .pb-comment-display { color: #1c1f26; }

/* Regle separee (pas #1c1f26) : sur le bleu de la palette Planning Travaux,
   #1c1f26 ne mesure que 4.14:1 (sous le seuil AA 4.5:1) ; le noir pur reste
   au-dessus de 4.5:1 sur les 7 couleurs de la palette (pire cas, le bleu : 5.27:1). */
.pb-cell[style] .tv-note { color: #000; }
/* opacity .7 (pas .55 comme ailleurs) : sur le jaune, le plus clair des 7, une
   opacite .55 ne laisse que 4.56:1 (marge quasi nulle) ; .7 remonte a 6.5:1+. */
.pb-cell[style] .tv-note::placeholder { color: #000; opacity: .7; }

/* Planning Travaux : reprend les styles Passage Boutique (tableau, palette, paint) */
.pb-cell .tv-note {
  display: block; width: 100%; text-align: center;
  padding: 2px 1px; box-sizing: border-box; min-width: 0;
  background: transparent; font-size: 0.72em;
}
.tv-header-input {
  width: 100%; text-align: center; font-size: 0.7em; font-weight: 600;
  padding: 2px 4px; box-sizing: border-box; border: 1px solid transparent;
  background: transparent; color: inherit; font-family: inherit;
}
.tv-header-input:hover, .tv-header-input:focus { border-color: var(--border); background: var(--bg); }

/* Colonnes Planning Travaux : les 8 colonnes existantes sont retrecies, les 2
   colonnes libres (A faire / Commentaire Stephane) sont tres larges. */
.tv-col-narrow { width: 5%; }
.tv-col-wide { width: 24%; }
.pb-cell.tv-col-wide { text-align: left; cursor: default; }
.pb-cell .tv-note-wide {
  display: block; width: 100%; box-sizing: border-box; min-width: 0;
  background: transparent; font-size: 0.78em; text-align: left;
  resize: vertical; font-family: inherit; border: 1px solid transparent;
  padding: 3px 4px;
}
.pb-cell .tv-note-wide:hover, .pb-cell .tv-note-wide:focus { border-color: var(--border); }
.tv-comment-wide { white-space: normal; text-align: left; font-size: 0.75em; }

.pb-palette {
  display: flex; align-items: center; flex-wrap: wrap; gap: 8px;
  padding: 10px 16px;
}
.pb-palette-label { font-weight: 600; font-size: 0.9em; }
.pb-swatch {
  width: 26px; height: 26px; border-radius: 6px; border: 2px solid var(--border);
  cursor: pointer; padding: 0; box-sizing: border-box;
}
.pb-swatch.is-active { border-color: var(--primary); box-shadow: 0 0 0 2px var(--primary-bg); }
.pb-swatch-clear { background: var(--card-bg); font-size: 0.85em; line-height: 1; color: var(--muted); }
.pb-palette-hint { flex-basis: 100%; margin-top: 4px; }

.pb-week-toggle {
  display: inline-flex; align-items: center; gap: 6px; font-weight: 600;
  cursor: pointer; margin-left: 8px;
}
.pb-week-toggle input { cursor: pointer; }
.pb-week-nav { display: inline-flex; gap: 6px; margin-left: 12px; }
.pb-week-nav-btn {
  display: inline-block; padding: 4px 12px; border-radius: 6px;
  border: 1px solid var(--border); color: var(--text); text-decoration: none;
  font-weight: 700;
}
.pb-week-nav-btn:hover { background: var(--primary-bg); color: var(--primary); }

/* Vue "Semaine en cours" : cases plus grandes */
.pb-block-week .pb-cell { padding: 6px 8px; }
.pb-block-week .pb-shop-colgroup { width: 10%; }

/* Vue semaine : une case a cocher par jour (a la place du champ "jour" libre) */
.pb-day-checkbox-cell { text-align: center; vertical-align: middle; }
/* Case a cocher au rendu natif desactive : non cochee, elle ressemblait a une
   case remplie en gris clair (confusion avec la couleur D9D9D9 "hors semaine
   de commande"). Dessinee a la main : contour seul si decochee, remplie de la
   couleur primaire avec un check blanc si cochee. */
.pb-day-checkbox-cell input[type=checkbox] {
  width: 17px; height: 17px; cursor: pointer; margin: 0;
  appearance: none; -webkit-appearance: none;
  border: 1.5px solid var(--border); border-radius: 3px;
  background: transparent; position: relative; vertical-align: middle;
}
.pb-day-checkbox-cell input[type=checkbox]:checked {
  background: var(--primary); border-color: var(--primary);
}
.pb-day-checkbox-cell input[type=checkbox]:checked::after {
  content: ""; position: absolute; left: 5px; top: 1px;
  width: 4px; height: 8px; border: solid white; border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}
.pb-day-checkbox-cell input[type=checkbox]:disabled { cursor: default; opacity: 0.55; }

/* Nom de boutique cliquable (vue semaine) : ouvre le sous-menu MAT/APREM,
   AVIS DE PASSAGE, INTERRO, REMPLACEMENT. */
.pb-shop-name-toggle {
  background: none; border: none; padding: 0; margin: 0; font: inherit;
  color: inherit; font-weight: 600; cursor: pointer; text-align: left;
  text-decoration: underline; text-decoration-style: dotted; text-underline-offset: 2px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%;
}
.pb-shop-name-toggle:hover { text-decoration: underline; }

/* Sous-menu (MAT/APREM, AVIS DE PASSAGE, INTERRO, REMPLACEMENT) : plus de
   bandeau/tableau imbrique separe — ce sont des lignes supplementaires de la
   MEME grille que la ligne de cases jour, donc chaque case cochable tombe
   naturellement au meme emplacement que la case de passage correspondante. */
.pb-submenu-flag-label {
  font-size: 0.68em; font-weight: 700; text-transform: uppercase;
  letter-spacing: 0.02em; color: var(--muted); text-align: left;
}
.pb-avis-link { margin-left: 3px; text-decoration: none; }
.pb-submenu-divers-cell select { width: 100%; font-size: 0.62em; padding: 1px 2px; box-sizing: border-box; }

/* Fenetre flottante au survol d'une case (vue mois / annee) */
.pb-cell-tooltip {
  position: fixed; z-index: 1000; display: none; max-width: 260px;
  padding: 8px 12px; border-radius: 8px; background: var(--card-bg);
  border: 1px solid var(--border); box-shadow: 0 6px 18px rgba(0, 0, 0, 0.35);
  font-size: 0.8em; line-height: 1.4; pointer-events: none;
}
.pb-cell-tooltip strong { display: block; font-size: 1.05em; margin-bottom: 3px; }
.pb-cell-tooltip .pb-tooltip-meta { color: var(--muted); font-size: 0.85em; margin-bottom: 4px; }
.pb-cell-tooltip .pb-tooltip-day { font-weight: 600; margin-bottom: 2px; }
.pb-cell-tooltip .pb-tooltip-comment { white-space: pre-wrap; }

/* ---- Avis de passage BV ---- */
.avis-date-label { display: flex; flex-direction: column; gap: 4px; font-size: 0.85em; color: var(--muted); margin-bottom: 16px; }
.avis-date-label input { width: auto; }

.avis-radio-group { display: inline-flex; gap: 6px; flex-wrap: wrap; }
.avis-radio {
  display: inline-flex; align-items: center; gap: 5px; padding: 4px 10px;
  border-radius: 999px; border: 1px solid var(--border); cursor: pointer;
  font-size: 0.75em; font-weight: 700; letter-spacing: 0.02em; user-select: none;
}
.avis-radio input { margin: 0; cursor: pointer; }
.avis-radio-tres_bien:has(input:checked) { background: #00E676; border-color: #00E676; color: #1c1f26; }
.avis-radio-correct:has(input:checked) { background: #FFEE00; border-color: #FFEE00; color: #1c1f26; }
.avis-radio-a_faire:has(input:checked) { background: #FF3B30; border-color: #FF3B30; color: #1c1f26; }

.avis-line { padding: 12px 0; border-bottom: 1px solid var(--border); }
.avis-line:last-of-type { border-bottom: none; }
.avis-line-head { display: flex; align-items: center; justify-content: space-between; gap: 14px; flex-wrap: wrap; }
.avis-line-label { font-weight: 600; min-width: 190px; }
.avis-remark-input { width: 100%; margin-top: 8px; box-sizing: border-box; }

.avis-block-label { display: block; margin-top: 18px; font-weight: 600; }
.avis-block-label textarea { margin-top: 6px; box-sizing: border-box; font-family: inherit; }
.avis-conclusion-input { font-weight: 700; }

.avis-card { padding: 14px 0; border-bottom: 1px solid var(--border); scroll-margin-top: 90px; transition: background-color 0.4s ease; }
.avis-card:last-child { border-bottom: none; }
.avis-card-highlight { background-color: var(--orange-bg); border-radius: 8px; }
.avis-card-head { display: flex; align-items: center; gap: 12px; margin-bottom: 8px; }
.avis-line-display { display: flex; align-items: center; gap: 10px; padding: 3px 0; font-size: 0.88em; flex-wrap: wrap; }
.avis-line-display .avis-line-label { min-width: 190px; font-weight: 600; }
.avis-badge { padding: 2px 9px; border-radius: 999px; font-size: 0.75em; font-weight: 700; color: #1c1f26; }
.avis-badge-tres_bien { background: #00E676; }
.avis-badge-correct { background: #FFEE00; }
.avis-badge-a_faire { background: #FF3B30; }
.avis-remark-display { color: var(--muted); font-style: italic; }
.avis-block-display { margin-top: 6px; font-size: 0.88em; }
.avis-conclusion-display { font-weight: 700; margin-top: 10px; }
.avis-media-grid { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 10px; }
.avis-media-item { display: block; border-radius: 8px; overflow: hidden; border: 1px solid var(--border); }
.avis-media-item img { width: 90px; height: 90px; object-fit: cover; display: block; }
.avis-media-video { width: 90px; height: 90px; display: flex; align-items: center; justify-content: center; text-align: center; font-size: 0.75em; padding: 4px; color: var(--muted); overflow: hidden; text-overflow: ellipsis; }

/* Fond toujours un pastel clair fixe (PASSAGE_SHOP_ORDER, fidele au fichier
   Excel d'origine) quel que soit le theme de l'appli : texte fonce fixe,
   jamais var(--text), sinon illisible en blanc sur blanc/pastel. */
.pb-shop-name { color: #1c1f26; font-weight: 600; display: flex; align-items: center; justify-content: space-between; gap: 4px; }
.pb-shop-name-text { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pb-row-paint {
  border: none; background: transparent; cursor: pointer; font-size: 0.85em;
  padding: 0 2px; flex-shrink: 0; opacity: 0.6;
}
.pb-row-paint:hover { opacity: 1; }

/* ---- Generateur Etiquette ---- */
.et-choices { display: flex; gap: 8px; flex-wrap: wrap; }
.et-choice {
  border: 1.5px solid var(--border); background: var(--bg); color: var(--text);
  padding: 8px 14px; border-radius: 8px; cursor: pointer; font-size: 0.85em;
}
.et-choice.is-selected { border-color: var(--primary); background: var(--primary-bg); font-weight: 600; color: var(--text); }
.et-choice-eliquide.is-selected { border-color: var(--cat-eliquide); background: var(--cat-eliquide-bg); }
.et-choice-sel_nicotine.is-selected { border-color: var(--orange); background: var(--orange-bg); }
.et-choice-diy.is-selected { border-color: var(--cat-concentres); background: var(--cat-concentres-bg); }

.et-search-results {
  margin-top: 8px; max-height: 260px; overflow-y: auto; border-radius: 8px;
  border: 1px solid var(--border);
}
.et-search-results:empty { border: none; }
.et-search-item {
  padding: 8px 10px; border-bottom: 1px solid var(--border); cursor: pointer;
  font-size: 0.85em; display: flex; justify-content: space-between; gap: 10px;
}
.et-search-item:last-child { border-bottom: none; }
.et-search-item:hover { background: var(--primary-bg); }
.et-search-item .et-ref { color: var(--muted); font-size: 0.85em; white-space: nowrap; }

.et-selected-list { list-style: none; margin: 0; padding: 0; }
.et-selected-list li {
  display: flex; justify-content: space-between; align-items: center;
  padding: 8px 10px; background: var(--bg); border-radius: 6px;
  margin-bottom: 6px; font-size: 0.85em;
}
.et-remove-btn { border: none; background: none; color: var(--rouge); cursor: pointer; font-size: 1.1em; line-height: 1; padding: 0; }

.et-primary-btn { width: 100%; padding: 14px; font-size: 1em; font-weight: 600; }
.et-primary-btn:disabled { background: var(--border); color: var(--muted); cursor: not-allowed; }

.et-status { margin-top: 14px; font-size: 0.85em; color: var(--muted); text-align: center; }
.et-status.et-status-error { color: var(--rouge); }

/* ---- Resume boutique ---- */
/* Disposition "masonry" (colonnes CSS) plutot qu'une grille classique : avec
   une grille, la hauteur de chaque rangee est celle de sa cellule la plus
   haute, ce qui laisse un grand vide sous les cartes courtes (ex. Fiche a
   cote de Note Google quand elle affiche 5 avis). Les colonnes CSS laissent
   les cartes suivantes remonter combler ce vide. */
.rb-grid { column-count: 2; column-gap: 16px; }
.rb-grid > .card { break-inside: avoid; }
@media (max-width: 900px) { .rb-grid { column-count: 1; } }
.rb-google-stars { font-size: 1.3em; color: #f2a51e; margin: 4px 0; }
.rb-google-warning { font-size: 0.85em; color: var(--orange); background: var(--orange-bg); border-radius: 6px; padding: 6px 10px; margin-top: 6px; }
.rb-google-warning code { font-size: 0.9em; }
/* Erreur reseau (fetch echoue/reponse network_error), a distinguer d'un
   simple message neutre : meme forme que .rb-google-warning ci-dessus, tokens
   danger (deja recalibres au Groupe 1) au lieu de warning. */
.rb-google-error { font-size: 0.85em; color: var(--rouge); background: var(--rouge-bg); border-radius: 6px; padding: 6px 10px; margin-top: 6px; }
/* .absence-shift/.absence-cell-wrap sont partages avec RH Employe (grille
   hebdo) : la surcharge ci-dessous est scopee a .rb-hours-table pour ne pas
   toucher RH Employe. Empiler les 2 inputs heure (au lieu de cote a cote)
   reduit la largeur minimale de chaque colonne jour, pour que la table
   "Horaires d'ouverture" (7 jours) montre plus de colonnes a la fois avant
   de devoir defiler horizontalement dans .table-scroll. */
.rb-hours-table .absence-shift { flex-direction: column; }
.rb-pa-table { width: 100%; border-collapse: collapse; table-layout: fixed; font-size: 0.78em; }
.rb-pa-table th, .rb-pa-table td { border: 1px solid var(--border); padding: 4px 5px; text-align: center; }
.rb-pa-table th:first-child, .rb-pa-table td:first-child { text-align: left; width: 40%; }
.rb-pa-table th { font-weight: 600; color: var(--muted); }
.rb-pa-table th a { color: var(--primary); text-decoration: none; }
.rb-pa-table th a:hover { text-decoration: underline; }
.rb-pa-cell-tres_bien { background: #00E676; color: #1c1f26; font-weight: 700; }
.rb-pa-cell-correct { background: #FFEE00; color: #1c1f26; font-weight: 700; }
.rb-pa-cell-a_faire { background: #FF3B30; color: #1c1f26; font-weight: 700; }
.rb-delta-up { color: var(--vert); font-weight: 600; }
.rb-delta-down { color: var(--rouge); font-weight: 600; }
.rb-delta-flat { color: var(--muted); font-weight: 600; }
.rb-reviews { margin-top: 14px; border-top: 1px solid var(--border); padding-top: 10px; }
.rb-reviews h3 { margin: 0 0 8px; font-size: 0.95em; }
.rb-review { padding: 8px 0; border-bottom: 1px solid var(--border); }
.rb-review:last-child { border-bottom: none; }
.rb-review-header { margin: 0 0 4px; }
.rb-review-header .rb-google-stars { font-size: 0.9em; margin: 0; }
.rb-review-text { margin: 0; font-size: 0.9em; color: var(--muted); }

/* ---- Site internet / MAJ stock ---- */
.si-conn-ok { color: var(--vert); font-weight: 600; }
.si-conn-error { color: var(--rouge); font-weight: 600; }
/* Couleurs neon (#00E676/#FFEE00/#FF3B30) hors palette + fond plein sur
   --muted (concu pour du texte, pas un aplat) mesurant ~2.1:1 pour "En
   attente" : remplaces par les memes tokens semantiques + le meme motif
   (fond translucide + texte vif) que tous les autres badges de NEXUS
   (badge-traitee, badge-pending, badge-closed...). */
.si-status { display: inline-block; padding: 2px 9px; border-radius: 999px; font-size: 0.82em; font-weight: 700; }
.si-status-pending { background: var(--border); color: var(--muted); }
.si-status-ok { background: var(--vert-bg); color: var(--vert); }
.si-status-not_found { background: var(--orange-bg); color: var(--orange); }
.si-status-error { background: var(--rouge-bg); color: var(--rouge); }

/* BDD PRODUITS NEXUS */
.bdd-toolbar { display: flex; gap: 14px; align-items: end; flex-wrap: wrap; }
.bdd-toolbar label { display: flex; flex-direction: column; gap: 5px; font-weight: 600; }
.bdd-search-label { min-width: 300px; flex: 1; }
.bdd-import-label { min-width: 220px; }
.bdd-layout { display: grid; grid-template-columns: minmax(280px, 360px) minmax(0, 1fr); gap: 16px; align-items: start; }
.bdd-results-card, .bdd-editor-card { min-height: 560px; }
.bdd-section-title, .bdd-editor-head { display: flex; justify-content: space-between; align-items: center; gap: 12px; }
.bdd-results { display: flex; flex-direction: column; gap: 5px; margin-top: 10px; max-height: 700px; overflow: auto; }
.bdd-result { border: 1px solid var(--border); background: var(--surface); color: var(--text); border-radius: 10px; padding: 10px; text-align: left; cursor: pointer; display: grid; gap: 2px; }
.bdd-result:hover { border-color: var(--primary); }
.bdd-result small { opacity: .65; color: var(--muted); }
.bdd-tabs { display: flex; gap: 6px; flex-wrap: wrap; margin: 16px 0; }
.bdd-tab { border: 1px solid var(--border); background: var(--surface-2); color: var(--text); padding: 8px 12px; border-radius: 8px; cursor: pointer; }
.bdd-tab.is-active { background: var(--primary); color: #fff; border-color: var(--primary); }
.bdd-tab-panel { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 9px; max-height: 650px; overflow: auto; padding-right: 5px; }
.bdd-field { display: flex; flex-direction: column; gap: 4px; }
.bdd-field span { font-size: 12px; font-weight: 700; opacity: .72; color: var(--muted); }
.bdd-field input { width: 100%; box-sizing: border-box; }
.bdd-image-card { border: 1px solid var(--border); border-radius: 10px; padding: 12px; display: flex; flex-direction: column; gap: 8px; }
.bdd-image-card img { width: 100%; height: 110px; object-fit: contain; background: var(--surface-2); border-radius: 8px; }
.bdd-no-image { height: 110px; display: grid; place-items: center; background: var(--surface-2); border-radius: 8px; opacity: .55; }
.bdd-image-card button { align-self: flex-start; }
.bdd-editor-head h2 { margin: 0; }
.bdd-editor-card { overflow: hidden; }
@media (max-width: 950px) {
  .bdd-layout { grid-template-columns: 1fr; }
  .bdd-results-card { min-height: 300px; }
}

/* Passage Boutique — grille interactive v2
   On conserve la structure HTML pour ne casser aucune regle metier, mais le
   rendu devient une vraie grille de planning : colonnes lisibles, cellules
   plus larges, selection persistante et couleurs prioritaires. */
.pb-block .pb-table-scroll {
  overflow-x: auto;
  overflow-y: visible;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--card-bg);
  scrollbar-width: thin;
}
.pb-block .pb-matrix {
  width: max-content;
  min-width: 100%;
  table-layout: fixed;
  border-collapse: separate;
  border-spacing: 0;
}
.pb-block .pb-matrix th,
.pb-block .pb-matrix td {
  box-sizing: border-box;
  border-right: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
}
.pb-block .pb-matrix th:last-child,
.pb-block .pb-matrix td:last-child { border-right: 0; }
.pb-block .pb-matrix tbody tr:last-child td { border-bottom: 0; }
.pb-block .pb-matrix col:not(.pb-shop-colgroup) { width: 82px; }
.pb-block .pb-matrix col.pb-shop-colgroup { width: 190px; }
.pb-block .pb-matrix thead th { min-width: 82px; }
.pb-block .pb-matrix thead .pb-shop-col,
.pb-block .pb-matrix tbody .pb-shop-col { min-width: 190px; width: 190px; }
.pb-block .pb-matrix tbody td.pb-cell { min-width: 82px; height: 48px; padding: 5px 6px; }
.pb-block-week .pb-matrix tbody td.pb-cell { min-width: 82px; height: 54px; }
.pb-block .pb-matrix tbody tr:hover td.pb-cell { box-shadow: inset 0 0 0 999px rgba(255,255,255,.025); }
.pb-block .pb-matrix td.pb-cell-selected {
  position: relative;
  box-shadow: inset 0 0 0 2px var(--primary), inset 0 0 0 999px rgba(255,255,255,.035) !important;
  z-index: 2;
}
.pb-block .pb-matrix td.pb-cell-flash::after {
  content: "";
  position: absolute;
  inset: 3px;
  border-radius: 6px;
  box-shadow: 0 0 0 2px rgba(255,255,255,.75);
  pointer-events: none;
  animation: pbCellSaved .35s ease-out;
}
@keyframes pbCellSaved { from { opacity: 1; transform: scale(.98); } to { opacity: 0; transform: scale(1); } }
.pb-block .pb-matrix td.pb-cell[style*="background-color"] {
  background-image: none !important;
}
/* Barre d'outils sticky (toujours visible pendant le scroll) : traitee comme
   une surface "niveau 2" (un peu plus lumineuse/presente qu'une simple
   card) via --glass-bg-elevated, coherent avec .topbar-search-results et
   .pp-dialog qui utilisent la meme logique d'elevation. */
.pb-palette {
  position: sticky;
  top: 8px;
  z-index: 20;
  border: 1px solid var(--glass-border-strong);
  border-top-color: var(--glass-border-top);
  box-shadow: var(--glass-shadow), var(--glass-highlight);
  background: var(--glass-sheen), var(--glass-bg-elevated);
  backdrop-filter: var(--glass-blur);
  -webkit-backdrop-filter: var(--glass-blur);
}
/* Chaque pastille expose desormais son nom en texte visible (pas seulement au
   survol/title) : #000 passe l'AA sur les 7 couleurs de PASSAGE_CELL_COLORS
   (deja verifie au Groupe 6 pour ce meme jeu de couleurs, pire cas Bleu
   5.27:1). Partage entre Passage Boutique et Planning Travaux (meme palette). */
.pb-swatch {
  width: auto; min-width: 32px; height: 32px; border-radius: 8px;
  padding: 0 8px; display: inline-flex; align-items: center; justify-content: center;
}
.pb-swatch-label { font-size: 0.72em; font-weight: 700; color: #000; white-space: nowrap; }
.pb-swatch-clear .pb-swatch-label { color: var(--muted); font-weight: 600; }
.pb-palette-hint { color: var(--muted); }
.pb-block .pb-shop-col { box-shadow: 5px 0 10px -9px rgba(0,0,0,.65); }
.pb-block .pb-matrix thead th { min-height: 42px; }
@media (max-width: 900px) {
  .pb-block .pb-matrix col.pb-shop-colgroup,
  .pb-block .pb-matrix thead .pb-shop-col,
  .pb-block .pb-matrix tbody .pb-shop-col { width: 155px; min-width: 155px; }
  .pb-block .pb-matrix col:not(.pb-shop-colgroup),
  .pb-block .pb-matrix thead th:not(.pb-shop-col),
  .pb-block .pb-matrix tbody td.pb-cell { width: 72px; min-width: 72px; }
}

/* --- PASSAGE BOUTIQUE v2 (refonte 2026-08-21, BONNE VAP uniquement) ---
   Prefixe pp-* deliberement distinct de pb-* : pb-* est deja partage avec
   Planning Travaux (templates/planning_travaux.html), un prefixe commun
   ferait deborder ce nouveau style vers cette fonctionnalite sans rapport. */
.pp-week-nav { display: inline-flex; gap: 6px; margin-left: 12px; }
.pp-week-nav-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 28px; border-radius: 6px; border: 1px solid var(--border);
  text-decoration: none; color: var(--text); font-weight: 700;
}
.pp-week-nav-btn:hover { border-color: var(--primary); color: var(--primary); }

.pp-grid-card { padding: 0; }
.pp-grid-scroll { max-width: 100%; max-height: 70vh; overflow-y: auto; }
.pp-grid { table-layout: fixed; border-collapse: separate; border-spacing: 0; }
.pp-grid col.pp-shop-colgroup { width: 170px; }
.pp-grid col:not(.pp-shop-colgroup) { width: 190px; }
.pp-grid th, .pp-grid td { border: 1px solid var(--border); vertical-align: top; }
.pp-grid thead th {
  position: sticky; top: 0; z-index: 3; background: var(--card-bg);
  padding: 10px 8px; font-size: 0.85em; text-align: center;
}
.pp-grid thead th.pp-current-day { color: var(--primary); }
.pp-grid .pp-shop-col {
  position: sticky; left: 0; z-index: 2; background: var(--card-bg);
  font-weight: 600; padding: 8px 10px; white-space: normal;
}
.pp-grid thead th.pp-shop-col { z-index: 4; text-align: left; }
/* Fond toujours un pastel clair fixe (PASSAGE_SHOP_ORDER, cf. .pb-shop-name) :
   texte fonce fixe, jamais var(--text). */
.pp-grid td.pp-shop-name, .pp-recap-table td.pp-shop-name { color: #1c1f26; }
.pp-grid td.pp-cell-td { padding: 0; }
.pp-grid td.pp-cell-td.pp-current-day { background: color-mix(in srgb, var(--primary-bg) 40%, transparent); }
/* Fermeture boutique definie depuis RESUME BOUTIQUE (ShopClosurePeriod) -
   purement visuel, ne bloque rien pour Bertrand/Marceau/Daniel. */
.pp-grid td.pp-cell-td.pp-cell-closed { background: rgba(255, 82, 82, 0.16); }
.pp-closed-badge {
  font-size: 0.62em; font-weight: 700; text-transform: uppercase; letter-spacing: 0.03em;
  color: #ff5252; text-align: center; margin-bottom: 2px;
}

.pp-cell { padding: 4px 6px; display: flex; flex-direction: column; gap: 1px; min-height: 100%; }
.pp-bmd-row {
  display: flex; gap: 4px; justify-content: space-between; padding: 1px 2px 2px;
  margin-bottom: 1px; border-bottom: 1px dashed var(--border); border-radius: 3px;
}
/* Semaine de commande de la boutique (roulement A/B/C, cf. current_semaine
   cote serveur) + au moins un de Bertrand/Marceau/Daniel coche -> vert fluo,
   meme couleur que l'ancien indicateur "semaine de commande" (PASSAGE_ORDER_WEEK_COLOR). */
tr[data-order-week="true"] .pp-bmd-row:has(input:checked) { background: #00E676; }
tr[data-order-week="true"] .pp-bmd-row:has(input:checked) .pp-bmd-flag { color: #06251c; }
.pp-bmd-flag { font-size: 0.6em !important; gap: 2px !important; }
/* Bertrand/Marceau/Daniel en conge ce jour-la (cf. staff_leave_days) : nom en
   rouge + barre, case non cochable (deja refuse cote serveur par
   update_passage_plan_cell). Priorite des etats sur le texte : la ligne
   "semaine de commande + coche" (#00E676, regle suivante) reste PRIORITAIRE
   sur la couleur — un texte rouge sur fond vert vif tombait a 1.91:1. Sans
   !important ici, la regle plus specifique de la semaine de commande
   l'emporte naturellement dans ce cas et fournit deja sa propre couleur
   lisible (#06251c) ; le barre (independant de la couleur) reste le signal
   "en conge" dans tous les cas, y compris quand le rouge est supplante. */
.pp-bmd-flag.pp-bmd-on-leave { color: #ff5252; text-decoration: line-through; text-decoration-thickness: 1px; }
.pp-bmd-flag.pp-bmd-on-leave input { cursor: not-allowed; }
.pp-period-label { font-size: 0.66em; font-weight: 600; color: var(--primary); text-align: center; line-height: 1.2; }
.pp-period-label:empty { display: none; }
.pp-flags-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0 6px; }
.pp-flag-row { display: flex; align-items: center; gap: 3px; font-size: 0.68em; line-height: 1.25; cursor: pointer; white-space: nowrap; border-radius: 3px; }
.pp-flag-row input { width: 11px; height: 11px; cursor: pointer; flex: none; }
/* Une case cochee met son libelle en gras — s'applique a tous les champs
   (Bertrand/Marceau/Daniel, Matin/Aprem/Avis/Remp, Interro). */
.pp-flag-row:has(input:checked) { font-weight: 700; }
/* Matin/Aprem/Avis/Remp/Interro cochee colore en plus leur propre ligne,
   independamment du gras ci-dessus. */
.pp-flag-row:has([data-field="matin"]:checked) { background: #A0E7D8; color: #06251c; padding: 0 2px; margin: 0 -2px; }
.pp-flag-row:has([data-field="aprem"]:checked) { background: #1B5E20; color: #eafbe9; padding: 0 2px; margin: 0 -2px; }
.pp-flag-row:has([data-field="avis"]:checked) { background: #E53935; color: #fff; padding: 0 2px; margin: 0 -2px; }
.pp-flag-row:has([data-field="remplacement"]:checked) { background: #D8B4FE; color: #06251c; padding: 0 2px; margin: 0 -2px; }
.pp-interro-row:has(.pp-interro-checkbox:checked) { background: #2979FF; color: #fff; padding: 0 2px; margin: 0 -2px; }
.pp-interro-row { justify-content: space-between; font-size: 0.68em; margin-top: 1px; }
.pp-interro-count {
  border: 1px solid var(--border); border-radius: 999px; padding: 0 6px;
  font-size: 0.95em; line-height: 1.4; background: var(--card-bg); cursor: pointer;
}
.pp-interro-count:hover { border-color: var(--primary); color: var(--primary); }
.pp-note-inline {
  margin-top: 1px; width: 100%; box-sizing: border-box; font-family: inherit;
  font-size: 0.66em; line-height: 1.2; padding: 1px 3px; border: 1px solid var(--border);
  border-radius: 4px; background: transparent; color: var(--text); resize: vertical; min-height: 20px;
}
textarea.pp-note-inline:focus { border-color: var(--primary); outline: none; }
.pp-note-inline-readonly { color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Recapitulatif de la semaine (Passage Boutique v2) : encart compact en
   haut a droite, a cote de la carte SEMAINE — lecture seule, uniquement
   derive de ce qui est coche dans le tableau principal. */
.pp-header-row { display: flex; align-items: flex-start; gap: 14px; flex-wrap: wrap; }
.pp-week-card { flex: 1 1 220px; margin-bottom: 0; }
.pp-recap-card { flex: 1 1 460px; width: 460px; max-width: 100%; margin-bottom: 0; padding: 12px 14px; }
.pp-recap-card h2 { margin: 0 0 8px; font-size: 0.85em; text-transform: uppercase; letter-spacing: 0.04em; color: var(--muted); cursor: help; }
.pp-recap-scroll { max-height: 220px; overflow-y: auto; }
.pp-recap-table { width: 100%; border-collapse: separate; border-spacing: 0; }
.pp-recap-table th, .pp-recap-table td { border: 1px solid var(--border); padding: 5px 10px; text-align: center; vertical-align: middle; font-size: 0.85em; }
.pp-recap-table thead th {
  position: sticky; top: 0; z-index: 2; background: var(--card-bg);
  font-size: 0.72em; text-transform: uppercase; letter-spacing: 0.03em; color: var(--muted); cursor: help;
}
.pp-recap-table th.pp-shop-col, .pp-recap-table td.pp-shop-col { text-align: left; min-width: 180px; }
.pp-recap-row[hidden] { display: none; }
.pp-recap-chip {
  display: inline-block; min-width: 1.1em; padding: 1px 5px; margin: 1px; border-radius: 999px;
  font-size: 0.82em; font-weight: 700; background: var(--success-bg); color: var(--success);
}
.pp-recap-chip-today { background: var(--primary-tint); color: var(--primary); box-shadow: inset 0 0 0 1px var(--primary); }
.pp-recap-empty { color: var(--text-disabled); }
.pp-recap-empty-state td { text-align: left; color: var(--muted); font-size: 0.85em; padding: 8px 6px; }

.pp-dialog {
  border: 1px solid var(--glass-border-strong); border-top-color: var(--glass-border-top); border-radius: var(--radius-lg); padding: 18px 20px;
  background: var(--glass-sheen), var(--glass-bg-elevated);
  backdrop-filter: var(--glass-blur);
  -webkit-backdrop-filter: var(--glass-blur);
  color: var(--text); max-width: 380px; width: 90vw;
  box-shadow: var(--glass-shadow), var(--glass-highlight);
}
.pp-dialog::backdrop { background: rgba(0,0,0,.5); }
.pp-dialog h3 { margin: 0 0 4px; }
.pp-interro-employee-list { display: flex; flex-direction: column; gap: 6px; max-height: 40vh; overflow-y: auto; margin: 10px 0; }
.pp-interro-employee { display: flex; align-items: center; gap: 8px; cursor: pointer; }
.pp-dialog-actions { display: flex; justify-content: flex-end; gap: 8px; }
.pp-dialog-actions button {
  padding: 6px 14px; border-radius: 6px; border: 1px solid var(--border);
  background: transparent; color: var(--text); cursor: pointer;
}
.pp-dialog-actions .pp-dialog-validate { background: var(--primary); border-color: var(--primary); color: #fff; }


/* =========================================================
   NEXUS — LIQUID GLASS / VISUAL POLISH
   Final visual layer — no business logic, layout logic or data changes.
   The home background is intentionally scoped to the home dashboard only.
   ========================================================= */

/* Deeper atmospheric base so translucent surfaces have something to reveal. */
:root {
  --bg: #061C23;
  --bg-secondary: #08242D;
  --surface: #0D3039;
  --surface-2: #123C47;
  --surface-hover: #1A4B57;
  --surface-elevated: #1F5A68;
  --card-bg: var(--surface);

  /* More visible glass: translucent enough to reveal the environment,
     opaque enough to preserve AA contrast and hierarchy. */
  --glass-bg: rgba(19, 67, 79, .56);
  --glass-bg-elevated: rgba(28, 88, 103, .62);
  --glass-sheen: linear-gradient(
    180deg,
    rgba(255,255,255,.105) 0%,
    rgba(255,255,255,.035) 22%,
    rgba(255,255,255,0) 52%
  );
  --glass-border: rgba(205, 244, 250, .15);
  --glass-border-top: rgba(220, 249, 255, .28);
  --glass-border-strong: rgba(220, 249, 255, .22);
  --glass-highlight:
    inset 0 1px 0 rgba(255,255,255,.11),
    inset 0 -24px 42px -30px rgba(0,0,0,.28);
  --glass-shadow:
    0 18px 45px rgba(0, 8, 12, .34),
    0 2px 8px rgba(0,0,0,.18);
  --glass-blur: blur(18px) saturate(135%);
}

/* Atmospheric background for the application. */
body {
  background-color: var(--bg);
  background-image:
    radial-gradient(ellipse 900px 700px at 8% -10%, rgba(41, 121, 255, .075), transparent 62%),
    radial-gradient(ellipse 850px 760px at 100% 0%, rgba(123, 97, 255, .055), transparent 60%),
    radial-gradient(ellipse 1000px 800px at 50% 115%, rgba(0, 230, 118, .035), transparent 64%);
}

/* The X artwork is the app-wide backdrop (every page, same rule, same
   cached image — one request total, no per-page logic). Kept behind the
   interface so the glass cards visibly refract/reveal it. */
body {
  background-image:
    linear-gradient(rgba(3, 20, 26, .12), rgba(3, 20, 26, .12)),
    url("../img/nexus-liquid-glass-home.png");
  background-size: cover;
  background-position: center center;
  background-repeat: no-repeat;
  background-attachment: fixed;
}

/* Persistent chrome: dark translucent glass rather than opaque panels. */
.topbar {
  background:
    linear-gradient(180deg, rgba(255,255,255,.055), rgba(255,255,255,0) 60%),
    rgba(5, 29, 36, .72);
  backdrop-filter: var(--glass-blur);
  -webkit-backdrop-filter: var(--glass-blur);
  border-bottom-color: var(--glass-border-top);
  box-shadow: 0 8px 28px rgba(0,0,0,.24);
}

.sidebar {
  background:
    linear-gradient(180deg, rgba(255,255,255,.045), rgba(255,255,255,0) 50%),
    rgba(5, 29, 36, .72);
  backdrop-filter: var(--glass-blur);
  -webkit-backdrop-filter: var(--glass-blur);
  border-right-color: var(--glass-border-top);
  box-shadow: 10px 0 30px rgba(0,0,0,.22);
}

/* Main glass surfaces. */
.card,
.hub-tile {
  background: var(--glass-sheen), var(--glass-bg);
  backdrop-filter: var(--glass-blur);
  -webkit-backdrop-filter: var(--glass-blur);
  border-color: var(--glass-border);
  border-top-color: var(--glass-border-top);
  border-radius: 16px;
  box-shadow: var(--glass-shadow), var(--glass-highlight);
}

/* Give adjacent glass panels enough separation without making them look
   like solid dashboard tiles. */
.card:hover,
.hub-tile:hover {
  border-color: var(--glass-border-strong);
}

.card h2 {
  letter-spacing: -0.015em;
}

/* Controls remain readable/opaque, but inherit the same visual language. */
input, select, textarea {
  border-color: rgba(205,244,250,.14);
  border-radius: 9px;
}

input:focus, select:focus, textarea:focus {
  border-color: rgba(76,159,255,.72);
  box-shadow: 0 0 0 3px rgba(76,159,255,.10);
}

.data-table th {
  background: rgba(20, 61, 72, .88);
  border-bottom-color: rgba(205,244,250,.14);
}

.data-table tbody tr:hover {
  background: rgba(38, 91, 103, .42);
}

/* Badges/chips: small glass objects, not flat colored blocks. */
.badge,
.home-passage-tag,
.pp-recap-chip {
  box-shadow: inset 0 1px 0 rgba(255,255,255,.08);
}

/* Active navigation gets a glass-blue lift rather than a solid rectangle. */
.sidebar-link.active {
  background:
    linear-gradient(180deg, rgba(255,255,255,.055), rgba(255,255,255,0)),
    rgba(76,159,255,.13);
  border-left-color: var(--primary);
  box-shadow:
    inset 0 0 0 1px rgba(76,159,255,.18),
    0 0 18px rgba(76,159,255,.07);
}

/* Search field in the chrome should feel embedded in glass. */
.topbar-search {
  background: rgba(7, 29, 36, .52);
  border-color: rgba(205,244,250,.16);
}

.topbar-search:focus {
  background: rgba(8, 35, 43, .66);
}

/* Home dashboard: let the artwork breathe between/through panels. */
.home-dashboard-grid {
  gap: 18px;
}

.home-dashboard-block {
  background: var(--glass-sheen), var(--glass-bg);
  backdrop-filter: var(--glass-blur);
  -webkit-backdrop-filter: var(--glass-blur);
}

/* Slightly stronger glass on the home page so the X remains visible without
   competing with the information. */
body:has(.home-dashboard-grid) .home-dashboard-block {
  background:
    linear-gradient(180deg, rgba(255,255,255,.075), rgba(255,255,255,0) 48%),
    rgba(14, 57, 68, .54);
}

/* On narrow screens, keep the artwork present without forcing a giant focal
   X behind every card. */
@media (max-width: 700px) {
  body {
    background-position: center center;
    background-size: auto 100%;
  }
}

/* =========================================================
   NEXUS — LIQUID GLASS / LIGHT EDITION
   Applied 2026-09-01 — visual layer only.
   Business logic, routes, forms, API calls and data behavior are untouched.
   ========================================================= */

:root {
  /* Light atmospheric palette */
  --bg: #e8f2f6;
  --bg-secondary: #dcecf2;
  --surface: rgba(255, 255, 255, .62);
  --surface-2: rgba(255, 255, 255, .78);
  --surface-hover: rgba(255, 255, 255, .9);
  --surface-elevated: rgba(255, 255, 255, .84);
  --card-bg: rgba(255, 255, 255, .62);

  --text: #142d3d;
  --text-secondary: #536b7a;
  --text-tertiary: #78909d;
  --text-disabled: #9aadb7;
  --muted: var(--text-secondary);

  --border: rgba(38, 91, 113, .16);
  --border-strong: rgba(38, 91, 113, .28);

  --primary: #1688e8;
  --primary-dark: #086fca;
  --primary-bg: rgba(22, 136, 232, .10);
  --primary-tint: rgba(22, 136, 232, .07);
  --accent-2: #7564df;
  --accent-2-bg: rgba(117, 100, 223, .10);
  --accent: var(--primary);
  --accent-soft: var(--primary-bg);

  --success: #0aaf68;
  --success-bg: rgba(10, 175, 104, .10);
  --success-soft: var(--success-bg);
  --success-solid: #07925a;
  --warning: #d88900;
  --warning-bg: rgba(216, 137, 0, .10);
  --warning-soft: var(--warning-bg);
  --danger: #df4f5f;
  --danger-bg: rgba(223, 79, 95, .10);
  --danger-soft: var(--danger-bg);
  --danger-solid: #c93c4c;
  --info: #187bd5;
  --info-bg: rgba(24, 123, 213, .10);
  --info-soft: var(--info-bg);

  --vert: var(--success); --vert-bg: var(--success-bg);
  --orange: var(--warning); --orange-bg: var(--warning-bg);
  --rouge: var(--danger); --rouge-bg: var(--danger-bg);

  /* Glass system */
  --glass-bg: rgba(255, 255, 255, .58);
  --glass-bg-elevated: rgba(255, 255, 255, .76);
  --glass-sheen: linear-gradient(
    180deg,
    rgba(255,255,255,.78) 0%,
    rgba(255,255,255,.34) 18%,
    rgba(255,255,255,0) 54%
  );
  --glass-border: rgba(255,255,255,.68);
  --glass-border-top: rgba(255,255,255,.92);
  --glass-border-strong: rgba(255,255,255,.88);
  --glass-highlight:
    inset 0 1px 0 rgba(255,255,255,.96),
    inset 0 -18px 38px -32px rgba(42, 105, 130, .22);
  --glass-shadow:
    0 22px 55px rgba(35, 83, 103, .12),
    0 4px 14px rgba(35, 83, 103, .08);
  --glass-blur: blur(22px) saturate(125%);
  --shadow-sm: 0 2px 8px rgba(38, 83, 102, .09);
  --shadow-md: 0 16px 38px rgba(38, 83, 102, .14);
}

html { background: var(--bg); }

body {
  color: var(--text);
  background-color: var(--bg);
  background-image:
    linear-gradient(rgba(239,248,252,.18), rgba(239,248,252,.18)),
    url("../img/nexus-liquid-glass-home-light.png");
  background-size: cover;
  background-position: center center;
  background-repeat: no-repeat;
  background-attachment: fixed;
}

/* Persistent chrome: translucent panes floating over the environment. */
.topbar {
  background:
    linear-gradient(180deg, rgba(255,255,255,.72), rgba(255,255,255,.38) 72%),
    rgba(242, 249, 252, .56);
  backdrop-filter: var(--glass-blur);
  -webkit-backdrop-filter: var(--glass-blur);
  border-bottom-color: rgba(255,255,255,.86);
  box-shadow: 0 8px 30px rgba(42, 87, 106, .10);
}

.sidebar {
  background:
    linear-gradient(180deg, rgba(255,255,255,.72), rgba(255,255,255,.38) 65%),
    rgba(242, 249, 252, .58);
  backdrop-filter: var(--glass-blur);
  -webkit-backdrop-filter: var(--glass-blur);
  border-right-color: rgba(255,255,255,.84);
  box-shadow: 10px 0 32px rgba(42, 87, 106, .09);
}

.sidebar-caption { color: #718996; }
.sidebar-link { color: #183447; }
.sidebar-link:hover {
  background: rgba(255,255,255,.56);
  color: #123247;
}
.sidebar-link.active {
  color: #0879d6;
  background:
    linear-gradient(180deg, rgba(255,255,255,.78), rgba(255,255,255,.32)),
    rgba(30, 143, 232, .10);
  border-left-color: #1688e8;
  box-shadow:
    inset 0 0 0 1px rgba(22,136,232,.14),
    0 8px 22px rgba(22,136,232,.08);
}
.sidebar-link.active .nav-icon { color: #1688e8; }
.sidebar-link-disabled { color: #9aadb7; }
.sidebar-link-disabled:hover { background: transparent; color: #9aadb7; }
.sidebar-home { color: #17364a; }

.topbar-search {
  background: rgba(255,255,255,.54);
  border-color: rgba(255,255,255,.82);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.8), 0 4px 16px rgba(44,87,105,.06);
}
.topbar-search:focus-within,
.topbar-search:focus {
  background: rgba(255,255,255,.72);
  border-color: rgba(22,136,232,.34);
  box-shadow: 0 0 0 3px rgba(22,136,232,.08), inset 0 1px 0 rgba(255,255,255,.9);
}
.topbar-search input { color: var(--text); }
.topbar-search input::placeholder { color: #78909d; }
.topbar-search-icon { color: #6f8794; }
.user-info { color: var(--text-secondary); }
.user-copy strong { color: var(--text); }
.topbar .user-info a { color: #607987; border-left-color: rgba(38,91,113,.14); }
.topbar .user-info a:hover { color: var(--primary); }
.user-avatar { background: rgba(22,136,232,.10); color: #0879d6; border-color: rgba(22,136,232,.12); }

/* Main glass surfaces. */
.card,
.hub-tile,
.home-dashboard-block {
  background: var(--glass-sheen), var(--glass-bg);
  backdrop-filter: var(--glass-blur);
  -webkit-backdrop-filter: var(--glass-blur);
  border-color: var(--glass-border);
  border-top-color: var(--glass-border-top);
  box-shadow: var(--glass-shadow), var(--glass-highlight);
}

.card:hover,
.hub-tile:hover { border-color: var(--glass-border-strong); }
.card h2 { color: #17364a; }
.page-head h1, h1 { color: #112f43; }
.hint, .breadcrumb, .breadcrumb a { color: var(--text-secondary); }

/* Inputs and selects become frosted controls, still opaque enough for data. */
input[type=text], input[type=password], input[type=number], input[type=date],
input[type=email], input[type=search], select, textarea,
input, .admin-inline-select {
  background: rgba(255,255,255,.72);
  color: var(--text);
  border-color: rgba(38,91,113,.16);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.72);
}
input::placeholder, textarea::placeholder { color: #8aa0ab; }
input:focus, select:focus, textarea:focus {
  border-color: rgba(22,136,232,.58);
  box-shadow: 0 0 0 3px rgba(22,136,232,.09), inset 0 1px 0 rgba(255,255,255,.82);
  outline: none;
}
.admin-inline-input { color: var(--text); }
.admin-inline-input:hover, .admin-inline-input:focus {
  border-color: rgba(38,91,113,.16);
  background: rgba(255,255,255,.56);
}

/* Buttons: blue glass/acrylic rather than flat fills. */
button, .button {
  background: linear-gradient(180deg, #35a1f3, #1688e8);
  border-color: rgba(255,255,255,.52);
  color: #fff;
  box-shadow: 0 7px 18px rgba(22,136,232,.16), inset 0 1px 0 rgba(255,255,255,.32);
}
button:hover, .button:hover {
  background: linear-gradient(180deg, #49adf5, #0f7fdc);
  color: #fff;
  box-shadow: 0 10px 24px rgba(22,136,232,.20), inset 0 1px 0 rgba(255,255,255,.38);
}
button.secondary, .button.secondary {
  background: rgba(255,255,255,.48);
  border-color: rgba(38,91,113,.18);
  color: #24485c;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.78), 0 4px 12px rgba(38,83,102,.06);
}
button.secondary:hover, .button.secondary:hover {
  background: rgba(255,255,255,.72);
  border-color: rgba(22,136,232,.28);
  color: #0b6fc1;
}
button.ghost, .button.ghost { background: transparent; color: #607987; box-shadow: none; }
button.ghost:hover, .button.ghost:hover { background: rgba(255,255,255,.48); color: #23465a; box-shadow: none; }
button.danger, .button.danger { background: linear-gradient(180deg, #e86a76, #c93c4c); color: #fff; }
button.danger:hover, .button.danger:hover { background: linear-gradient(180deg, #ed7782, #bc3445); }
button.link-btn, a.link-btn { color: #0879d6; }
button.link-btn:hover, a.link-btn:hover { color: #056bbf; }

.section-nav-btn {
  background: rgba(255,255,255,.46);
  color: #24485c;
  border-color: rgba(38,91,113,.16);
}
.section-nav-btn:hover { background: rgba(255,255,255,.72); color: #0879d6; }

.pc-collapsible summary {
  background: rgba(255,255,255,.38);
  color: #24485c;
}
.pc-collapsible summary:hover { background: rgba(255,255,255,.64); }

.locked-notice {
  background: rgba(255,255,255,.42);
  border-color: rgba(38,91,113,.18);
}

/* Data surfaces: crisp and calm on the glass. */
.data-table th {
  background: rgba(230,241,246,.78);
  color: #5a7482;
  border-bottom-color: rgba(38,91,113,.14);
}
.data-table td { border-bottom-color: rgba(38,91,113,.12); }
.data-table tbody tr:hover { background: rgba(255,255,255,.42); }
.table-scroll { border-color: rgba(38,91,113,.12); }

/* Drop zones and utility panels. */
.dropzone {
  background: rgba(255,255,255,.28);
  border-color: rgba(38,91,113,.22);
}
.dropzone:hover,
.dropzone.dropzone-active {
  background: rgba(255,255,255,.55);
  border-color: rgba(22,136,232,.48);
}

/* Light glass dialogs and popovers. */
.pp-dialog,
.topbar-search-results,
.pb-palette {
  background: var(--glass-sheen), var(--glass-bg-elevated);
  backdrop-filter: var(--glass-blur);
  -webkit-backdrop-filter: var(--glass-blur);
  border-color: var(--glass-border-strong);
  box-shadow: var(--glass-shadow), var(--glass-highlight);
  color: var(--text);
}
.pp-dialog::backdrop { background: rgba(25,58,72,.20); backdrop-filter: blur(4px); }

/* Keep product/status colors functional while making their containers feel integrated. */
.badge, .home-passage-tag, .pp-recap-chip {
  box-shadow: inset 0 1px 0 rgba(255,255,255,.72), 0 2px 6px rgba(38,83,102,.05);
}

/* Planning / dense grids: readable light surfaces with a glass header. */
.pb-palette { border-top-color: rgba(255,255,255,.95); }
.pb-swatch-clear .pb-swatch-label { color: #617986; }
.pp-grid thead th,
.pp-recap-table thead th {
  background: rgba(241,248,251,.88);
  color: #597380;
}
.pp-grid .pp-shop-col { background: rgba(248,252,254,.86); }
.pp-grid th, .pp-grid td,
.pp-recap-table th, .pp-recap-table td { border-color: rgba(38,91,113,.13); }
.pp-note-inline { background: rgba(255,255,255,.68); color: var(--text); border-color: rgba(38,91,113,.14); }

/* Mobile glass treatment. */
.sidebar-backdrop { background: rgba(31,65,80,.18); backdrop-filter: blur(5px); }
@media (max-width: 720px) {
  .sidebar {
    background:
      linear-gradient(180deg, rgba(255,255,255,.82), rgba(255,255,255,.60)),
      rgba(242,249,252,.72);
  }
  body {
    background-position: center center;
    background-size: auto 100%;
  }
}

/* Login follows the same visual language. */
.login-body {
  background-color: var(--bg);
  background-image:
    linear-gradient(rgba(239,248,252,.18), rgba(239,248,252,.18)),
    url("../img/nexus-liquid-glass-home-light.png");
  background-size: cover;
  background-position: center;
}
.login-card {
  background: var(--glass-sheen), var(--glass-bg-elevated);
  backdrop-filter: var(--glass-blur);
  -webkit-backdrop-filter: var(--glass-blur);
  border-color: var(--glass-border-strong);
  box-shadow: var(--glass-shadow), var(--glass-highlight);
  color: var(--text);
}

/* =========================================================
   NEXUS — LIQUID GLASS LIGHT / FINAL REFINEMENT
   Objectif : verre clair premium, lisibilité forte, profondeur douce.
   Aucun changement de logique ou de comportement.
   ========================================================= */
:root {
  --bg: #eaf4f9;
  --bg-secondary: #dfeef5;
  --surface: rgba(255,255,255,.82);
  --surface-2: rgba(255,255,255,.90);
  --surface-hover: rgba(255,255,255,.96);
  --surface-elevated: rgba(255,255,255,.94);
  --card-bg: rgba(255,255,255,.80);
  --text: #102c43;
  --text-secondary: #526d80;
  --text-tertiary: #7892a3;
  --text-disabled: #a0b2be;
  --muted: #617b8c;
  --border: rgba(57,103,127,.16);
  --border-strong: rgba(37,119,176,.28);
  --primary: #1688e8;
  --primary-dark: #086fca;
  --primary-bg: rgba(22,136,232,.10);
  --primary-tint: rgba(22,136,232,.065);
  --success: #08a866;
  --success-bg: rgba(8,168,102,.10);
  --success-solid: #07945c;
  --warning: #d58a00;
  --warning-bg: rgba(213,138,0,.10);
  --danger: #db4d5e;
  --danger-bg: rgba(219,77,94,.10);
  --danger-solid: #c63c4d;
  --info: #187bd5;

  --glass-bg: rgba(255,255,255,.80);
  --glass-bg-elevated: rgba(255,255,255,.91);
  --glass-sheen: linear-gradient(180deg, rgba(255,255,255,.92) 0%, rgba(255,255,255,.64) 18%, rgba(255,255,255,.26) 100%);
  --glass-border: rgba(255,255,255,.82);
  --glass-border-top: rgba(255,255,255,.98);
  --glass-border-strong: rgba(255,255,255,.98);
  --glass-highlight: inset 0 1px 0 rgba(255,255,255,.98), inset 0 -1px 0 rgba(73,139,172,.06);
  --glass-shadow: 0 18px 45px rgba(54,105,132,.10), 0 3px 12px rgba(54,105,132,.07);
  --glass-blur: blur(24px) saturate(130%);
  --shadow-sm: 0 3px 10px rgba(43,91,117,.08);
  --shadow-md: 0 16px 38px rgba(43,91,117,.12);
}

html { background: var(--bg); }

body {
  color: var(--text);
  background-color: var(--bg);
  background-image:
    linear-gradient(rgba(239,248,253,.42), rgba(239,248,253,.42)),
    url("../img/nexus-liquid-glass-home-light.png");
  background-size: cover;
  background-position: center center;
  background-repeat: no-repeat;
  background-attachment: fixed;
}

.topbar {
  height: 70px;
  padding: 0 22px;
  background: linear-gradient(180deg, rgba(255,255,255,.88), rgba(255,255,255,.68));
  backdrop-filter: var(--glass-blur);
  -webkit-backdrop-filter: var(--glass-blur);
  border-bottom: 1px solid rgba(255,255,255,.96);
  box-shadow: 0 7px 24px rgba(43,91,117,.08);
}

.brand-logo { height: 32px; }

.topbar-search {
  max-width: 430px;
  margin-left: 10px;
  background: rgba(255,255,255,.76);
  border: 1px solid rgba(255,255,255,.94);
  border-radius: 12px;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.98), 0 5px 18px rgba(47,96,122,.07);
}
.topbar-search input {
  background: transparent;
  border: 0;
  color: var(--text);
  padding-top: 9px;
  padding-bottom: 9px;
}
.topbar-search input:focus { box-shadow: none; }
.topbar-search:focus-within {
  background: rgba(255,255,255,.90);
  border-color: rgba(22,136,232,.28);
  box-shadow: 0 0 0 3px rgba(22,136,232,.07), inset 0 1px 0 rgba(255,255,255,.98);
}
.topbar-search-icon { stroke: #638095; }

.user-info { color: #60798a; }
.user-copy strong { color: #17354b; }
.user-copy span { color: #718a9a; }
.topbar .user-info a { color: #587184; border-left-color: rgba(58,101,124,.14); }
.topbar .user-info a:hover { color: var(--primary); }
.user-avatar { background: rgba(22,136,232,.08); border-color: rgba(22,136,232,.14); color: #0879d6; }

.app-shell { min-height: calc(100vh - 70px); }

.sidebar {
  width: 230px;
  top: 70px;
  height: calc(100vh - 70px);
  padding: 14px 10px;
  background: linear-gradient(180deg, rgba(255,255,255,.88), rgba(245,251,254,.72));
  backdrop-filter: var(--glass-blur);
  -webkit-backdrop-filter: var(--glass-blur);
  border-right: 1px solid rgba(255,255,255,.96);
  box-shadow: 10px 0 30px rgba(43,91,117,.07);
}
.sidebar-caption { color: #7891a0; }
.sidebar-link { color: #19384e; border-left-color: transparent; }
.sidebar-link:hover { background: rgba(255,255,255,.72); color: #0e3048; }
.sidebar-link.active {
  color: #0879d6;
  background: linear-gradient(180deg, rgba(255,255,255,.94), rgba(222,241,253,.76));
  border-left-color: #1688e8;
  box-shadow: inset 0 0 0 1px rgba(22,136,232,.13), 0 7px 18px rgba(22,136,232,.08);
}
.sidebar-link.active .nav-icon { color: #1688e8; }
.sidebar-link-disabled { color: #9bafbb; }
.sidebar-link-disabled:hover { background: transparent; color: #9bafbb; }

.container { padding: 30px 32px 40px; }
.page-head h1, h1 { color: #102d44; }
.card h2 { color: #17364e; }
.hint, .breadcrumb, .breadcrumb a { color: #607b8d; }

/* All major panels: lighter, more opaque glass for reliable text contrast. */
.card,
.hub-tile,
.home-dashboard-block,
.home-tournee-card {
  background: var(--glass-sheen), var(--glass-bg) !important;
  backdrop-filter: var(--glass-blur);
  -webkit-backdrop-filter: var(--glass-blur);
  border: 1px solid var(--glass-border);
  border-top-color: var(--glass-border-top);
  border-radius: 18px;
  box-shadow: var(--glass-shadow), var(--glass-highlight);
}
.card:hover, .hub-tile:hover { border-color: rgba(255,255,255,.98); }

/* Home dashboard: avoid the previous dark translucent override entirely. */
body:has(.home-dashboard-grid) .home-dashboard-block {
  background: var(--glass-sheen), rgba(255,255,255,.79) !important;
  color: var(--text);
}
.home-dashboard-grid { gap: 18px; }
.home-dashboard-block { height: 303px; }
.home-dashboard-block h2 { margin-bottom: 12px; }
.home-mini-list { color: #18384f; }
.home-mini-list li { border-color: rgba(56,105,130,.10); }
.home-progress-label { color: #284a61; }

/* Progress tracks and status pills are toned down so they don't dominate. */
.progress-bar {
  height: 12px;
  border-radius: 999px;
  background: rgba(80,126,151,.12);
  box-shadow: inset 0 1px 2px rgba(36,80,103,.08);
}
.progress-bar-fill { border-radius: 999px; }
.progress-bar-segment { border-radius: 999px; }
.progress-bar-segment-rouge { background: linear-gradient(180deg, #e96a79, #cf4556); }
.progress-bar-segment-vert { background: linear-gradient(180deg, #35c785, #0ca96a); }
.progress-bar-segment-bleu { background: linear-gradient(180deg, #58a5ee, #247dce); }
.progress-bar-label, .progress-bar-segment-label { font-size: .70em; }

/* Inputs / selects: white acrylic controls with clear boundaries. */
input, select, textarea, .admin-inline-select {
  background: rgba(255,255,255,.88);
  color: #17384f;
  border-color: rgba(50,99,124,.16);
  border-radius: 10px;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.96);
}
input:focus, select:focus, textarea:focus {
  border-color: rgba(22,136,232,.48);
  box-shadow: 0 0 0 3px rgba(22,136,232,.08), inset 0 1px 0 rgba(255,255,255,.98);
}

button, .button {
  border-radius: 10px;
  background: linear-gradient(180deg, #3aa2f3, #1688e8);
  border-color: rgba(255,255,255,.72);
  box-shadow: 0 7px 17px rgba(22,136,232,.15), inset 0 1px 0 rgba(255,255,255,.42);
}
button:hover, .button:hover { background: linear-gradient(180deg, #4aacf5, #0f7fdc); }
button.secondary, .button.secondary {
  background: rgba(255,255,255,.74);
  color: #244a62;
  border-color: rgba(45,96,123,.16);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.98), 0 4px 12px rgba(38,83,102,.05);
}
button.secondary:hover, .button.secondary:hover { background: rgba(255,255,255,.94); color: #0879d6; }

.data-table th { background: rgba(233,244,249,.94); color: #557184; }
.data-table td { border-bottom-color: rgba(52,101,127,.11); color: #24475d; }
.data-table tbody tr:hover { background: rgba(255,255,255,.64); }
.table-scroll { border-color: rgba(50,99,124,.13); }

.dropzone { background: rgba(255,255,255,.60); border-color: rgba(50,99,124,.18); }
.dropzone:hover, .dropzone.dropzone-active { background: rgba(255,255,255,.82); border-color: rgba(22,136,232,.40); }

.pp-dialog, .topbar-search-results, .pb-palette {
  background: var(--glass-sheen), var(--glass-bg-elevated);
  backdrop-filter: var(--glass-blur);
  -webkit-backdrop-filter: var(--glass-blur);
  color: #17384f;
  border-color: rgba(255,255,255,.96);
  box-shadow: var(--glass-shadow), var(--glass-highlight);
}
.pp-dialog::backdrop { background: rgba(31,69,88,.16); backdrop-filter: blur(5px); }

.locked-notice { background: rgba(255,255,255,.66); border-color: rgba(50,99,124,.16); color: #48677a; }
.section-nav-btn { background: rgba(255,255,255,.68); color: #244a62; border-color: rgba(50,99,124,.15); }
.section-nav-btn:hover { background: rgba(255,255,255,.92); color: #0879d6; }
.pc-collapsible summary { background: rgba(255,255,255,.62); color: #244a62; }
.pc-collapsible summary:hover { background: rgba(255,255,255,.88); }

/* Status chips remain saturated only where the status itself matters. */
.badge, .home-passage-tag, .pp-recap-chip {
  box-shadow: inset 0 1px 0 rgba(255,255,255,.68), 0 2px 7px rgba(42,87,108,.06);
}

@media (max-width: 720px) {
  .topbar { height: 62px; padding: 0 12px; }
  .app-shell { min-height: calc(100vh - 62px); }
  .sidebar { top: 62px; height: calc(100vh - 62px); }
  .container { padding: 22px 16px 30px; }
  body { background-position: center center; background-size: auto 100%; }
}
