/* Réinitialisation et mise en page globale du portail — le détail des couleurs vit dans theme.css. */

* {
  box-sizing: border-box;
}

html, body {
  margin: 0;
  padding: 0;
  height: 100%;
  font-family: var(--font-sans);
  background: var(--surface-page);
  color: var(--text-primary);
}

a {
  color: var(--accent-primary);
  text-decoration: none;
}

a:hover {
  color: var(--accent-primary-hover);
}

button {
  font-family: inherit;
}

#app {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}

.content {
  flex: 1;
  padding: 24px 32px;
}

/*
  Chrome de la barre de menu et de l'UI d'erreur Blazor. Volontairement ici plutôt qu'en CSS
  scopé (MainLayout.razor.css) : le bundle de CSS scopé (*.styles.css) ne se sert pas
  correctement en dev dans ce montage (PortalApp héberge un projet WASM référencé sans
  wwwroot propre) — il répond 503, donc tout style scopé était silencieusement ignoré. Voir
  docs/Conception/Implémentation.md.
*/

.top-menu {
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 0 24px;
  height: 56px;
  background: var(--surface-panel);
  border-bottom: 1px solid var(--border-default);
  flex: none;
}

.top-menu .brand {
  font-weight: 700;
  letter-spacing: 0.02em;
  color: var(--text-primary);
  margin-right: 24px;
}

.top-menu .brand .shu {
  color: var(--accent-primary);
}

.top-menu nav {
  display: flex;
  gap: 4px;
}

.top-menu nav a {
  color: var(--text-secondary);
  padding: 8px 14px;
  border-radius: 6px;
  font-size: 14px;
}

.top-menu nav a:hover {
  color: var(--text-primary);
  background: var(--surface-panel-raised);
}

.top-menu nav a.active {
  color: var(--text-primary);
  background: var(--surface-panel-raised);
  box-shadow: inset 0 -2px 0 var(--accent-primary);
}

#blazor-error-ui {
  color-scheme: light only;
  background: var(--color-orange);
  color: var(--color-sumi);
  bottom: 0;
  box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.4);
  box-sizing: border-box;
  display: none;
  left: 0;
  padding: 0.6rem 1.25rem 0.7rem 1.25rem;
  position: fixed;
  width: 100%;
  z-index: 1000;
}

#blazor-error-ui .dismiss {
  cursor: pointer;
  position: absolute;
  right: 0.75rem;
  top: 0.5rem;
}

/* Boutons, formulaire inline et tableau — écran Configuration des Runs et suivants. */

.btn-primary, .btn-ghost {
  border: 1px solid var(--border-default);
  border-radius: 6px;
  padding: 8px 16px;
  font-size: 14px;
  cursor: pointer;
}

.btn-primary {
  background: var(--accent-primary);
  border-color: var(--accent-primary);
  color: var(--color-washi);
}

.btn-primary:hover {
  background: var(--accent-primary-hover);
}

.btn-primary:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.btn-ghost {
  background: transparent;
  color: var(--text-secondary);
}

.btn-ghost:hover {
  color: var(--text-primary);
}

.inline-form {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 12px;
}

.inline-form input {
  background: var(--surface-panel);
  border: 1px solid var(--border-default);
  border-radius: 6px;
  padding: 8px 12px;
  color: var(--text-primary);
  font-size: 14px;
}

table.runs-table {
  width: 100%;
  margin-top: 20px;
  border-collapse: collapse;
}

table.runs-table th {
  text-align: left;
  padding: 10px 12px;
  color: var(--text-secondary);
  font-weight: 600;
  border-bottom: 1px solid var(--border-default);
}

table.runs-table td {
  padding: 10px 12px;
  border-bottom: 1px solid var(--color-line);
}

table.runs-table tbody tr {
  cursor: pointer;
}

table.runs-table tbody tr:hover {
  background: var(--surface-panel);
}

/* Composant RunPanel : en-tête, cartes de postes, pop-up (Ajouter un poste / confirmation). */

.btn-danger {
  background: transparent;
  border: 1px solid var(--color-rouge);
  border-radius: 6px;
  padding: 8px 16px;
  font-size: 14px;
  color: var(--color-rouge);
  cursor: pointer;
}

.btn-danger:hover {
  background: var(--color-rouge);
  color: var(--color-washi);
}

.run-header {
  display: flex;
  align-items: center;
  gap: 16px;
  margin-bottom: 20px;
}

.run-header h2 {
  margin: 0;
}

.run-header .run-meta {
  color: var(--text-secondary);
  font-size: 14px;
  flex: 1;
}

.postes-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 16px;
}

.poste-card {
  background: var(--surface-panel);
  border: 1px solid var(--border-default);
  border-radius: 10px;
  padding: 16px;
}

.poste-card-header {
  display: flex;
  align-items: baseline;
  gap: 8px;
  margin-bottom: 10px;
}

.poste-ordre {
  color: var(--accent-primary);
  font-weight: 700;
  font-family: var(--font-mono);
}

.poste-nom {
  font-weight: 600;
}

.poste-nom-editable {
  cursor: pointer;
}

.poste-nom-editable:hover {
  text-decoration: underline;
}

.poste-delete-btn {
  margin-left: auto;
  padding: 4px 12px;
  font-size: 13px;
}

.poste-empty {
  color: var(--text-secondary);
  font-size: 13px;
  margin: 0;
}

/*
  Tableau des tâches d'un poste. Le tableau est préféré à une liste parce que cet écran sert
  d'abord à repérer ce qui manque : une cellule vide dans une colonne alignée se voit, une
  absence de badge dans une liste en vrac non.
*/

.taches-table-wrap {
  overflow-x: auto;
}

/*
  Largeurs fixes : chaque poste a son propre <table>, donc sans cela les colonnes se décalent
  d'une carte à l'autre selon le contenu et l'œil ne peut plus balayer verticalement la page.
*/
table.taches-table {
  width: 100%;
  min-width: 880px;
  table-layout: fixed;
  border-collapse: collapse;
  font-size: 13px;
}

table.taches-table th {
  text-align: left;
  padding: 6px 10px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-secondary);
  border-bottom: 1px solid var(--border-default);
  white-space: nowrap;
}

table.taches-table td {
  padding: 8px 10px;
  vertical-align: top;
  color: var(--text-secondary);
  border-bottom: 1px solid var(--color-line);
}

table.taches-table tbody tr:last-child td {
  border-bottom: none;
}

table.taches-table .col-ordre {
  width: 30px;
  font-family: var(--font-mono);
  text-align: right;
}

table.taches-table .col-budget {
  width: 100px;
  white-space: nowrap;
}

table.taches-table .col-actions {
  width: 34px;
  text-align: right;
}

/* Le nom porte l'action d'édition : il doit ressortir des colonnes de rattachement. */
table.taches-table td:nth-child(2) {
  color: var(--text-primary);
}

table.taches-table th:nth-child(2) { width: 17%; }
table.taches-table th:nth-child(4) { width: 24%; }
table.taches-table th:nth-child(5) { width: 18%; }
table.taches-table th:nth-child(6) { width: 24%; }

.chips {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
}

.chip {
  background: var(--surface-panel-raised);
  border: 1px solid var(--border-default);
  border-radius: 4px;
  padding: 1px 6px;
  font-size: 12px;
  white-space: nowrap;
}

.chip-editable {
  cursor: pointer;
}

.chip-editable:hover {
  color: var(--text-primary);
  border-color: var(--accent-primary);
}

.cell-vide {
  color: var(--border-default);
}

.tache-nom-editable {
  cursor: pointer;
}

.tache-nom-editable:hover {
  text-decoration: underline;
}

.tache-budget {
  color: var(--text-secondary);
  font-family: var(--font-mono);
  font-size: 12px;
}

.tache-delete-btn {
  margin-left: auto;
  background: transparent;
  border: none;
  color: var(--text-secondary);
  cursor: pointer;
  font-size: 13px;
  line-height: 1;
  padding: 2px 4px;
}

.tache-delete-btn:hover {
  color: var(--color-rouge);
}

.poste-add-tache-btn {
  background: transparent;
  border: 1px dashed var(--border-default);
  border-radius: 6px;
  color: var(--text-secondary);
  cursor: pointer;
  font-size: 12px;
  padding: 4px 8px;
  margin-top: 8px;
  align-self: flex-start;
}

.poste-add-tache-btn:hover {
  color: var(--text-primary);
  border-color: var(--accent-primary);
}

.controles-section {
  margin-top: 16px;
}

.controles-section h4 {
  margin: 0 0 8px;
  font-size: 13px;
  color: var(--text-secondary);
}

.controles-list,
.defauts-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.controles-list li,
.defauts-list li {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 13px;
  color: var(--text-secondary);
}

.controle-nom-editable {
  cursor: pointer;
}

.controle-nom-editable:hover {
  text-decoration: underline;
}

.controle-detail {
  color: var(--text-secondary);
  font-family: var(--font-mono);
  font-size: 12px;
}

.controle-hint {
  margin: 4px 0 0;
  color: var(--text-secondary);
  font-size: 12px;
}

.tache-sejour {
  color: var(--accent-primary);
  font-size: 11px;
  border: 1px solid var(--border-default);
  border-radius: 4px;
  padding: 1px 6px;
}

.poste-kanban {
  color: var(--text-secondary);
  font-family: var(--font-mono);
  font-size: 12px;
}

table.runs-table td.cell-actions {
  text-align: right;
  width: 40px;
}

.poste-card-add {
  background: transparent;
  border: 1px dashed var(--border-default);
  border-radius: 10px;
  color: var(--text-secondary);
  cursor: pointer;
  min-height: 80px;
  font-size: 14px;
}

.poste-card-add:hover {
  color: var(--text-primary);
  border-color: var(--accent-primary);
}

.overlay {
  position: fixed;
  inset: 0;
  background: rgba(8, 7, 6, 0.72);
  backdrop-filter: blur(3px);
  z-index: 80;
  display: flex;
  align-items: center;
  justify-content: center;
}

.modal {
  background: var(--surface-panel);
  border: 1px solid var(--border-default);
  border-radius: 16px;
  width: min(480px, calc(100vw - 32px));
  max-height: calc(100vh - 64px);
  overflow-y: auto;
  padding: 24px;
}

.modal h3 {
  margin-top: 0;
}

.modal label {
  display: block;
  font-size: 13px;
  color: var(--text-secondary);
  margin-top: 12px;
}

.modal label input, .modal label select {
  display: block;
  width: 100%;
  margin-top: 4px;
  background: var(--surface-panel-raised);
  border: 1px solid var(--border-default);
  border-radius: 6px;
  padding: 8px 12px;
  color: var(--text-primary);
  font-size: 14px;
}

.modal label select:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

.duree-input {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: 4px;
}

.modal label .duree-input input {
  display: inline-block;
  width: 64px;
  margin-top: 0;
  background: var(--surface-panel-raised);
  border: 1px solid var(--border-default);
  border-radius: 6px;
  padding: 8px 10px;
  color: var(--text-primary);
  font-size: 14px;
}

.duree-input-unit {
  color: var(--text-secondary);
  font-size: 13px;
}

.tache-row {
  display: flex;
  gap: 8px;
  align-items: center;
  margin-top: 8px;
}

.tache-row input {
  background: var(--surface-panel-raised);
  border: 1px solid var(--border-default);
  border-radius: 6px;
  padding: 6px 10px;
  color: var(--text-primary);
  font-size: 13px;
}

.tache-row input:nth-child(1) {
  flex: 2;
}

.tache-row input:nth-child(2), .tache-row input:nth-child(3) {
  flex: 1;
  width: 0;
}

.modal-actions {
  display: flex;
  gap: 8px;
  margin-top: 20px;
}

/* =========================================================================================
   Simulation d'exécution — supervision de ligne et écran de poste.

   Deux publics, deux densités : la supervision est lue de loin par un chef d'équipe qui balaie
   sept postes d'un regard ; l'écran de poste est touché avec des gants, ses cibles ne descendent
   jamais sous 56 px de haut et il n'y a pas un seul champ de saisie libre.
   ========================================================================================= */

.titre-section {
  margin: 20px 0 10px;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-secondary);
}

.refus {
  color: var(--color-rouge);
}

/* --- Supervision ------------------------------------------------------------------------ */

.supervision-header {
  display: flex;
  align-items: center;
  gap: 24px;
  flex-wrap: wrap;
  margin-bottom: 16px;
}

.supervision-header h2 {
  margin: 0;
}

.horloge {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 6px 20px;
  border: 1px solid var(--border-default);
  border-radius: 10px;
  background: var(--surface-panel);
}

.horloge-heure {
  font-family: var(--font-mono);
  font-size: 34px;
  font-weight: 700;
  line-height: 1.1;
  color: var(--text-primary);
}

.horloge-etiquette {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-secondary);
}

.horloge-actions {
  display: flex;
  gap: 8px;
  margin-left: auto;
}

.btn-primary.actif {
  background: var(--color-orange);
  border-color: var(--color-orange);
}

.kpi-bandeau {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: 12px;
}

.kpi {
  background: var(--surface-panel);
  border: 1px solid var(--border-default);
  border-radius: 10px;
  padding: 12px 16px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.kpi-etiquette {
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-secondary);
}

.kpi-valeur {
  font-size: 26px;
  font-weight: 700;
  font-family: var(--font-mono);
}

/* Les sept postes tiennent sur une seule rangée : c'est la ligne de production, la casser en
   deux ferait perdre la lecture du flux. */
.ligne-postes {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(140px, 1fr);
  gap: 10px;
  overflow-x: auto;
  padding-bottom: 6px;
}

.poste-vignette {
  display: flex;
  flex-direction: column;
  gap: 6px;
  align-items: flex-start;
  text-align: left;
  min-height: 150px;
  padding: 12px;
  background: var(--surface-panel);
  border: 1px solid var(--border-default);
  border-top: 4px solid var(--color-gris);
  border-radius: 10px;
  color: var(--text-primary);
  font-family: inherit;
  cursor: pointer;
}

.poste-vignette:hover {
  background: var(--surface-panel-raised);
}

.poste-vignette.poste-vert { border-top-color: var(--color-vert); }
.poste-vignette.poste-orange { border-top-color: var(--color-orange); }
.poste-vignette.poste-rouge { border-top-color: var(--color-rouge); }
.poste-vignette.poste-bloque { border-top-color: var(--color-bleu); }
.poste-vignette.poste-inactif { border-top-color: var(--color-line-strong); }

.poste-vignette-ordre {
  font-family: var(--font-mono);
  font-size: 20px;
  font-weight: 700;
  color: var(--text-secondary);
}

.poste-vignette-nom {
  font-weight: 600;
  font-size: 13px;
  line-height: 1.3;
}

.poste-vignette-badge {
  font-size: 11px;
  padding: 2px 8px;
  border-radius: 999px;
  background: var(--surface-panel-raised);
  color: var(--text-secondary);
}

.poste-vert .poste-vignette-badge { background: var(--color-vert); color: var(--color-washi); }
.poste-orange .poste-vignette-badge { background: var(--color-orange); color: var(--color-sumi); }
.poste-rouge .poste-vignette-badge { background: var(--color-rouge); color: var(--color-washi); }
.poste-bloque .poste-vignette-badge { background: var(--color-bleu); color: var(--color-washi); }

.poste-vignette-vide {
  color: var(--border-default);
}

.poste-vignette-tache {
  display: flex;
  gap: 8px;
  align-items: baseline;
  font-size: 12px;
  width: 100%;
}

.poste-vignette-tache .lot {
  font-family: var(--font-mono);
  color: var(--text-secondary);
}

.chrono {
  font-family: var(--font-mono);
  margin-left: auto;
}

.chrono-vert { color: var(--color-vert); }
.chrono-orange { color: var(--color-orange); }
.chrono-rouge { color: var(--color-rouge); }
.chrono-sejour { color: var(--color-bleu); }

.poste-vignette-pied {
  margin-top: auto;
  font-size: 11px;
  color: var(--text-secondary);
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}

.pastille-lancable {
  color: var(--accent-primary);
}

/* --- Écran de poste --------------------------------------------------------------------- */

.overlay-poste {
  position: fixed;
  inset: 0;
  z-index: 90;
  background: var(--surface-page);
  overflow-y: auto;
}

.ecran-poste {
  padding: 20px 28px 40px;
  max-width: 1400px;
  margin: 0 auto;
}

.ecran-poste-header {
  display: flex;
  align-items: center;
  gap: 24px;
  padding-bottom: 14px;
  border-bottom: 1px solid var(--border-default);
}

.ecran-poste-header h2 {
  margin: 2px 0 0;
  font-size: 26px;
}

.ecran-poste-etape {
  font-size: 12px;
  letter-spacing: 0.08em;
  color: var(--accent-primary);
  font-weight: 700;
}

.ecran-poste-meta {
  margin-left: auto;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  font-size: 12px;
  color: var(--text-secondary);
}

.ecran-poste-heure {
  font-family: var(--font-mono);
  font-size: 22px;
  color: var(--text-primary);
}

.ecran-poste-fermer {
  min-height: 44px;
}

/*
  Grille et non flex : toutes les cartes gardent la même largeur, quelle que soit leur rangée
  (décision François, 2026-09-06). auto-fit plutôt qu'auto-fill pour que cette largeur commune
  s'adapte — deux tâches donnent deux cartes larges, sept en donnent quatre par rangée. Le seul
  vide toléré est celui d'une dernière rangée incomplète : la régularité prime.
*/
.cartes-taches {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 12px;
}

.carte-tache {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 16px;
  background: var(--surface-panel);
  border: 1px solid var(--border-default);
  border-left: 4px solid var(--color-gris);
  border-radius: 12px;
}

.carte-verte { border-left-color: var(--color-vert); }
.carte-orange { border-left-color: var(--color-orange); }
.carte-rouge { border-left-color: var(--color-rouge); }
.carte-sejour { border-left-color: var(--color-bleu); }
.carte-tache-lancable { border-left-color: var(--accent-primary); border-style: dashed; }

.carte-tache-entete {
  display: flex;
  justify-content: space-between;
  font-size: 12px;
  color: var(--text-secondary);
}

.carte-lot {
  font-family: var(--font-mono);
  color: var(--text-primary);
}

.carte-tache-nom {
  font-size: 17px;
  font-weight: 600;
}

.carte-chrono {
  display: flex;
  align-items: baseline;
  gap: 10px;
}

.carte-chrono-valeur {
  font-family: var(--font-mono);
  font-size: 38px;
  font-weight: 700;
  line-height: 1;
}

.carte-verte .carte-chrono-valeur { color: var(--color-vert); }
.carte-orange .carte-chrono-valeur { color: var(--color-orange); }
.carte-rouge .carte-chrono-valeur { color: var(--color-rouge); }
.carte-sejour .carte-chrono-valeur { color: var(--color-bleu); }

.carte-chrono-budget {
  font-size: 12px;
  color: var(--text-secondary);
}

.jauge {
  height: 8px;
  border-radius: 999px;
  background: var(--surface-panel-raised);
  overflow: hidden;
}

.jauge-remplissage {
  height: 100%;
  background: var(--color-gris);
}

.carte-verte .jauge-remplissage { background: var(--color-vert); }
.carte-orange .jauge-remplissage { background: var(--color-orange); }
.carte-rouge .jauge-remplissage { background: var(--color-rouge); }
.carte-sejour .jauge-remplissage { background: var(--color-bleu); }

.carte-tache-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  align-items: center;
  font-size: 12px;
  color: var(--text-secondary);
}

.carte-blocage {
  margin: 0;
  font-size: 12px;
  color: var(--color-bleu);
}

/* Trois actions, trois couleurs, jamais moins de 56 px de haut : utilisables avec des gants. */
.btn-valider, .btn-demarrer, .btn-defaut, .btn-andon {
  min-height: 56px;
  border: none;
  border-radius: 10px;
  font-family: inherit;
  font-size: 17px;
  font-weight: 700;
  letter-spacing: 0.02em;
  cursor: pointer;
  padding: 0 20px;
}

.btn-valider {
  background: var(--color-vert);
  color: var(--color-washi);
}

.btn-valider:disabled {
  background: var(--surface-panel-raised);
  color: var(--text-secondary);
  cursor: not-allowed;
}

.btn-demarrer {
  background: var(--accent-primary);
  color: var(--color-washi);
}

.btn-demarrer:disabled {
  background: var(--surface-panel-raised);
  color: var(--text-secondary);
  cursor: not-allowed;
}

.btn-defaut {
  background: var(--color-orange);
  color: var(--color-sumi);
}

.btn-defaut:disabled {
  background: var(--surface-panel-raised);
  color: var(--text-secondary);
  cursor: not-allowed;
}

.btn-andon {
  background: var(--color-rouge);
  color: var(--color-washi);
}

.liste-bloquees {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.liste-bloquees li {
  display: flex;
  gap: 12px;
  align-items: baseline;
  font-size: 13px;
  padding: 6px 10px;
  background: var(--surface-panel);
  border-radius: 6px;
}

.bloquee-nom {
  color: var(--text-primary);
}

.bloquee-raison {
  margin-left: auto;
  color: var(--color-bleu);
  font-size: 12px;
}

/* --- Sélection tactile ------------------------------------------------------------------ */

.modal-tactile {
  width: min(720px, calc(100vw - 32px));
}

.tuiles {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 8px;
}

.tuile {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 2px;
  min-height: 60px;
  padding: 10px 12px;
  background: var(--surface-panel-raised);
  border: 2px solid transparent;
  border-radius: 10px;
  color: var(--text-primary);
  font-family: inherit;
  text-align: left;
  cursor: pointer;
}

.tuile:hover {
  border-color: var(--border-default);
}

.tuile-active {
  border-color: var(--accent-primary);
  background: var(--surface-panel);
}

.tuile-nom {
  font-size: 15px;
  font-weight: 600;
}

.tuile-code {
  font-family: var(--font-mono);
  font-size: 12px;
  color: var(--text-secondary);
}

.controle-saisie {
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid var(--color-line);
}

.pave {
  display: flex;
  flex-direction: column;
  gap: 8px;
  max-width: 260px;
}

.pave-affichage {
  font-family: var(--font-mono);
  font-size: 30px;
  text-align: right;
  padding: 8px 14px;
  background: var(--surface-panel-raised);
  border: 1px solid var(--border-default);
  border-radius: 8px;
}

.pave-touches {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 6px;
}

.pave-touche {
  min-height: 56px;
  font-size: 20px;
  font-family: var(--font-mono);
  background: var(--surface-panel-raised);
  border: 1px solid var(--border-default);
  border-radius: 8px;
  color: var(--text-primary);
  cursor: pointer;
}

.pave-touche:hover {
  border-color: var(--accent-primary);
}

.pave-effacer {
  color: var(--color-orange);
}

.cadence {
  background: var(--surface-panel-raised);
  border: 1px solid var(--border-default);
  border-radius: 6px;
  padding: 8px 12px;
  color: var(--text-primary);
  font-family: inherit;
  font-size: 13px;
}

/* --- Fil des runs de la journée, en-tête de l'écran de poste -----------------------------

   Chevrons emboîtés pointant vers la droite : la journée se lit comme une progression, du run 1
   au run N. Chaque case dit où en est CE run vis-à-vis de CE poste — le même run est « passé »
   pour le poste 1 et « pas encore là » pour le poste 7.

   La pointe et l'encoche sont découpées au clip-path plutôt que dessinées en bordures : la forme
   reste nette quelle que soit la couleur de fond, et une seule règle suffit pour les cinq états.
*/

.fil-runs {
  display: flex;
  flex: 1;
  align-items: center;
  min-width: 0;
  overflow-x: auto;
  padding: 2px 0;
}

.fil-run {
  /* Les chevrons se partagent la largeur disponible au lieu de garder une taille fixe : le fil
     occupe toute la place entre le nom du poste et l'horloge, quel que soit le nombre de runs.
     Le min-width garde deux chiffres lisibles ; au-delà de ce qu'il permet, le fil défile. */
  flex: 1 1 0;
  min-width: 24px;
  height: 26px;
  padding: 0 6px 0 12px;
  margin-left: -6px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-mono);
  font-size: 11px;
  font-weight: 600;
  line-height: 1;
  background: var(--fil-fond);
  clip-path: polygon(0 0, calc(100% - 7px) 0, 100% 50%, calc(100% - 7px) 100%, 0 100%, 7px 50%);
}

/* Le numéro est positionné pour passer devant le masque de l'anneau pointillé : sans cela le
   pseudo-élément, positionné lui aussi, se peindrait par-dessus le texte. */
.fil-run-numero {
  position: relative;
  z-index: 1;
}

/* Le premier n'a personne devant lui : son bord gauche reste droit. */
.fil-run:first-child {
  margin-left: 0;
  clip-path: polygon(0 0, calc(100% - 7px) 0, 100% 50%, calc(100% - 7px) 100%, 0 100%);
}

/* Cinq états, du plus froid au plus chaud : ce qui est fait s'efface, ce qui appelle une action
   ressort. Le rouge shu est réservé au « prêt à lancer » — c'est la seule case sur laquelle
   l'opérateur a quelque chose à faire. */
.run-nonentre {
  --fil-fond: var(--surface-panel-raised);
  color: var(--color-gris);
}

.run-attente {
  --fil-fond: var(--surface-panel-raised);
  color: var(--color-bleu);
}

.run-pret {
  --fil-fond: var(--accent-primary);
  color: var(--color-washi);
}

.run-encours {
  --fil-fond: var(--color-vert);
  color: var(--color-washi);
}

.run-termine {
  --fil-fond: var(--color-sumi-3);
  color: var(--text-secondary);
  opacity: 0.55;
}

/* Un chevron cliquable est un vrai bouton : il faut annuler le chrome par défaut, sinon il
   déborde de la découpe au clip-path. */
button.fil-run {
  border: none;
  font-family: var(--font-mono);
  cursor: pointer;
}

button.fil-run:hover {
  filter: brightness(1.25);
}

/* Le run choisi porte un liseré pointillé qui tourne lentement autour du chevron, pour rester
   repérable d'un coup d'œil dans un ruban de vingt-cinq.

   Ni border ni box-shadow : le clip-path qui découpe le chevron emporte l'un comme l'autre. Le
   liseré est donc reconstitué en deux couches, et c'est le clip-path du parent — qui s'applique à
   tout son sous-arbre, pseudo-éléments compris — qui leur donne la forme du chevron :

     1. le fond du chevron reçoit un dégradé conique de pointillés, par-dessus sa couleur d'état ;
     2. ::after recouvre l'intérieur, en retrait de 3 px, avec cette même couleur d'état.

   Ne subsiste que l'anneau de 3 px, où les pointillés sont visibles. Le dégradé étant conique, le
   faire pivoter fait tourner les pointillés autour du chevron.

   L'angle passe par une propriété enregistrée : une variable ordinaire ne s'anime pas, le navigateur
   ne sachant pas qu'elle contient un angle. Là où @property manque, la valeur initiale reste lue et
   le liseré s'affiche, immobile. */
@property --fil-angle {
  syntax: "<angle>";
  inherits: false;
  initial-value: 0deg;
}

.run-choisi {
  outline: none;
  position: relative;
  background:
    repeating-conic-gradient(
      from var(--fil-angle, 0deg) at 50% 50%,
      var(--color-washi) 0deg 8deg,
      transparent 8deg 16deg),
    var(--fil-fond);
  animation: rotation-pointilles 8s linear infinite;
}

.run-choisi::after {
  content: "";
  position: absolute;
  /* Le retrait donne l'épaisseur du liseré. clip-path: inherit reprend le polygone du parent, y
     compris la variante à bord gauche droit du premier chevron, et ses pourcentages se résolvent
     sur cette boîte plus petite : la pointe reste une pointe. */
  inset: 3px;
  clip-path: inherit;
  background: var(--fil-fond);
}

@keyframes rotation-pointilles {
  to {
    --fil-angle: 360deg;
  }
}

/* Les systèmes réglés pour limiter les animations gardent le liseré, mais fixe. */
@media (prefers-reduced-motion: reduce) {
  .run-choisi {
    animation: none;
  }
}

.filtre-actif {
  display: flex;
  align-items: center;
  gap: 16px;
  margin-top: 14px;
  padding: 8px 14px;
  background: var(--surface-panel);
  border-left: 3px solid var(--accent-primary);
  border-radius: 6px;
  font-size: 13px;
  color: var(--text-secondary);
}

/* Les quatre états d'une carte de tâche. La carte ne bouge jamais de place : seuls son liseré et
   son bouton changent, pour que l'opérateur retrouve la même tâche au même endroit du début à la
   fin du run. */

.carte-attente {
  border-left-color: var(--color-gris);
}

.carte-terminee {
  border-left-color: var(--color-vert);
  opacity: 0.5;
}

/* Bouton d'une tâche validée : vert, mais éteint. Il dit ce qui a été fait, il n'appelle plus
   d'action — d'où la couleur conservée et le contraste abaissé. */
.btn-termine {
  min-height: 56px;
  border: none;
  border-radius: 10px;
  font-family: inherit;
  font-size: 17px;
  font-weight: 700;
  letter-spacing: 0.02em;
  padding: 0 20px;
  background: color-mix(in srgb, var(--color-vert) 30%, transparent);
  color: var(--color-vert);
  cursor: default;
}

/* =========================================================================================
   Écran de poste sur tablette murale 1920×1080.

   L'opérateur est à plusieurs mètres, debout, parfois ganté : rien ne doit demander de
   s'approcher pour lire, ni de viser pour toucher. D'où trois partis pris qui gouvernent tout
   ce bloc :

   1. Plein cadre — la page occupe exactement la hauteur de l'écran, jamais plus : ce qui compte
      doit être visible sans défiler, et le pied (DÉFAUT / ANDON) reste toujours au même endroit.
   2. Tailles doublées par rapport au poste de bureau — les valeurs de base servent encore aux
      écrans de configuration, elles ne sont donc pas modifiées mais surchargées ici.
   3. Cibles de 84 px — un bouton se touche sans viser.
   ========================================================================================= */

.overlay-poste {
  overflow: hidden;
}

.ecran-poste {
  height: 100%;
  max-width: none;
  margin: 0;
  padding: 22px 32px 26px;
  display: flex;
  flex-direction: column;
  gap: 18px;
}

/* La liste des tâches absorbe la place restante ; seule la zone interne défile si un poste en
   compte beaucoup, l'en-tête, le titre et le pied restant fixes. */
.ecran-poste .ecran-bloc {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
}

.ecran-poste-header {
  gap: 32px;
  padding-bottom: 18px;
}

.ecran-poste-etape {
  font-size: 17px;
  letter-spacing: 0.1em;
}

.ecran-poste-header h2 {
  font-size: 40px;
  margin-top: 4px;
}

.ecran-poste-heure {
  font-size: 40px;
  line-height: 1.1;
}

.ecran-poste-meta {
  font-size: 17px;
  gap: 2px;
}

.ecran-poste-fermer {
  min-height: 60px;
  font-size: 18px;
  padding: 0 22px;
}

/* Le fil des runs doit rester lisible de loin : des chevrons deux fois plus hauts et des
   numéros à 18 px, quitte à ce que le fil défile au-delà d'une trentaine de runs. */
.ecran-poste .fil-runs {
  padding: 4px 0 8px;
}

/* Le cadre du fil se comporte comme les autres zones défilantes, mais sur l'axe horizontal. */
.fil-cadre {
  flex: 1;
  min-width: 0;
  align-items: center;
}

.fil-ancre {
  display: inline-block;
  width: 0;
  outline: none;
  scroll-margin-left: 12px;
  scroll-margin-right: 12px;
}

.ecran-poste .fil-run {
  height: 44px;
  min-width: 40px;
  font-size: 18px;
  padding: 0 12px;
  margin-left: -8px;
  clip-path: polygon(0 0, calc(100% - 10px) 0, 100% 50%, calc(100% - 10px) 100%, 0 100%, 10px 50%);
}

.ecran-poste .fil-run:first-child {
  margin-left: 0;
  clip-path: polygon(0 0, calc(100% - 10px) 0, 100% 50%, calc(100% - 10px) 100%, 0 100%);
}

.ecran-poste .titre-section {
  font-size: 17px;
  margin: 0 0 14px;
}

/* Quatre cartes de front sur 1920, deux rangées pour les sept pesées d'un run. */
.ecran-poste .cartes-taches {
  gap: 18px;
}

.ecran-poste .carte-tache {
  padding: 22px 24px;
  gap: 12px;
  border-left-width: 6px;
  border-radius: 14px;
}

.ecran-poste .carte-tache-entete {
  font-size: 16px;
}

.ecran-poste .carte-tache-nom {
  font-size: 27px;
  line-height: 1.2;
}

.ecran-poste .carte-chrono-valeur {
  font-size: 58px;
}

.ecran-poste .carte-chrono-budget {
  font-size: 17px;
}

.ecran-poste .jauge {
  height: 12px;
}

.ecran-poste .carte-tache-meta {
  font-size: 16px;
  gap: 10px;
}

.ecran-poste .carte-tache-meta .chip,
.ecran-poste .carte-tache-meta .tache-sejour {
  font-size: 15px;
  padding: 3px 10px;
}

.ecran-poste .carte-blocage {
  font-size: 17px;
}

/* Les cibles. 84 px de haut : on touche sans viser, avec des gants. */
.ecran-poste .btn-valider,
.ecran-poste .btn-demarrer,
.ecran-poste .btn-termine,
.ecran-poste .btn-defaut,
.ecran-poste .btn-andon {
  min-height: 84px;
  font-size: 25px;
  border-radius: 12px;
}

/* Les pop-ups vivent hors de .ecran-poste dans le DOM : elles se dimensionnent seules, mais
   servent le même écran et le même geste. */
.modal-tactile {
  width: min(1000px, calc(100vw - 48px));
  padding: 32px;
}

.modal-tactile h3 {
  font-size: 30px;
}

.modal-tactile .titre-section {
  font-size: 17px;
}

.modal-tactile .controle-hint {
  font-size: 17px;
}

.modal-tactile .tuiles {
  grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
  gap: 12px;
}

.modal-tactile .tuile {
  min-height: 84px;
  padding: 14px 18px;
}

.modal-tactile .tuile-nom {
  font-size: 20px;
}

.modal-tactile .tuile-code {
  font-size: 15px;
}

.modal-tactile .btn-valider,
.modal-tactile .btn-demarrer {
  min-height: 84px;
  font-size: 25px;
  border-radius: 12px;
}

.modal-tactile .btn-ghost {
  min-height: 84px;
  font-size: 20px;
  padding: 0 28px;
}

.modal-tactile .pave {
  max-width: 340px;
}

.modal-tactile .pave-affichage {
  font-size: 38px;
  padding: 10px 18px;
}

.modal-tactile .pave-touche {
  min-height: 76px;
  font-size: 26px;
}

/* --- Alignement des cartes entre elles ---------------------------------------------------

   Toutes les lignes d'une carte occupent leur place, renseignées ou non : une tâche sans nature
   de temps, sans équipement ou sans motif de blocage laisse la ligne vide plutôt que de la
   supprimer. Sans cela, deux cartes voisines n'ont pas leur bouton au même niveau et la rangée
   part en escalier.
*/

.carte-tache-meta {
  min-height: 24px;
}

.carte-blocage {
  min-height: 18px;
}

/* Le bouton est le point d'ancrage du regard et du doigt : il reste collé en bas, quelle que
   soit la longueur du nom de la tâche au-dessus. */
.carte-tache > button {
  margin-top: auto;
}

.ecran-poste .carte-tache-meta {
  min-height: 30px;
}

.ecran-poste .carte-blocage {
  min-height: 22px;
}

/* Même logique pour les vignettes de la supervision : les noms de poste vont d'un mot à trois
   lignes, le reste de la vignette ne doit pas suivre ces variations. */
.poste-vignette-nom {
  min-height: 34px;
}

/* --- Supervision sur écran mural ---------------------------------------------------------

   Même contrainte que l'écran de poste : la vue est lue de loin et doit remplir la page. Les
   vignettes prennent la hauteur restante au lieu de laisser la moitié de l'écran vide.
*/

.supervision {
  display: flex;
  flex-direction: column;
  gap: 16px;
  /* Hauteur de la fenêtre moins tout ce qui la précède : barre de menu (56), marges hautes et
     basses du contenu (2 × 24) et bouton « Retour aux journées » (≈ 41). Sans ce dernier terme la
     page dépassait de quelques dizaines de pixels et affichait un ascenseur général. */
  min-height: calc(100vh - 56px - 48px - 41px);
}

.supervision .ligne-postes {
  flex: 1;
  align-items: stretch;
}

.supervision-header h2 {
  font-size: 32px;
}

.horloge-heure {
  font-size: 44px;
}

.horloge-etiquette,
.kpi-etiquette {
  font-size: 14px;
}

.kpi-valeur {
  font-size: 38px;
}

.poste-vignette {
  padding: 16px;
  gap: 8px;
}

.poste-vignette-ordre {
  font-size: 30px;
}

.poste-vignette-nom {
  font-size: 18px;
  min-height: 48px;
}

.poste-vignette-badge {
  font-size: 15px;
  padding: 4px 12px;
}

.poste-vignette-tache {
  font-size: 17px;
}

.poste-vignette-pied {
  font-size: 15px;
  gap: 8px;
}

.cadence,
.horloge-actions .btn-primary,
.horloge-actions .btn-ghost {
  min-height: 48px;
  font-size: 16px;
}

/* Compactage vertical : sept tâches font deux rangées, et les deux doivent tenir dans la page
   sans défiler. On rogne sur les marges et sur le chronomètre, jamais sur la taille des cibles
   ni sur le nom de la tâche — ce sont eux qui doivent rester lisibles de loin. */
.ecran-poste .cartes-taches {
  gap: 14px;
}

.ecran-poste .carte-tache {
  padding: 14px 20px;
  gap: 8px;
}

.ecran-poste .carte-tache-nom {
  font-size: 24px;
}

.ecran-poste .carte-chrono-valeur {
  font-size: 46px;
}

.ecran-poste .carte-tache-meta {
  min-height: 26px;
}

/* --- Colonne « en cours et à venir » -----------------------------------------------------

   Le travail à gauche, ce qui arrive à droite. La colonne est purement informative : rien n'y
   est cliquable, elle répond à la seule question « qu'est-ce qui me tombe dessus après ». Sa
   largeur est fixe pour que la zone de travail ne se rétrécisse pas quand un run entre ou sort.
*/

.ecran-corps {
  flex: 1;
  min-height: 0;
  display: grid;
  grid-template-columns: 1fr 340px;
  gap: 22px;
}

.ecran-poste .ecran-corps .ecran-bloc {
  min-height: 0;
}

.ecran-apercu {
  /* flex: 1 indispensable : le cadre qui porte les flèches est un conteneur flex en ligne, sans
     quoi la colonne se réduit à la largeur de son texte et laisse une bande vide à droite. */
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 12px;
  min-height: 0;
  overflow-y: auto;
}

.apercu-carte {
  background: var(--surface-panel);
  border: 1px solid var(--border-default);
  border-left: 6px solid var(--color-gris);
  border-radius: 12px;
  padding: 14px 16px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

/* Le run sur lequel on travaille se distingue de ceux qui arrivent : c'est le seul dont les
   tâches sont à l'écran, il ne doit pas se confondre avec une prévision. Un simple fond plus clair
   ne suffisait pas — d'où le contour franc, qui répond au chevron sélectionné dans le fil. */
.apercu-courant {
  background: var(--surface-panel-raised);
  box-shadow: inset 0 0 0 2px var(--color-washi);
}

/* Le liseré reprend les couleurs du fil des runs : même code, même sens. */
.apercu-carte.run-termine { border-left-color: var(--color-vert); }
.apercu-carte.run-encours { border-left-color: var(--color-vert); }
.apercu-carte.run-pret { border-left-color: var(--accent-primary); }
.apercu-carte.run-attente { border-left-color: var(--color-bleu); }
.apercu-carte.run-nonentre { border-left-color: var(--color-gris); }

/* Les classes du fil portent aussi un fond et une opacité, inutiles ici. */
.apercu-carte.run-termine,
.apercu-carte.run-encours,
.apercu-carte.run-pret,
.apercu-carte.run-attente,
.apercu-carte.run-nonentre {
  color: var(--text-primary);
  opacity: 1;
}

.apercu-entete {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
}

.apercu-numero {
  font-size: 22px;
  font-weight: 700;
}

.apercu-badge {
  font-size: 14px;
  color: var(--text-secondary);
  text-align: right;
}

.apercu-lot {
  font-family: var(--font-mono);
  font-size: 16px;
  color: var(--text-secondary);
}

.apercu-ligne {
  font-size: 16px;
  color: var(--text-secondary);
}

.apercu-avancement {
  font-family: var(--font-mono);
}

/* Réservée même vide, comme les lignes des cartes de tâches : les trois cartes gardent la même
   hauteur, qu'un run attende quelque chose ou non. */
.apercu-attente {
  min-height: 22px;
  font-size: 15px;
  color: var(--color-bleu);
}

/* La colonne d'aperçu prend 340 px sur la largeur : les cartes de tâches sont resserrées pour
   rester à quatre de front, donc deux rangées pour les sept tâches d'un run — sans quoi une
   troisième rangée apparaît et l'écran se remet à défiler.

   La largeur minimale de 350 px donne quatre cartes de front sur 1920. */
.ecran-poste .cartes-taches {
  grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));
}

/* La carte d'aperçu est un bouton pleine surface : sur une tablette, on touche la carte, pas un
   lien qu'il faudrait viser dedans. Les styles de bouton par défaut sont donc annulés. */
button.apercu-carte {
  width: 100%;
  text-align: left;
  font-family: inherit;
  cursor: pointer;
}

button.apercu-carte:disabled {
  cursor: default;
}

button.apercu-carte:not(:disabled):hover {
  border-color: var(--accent-primary);
}

.apercu-carte .apercu-lot,
.apercu-carte .apercu-ligne,
.apercu-carte .apercu-attente {
  display: block;
}

/* Le run affiché est déjà à l'écran : sa carte le rappelle sans inviter à le rouvrir. */
.apercu-courant {
  cursor: default;
}

/* Ancre de recentrage : sans dimension, elle marque seulement l'endroit où ramener la vue.
   La marge de défilement laisse la carte respirer sous le titre de la colonne. */
.apercu-ancre {
  display: block;
  height: 0;
  outline: none;
  scroll-margin-top: 8px;
}

/* Cause 2 : l'écran de poste couvre la page mais ne l'empêchait pas de défiler derrière lui.
   Sur une tablette murale, la page entière ne doit jamais défiler — l'opérateur ne va pas au mur
   pour faire glisser un écran. Seules les zones qui portent une action (les tâches, la liste des
   runs) ont le droit à un ascenseur interne. */
body:has(.overlay-poste) {
  overflow: hidden;
}

/* --- Ascenseurs internes -----------------------------------------------------------------

   Les barres natives de Windows jurent avec le reste : blanches, larges, en relief. On les
   reprend aux couleurs de l'application. Deux syntaxes : la standard (Firefox, Chrome 121+) et
   celle des moteurs WebKit/Blink, qui seule permet d'arrondir et de marger la poignée.
*/

.zone-defilante,
.taches-table-wrap,
.ligne-postes,
.modal {
  scrollbar-width: thin;
  scrollbar-color: var(--color-line-strong) transparent;
}

.zone-defilante::-webkit-scrollbar,
.taches-table-wrap::-webkit-scrollbar,
.ligne-postes::-webkit-scrollbar,
.modal::-webkit-scrollbar {
  width: 10px;
  height: 10px;
}

.zone-defilante::-webkit-scrollbar-track,
.taches-table-wrap::-webkit-scrollbar-track,
.ligne-postes::-webkit-scrollbar-track,
.modal::-webkit-scrollbar-track {
  background: transparent;
}

.zone-defilante::-webkit-scrollbar-thumb,
.taches-table-wrap::-webkit-scrollbar-thumb,
.ligne-postes::-webkit-scrollbar-thumb,
.modal::-webkit-scrollbar-thumb {
  background: var(--color-line-strong);
  border-radius: 999px;
  /* La bordure transparente amincit la poignée sans réduire la zone de préhension : sur une
     tablette, on attrape encore une bande de 10 px. */
  border: 3px solid transparent;
  background-clip: padding-box;
}

.zone-defilante::-webkit-scrollbar-thumb:hover,
.taches-table-wrap::-webkit-scrollbar-thumb:hover,
.ligne-postes::-webkit-scrollbar-thumb:hover,
.modal::-webkit-scrollbar-thumb:hover {
  background: var(--color-gris);
  background-clip: padding-box;
}

.zone-defilante::-webkit-scrollbar-corner {
  background: transparent;
}

/* Sitôt qu'on redéfinit ::-webkit-scrollbar, Chrome réintroduit ses deux boutons fléchés aux
   extrémités de la barre. Gris système, minuscules, ils n'ont pas leur place sur une tablette. */
.zone-defilante::-webkit-scrollbar-button,
.taches-table-wrap::-webkit-scrollbar-button,
.ligne-postes::-webkit-scrollbar-button,
.modal::-webkit-scrollbar-button {
  display: none;
}

/* --- Repères de défilement de la colonne des runs -----------------------------------------

   Deux chevrons aplatis, l'un en haut l'autre en bas, qui n'apparaissent que s'il reste
   vraiment quelque chose à voir de ce côté. Ils sont posés en surimpression sur la zone et ne
   captent pas le doigt : ce sont des repères, pas des boutons.
*/

.ecran-apercu-zone {
  position: relative;
  display: flex;
  flex-direction: column;
  min-height: 0;
}

/* Cadre sans le titre : les repères se positionnent sur la zone défilante elle-même, et non
   sur l'ensemble du bloc — sinon leur place dépendrait de la hauteur du titre. Le même cadre sert
   à la liste des tâches et à la colonne des runs. */
.zone-defilante-cadre {
  position: relative;
  flex: 1;
  min-height: 0;
  display: flex;
}

.zone-defilante {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
}

.fil-cadre .zone-defilante {
  overflow-x: auto;
  overflow-y: hidden;
}

.fleche-defilement {
  position: absolute;
  left: 0;
  right: 10px;
  height: 30px;
  pointer-events: none;
  opacity: 0;
  transition: opacity 120ms ease;
}

/* Le chevron lui-même : un triangle volontairement écrasé (28 × 7), assez large pour se voir de
   loin, assez plat pour ne pas manger la carte qu'il recouvre. */
.fleche-defilement::after {
  content: "";
  position: absolute;
  left: 50%;
  width: 34px;
  height: 9px;
  margin-left: -17px;
  background: var(--text-primary);
}

.fleche-defilement-haut {
  top: 0;
  background: linear-gradient(to bottom, var(--surface-page) 55%, transparent);
}

.fleche-defilement-haut::after {
  top: 3px;
  clip-path: polygon(50% 0, 100% 100%, 0 100%);
}

.fleche-defilement-bas {
  bottom: 0;
  background: linear-gradient(to top, var(--surface-page) 55%, transparent);
}

.fleche-defilement-bas::after {
  bottom: 3px;
  clip-path: polygon(0 0, 100% 0, 50% 100%);
}

/* Le script pose ces deux classes sur la zone : le chevron correspondant se révèle. */
.zone-defilante.a-plus-haut ~ .fleche-defilement-haut,
.zone-defilante.a-plus-bas ~ .fleche-defilement-bas {
  opacity: 1;
}

/* Repères horizontaux : mêmes règles que les verticaux, tournés d'un quart de tour. */
.fleche-defilement-gauche,
.fleche-defilement-droite {
  top: 0;
  bottom: 0;
  left: auto;
  right: auto;
  height: auto;
  width: 26px;
}

.fleche-defilement-gauche {
  left: 0;
  background: linear-gradient(to right, var(--surface-page) 55%, transparent);
}

.fleche-defilement-droite {
  right: 0;
  background: linear-gradient(to left, var(--surface-page) 55%, transparent);
}

.fleche-defilement-gauche::after,
.fleche-defilement-droite::after {
  top: 50%;
  left: auto;
  width: 9px;
  height: 34px;
  margin-left: 0;
  margin-top: -17px;
}

.fleche-defilement-gauche::after {
  left: 3px;
  clip-path: polygon(100% 0, 100% 100%, 0 50%);
}

.fleche-defilement-droite::after {
  right: 3px;
  clip-path: polygon(0 0, 0 100%, 100% 50%);
}

.zone-defilante.a-plus-gauche ~ .fleche-defilement-gauche,
.zone-defilante.a-plus-droite ~ .fleche-defilement-droite {
  opacity: 1;
}

/* --- Identification de l'opérateur -------------------------------------------------------

   Seul écran de la simulation où l'on ne travaille pas : il est centré, dépouillé, et n'offre
   qu'une action. Le pavé y est plus grand qu'ailleurs — c'est le premier geste de la prise de
   poste, souvent fait avec des gants.
*/

.connexion {
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 18px;
  padding: 32px;
}

.connexion-entete {
  text-align: center;
}

.connexion-entete h2 {
  margin: 4px 0 0;
  font-size: 40px;
}

.connexion-consigne {
  margin: 0;
  font-size: 22px;
  color: var(--text-secondary);
}

.connexion .pave {
  max-width: 400px;
  width: 100%;
  gap: 14px;
}

.connexion .pave-touche {
  min-height: 96px;
  font-size: 32px;
}

/* Les pastilles remplacent les chiffres : on voit qu'un appui a été pris, jamais lequel. */
.connexion .pave-affichage {
  font-size: 44px;
  letter-spacing: 0.35em;
  text-align: center;
  padding: 14px 20px 14px 34px;
}

.pave-masque {
  color: var(--text-primary);
}

/* Réservée en permanence : sans cela, l'apparition du message décalerait le pavé sous les doigts
   au moment précis où l'opérateur s'apprête à retaper son code. */
.connexion-erreur {
  margin: 0;
  min-height: 30px;
  font-size: 20px;
  font-weight: 600;
  color: var(--color-rouge);
}

.connexion-retour {
  min-height: 56px;
  font-size: 17px;
}

/* --- Opérateur en poste ------------------------------------------------------------------ */

.ecran-poste-operateur {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 2px;
  min-height: 60px;
  padding: 0 18px;
}

.operateur-nom {
  font-size: 19px;
  font-weight: 600;
  color: var(--text-primary);
}

.operateur-action {
  font-size: 13px;
  color: var(--text-secondary);
}

/* Passage d'un run au suivant : un arrêt franc, centré, avec une seule action. C'est le seul
   moment où l'écran interrompt le travail pour annoncer quelque chose. */
.modal-transition {
  width: min(620px, calc(100vw - 48px));
  text-align: center;
}

.modal-transition h3 {
  font-size: 30px;
  margin: 12px 0 0;
}

.transition-marque {
  display: block;
  font-size: 56px;
  line-height: 1;
  color: var(--color-vert);
}

.transition-suite {
  font-size: 22px;
  color: var(--text-secondary);
  margin: 10px 0 0;
}

.transition-suite strong {
  color: var(--text-primary);
}

/* Les pop-ups tactiles sont regardées de loin et visées au doigt : leurs boutons sont centrés,
   sous le contenu qu'ils valident, plutôt que rangés dans un coin. Vaut pour le choix de
   l'équipement, la validation, le constat de défaut et le passage au run suivant. */
.modal-tactile .modal-actions {
  justify-content: center;
}

.modal-transition .btn-valider {
  min-width: 280px;
}

/* --- Constat de défaut -------------------------------------------------------------------

   Le défaut se constate à la tâche : son bouton vit dans la carte, aux côtés de l'action. La
   rangée les met sur la même ligne, l'action gardant la priorité de largeur — c'est elle qu'on
   vise en premier, le défaut est l'exception.
*/

.carte-actions {
  display: flex;
  gap: 10px;
  align-items: stretch;
}

.carte-actions > .btn-valider,
.carte-actions > .btn-demarrer,
.carte-actions > .btn-termine {
  flex: 1 1 auto;
  min-width: 0;
}

/* Largeur au contenu, sans jamais se laisser écraser : le mot doit rester lisible de loin. */
.carte-actions > .btn-defaut {
  flex: 0 0 auto;
}

/* Une tâche qui porte déjà des constats le dit sur son bouton : l'écran est relu par l'équipe
   suivante, et un défaut déclaré ne doit pas disparaître au premier rafraîchissement. */
.btn-defaut-marque {
  box-shadow: inset 0 0 0 3px var(--color-washi);
}

/* Cocher le défaut d'abord, le qualifier ensuite : sans cette bascule, la pop-up demanderait de
   remplir tout le catalogue alors qu'on ne constate qu'un défaut à la fois, ou deux. */
/* « Aucun » n'est pas une valeur du catalogue mais l'absence de constat : il ouvre la rangée et
   se distingue par un fond neutre, pour ne pas se lire comme un défaut de plus. */
.tuile-aucun {
  background: var(--surface-panel-raised);
  color: var(--text-secondary);
}

.tuile-aucun.tuile-active {
  color: var(--text-primary);
}

/* L'ANDON quitte le pied de page pour le bas de la colonne des runs : l'arrêt de ligne n'est pas
   une action de tâche. Il s'aligne sur la largeur des cartes, dont il partage la gouttière
   d'ascenseur — d'où la marge droite, sans quoi il dépasserait d'une dizaine de pixels. */
.ecran-apercu-zone > .btn-andon {
  flex: 0 0 auto;
  width: auto;
  margin-top: 14px;
  margin-right: 10px;
  padding: 14px 12px;
  font-size: 21px;
  line-height: 1.25;
}

/* --- Édition d'une tâche en trois colonnes ------------------------------------------------

   Une tâche porte cinq listes en plus de ses champs propres. Empilées, elles faisaient une
   modale interminable où l'on perdait de vue ce qu'on venait de saisir. Trois colonnes, et non
   des onglets : tout doit rester visible d'un coup d'œil.
*/

.modal-tache {
  width: min(1280px, calc(100vw - 48px));
}

.tache-colonnes {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0 28px;
  /* Chaque colonne garde sa hauteur propre : sans cela la plus longue étirerait les autres et
     leur séparateur descendrait dans le vide. */
  align-items: start;
}

/* min-width indispensable sur une piste de grille : une liste de valeurs un peu longue ferait
   sinon déborder sa colonne au lieu de s'y replier. */
.tache-colonne {
  min-width: 0;
}

/* Un filet plutôt qu'un cadre : il sépare sans enfermer, et disparaît de lui-même quand la
   grille se replie sur une seule colonne. */
.tache-colonnes > .tache-colonne + .tache-colonne {
  padding-left: 28px;
  border-left: 1px solid var(--border-default);
}

.tache-colonne-titre {
  margin: 0 0 14px;
  padding-bottom: 8px;
  border-bottom: 1px solid var(--color-line);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--accent-primary);
}

/* Le premier bloc d'une colonne touche déjà son titre : sa marge haute ferait un décrochage
   entre les trois colonnes, dont les titres sont alignés. */
.tache-colonne > .controles-section:first-of-type {
  margin-top: 0;
}

/* Le portail est un back-office de bureau, mais rien ne garantit la largeur : la grille se
   replie plutôt que de comprimer les listes jusqu'à l'illisible. */
@media (max-width: 1180px) {
  .tache-colonnes {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  /* La troisième colonne passe à la ligne : c'est elle qui perd son filet, pas la deuxième. */
  .tache-colonnes > .tache-colonne:nth-child(3) {
    padding-left: 0;
    border-left: none;
    margin-top: 24px;
  }
}

@media (max-width: 760px) {
  .tache-colonnes {
    grid-template-columns: minmax(0, 1fr);
  }

  .tache-colonnes > .tache-colonne + .tache-colonne {
    padding-left: 0;
    border-left: none;
    margin-top: 24px;
  }
}

/* --- Saisie chiffrée d'un défaut ----------------------------------------------------------

   Un défaut chiffré se saisit depuis une tuile, comme les autres se choisissent : elle affiche
   « Saisie », puis la valeur. Le pavé s'ouvre dans sa propre pop-up centrée — posé à demeure dans
   le constat, il en occupait toute la hauteur pour un cas qui reste rare.
*/

/* La tuile qui ouvre une saisie porte un cartouche « 123 » : des chiffres disent ce qui s'ouvre
   plus vite qu'une grille de points, qu'on peut prendre pour un motif. Le cadre arrondi en fait
   une touche plutôt qu'un simple texte.

   Composé en CSS et non en emoji : le symbole Unicode du pavé numérique est rendu en couleur par
   le système, et jurerait dans une interface monochrome. */
/* L'icône est calée contre le bord droit de la tuile, en surimpression. Étant hors flux, elle
   ignore le padding de la tuile et ne pèse pas sur sa hauteur : ses trois rangées tiennent donc
   dans les 84 px de la tuile sans la faire grandir d'un pixel, là où la boîte de contenu n'en
   offrait que 56. Le libellé, lui, reste centré sur toute la largeur. */
.tuile-clavier {
  position: absolute;
  right: 10px;
  top: 50%;
  /* translateY plutôt qu'une marge chiffrée : la hauteur de trois lignes dépend de la police et
     n'est pas connue d'avance. */
  transform: translateY(-50%);
  padding: 3px 7px;
  border: 2px solid currentColor;
  border-radius: 6px;
  font-family: var(--font-mono);
  font-size: 20px;
  font-weight: 700;
  /* Interligne à 1 : c'est ce qui fait entrer les trois rangées dans la hauteur disponible sans
     toucher au corps de la police. */
  line-height: 1;
  letter-spacing: 1px;
  text-align: center;
  color: var(--text-secondary);
}

/* Les rangées dans l'ordre du pavé qu'elles ouvrent — 789 en haut, 123 en bas — et non dans
   l'ordre croissant : c'est la disposition qu'aura le clavier sous les doigts. \A est le retour
   à la ligne en CSS ; l'espace qui le suit ferme l'échappement et n'est pas rendu, d'où
   white-space: pre pour conserver les sauts. */
.tuile-clavier::before {
  content: "789\A 456\A 123";
  white-space: pre;
}

/* Repère de position pour l'icône, calée contre son bord droit. */
.tuile-saisie {
  position: relative;
}

/* Posée par-dessus la pop-up de constat, qui reste visible derrière : l'opérateur ne perd pas de
   vue ce qu'il est en train de qualifier. Au-dessus de .overlay (80) et de .overlay-poste (90) —
   être rendue après ne suffit pas, un z-index inférieur la faisait passer dessous. */
.overlay-pave {
  z-index: 100;
}

.modal-pave {
  width: min(460px, calc(100vw - 32px));
  text-align: center;
}

.modal-pave .pave {
  margin: 0 auto;
}

.modal-pave .btn-valider {
  min-width: 220px;
}

/* --- Centrage des écrans de saisie --------------------------------------------------------

   Constat de défaut et validation de contrôle ont la même forme — un titre, des rangées de tuiles
   — et le même geste : ces écrans ne se lisent pas, ils se pointent. Rien à y parcourir de gauche
   à droite, tout y est donc centré. La règle vise .controle-saisie, le bloc que ces deux pop-ups
   sont seules à employer.
*/

.modal-tactile .controle-saisie {
  text-align: center;
}

.modal-tactile .controle-saisie .tuile {
  align-items: center;
  text-align: center;
}

/* La valeur saisie s'aligne sur le pavé qu'elle surmonte, dont les touches sont centrées. Alignée
   à droite — l'usage d'une calculatrice — elle se décalait du bloc de chiffres juste en dessous. */
.modal-pave .pave-affichage {
  text-align: center;
}
