/* Console SCOS-arms : styles du VISUEL arms uniquement, au-dessus du cadre
   workbench partage (scos-ui : tokens + components). Ne redefinit AUCUNE classe
   .wb-*/.seg : le cadre (display a gauche, panneau outil a droite, KPI 2x2,
   accordeons, feuille mobile) vient de packages/scos-ui/components.css.
   Ici : scene isometrique, illustrations machines, jauges, cards, journal,
   panneau autonomie, surcouches flottantes (horloge, alerte). Chrome monochrome
   encre/papier ; la couleur n'apparait que dans la donnee et l'etat critique. */

/* --------------------------------------------------------------------------
   Surcouche flottante du temps : horloge + lecture/pause + vitesses (.seg).
   Posee dans .wb-float (haut-gauche du display, fourni par le cadre).
   -------------------------------------------------------------------------- */
.time-ctrl {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  background: rgba(255,255,255,0.94); border: 2px solid var(--ink);
  padding: 8px 12px; backdrop-filter: blur(8px);
}
.time-clock-value {
  font-family: var(--sans-en); font-size: 26px; font-weight: 800;
  line-height: 1; letter-spacing: 0.02em; font-variant-numeric: tabular-nums; color: var(--ink);
}
.time-play {
  min-height: 40px; padding: 0 16px; background: var(--ink); color: var(--paper);
  border: 0; font-family: var(--sans-kr), var(--sans-en); font-size: 14px; font-weight: 800;
}
.time-play:hover { background: #000; }
.time-play.is-playing { background: var(--paper); color: var(--ink); border: 2px solid var(--ink); }
.time-play .be { color: var(--rule-soft); }
.time-play.is-playing .be { color: var(--ink-mid); }

/* --------------------------------------------------------------------------
   Bandeau d'alerte global : critique, persistant jusqu'au clic 확인.
   Pose dans .wb-float-bottom (surcouche basse du display, fourni par le cadre).
   -------------------------------------------------------------------------- */
.global-alert {
  display: flex; align-items: center; gap: 16px;
  background: var(--paper); border: 3px solid var(--crit); padding: 12px 16px;
}
.global-alert-text { flex: 1; margin: 0; color: var(--crit); font-weight: 700; font-size: 15.5px; line-height: 1.5; }
#global-alert-ack { border-color: var(--crit); color: var(--crit); flex: none; }
#global-alert-ack:hover { background: var(--crit); color: var(--paper); }
#global-alert-ack:hover .be { color: var(--paper); }

/* --------------------------------------------------------------------------
   Scene isometrique 매장 전경 : remplit le display.
   -------------------------------------------------------------------------- */
.iso-wrap {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
  background: var(--paper); overflow: auto;
}
.iso-scene { display: block; width: 100%; height: 100%; max-height: 100%; }
.iso-machine { cursor: pointer; transition: filter 0.2s ease; }
.iso-machine:focus { outline: 3px solid var(--ink); outline-offset: 2px; }
/* Faces du prisme : transitions de selection et de survol (souleve la machine). */
.iso-machine .iso-top,
.iso-machine .iso-left,
.iso-machine .iso-right { transition: stroke-width 0.15s ease, fill 0.2s ease; }
.iso-machine:hover .iso-top { fill: var(--paper-soft); }
.iso-machine:hover { filter: drop-shadow(0 2px 0 var(--rule-soft)); }
/* Glyphe de famille : discret au repos, encre pleine en survol/selection. */
.iso-glyph { opacity: 0.45; pointer-events: none; transition: opacity 0.2s ease; }
.iso-machine:hover .iso-glyph,
.iso-machine:focus .iso-glyph,
.iso-machine.is-selected .iso-glyph,
.iso-machine[data-mode="live"] .iso-glyph { opacity: 0.85; }
.iso-machine[data-mode="error"] .iso-glyph { stroke: var(--crit); opacity: 1; }
/* Pastille d'etat : invisible au repos, pulse en opacity quand la machine
   travaille (live), fixe rouge en erreur. On lit "qui travaille" sans cliquer. */
.iso-dot { opacity: 0; pointer-events: none; }
.iso-machine[data-mode="live"] .iso-dot {
  opacity: 1; animation: iso-dot-pulse 2.4s ease-in-out infinite;
  animation-delay: var(--iso-delay, 0s);
}
.iso-machine[data-mode="error"] .iso-dot { opacity: 1; fill: var(--crit); }
/* Labels masqués au repos (sinon ils se chevauchent sur 14 machines) ; révélés
   au survol, au focus clavier et sur la machine sélectionnée. Le nom complet vit
   dans le panneau (선택 장비) au clic, comme ds renseigne au clic sur la carte. */
.iso-label {
  font-family: var(--sans-kr), var(--sans-en); font-size: 10.5px; font-weight: 700;
  fill: var(--ink-mid); opacity: 0; transition: opacity 0.15s ease; pointer-events: none;
  paint-order: stroke; stroke: var(--paper); stroke-width: 3px; stroke-linejoin: round;
}
.iso-machine:hover .iso-label,
.iso-machine:focus .iso-label,
.iso-machine.is-selected .iso-label { opacity: 1; }
.iso-machine[data-mode="live"] .iso-top {
  animation: iso-pulse 2.4s ease-in-out infinite;
  animation-delay: var(--iso-delay, 0s);
}
.iso-machine[data-mode="error"] polygon { stroke: var(--crit); }
.iso-machine[data-mode="error"] .iso-label { fill: var(--crit); opacity: 1; }
.iso-machine[data-mode="error"] { animation: illus-blink 1.3s step-start infinite; }
/* Machine selectionnee : contour appuye (transition stroke-width), libelle plein. */
.iso-machine.is-selected .iso-top,
.iso-machine.is-selected .iso-left,
.iso-machine.is-selected .iso-right { stroke-width: 2.6; }
.iso-machine.is-selected .iso-label { fill: var(--ink); font-weight: 800; }

/* --------------------------------------------------------------------------
   Detail de la machine selectionnee (accordeon 선택 장비).
   -------------------------------------------------------------------------- */
.detail-host { display: flex; flex-direction: column; gap: 12px; transition: background 0.25s ease; }
.detail-host .machine-card { transition: opacity 0.18s ease; }
/* Entree de la card selectionnee dans le panneau detail : fondu + montee. */
.detail-host.detail-enter .machine-card { animation: detail-in 0.2s ease-out; }
/* Flash bref du host a l'insertion. */
.detail-host.detail-flash { background: var(--paper-soft); }
@keyframes detail-in { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: translateY(0); } }
/* Flash bref d'une card KPI qui change (count-up de l'agent, etc.). */
.wb-card { transition: background 0.25s ease; }
.wb-card.kpi-flash { background: var(--paper-soft); }
.detail-empty { font-size: 14px; color: var(--ink-soft); line-height: 1.6; }
.detail-empty .be { display: block; font-size: 12px; margin-top: 4px; }
.pane-lead { font-size: 13.5px; color: var(--ink-soft); line-height: 1.55; margin-bottom: 14px; }
.pane-lead .be { display: block; font-size: 12px; margin-top: 2px; }

/* Onglet 자동화 : blocs empiles sur une colonne dans le panneau. */
.autonomy-stack { display: flex; flex-direction: column; gap: 16px; align-items: stretch; }

/* --------------------------------------------------------------------------
   Grille atelier et cards machine (accordeon 전체 장비)
   -------------------------------------------------------------------------- */
.atelier-grid { display: grid; grid-template-columns: 1fr; gap: 14px; }
.machine-card {
  border: 1px solid var(--ink); background: var(--paper);
  padding: 16px 16px 14px; display: flex; flex-direction: column; gap: 12px;
}
.machine-card.is-error { border: 2px solid var(--crit); padding: 15px 15px 13px; }
.card-head-row { display: flex; justify-content: space-between; align-items: flex-start; gap: 10px; }
.card-names h3 { font-size: 17px; line-height: 1.3; }
.card-names .be { display: block; font-size: 12px; letter-spacing: 0.04em; }
.card-head-row .badge { flex: none; white-space: nowrap; }
.card-pending { font-size: 13.5px; font-weight: 700; color: var(--ink-mid); }
.card-alert { color: var(--crit); font-weight: 700; font-size: 14.5px; line-height: 1.5; }

/* Jauges */
.card-gauges { display: flex; flex-direction: column; gap: 10px; }
.gauge { display: flex; flex-direction: column; gap: 3px; }
.gauge-head { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; }
.gauge-key { font-family: var(--sans-en); font-size: 12px; font-weight: 700; letter-spacing: 0.05em; color: var(--ink-mid); }
.gauge-value { font-family: var(--sans-en); font-size: 15px; font-weight: 800; font-variant-numeric: tabular-nums; color: var(--ink); }
.gauge-value.is-crit { color: var(--crit); }
.gauge-bar { display: block; width: 100%; height: 14px; }
.gauge-scale { display: flex; justify-content: space-between; font-family: var(--sans-en); font-size: 11px; color: var(--ink-dim); }

/* Boutons d'action : un par action, toujours visibles, desactives = explication */
.card-actions { display: flex; flex-wrap: wrap; gap: 8px; }
.btn-act {
  min-height: var(--tap-min); padding: 6px 12px;
  background: var(--paper); color: var(--ink); border: 1px solid var(--ink);
  font-family: var(--sans-kr), var(--sans-en); font-size: 14px; font-weight: 700;
}
.btn-act .be { font-size: 11.5px; }
.btn-act:hover:not(:disabled) { background: var(--paper-soft); }
.btn-act:disabled { border-color: var(--rule-soft); color: var(--ink-dim); cursor: not-allowed; }
.btn-act:disabled .be { color: var(--ink-dim); }
.btn-act.is-urgent { border: 2px solid var(--crit); color: var(--crit); font-weight: 800; }
.btn-act.is-urgent .be { color: var(--crit); }
.card-msg { margin: 0; }

/* Mini-formulaire inline de parametres (sous la card, jamais de modal) */
.param-form {
  border: 1px dashed var(--ink); background: var(--paper-soft);
  padding: 12px 14px 14px; display: flex; flex-direction: column; gap: 10px;
}
.param-form-title { font-size: 14.5px; color: var(--ink); }
.param-form .field input, .param-form .field select { height: 44px; font-size: 15px; }
.param-form-actions { display: flex; gap: 10px; }
.param-form-actions .btn-secondary { height: 44px; padding: 0 16px; }
.btn-run { background: var(--ink); color: var(--paper); }
.btn-run:hover { background: #000; }
.btn-run .be { color: var(--rule-soft); }

/* Injection de pannes (outil de demonstration, replie par defaut) */
.fault-box { border-top: 1px solid var(--rule-soft); padding-top: 8px; }
.fault-box summary {
  cursor: pointer; min-height: var(--tap-min); display: flex; align-items: center; gap: 6px;
  font-size: 13px; font-weight: 700; color: var(--ink-mid);
}
.fault-row { padding: 6px 0 2px; }
.btn-fault { border-style: dashed; }

/* --------------------------------------------------------------------------
   Journal des evenements (accordeon 일지)
   -------------------------------------------------------------------------- */
.journal-filters { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 12px; }
.btn-filter {
  min-height: var(--tap-min); padding: 4px 12px;
  background: var(--paper); color: var(--ink); border: 1px solid var(--rule-soft);
  font-family: var(--sans-kr), var(--sans-en); font-size: 13.5px; font-weight: 700;
}
.btn-filter:hover { border-color: var(--ink); }
.btn-filter.active { background: var(--ink); border-color: var(--ink); color: var(--paper); }
.journal-meta { font-size: 13px; color: var(--ink-mid); margin-bottom: 10px; }
.journal-table .num { white-space: nowrap; text-align: left; }
.journal-kind {
  display: inline-block; padding: 1px 7px; border: 1px solid var(--rule-soft);
  font-size: 12px; font-weight: 800; white-space: nowrap; color: var(--ink-mid);
}
.journal-kind.is-crit { color: var(--crit); border-color: var(--crit); }
.journal-kind.is-warn { color: var(--warn); border-color: var(--warn); }
.journal-detail { line-height: 1.55; }

/* --------------------------------------------------------------------------
   Illustrations machines : monochrome encre/papier, animees par data-state
   (CSS) ; JS n'ecrit que niveaux et aiguilles au tick telemetrie.
   -------------------------------------------------------------------------- */
.illus { border-bottom: 1px solid var(--rule-soft); padding-bottom: 6px; }
.illus-svg { display: block; width: 100%; height: 140px; }

@keyframes illus-spin { to { transform: rotate(360deg); } }
@keyframes illus-blink { 0%, 100% { opacity: 1; } 50% { opacity: 0.15; } }
@keyframes illus-steam { 0% { transform: translateY(0); opacity: 0.9; } 100% { transform: translateY(-7px); opacity: 0; } }
@keyframes illus-wave { to { transform: translateX(-24px); } }
@keyframes illus-heat { to { transform: translateX(-20px); } }
@keyframes illus-fill { from { transform: scaleY(0); } to { transform: scaleY(1); } }
@keyframes illus-scroll { to { transform: translateY(-34px); } }
@keyframes illus-drop { 0% { transform: translateY(0); opacity: 1; } 100% { transform: translateY(14px); opacity: 0; } }
@keyframes illus-arm1 { from { transform: rotate(-18deg); } to { transform: rotate(22deg); } }
@keyframes illus-arm2 { from { transform: rotate(24deg); } to { transform: rotate(-20deg); } }
/* Pulsation des machines actives : ecart ~8% (perceptible mais sobre), 2.4s. */
@keyframes iso-pulse { 0%, 100% { fill: #fff; } 50% { fill: #ececec; } }
@keyframes iso-dot-pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.25; } }

/* Mouvement reduit : on coupe les animations infinies de la scene (respiration
   et pastilles). L'etat reste lisible par le glyphe, le contour et la pastille
   fixes ; le clignotement --crit d'erreur est conserve (securite). */
@media (prefers-reduced-motion: reduce) {
  .iso-machine[data-mode="live"] .iso-top { animation: none; fill: #f4f4f4; }
  .iso-machine[data-mode="live"] .iso-dot { animation: none; opacity: 1; }
}

/* Erreur : l'illustration le montre, clignotement sobre en --crit. */
.illus-svg .illus-err { opacity: 0; }
.illus-svg[data-state="error"] .illus-err { opacity: 1; animation: illus-blink 1.3s step-start infinite; }

/* Pieces tournantes (meule, lame, tambour). */
.illus-svg .spin, .illus-svg .spin-slow { transform-box: fill-box; transform-origin: center; }

/* Vapeur : cachee par defaut, filets montants quand l'etat la justifie. */
.illus-svg .steam { opacity: 0; }
.illus-svg .steam path { transform-box: fill-box; }
.illus-espresso-machine[data-state="heating"] .steam,
.illus-espresso-machine[data-state="brewing"] .steam,
.illus-dishwasher[data-state="drying"] .steam,
.illus-milk-steamer[data-state="heating"] .steam { opacity: 1; }
.illus-espresso-machine[data-state="heating"] .steam path,
.illus-espresso-machine[data-state="brewing"] .steam path,
.illus-dishwasher[data-state="drying"] .steam path { animation: illus-steam 1.6s linear infinite; }
.illus-svg .steam .s2 { animation-delay: 0.8s; }

/* Espresso : la tasse se remplit pendant l'extraction (duree contractuelle 28 s). */
.illus-espresso-machine .cup-fill { transform-box: fill-box; transform-origin: bottom; transform: scaleY(0); }
.illus-espresso-machine[data-state="brewing"] .cup-fill { animation: illus-fill 28s linear forwards; }
.illus-espresso-machine[data-state="cleaning"] .cup-fill { transform: scaleY(0); }

/* Grinder : meule qui tourne en grinding. */
.illus-grinder[data-state="grinding"] .burr { animation: illus-spin 0.6s linear infinite; }

/* Mixer : lame et remous pendant le blend. */
.illus-mixer .slosh { opacity: 0; }
.illus-mixer[data-state="mixing"] .slosh { opacity: 1; }
.illus-mixer[data-state="mixing"] .blade { animation: illus-spin 0.3s linear infinite; }

/* Robot : bras 2 segments qui pivote entre poses, repli e-stop en erreur. */
.illus-robot-arm .seg1, .illus-robot-arm .seg2 {
  transform-box: fill-box; transform-origin: 50% 100%; transition: transform 0.8s ease;
}
.illus-robot-arm[data-state="running"] .seg1 { animation: illus-arm1 3.2s ease-in-out infinite alternate; }
.illus-robot-arm[data-state="running"] .seg2 { animation: illus-arm2 1.6s ease-in-out infinite alternate; }
.illus-robot-arm[data-state="homing"] .seg1 { animation: illus-arm1 6s ease-in-out infinite alternate; }
.illus-robot-arm[data-state="error"] .seg1 { transform: rotate(-55deg); }
.illus-robot-arm[data-state="error"] .seg2 { transform: rotate(95deg); }

/* Frigo, vitrine, four : porte pilotee par data-door, givre en defrost. */
.illus-svg .door { transform-box: fill-box; transition: transform 0.6s ease; }
.illus-fridge .door, .illus-showcase-fridge .door { transform-origin: left center; }
.illus-fridge[data-door="1"] .door,
.illus-showcase-fridge[data-door="1"] .door { transform: scaleX(0.18) skewY(-6deg); }
.illus-oven .door { transform-origin: center bottom; }
.illus-oven[data-door="1"] .door { transform: scaleY(0.22) skewX(-8deg); }
.illus-svg .frost { opacity: 0; }
.illus-fridge[data-state="defrost"] .frost,
.illus-showcase-fridge[data-state="defrost"] .frost { opacity: 1; animation: illus-blink 2.8s ease-in-out infinite; }

/* Lave-vaisselle : vagues derriere le hublot pendant le lavage. */
.illus-dishwasher .waves { opacity: 0; }
.illus-dishwasher[data-state="washing"] .waves { opacity: 1; }
.illus-dishwasher[data-state="washing"] .waves path { animation: illus-wave 1.6s linear infinite; }

/* Kiosque : tickets visibles ouvert, ecran eteint sinon. */
.illus-kiosk .tickets { opacity: 0; }
.illus-kiosk[data-state="open"] .tickets { opacity: 1; }
.illus-kiosk .screen-off { opacity: 0; }
.illus-kiosk[data-state="closed"] .screen-off,
.illus-kiosk[data-state="maintenance"] .screen-off,
.illus-kiosk[data-state="error"] .screen-off { opacity: 0.85; }

/* Machine a glace : glacons qui tombent pendant la production. */
.illus-ice-machine .cubes { opacity: 0; }
.illus-ice-machine[data-state="making"] .cubes { opacity: 1; }
.illus-ice-machine .cube { transform-box: fill-box; }
.illus-ice-machine[data-state="making"] .c1 { animation: illus-drop 1.2s linear infinite; }
.illus-ice-machine[data-state="making"] .c2 { animation: illus-drop 1.2s linear infinite 0.4s; }
.illus-ice-machine[data-state="making"] .c3 { animation: illus-drop 1.2s linear infinite 0.8s; }

/* Torrefacteur : tambour qui tourne, hachures de chauffe pilotees par bean_temp (JS). */
.illus-roaster[data-state="preheating"] .drum,
.illus-roaster[data-state="ready"] .drum,
.illus-roaster[data-state="roasting"] .drum { animation: illus-spin 2.4s linear infinite; }
.illus-roaster[data-state="cooling"] .drum { animation: illus-spin 4.5s linear infinite; }

/* Four : ondes de chaleur en prechauffe et cuisson. */
.illus-oven .waves { opacity: 0; }
.illus-oven[data-state="preheating"] .waves,
.illus-oven[data-state="ready"] .waves,
.illus-oven[data-state="baking"] .waves { opacity: 1; }
.illus-oven[data-state="preheating"] .waves path,
.illus-oven[data-state="baking"] .waves path { animation: illus-heat 2.2s linear infinite; }

/* Steamer : jet de vapeur vers le pichet pendant le moussage. */
.illus-milk-steamer .jet { opacity: 0; }
.illus-milk-steamer[data-state="steaming"] .jet { opacity: 1; animation: illus-blink 0.5s linear infinite; }

/* Eclairage et sayniage : rayons/halo (JS) et defilement du contenu. */
.illus-signage .scroll rect { transform-box: fill-box; }
.illus-signage[data-state="playing"] .scroll { animation: illus-scroll 6s linear infinite; }
.illus-signage .screen-off { opacity: 0; }
.illus-signage[data-state="off"] .screen-off,
.illus-signage[data-state="error"] .screen-off { opacity: 0.85; }

/* --------------------------------------------------------------------------
   Panneau 자동화 : analyse 1 clic, niveaux, mandats, regles. KILL-SWITCH
   (즉시 중지 par mandat + 전체 즉시 중지) gros, visibles, bordure --crit.
   -------------------------------------------------------------------------- */
.auto-block {
  border: 1px solid var(--ink); background: var(--paper);
  padding: 16px 16px 18px; display: flex; flex-direction: column; gap: 12px;
}
.auto-block-title { font-size: 17px; }
.auto-block-title .be { font-size: 12px; font-weight: 600; margin-left: 6px; }
.auto-lead { font-size: 14px; color: var(--ink-soft); line-height: 1.55; }
.btn-analyze {
  align-self: flex-start; min-height: 52px; padding: 0 24px;
  background: var(--ink); color: var(--paper); font-size: 16px; font-weight: 800;
}
.btn-analyze:hover { background: #000; }
.btn-analyze .be { color: var(--rule-soft); }
.auto-status { font-size: 14px; font-weight: 700; line-height: 1.5; }
.auto-finding-list { padding-left: 20px; font-size: 14px; line-height: 1.65; }
.auto-candidates { display: flex; flex-direction: column; gap: 10px; }
.auto-candidate { border: 1px dashed var(--ink); background: var(--paper-soft); padding: 10px 12px; }
.auto-candidate-main { display: flex; gap: 10px; cursor: pointer; }
.auto-candidate-main input, .auto-rule-toggle input {
  width: 20px; height: 20px; accent-color: var(--ink); flex: none; margin-top: 2px;
}
.auto-candidate-body { display: flex; flex-direction: column; gap: 4px; }
.auto-candidate-name { font-size: 15px; font-weight: 700; line-height: 1.4; }
.badge.src {
  margin-left: 8px; display: inline-block; padding: 1px 7px;
  border: 1px solid var(--ink-mid); color: var(--ink-mid);
  font-size: 11.5px; font-weight: 800; white-space: nowrap;
}
.badge.src-ai { border-style: dashed; color: var(--ink); border-color: var(--ink); }
.auto-candidate-trigger { font-size: 13px; color: var(--ink-mid); }
.auto-candidate-why { font-size: 13.5px; line-height: 1.55; }
.auto-apply-row { display: flex; gap: 10px; }
.auto-apply-row .btn-run { min-height: 50px; padding: 0 20px; }

.auto-levels { display: flex; flex-direction: column; }
.auto-level-row {
  display: flex; justify-content: space-between; align-items: center; gap: 10px;
  border-bottom: 1px solid var(--rule-soft); padding: 7px 0; flex-wrap: wrap;
}
.auto-level-name { font-size: 14.5px; font-weight: 700; }
.auto-level-set { display: flex; gap: 6px; flex-wrap: wrap; }
.level-opt { font-family: var(--sans-kr), var(--sans-en); font-size: 13px; padding: 0 10px; }
.grant-confirm { border: 2px solid var(--ink); background: var(--paper-soft); padding: 12px 14px; margin: 8px 0; }
.grant-confirm-title { font-size: 14.5px; font-weight: 700; margin-bottom: 8px; }
.grant-terms { padding-left: 20px; font-size: 13.5px; line-height: 1.65; }

.btn-kill {
  min-height: 52px; padding: 0 22px; cursor: pointer;
  background: var(--paper); border: 3px solid var(--crit); color: var(--crit);
  font-family: var(--sans-kr), var(--sans-en); font-size: 15px; font-weight: 800;
}
.btn-kill:hover { background: var(--crit); color: var(--paper); }
.btn-kill:hover .be { color: var(--paper); }
.btn-kill-all { align-self: flex-start; }
.auto-grants { display: flex; flex-direction: column; gap: 12px; }
.grant-card { border: 1px solid var(--ink); padding: 12px 14px; display: flex; flex-direction: column; gap: 8px; }
.grant-head { display: flex; justify-content: space-between; align-items: center; gap: 8px; font-size: 15px; }
.grant-card .btn-kill { align-self: flex-start; }

.auto-rules { display: flex; flex-direction: column; }
.auto-rule-row {
  display: flex; gap: 10px; align-items: flex-start;
  border-bottom: 1px solid var(--rule-soft); padding: 9px 0;
}
.auto-rule-toggle { display: flex; gap: 10px; flex: 1; cursor: pointer; }
.auto-rule-row .btn-act { flex: none; }
.auto-hist-title { font-size: 14px; font-weight: 700; margin-top: 4px; }
.auto-history { display: flex; flex-direction: column; gap: 4px; }
.auto-hist-line { font-size: 13px; line-height: 1.55; color: var(--ink-soft); font-variant-numeric: tabular-nums; }
.auto-hist-line.is-skipped { color: var(--ink-dim); }
.auto-empty { font-size: 13.5px; color: var(--ink-dim); line-height: 1.5; }

/* Badge AI du journal : action de l'autopilote, mandat reference. */
.journal-kind.is-ai { margin-left: 6px; border-style: dashed; border-color: var(--ink); color: var(--ink); }

/* --------------------------------------------------------------------------
   Responsive du visuel arms (le cadre .wb-* gere deja layout et feuille mobile).
   La scene iso defile horizontalement dans son cadre plutot que de deborder ;
   inputs >= 16px (pas de zoom iOS) ; kill-switch toujours gros et visibles.
   -------------------------------------------------------------------------- */
@media (max-width: 820px) {
  /* Garde anti-scroll horizontal de page (rien ne doit deborder en largeur). */
  body.wb-app { overflow-x: hidden; }

  /* Decision actee : la scene RENTRE dans l'ecran, zero scroll lateral. On
     retire tout min-width force ; le viewBox 760x300 se redimensionne pour
     tenir dans la largeur (preserveAspectRatio meet par defaut, height auto),
     centre verticalement dans le display heros. */
  .iso-wrap { position: absolute; inset: 0; overflow: hidden; display: block; }
  /* Pattern éprouvé (cf. eye) : le SVG remplit le wrap, le contenu se met a
     l'échelle dedans (preserveAspectRatio meet) -> rentre toujours en largeur. */
  .iso-scene { min-width: 0; width: 100%; height: 100%; max-height: none; }

  /* Controle du temps : horloge + lecture + vitesses sur une surcouche compacte
     qui tient dans la largeur (flex-wrap propre, cibles >= 44px). */
  .time-ctrl { gap: 8px; padding: 6px 10px; max-width: 100%; }
  .time-clock-value { font-size: 22px; }
  .time-play { min-height: 44px; }
  .seg button { min-height: 44px; }
}

@media (max-width: 640px) {
  /* Boutons d'action des machines : pleine largeur, cible >= 44px. */
  .card-actions { gap: 10px; }
  .card-actions .btn-act { flex: 1 1 100%; min-height: 48px; text-align: center; }
  /* Formulaire inline de parametres : champs >= 16px, boutons pleine largeur. */
  .param-form .field input, .param-form .field select { height: 50px; font-size: 16px; }
  .param-form-actions { flex-direction: column; }
  .param-form-actions .btn-secondary { width: 100%; height: 50px; }
  .fault-row .btn-fault { width: 100%; min-height: 44px; }

  /* Panneau autonomie : bouton d'analyse pleine largeur. */
  .btn-analyze { align-self: stretch; width: 100%; text-align: center; }
  .auto-level-row { align-items: stretch; }
  .auto-level-name { width: 100%; }
  .auto-level-set { width: 100%; gap: 8px; }
  .level-opt { flex: 1 1 0; justify-content: center; min-height: 48px; }
  .auto-apply-row { flex-direction: column; }
  .auto-apply-row .btn-run { width: 100%; }
  .auto-rule-row { flex-wrap: wrap; }
  .auto-rule-row .btn-act { width: 100%; min-height: 44px; text-align: center; }

  /* Kill-switch : pleine largeur et bien hauts (securite, toujours visibles). */
  .btn-kill { width: 100%; min-height: 56px; }
  .btn-kill-all { align-self: stretch; }
  .grant-card .btn-kill { align-self: stretch; }

  /* Journal : la table seule defile horizontalement. */
  .journal-table { display: block; overflow-x: auto; -webkit-overflow-scrolling: touch; }
  .journal-detail { min-width: 220px; }
  .journal-filters .btn-filter { min-height: 44px; }

  /* Alerte globale : empilee, bouton 확인 pleine largeur. */
  .global-alert { flex-direction: column; align-items: stretch; gap: 10px; }
  #global-alert-ack { width: 100%; min-height: 48px; }
}

@media (max-width: 820px) {
  /* La feuille peek occupe ~128px en bas (cf. sheet.js). On remonte le bandeau
     d'alerte au-dessus de cette bande pour que le message et le bouton 확인
     restent visibles et atteignables tant que la feuille n'est pas ouverte. */
  .wb-float-bottom { bottom: 140px; }
}

@media (max-width: 480px) {
  /* La scene reste pleine largeur sans min-width (pas de scroll lateral). On
     l'ancre vers le haut-centre du display heros : la bande visible au-dessus
     de la feuille peek est la partie haute de l'ecran, c'est la qu'on veut la
     scene plutot que centree (et donc cachee) sur toute la hauteur. Ceci
     resorbe le grand vide vertical sous la scene. */
  .iso-wrap { align-items: flex-start; padding-top: 12dvh; }
  .iso-scene { min-width: 0; width: 100%; }
}

/* Paysage telephone (bas plafond vertical) : la bande visible est mince, on
   recentre la scene et on resserre la surcouche temps. */
@media (max-width: 820px) and (max-height: 640px) {
  .iso-wrap { align-items: center; padding-top: 0; }
  .time-ctrl { gap: 6px; padding: 5px 8px; }
  .time-clock-value { font-size: 19px; }
}
