Files
siop2/docs/02-design/maquettes/maquette-r3.html
pr-daaif d5041c6f05 docs(r3): kickoff design-first — maquettes de la gestion (7 écrans) à valider
- maquette-r3.html (moule validé) : stock DÉRIVÉ des mouvements (alertes
  sous seuil → préparer le BC), fiche pièce (les mouvements sont le stock),
  bons de commande (réception → entrées, PU figé), coûts sur OT (pièces à
  prix figé, main-d'œuvre à taux figé), statistiques (pannes par organe
  depuis les bilans codés, coûts, top équipements — palette CVD), tiers,
  bibliothèque (documents typés rattachés, MinIO via FileStorage)
- 4 décisions soumises (stock jamais saisi, prix/taux figés, réception
  créatrice de mouvements, types de documents fermés)
- rendu vérifié (7 écrans, bi-thème, zéro erreur)
- BLOQUANT : validation du référent avant tout code applicatif R3

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 18:16:00 +01:00

841 lines
58 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!doctype html>
<html lang="fr">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>SIOP V2 — Maquettes HD · R3 Gestion</title>
</head>
<body>
<!--
SIOP V2 — Maquettes HD de la release R3 « Gestion » (design-first).
À VALIDER PAR LE RÉFÉRENT AVANT TOUT CODE APPLICATIF R3 (principe n°1).
Écrans déjà validés non redessinés : la tuile « Coût » du tableau de bord et
la carte « Pièces & main-d'œuvre » de la fiche OT (maquette-web, R0).
CSS répliquée des maquettes validées ; ajouts R3 dans le dernier bloc <style>.
-->
<style>
/* ═══ Tokens (répliques de ../tokens.css) ═══ */
:root{
--primaire:#1f4fb8;--primaire-actif:#1a439c;--primaire-doux:#eaf0fb;
--safran:#dd8a0b;--safran-doux:#fdf3e3;
--fond:#f5f7fa;--surface:#ffffff;--surface-2:#eef2f7;
--bordure:#dce3ec;--bordure-forte:#b9c4d4;
--encre:#1b2534;--encre-2:#55647a;--encre-3:#8494ab;
--st-ouvert:#3d6fe0;--st-ouvert-fond:#e9effc;--st-encours:#6d5bd8;--st-encours-fond:#efecfa;
--st-attente:#b96f07;--st-attente-fond:#fbf1df;--st-termine:#178a50;--st-termine-fond:#e6f5ec;
--st-annule:#68788f;--st-annule-fond:#edf0f4;
--prio-bloque:#d92626;--prio-bloque-fond:#fdeaea;--prio-haute:#d92626;
--prio-moyenne:#b96f07;--prio-basse:#178a50;--prio-aucune:#8494ab;
--succes:#178a50;--alerte:#b96f07;--danger:#d92626;--info:#3d6fe0;
--graf-1:#3b69d6;--graf-2:#dd8a0b;--graf-3:#1f9e8e;--graf-4:#8a63d2;--graf-grille:#e6ebf2;
--nav-fond:#16233b;--nav-encre:#c6d2e4;--nav-encre-vif:#ffffff;--nav-bordure:#24344f;
--police-ui:"Manrope","Avenir Next","Segoe UI Variable",system-ui,sans-serif;
--rayon:10px;--rayon-controle:8px;--ombre-menu:0 8px 24px rgb(16 30 54/.14);
--transition:140ms ease-out;
}
@media (prefers-color-scheme:dark){:root{
--primaire:#6e92e8;--primaire-actif:#8facf0;--primaire-doux:#1d2c4c;
--safran:#e89a1f;--safran-doux:#33270f;
--fond:#0f1622;--surface:#182234;--surface-2:#1e2a40;
--bordure:#2b3850;--bordure-forte:#3d4d6b;
--encre:#e8edf5;--encre-2:#a7b4c8;--encre-3:#6d7d96;
--st-ouvert:#7da2ee;--st-ouvert-fond:#1c2a47;--st-encours:#a394ec;--st-encours-fond:#262040;
--st-attente:#e0a33c;--st-attente-fond:#322510;--st-termine:#4bc084;--st-termine-fond:#12301f;
--st-annule:#93a3ba;--st-annule-fond:#222d3f;
--prio-bloque:#f26d6d;--prio-bloque-fond:#3a1414;--prio-haute:#f26d6d;
--prio-moyenne:#e0a33c;--prio-basse:#4bc084;--prio-aucune:#6d7d96;
--succes:#4bc084;--alerte:#e0a33c;--danger:#f26d6d;--info:#7da2ee;
--graf-1:#5580e4;--graf-2:#c7820a;--graf-3:#26a896;--graf-4:#9673de;--graf-grille:#24304a;
--nav-fond:#0c1524;--nav-encre:#a7b4c8;--nav-encre-vif:#f2f6fc;--nav-bordure:#1e2c44;
--ombre-menu:0 8px 24px rgb(0 0 0/.45);
}}
:root[data-theme="light"]{
--primaire:#1f4fb8;--primaire-actif:#1a439c;--primaire-doux:#eaf0fb;
--safran:#dd8a0b;--safran-doux:#fdf3e3;
--fond:#f5f7fa;--surface:#ffffff;--surface-2:#eef2f7;
--bordure:#dce3ec;--bordure-forte:#b9c4d4;
--encre:#1b2534;--encre-2:#55647a;--encre-3:#8494ab;
--st-ouvert:#3d6fe0;--st-ouvert-fond:#e9effc;--st-encours:#6d5bd8;--st-encours-fond:#efecfa;
--st-attente:#b96f07;--st-attente-fond:#fbf1df;--st-termine:#178a50;--st-termine-fond:#e6f5ec;
--st-annule:#68788f;--st-annule-fond:#edf0f4;
--prio-bloque:#d92626;--prio-bloque-fond:#fdeaea;--prio-haute:#d92626;
--prio-moyenne:#b96f07;--prio-basse:#178a50;--prio-aucune:#8494ab;
--succes:#178a50;--alerte:#b96f07;--danger:#d92626;--info:#3d6fe0;
--graf-1:#3b69d6;--graf-2:#dd8a0b;--graf-3:#1f9e8e;--graf-4:#8a63d2;--graf-grille:#e6ebf2;
--nav-fond:#16233b;--nav-encre:#c6d2e4;--nav-encre-vif:#ffffff;--nav-bordure:#24344f;
--ombre-menu:0 8px 24px rgb(16 30 54/.14);
}
:root[data-theme="dark"]{
--primaire:#6e92e8;--primaire-actif:#8facf0;--primaire-doux:#1d2c4c;
--safran:#e89a1f;--safran-doux:#33270f;
--fond:#0f1622;--surface:#182234;--surface-2:#1e2a40;
--bordure:#2b3850;--bordure-forte:#3d4d6b;
--encre:#e8edf5;--encre-2:#a7b4c8;--encre-3:#6d7d96;
--st-ouvert:#7da2ee;--st-ouvert-fond:#1c2a47;--st-encours:#a394ec;--st-encours-fond:#262040;
--st-attente:#e0a33c;--st-attente-fond:#322510;--st-termine:#4bc084;--st-termine-fond:#12301f;
--st-annule:#93a3ba;--st-annule-fond:#222d3f;
--prio-bloque:#f26d6d;--prio-bloque-fond:#3a1414;--prio-haute:#f26d6d;
--prio-moyenne:#e0a33c;--prio-basse:#4bc084;--prio-aucune:#6d7d96;
--succes:#4bc084;--alerte:#e0a33c;--danger:#f26d6d;--info:#7da2ee;
--graf-1:#5580e4;--graf-2:#c7820a;--graf-3:#26a896;--graf-4:#9673de;--graf-grille:#24304a;
--nav-fond:#0c1524;--nav-encre:#a7b4c8;--nav-encre-vif:#f2f6fc;--nav-bordure:#1e2c44;
--ombre-menu:0 8px 24px rgb(0 0 0/.45);
}
/* ═══ Base ═══ */
*{box-sizing:border-box;margin:0}
html,body{background:var(--fond)}
body{font-family:var(--police-ui);color:var(--encre);font-size:14px;line-height:1.5}
button{font:inherit;cursor:pointer;border:0;background:none;color:inherit}
button:focus-visible,a:focus-visible{outline:2px solid var(--primaire);outline-offset:2px;border-radius:4px}
table{border-collapse:collapse;font-variant-numeric:tabular-nums}
.num{font-variant-numeric:tabular-nums}
/* ═══ Barre de revue (outil maquette, pas l'app) ═══ */
.revue{position:sticky;top:0;z-index:50;display:flex;align-items:center;gap:12px;flex-wrap:wrap;
padding:10px 16px;background:var(--nav-fond);color:var(--nav-encre);font-size:13px}
.revue b{color:var(--nav-encre-vif);letter-spacing:.02em}
.revue .onglets{display:flex;gap:4px;flex-wrap:wrap}
.revue .onglets button{padding:6px 10px;border-radius:6px;color:var(--nav-encre)}
.revue .onglets button:hover{background:rgb(255 255 255/.08);color:var(--nav-encre-vif)}
.revue .onglets button[aria-selected="true"]{background:rgb(255 255 255/.12);color:var(--nav-encre-vif);
box-shadow:inset 3px 0 0 var(--safran)}
.revue .droite{margin-left:auto;display:flex;align-items:center;gap:8px}
.revue .theme{padding:6px 10px;border:1px solid var(--nav-bordure);border-radius:6px}
.note-ecran{max-width:1280px;margin:14px auto 0;padding:0 20px;color:var(--encre-2);font-size:13px}
.note-ecran b{color:var(--encre)}
/* ═══ Coquille applicative ═══ */
.ecran{display:none;max-width:1280px;margin:14px auto 40px;padding:0 20px}
.ecran.actif{display:block}
.app{display:grid;grid-template-columns:232px 1fr;min-height:720px;border:1px solid var(--bordure);
border-radius:14px;overflow:hidden;background:var(--fond)}
.app.pleine{grid-template-columns:1fr}
/* Sidebar (toujours sombre — identité) */
.nav{background:var(--nav-fond);color:var(--nav-encre);display:flex;flex-direction:column;padding:16px 0}
.logo{display:flex;align-items:center;gap:10px;padding:2px 18px 16px;color:var(--nav-encre-vif)}
.logo .marque{display:flex;flex-direction:column;line-height:.55;font-size:11px;color:var(--safran)}
.logo b{font-size:19px;letter-spacing:.04em}
.logo small{color:var(--nav-encre);font-weight:400;font-size:11px;display:block;margin-top:2px}
.nav .groupe{padding:12px 18px 4px;font-size:10.5px;letter-spacing:.08em;text-transform:uppercase;color:#6b7f9e}
.nav a{display:flex;align-items:center;gap:10px;padding:8px 18px;color:var(--nav-encre);
text-decoration:none;font-size:13.5px;border-left:3px solid transparent;transition:background var(--transition)}
.nav a:hover{background:rgb(255 255 255/.06);color:var(--nav-encre-vif)}
.nav a.actif{background:rgb(255 255 255/.09);color:var(--nav-encre-vif);border-left-color:var(--safran)}
.nav a .badge-nav{margin-left:auto;background:var(--prio-bloque);color:#fff;font-size:11px;
padding:1px 7px;border-radius:999px;font-weight:700}
.nav svg{width:17px;height:17px;stroke-width:1.75;flex:none}
/* Topbar */
.contenu{display:flex;flex-direction:column;min-width:0}
.topbar{display:flex;align-items:center;gap:12px;padding:12px 24px;background:var(--surface);
border-bottom:1px solid var(--bordure)}
.recherche{flex:1;max-width:420px;display:flex;align-items:center;gap:8px;background:var(--surface-2);
border:1px solid var(--bordure);border-radius:8px;padding:7px 12px;color:var(--encre-3);font-size:13px}
.recherche svg{width:15px;height:15px}
.chip-urgence{display:flex;align-items:center;gap:7px;background:var(--prio-bloque-fond);
color:var(--prio-bloque);border:1px solid color-mix(in srgb,var(--prio-bloque) 30%,transparent);
padding:6px 12px;border-radius:999px;font-weight:700;font-size:12.5px}
.point-pulse{width:8px;height:8px;border-radius:50%;background:var(--prio-bloque);animation:pulse 1.4s ease-out infinite}
@keyframes pulse{0%{box-shadow:0 0 0 0 color-mix(in srgb,var(--prio-bloque) 45%,transparent)}
70%{box-shadow:0 0 0 8px transparent}100%{box-shadow:0 0 0 0 transparent}}
@media (prefers-reduced-motion:reduce){.point-pulse{animation:none}}
.compte{margin-left:auto;display:flex;align-items:center;gap:10px}
.chip-demo{font-size:11px;font-weight:700;letter-spacing:.05em;color:var(--safran);
background:var(--safran-doux);padding:3px 9px;border-radius:999px;border:1px dashed var(--safran)}
.avatar{width:30px;height:30px;border-radius:50%;background:var(--primaire);color:#fff;display:flex;
align-items:center;justify-content:center;font-size:12px;font-weight:700;flex:none}
.compte .qui{line-height:1.15;font-size:12.5px}
.compte .qui small{color:var(--encre-2)}
/* Corps de page */
.page{padding:20px 24px;display:flex;flex-direction:column;gap:16px}
.entete-page{display:flex;align-items:center;gap:12px;flex-wrap:wrap}
.entete-page h1{font-size:21px;font-weight:700;letter-spacing:-.01em;text-wrap:balance}
.entete-page .actions{margin-left:auto;display:flex;gap:8px}
.filajout{color:var(--encre-3);font-size:12.5px}
.filajout a{color:var(--encre-2);text-decoration:none}
/* Boutons */
.btn{display:inline-flex;align-items:center;gap:7px;padding:8px 14px;border-radius:8px;font-size:13.5px;
font-weight:600;border:1px solid var(--bordure-forte);background:var(--surface);color:var(--encre);
transition:filter var(--transition)}
.btn:hover{filter:brightness(.97)}
.btn.prim{background:var(--primaire);border-color:var(--primaire);color:#fff}
.btn.succes{background:var(--succes);border-color:var(--succes);color:#fff}
.btn.danger-l{color:var(--danger);border-color:color-mix(in srgb,var(--danger) 40%,transparent);background:transparent}
.btn.ghost{border-color:transparent;background:transparent;color:var(--encre-2)}
.btn:disabled{opacity:.45;cursor:not-allowed}
.btn svg{width:15px;height:15px;stroke-width:2}
/* Cartes */
.carte{background:var(--surface);border:1px solid var(--bordure);border-radius:var(--rayon);padding:16px 18px}
.carte h2{font-size:13px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:var(--encre-2);margin-bottom:12px}
.grille-2{display:grid;grid-template-columns:1fr 1fr;gap:16px}
.grille-3{display:grid;grid-template-columns:repeat(3,1fr);gap:16px}
@media(max-width:900px){.grille-2,.grille-3{grid-template-columns:1fr}}
/* Tuiles KPI */
.kpis{display:grid;grid-template-columns:repeat(5,1fr);gap:12px}
@media(max-width:1100px){.kpis{grid-template-columns:repeat(2,1fr)}}
.kpi{background:var(--surface);border:1px solid var(--bordure);border-radius:var(--rayon);padding:14px 16px}
.kpi .lib{font-size:11.5px;letter-spacing:.05em;text-transform:uppercase;color:var(--encre-2);font-weight:600}
.kpi .val{font-size:27px;font-weight:700;letter-spacing:-.02em;margin-top:4px}
.kpi .delta{font-size:12px;font-weight:600;margin-top:2px}
.delta.bon{color:var(--succes)}.delta.mauvais{color:var(--danger)}.delta.neutre{color:var(--encre-3)}
.kpi.alarme{border-color:color-mix(in srgb,var(--danger) 45%,transparent)}
.kpi.alarme .val{color:var(--danger)}
.anneau{display:flex;align-items:center;gap:12px}
.anneau svg{flex:none}
/* Pastilles statut / priorité */
.st{display:inline-flex;align-items:center;gap:6px;padding:2px 10px;border-radius:999px;font-size:12px;font-weight:700}
.st::before{content:"";width:7px;height:7px;border-radius:50%;background:currentColor}
.st.ouvert{color:var(--st-ouvert);background:var(--st-ouvert-fond)}
.st.encours{color:var(--st-encours);background:var(--st-encours-fond)}
.st.attente{color:var(--st-attente);background:var(--st-attente-fond)}
.st.termine{color:var(--st-termine);background:var(--st-termine-fond)}
.st.annule{color:var(--st-annule);background:var(--st-annule-fond)}
.prio{display:inline-flex;align-items:center;gap:6px;font-size:12.5px;font-weight:600}
.prio i{width:8px;height:8px;border-radius:50%;flex:none}
.prio.bloque{color:var(--prio-bloque)}.prio.bloque i{background:var(--prio-bloque);animation:pulse 1.4s ease-out infinite}
.prio.haute{color:var(--prio-haute)}.prio.haute i{background:var(--prio-haute)}
.prio.moyenne{color:var(--prio-moyenne)}.prio.moyenne i{background:var(--prio-moyenne)}
.prio.basse{color:var(--prio-basse)}.prio.basse i{background:var(--prio-basse)}
/* Bandeau urgence */
.bandeau-urgence{display:flex;align-items:center;gap:14px;background:var(--prio-bloque-fond);
border:1px solid color-mix(in srgb,var(--prio-bloque) 35%,transparent);border-left:4px solid var(--prio-bloque);
border-radius:var(--rayon);padding:12px 16px}
.bandeau-urgence b{color:var(--prio-bloque)}
.bandeau-urgence .depuis{color:var(--encre-2);font-size:12.5px}
/* Tables */
.table{width:100%;overflow-x:auto}
.table table{width:100%;font-size:13.5px}
.table th{font-size:11px;letter-spacing:.06em;text-transform:uppercase;color:var(--encre-2);text-align:left;
padding:9px 12px;border-bottom:1px solid var(--bordure);background:var(--surface-2);white-space:nowrap}
.table td{padding:9px 12px;border-bottom:1px solid var(--bordure);vertical-align:middle}
.table tbody tr:hover{background:var(--primaire-doux)}
.table .ref{font-weight:700;color:var(--primaire)}
.table .sous{color:var(--encre-2);font-size:12px;display:block}
.ligne-bloque td:first-child{box-shadow:inset 3px 0 0 var(--prio-bloque)}
.avatars{display:flex}
.avatars .avatar{width:24px;height:24px;font-size:10px;border:2px solid var(--surface);margin-left:-6px}
.avatars .avatar:first-child{margin-left:0}
/* Filtres */
.filtres{display:flex;gap:8px;flex-wrap:wrap;align-items:center}
.select{display:inline-flex;align-items:center;gap:6px;border:1px solid var(--bordure-forte);
border-radius:8px;padding:7px 11px;font-size:13px;background:var(--surface);color:var(--encre-2)}
.select b{color:var(--encre);font-weight:600}
/* Graphiques */
.graf{display:flex;flex-direction:column;gap:10px}
.barres-h .ligne-b{display:grid;grid-template-columns:110px 1fr 40px;align-items:center;gap:10px;font-size:13px}
.barres-h .fond-b{background:var(--graf-grille);border-radius:4px;height:14px;overflow:hidden}
.barres-h .rempli{height:100%;border-radius:4px 0 0 4px}
.barres-h .valeur{text-align:right;font-weight:600}
.legende{display:flex;gap:14px;flex-wrap:wrap;font-size:12px;color:var(--encre-2)}
.legende span{display:inline-flex;align-items:center;gap:6px}
.legende i{width:9px;height:9px;border-radius:3px}
/* Connexion */
.conn{min-height:640px;display:flex;align-items:center;justify-content:center;background:
linear-gradient(160deg,var(--fond) 55%,color-mix(in srgb,var(--primaire) 7%,var(--fond)))}
.carte-conn{width:400px;max-width:94%;background:var(--surface);border:1px solid var(--bordure);
border-radius:14px;padding:32px;display:flex;flex-direction:column;gap:14px}
.carte-conn .logo{padding:0 0 4px;color:var(--encre)}
.carte-conn .logo small{color:var(--encre-2)}
.champ label{display:block;font-size:12.5px;font-weight:600;color:var(--encre-2);margin-bottom:5px}
.champ input{width:100%;padding:9px 12px;border:1px solid var(--bordure-forte);border-radius:8px;
font:inherit;background:var(--surface);color:var(--encre)}
.champ input::placeholder{color:var(--encre-3)}
.sep{display:flex;align-items:center;gap:10px;color:var(--encre-3);font-size:11.5px;
letter-spacing:.06em;text-transform:uppercase;margin-top:6px}
.sep::before,.sep::after{content:"";flex:1;height:1px;background:var(--bordure)}
.demo-liste{display:flex;flex-direction:column;gap:6px}
.demo-liste button{display:flex;align-items:center;gap:10px;padding:8px 10px;border:1px solid var(--bordure);
border-radius:8px;background:var(--surface);text-align:left;transition:border-color var(--transition)}
.demo-liste button:hover{border-color:var(--primaire);background:var(--primaire-doux)}
.demo-liste .role{margin-left:auto;font-size:11.5px;color:var(--encre-2)}
/* Fiche : listes de définitions */
.infos{display:grid;grid-template-columns:130px 1fr;row-gap:9px;font-size:13.5px}
.infos dt{color:var(--encre-2)}
.infos dd{font-weight:500}
.infos a{color:var(--primaire);text-decoration:none;font-weight:600}
.chrono{list-style:none;display:flex;flex-direction:column;gap:0;font-size:13px}
.chrono li{position:relative;padding:0 0 16px 22px}
.chrono li::before{content:"";position:absolute;left:5px;top:5px;width:8px;height:8px;border-radius:50%;
background:var(--bordure-forte)}
.chrono li.fait::before{background:var(--primaire)}
.chrono li::after{content:"";position:absolute;left:8.5px;top:15px;bottom:-2px;width:1px;background:var(--bordure)}
.chrono li:last-child::after{display:none}
.chrono .quand{color:var(--encre-3);font-size:11.5px}
.check{display:flex;align-items:center;gap:10px;padding:9px 0;border-bottom:1px solid var(--bordure);font-size:13.5px}
.check:last-of-type{border-bottom:0}
.coche{width:19px;height:19px;border-radius:5px;border:1.5px solid var(--bordure-forte);flex:none;
display:flex;align-items:center;justify-content:center;color:#fff}
.coche.ok{background:var(--succes);border-color:var(--succes)}
.coche.na{background:var(--encre-3);border-color:var(--encre-3)}
.check .qui-fait{margin-left:auto;color:var(--encre-3);font-size:12px}
.total{display:flex;justify-content:space-between;font-weight:700;padding-top:10px;font-size:14px}
/* Bilan codé */
.bilan{display:grid;grid-template-columns:1fr 1fr;gap:10px 14px}
@media(max-width:900px){.bilan{grid-template-columns:1fr}}
.bilan .champ-b{font-size:12.5px}
.bilan .champ-b label{color:var(--encre-2);font-weight:600;display:block;margin-bottom:4px}
.bilan .champ-b label em{color:var(--danger);font-style:normal}
.faux-select{display:flex;justify-content:space-between;align-items:center;border:1px solid var(--bordure-forte);
border-radius:8px;padding:8px 11px;background:var(--surface);color:var(--encre)}
.faux-select.vide{color:var(--encre-3)}
/* Organes / documents */
.item-liste{display:flex;align-items:center;gap:12px;padding:10px 0;border-bottom:1px solid var(--bordure);font-size:13.5px}
.item-liste:last-child{border-bottom:0}
.item-liste .ico{width:34px;height:34px;border-radius:8px;background:var(--surface-2);display:flex;
align-items:center;justify-content:center;color:var(--encre-2);flex:none}
.item-liste .ico svg{width:16px;height:16px;stroke-width:1.75}
.item-liste .fin{margin-left:auto;display:flex;align-items:center;gap:10px;color:var(--encre-2);font-size:12.5px}
.qr{display:flex;gap:16px;align-items:center}
.qr svg{border:1px solid var(--bordure);border-radius:8px;background:#fff;padding:8px;flex:none}
/* Portail demandeur */
.portail{max-width:430px;margin:28px auto;display:flex;flex-direction:column;gap:14px}
.gros-toggle{display:flex;align-items:center;gap:12px;background:var(--prio-bloque-fond);
border:1px solid color-mix(in srgb,var(--prio-bloque) 30%,transparent);border-radius:10px;padding:12px 14px}
.gros-toggle b{color:var(--prio-bloque)}
.interrupteur{margin-left:auto;width:44px;height:24px;border-radius:999px;background:var(--bordure-forte);position:relative;flex:none}
.interrupteur::after{content:"";position:absolute;top:2px;left:2px;width:20px;height:20px;border-radius:50%;background:#fff}
.zone-photo{border:1.5px dashed var(--bordure-forte);border-radius:10px;padding:18px;text-align:center;color:var(--encre-2);font-size:13px}
.suivi-simple{display:flex;align-items:center;gap:0;font-size:11.5px;color:var(--encre-3);margin-top:6px}
.suivi-simple .etape{display:flex;align-items:center;gap:6px}
.suivi-simple .etape.fait{color:var(--succes);font-weight:700}
.suivi-simple .lien-e{width:26px;height:1px;background:var(--bordure-forte);margin:0 6px}
/* Mobile */
.tels{display:flex;gap:24px;justify-content:center;flex-wrap:wrap}
.tel{width:300px;border:1px solid var(--bordure-forte);border-radius:28px;overflow:hidden;background:var(--fond);
box-shadow:var(--ombre-menu)}
.tel .encoche{height:26px;background:var(--nav-fond);display:flex;justify-content:center;align-items:center}
.tel .encoche i{width:70px;height:7px;border-radius:999px;background:rgb(255 255 255/.18)}
.tel .ecran-tel{padding:14px;display:flex;flex-direction:column;gap:10px;min-height:520px}
.tel h3{font-size:16px;font-weight:700;display:flex;align-items:center;gap:8px}
.tel h3 .sync{margin-left:auto;font-size:10.5px;font-weight:700;color:var(--st-termine);
background:var(--st-termine-fond);padding:2px 8px;border-radius:999px}
.tel h3 .sync.off{color:var(--st-attente);background:var(--st-attente-fond)}
.carte-ot-tel{background:var(--surface);border:1px solid var(--bordure);border-radius:12px;padding:12px}
.carte-ot-tel .type-t{font-size:10.5px;letter-spacing:.06em;text-transform:uppercase;color:var(--encre-2);
font-weight:700;display:flex;justify-content:space-between;align-items:center}
.carte-ot-tel b{display:block;margin:3px 0 2px;font-size:14.5px}
.carte-ot-tel .ou{color:var(--encre-2);font-size:12.5px}
.btn-tel{display:flex;justify-content:center;align-items:center;gap:8px;padding:12px;border-radius:10px;
font-weight:700;font-size:14.5px;background:var(--primaire);color:#fff;width:100%}
.btn-tel.vert{background:var(--succes)}
.btn-tel.gris{background:var(--bordure-forte);color:var(--surface)}
.paire-boutons{display:flex;gap:8px}
.btn-choix{flex:1;text-align:center;padding:9px;border:1.5px solid var(--bordure-forte);border-radius:9px;font-weight:600;font-size:13px}
.btn-choix.actif{border-color:var(--primaire);background:var(--primaire-doux);color:var(--primaire)}
.viseur{flex:1;min-height:330px;border-radius:12px;background:
radial-gradient(circle at 50% 45%, #2c3a52 0%, #131c2c 70%);position:relative;display:flex;
align-items:center;justify-content:center}
.viseur .cadre-qr{width:170px;height:170px;border-radius:14px;border:2.5px solid var(--safran);
box-shadow:0 0 0 2000px rgb(9 14 22/.45)}
.viseur p{position:absolute;bottom:14px;color:#dfe7f2;font-size:12.5px}
/* Design system : nuanciers */
.nuancier{display:flex;gap:8px;flex-wrap:wrap}
.puce-c{width:84px;font-size:10.5px;color:var(--encre-2)}
.puce-c i{display:block;height:40px;border-radius:8px;border:1px solid var(--bordure);margin-bottom:4px}
</style>
<style>
/* ═══ Ajouts R1 (à reverser dans l'app après validation) ═══ */
/* Statuts d'ÉQUIPEMENT (distincts des statuts OT) */
.st.arret{color:var(--danger);background:var(--prio-bloque-fond)}
.st.maintenance{color:var(--st-encours);background:var(--st-encours-fond)}
/* Carte géographique (placeholder — Leaflet/OSM + PostGIS dans l'app) */
.geo{position:relative;border:1px solid var(--bordure);border-radius:var(--rayon);overflow:hidden;
background:
linear-gradient(var(--graf-grille) 1px,transparent 1px),
linear-gradient(90deg,var(--graf-grille) 1px,transparent 1px),
linear-gradient(160deg,var(--surface-2),var(--surface));
background-size:34px 34px,34px 34px,100% 100%;min-height:320px}
.geo .voie{position:absolute;background:var(--bordure);border-radius:2px}
.geo .pin{position:absolute;display:flex;flex-direction:column;align-items:center;transform:translate(-50%,-100%)}
.geo .pin i{width:26px;height:26px;border-radius:50% 50% 50% 0;transform:rotate(-45deg);
background:var(--primaire);border:2px solid var(--surface);box-shadow:var(--ombre-menu)}
.geo .pin i::after{content:"";position:absolute;inset:7px;border-radius:50%;background:var(--surface)}
.geo .pin.alerte i{background:var(--prio-bloque)}
.geo .pin b{margin-top:5px;font-size:11px;background:var(--surface);border:1px solid var(--bordure);
padding:2px 7px;border-radius:999px;white-space:nowrap}
.geo .attribution{position:absolute;right:8px;bottom:6px;font-size:10px;color:var(--encre-3)}
/* Arborescence des emplacements */
.arbre{list-style:none;padding:0;font-size:13.5px}
.arbre li{position:relative;padding:7px 0 7px 26px;border-bottom:1px solid var(--bordure)}
.arbre li:last-child{border-bottom:0}
.arbre li::before{content:"";position:absolute;left:8px;top:0;bottom:0;width:1px;background:var(--bordure)}
.arbre li::after{content:"";position:absolute;left:8px;top:50%;width:12px;height:1px;background:var(--bordure)}
.arbre li.racine{padding-left:0}
.arbre li.racine::before,.arbre li.racine::after{display:none}
.arbre .n2{margin-left:22px}
.arbre .meta{color:var(--encre-2);font-size:12px;margin-left:8px}
.arbre .fin{float:right;color:var(--encre-2);font-size:12px}
/* Formulaires R1 */
.form-grille{display:grid;grid-template-columns:1fr 1fr;gap:12px 14px}
@media(max-width:900px){.form-grille{grid-template-columns:1fr}}
.form-grille .pleine-l{grid-column:1/-1}
.ligne-organe{display:flex;gap:8px;align-items:center;padding:8px 0;border-bottom:1px solid var(--bordure)}
.ligne-organe:last-of-type{border-bottom:0}
.ligne-organe .faux-select{flex:1}
.btn-suppr{color:var(--encre-3);padding:6px;border-radius:6px}
.btn-suppr:hover{color:var(--danger);background:var(--prio-bloque-fond)}
/* Étiquette QR imprimable (A6) */
.zone-impression{display:flex;gap:24px;align-items:flex-start;flex-wrap:wrap}
.etiquette{width:340px;background:#fff;color:#1b2534;border:1px solid var(--bordure-forte);
border-radius:12px;padding:22px;display:flex;flex-direction:column;gap:12px;
box-shadow:var(--ombre-menu)}
.etiquette .tete{display:flex;align-items:center;gap:10px;border-bottom:2px solid #1b2534;padding-bottom:10px}
.etiquette .tete .marque{display:flex;flex-direction:column;line-height:.55;font-size:12px;color:#dd8a0b}
.etiquette .tete b{font-size:20px;letter-spacing:.04em}
.etiquette .corps{display:flex;gap:16px;align-items:center}
.etiquette .qr-grand{flex:none;border:1px solid #dce3ec;border-radius:8px;padding:6px;background:#fff}
.etiquette h3{font-size:15px;font-weight:700;margin:0}
.etiquette .ou{font-size:12px;color:#55647a}
.etiquette .consigne{font-size:12.5px;background:#fdf3e3;border:1px dashed #dd8a0b;color:#8a5a06;
border-radius:8px;padding:8px 10px;text-align:center;font-weight:600}
.etiquette .ref{font-size:11px;color:#8494ab;text-align:center;font-variant-numeric:tabular-nums}
/* Modale (invitation) — présentée ouverte dans la maquette */
.voile{background:color-mix(in srgb,var(--encre) 32%,transparent);border-radius:var(--rayon);
padding:34px;display:flex;align-items:flex-start;justify-content:center}
.modale{width:430px;max-width:100%;background:var(--surface);border:1px solid var(--bordure);
border-radius:12px;box-shadow:var(--ombre-menu);padding:20px;display:flex;flex-direction:column;gap:12px}
.modale h3{font-size:15px;font-weight:700}
.modale .pied{display:flex;justify-content:flex-end;gap:8px;margin-top:4px}
/* Équipes */
.equipes{display:grid;grid-template-columns:repeat(3,1fr);gap:12px}
@media(max-width:1000px){.equipes{grid-template-columns:1fr}}
.equipe{border:1px solid var(--bordure);border-radius:var(--rayon);padding:12px 14px;display:flex;
flex-direction:column;gap:8px;background:var(--surface)}
.equipe b{font-size:13.5px}
.equipe .zone{font-size:12px;color:var(--encre-2)}
</style>
<style>
/* ═══ Ajouts R3 (à reverser dans l'app après validation) ═══ */
/* Statuts de BON DE COMMANDE */
.st.brouillon{color:var(--st-annule);background:var(--st-annule-fond)}
.st.envoye{color:var(--st-ouvert);background:var(--st-ouvert-fond)}
.st.recu{color:var(--st-termine);background:var(--st-termine-fond)}
/* Alerte de stock sous seuil */
.stock-bas{display:inline-flex;align-items:center;gap:6px;color:var(--alerte);font-weight:700;font-size:12.5px}
.stock-bas::before{content:"";width:8px;height:8px;border-radius:50%;background:var(--alerte)}
.ligne-seuil td:first-child{box-shadow:inset 3px 0 0 var(--alerte)}
/* Mouvements de stock : entrée / sortie */
.mvt{display:inline-flex;align-items:center;gap:5px;font-weight:700;font-size:12.5px}
.mvt.entree{color:var(--succes)}
.mvt.sortie{color:var(--danger)}
/* Documents (bibliothèque) */
.docs{display:grid;grid-template-columns:repeat(4,1fr);gap:12px}
@media(max-width:1100px){.docs{grid-template-columns:repeat(2,1fr)}}
.doc{border:1px solid var(--bordure);border-radius:var(--rayon);background:var(--surface);
padding:12px;display:flex;flex-direction:column;gap:8px;font-size:12.5px}
.doc .vignette{height:84px;border-radius:8px;background:var(--surface-2);display:flex;
align-items:center;justify-content:center;color:var(--encre-3);font-size:24px}
.doc b{font-size:13px;word-break:break-all}
.doc .meta{color:var(--encre-2);font-size:11.5px}
.type-doc{display:inline-flex;font-size:10.5px;font-weight:700;letter-spacing:.05em;
text-transform:uppercase;color:var(--primaire);background:var(--primaire-doux);
padding:2px 8px;border-radius:999px;align-self:flex-start}
/* Total & lignes de coûts */
.total{display:flex;justify-content:space-between;font-weight:700;padding-top:10px;font-size:14px}
.item-liste .ico{width:34px;height:34px;border-radius:8px;background:var(--surface-2);display:flex;
align-items:center;justify-content:center;color:var(--encre-2);flex:none}
.item-liste .ico svg{width:16px;height:16px;stroke-width:1.75}
</style>
<!-- ═══════════ BARRE DE REVUE ═══════════ -->
<header class="revue">
<b>SIOP V2 · Maquettes R3 — Gestion</b>
<nav class="onglets" role="tablist" aria-label="Écrans">
<button role="tab" aria-selected="true" data-cible="stock">1 · Stock</button>
<button role="tab" aria-selected="false" data-cible="fiche-piece">2 · Fiche pièce</button>
<button role="tab" aria-selected="false" data-cible="bons">3 · Bons de commande</button>
<button role="tab" aria-selected="false" data-cible="couts-ot">4 · Coûts sur OT</button>
<button role="tab" aria-selected="false" data-cible="statistiques">5 · Statistiques</button>
<button role="tab" aria-selected="false" data-cible="tiers">6 · Tiers</button>
<button role="tab" aria-selected="false" data-cible="bibliotheque">7 · Bibliothèque</button>
</nav>
<div class="droite"><button class="theme" id="btn-theme">Thème : auto</button></div>
</header>
<!-- ═══════════ 1 · STOCK ═══════════ -->
<p class="note-ecran" data-note="stock"><b>Intention :</b> le stock est <b>DÉRIVÉ des mouvements</b> (décision v1 éprouvée) — jamais de champ « quantité » éditable. Sous le seuil : strie ambre + alerte, et le bouton « préparer le BC » prérempli. Prix unitaire = dernier prix d'achat (figé à chaque consommation).</p>
<section class="ecran actif" id="stock">
<div class="app"><aside class="nav">
<div class="logo"><span class="marque"><br></span><div><b>SIOP</b></div></div>
<div class="groupe">Ressources</div>
<a href="#" class="actif"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="M21 8l-9-5-9 5v8l9 5 9-5V8zM3.3 8.3L12 13l8.7-4.7M12 13v9"/></svg>Stock &amp; achats</a>
<a href="#"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="M9 21a7 7 0 1 1 6-11l6 6v3h-3l-1-1-2 1-1-2-2 1z" transform="rotate(180 12 12)"/><circle cx="9" cy="9" r="1.5"/></svg>Tiers</a>
<a href="#"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><path d="M14 2v6h6"/></svg>Fichiers</a>
</aside>
<div class="contenu">
<div class="topbar">
<div class="recherche"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><circle cx="11" cy="11" r="7"/><path d="m21 21-4-4"/></svg>Rechercher une pièce…</div>
<div class="compte"><span class="chip-demo">DÉMO</span><span class="avatar" style="background:var(--graf-4)">NB</span>
<div class="qui"><b>Nadia Berrada</b><br><small>Gestionnaire ▾</small></div></div>
</div>
<div class="page">
<div class="entete-page">
<h1>Stock de pièces</h1><span class="filajout">42 références · <span class="stock-bas">2 sous le seuil</span></span>
<div class="actions">
<button class="btn">Entrée de stock</button>
<button class="btn prim"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="M12 5v14M5 12h14"/></svg>Nouvelle pièce</button>
</div>
</div>
<div class="filtres">
<span class="select">Alerte : <b>Toutes</b></span>
<span class="select">Fournisseur : <b>Tous</b></span>
</div>
<div class="carte" style="padding:0"><div class="table"><table>
<thead><tr><th>Réf.</th><th>Désignation</th><th>Stock</th><th>Seuil</th><th>Dernier PU</th><th>Fournisseur</th><th></th></tr></thead>
<tbody>
<tr class="ligne-seuil"><td class="ref num">P-0113</td><td>Contact de porte NC-31</td><td class="num"><b>2</b></td><td class="num">5</td><td class="num">85 MAD</td><td>Ascentech Maroc</td><td><span class="stock-bas">Sous le seuil</span> · <a href="#" style="color:var(--primaire);font-weight:600">Préparer le BC</a></td></tr>
<tr class="ligne-seuil"><td class="ref num">P-0087</td><td>Coulisseau de guide 16 mm</td><td class="num"><b>4</b></td><td class="num">6</td><td class="num">120 MAD</td><td>Ascentech Maroc</td><td><span class="stock-bas">Sous le seuil</span> · <a href="#" style="color:var(--primaire);font-weight:600">Préparer le BC</a></td></tr>
<tr><td class="ref num">P-0042</td><td>Graisse guide (cartouche 400 g)</td><td class="num">18</td><td class="num">8</td><td class="num">85 MAD</td><td>Lubmaroc</td><td></td></tr>
<tr><td class="ref num">P-0031</td><td>Bouton palier lumineux Ø22</td><td class="num">26</td><td class="num">10</td><td class="num">45 MAD</td><td>Ascentech Maroc</td><td></td></tr>
<tr><td class="ref num">P-0019</td><td>Cellule barrière porte (paire)</td><td class="num">7</td><td class="num">4</td><td class="num">640 MAD</td><td>SchindlerParts</td><td></td></tr>
</tbody>
</table></div></div>
<div class="carte" style="border-style:dashed;color:var(--encre-2);font-size:13px">
Le stock affiché = somme des mouvements (réceptions de BC, entrées manuelles, consommations d'OT,
ajustements d'inventaire motivés). <b>Aucune saisie directe de quantité.</b>
</div>
</div>
</div>
</div>
</section>
<!-- ═══════════ 2 · FICHE PIÈCE ═══════════ -->
<p class="note-ecran" data-note="fiche-piece" hidden><b>Intention :</b> l'histoire d'une pièce — chaque ligne de stock vient d'un mouvement daté, tracé, motivé (réception BC, consommation OT, ajustement). Le lien vers l'OT ou le BC est toujours cliquable.</p>
<section class="ecran" id="fiche-piece">
<div class="app"><aside class="nav">
<div class="logo"><span class="marque"><br></span><div><b>SIOP</b></div></div>
<div class="groupe">Ressources</div>
<a href="#" class="actif"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="M21 8l-9-5-9 5v8l9 5 9-5V8zM3.3 8.3L12 13l8.7-4.7M12 13v9"/></svg>Stock &amp; achats</a>
</aside>
<div class="contenu">
<div class="topbar">
<div class="recherche"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><circle cx="11" cy="11" r="7"/><path d="m21 21-4-4"/></svg>Rechercher…</div>
<div class="compte"><span class="chip-demo">DÉMO</span><span class="avatar" style="background:var(--graf-4)">NB</span>
<div class="qui"><b>Nadia Berrada</b><br><small>Gestionnaire ▾</small></div></div>
</div>
<div class="page">
<div class="filajout"><a href="#">Stock</a> / P-0113</div>
<div class="entete-page">
<h1>Contact de porte NC-31</h1><span class="stock-bas">Sous le seuil</span>
<div class="actions"><button class="btn">Ajustement d'inventaire</button><button class="btn prim">Préparer le BC</button></div>
</div>
<div class="grille-2">
<div class="carte">
<h2>Identité</h2>
<dl class="infos">
<dt>Référence</dt><dd class="num">P-0113</dd>
<dt>Stock actuel</dt><dd class="num"><b>2</b> (seuil : 5)</dd>
<dt>Dernier PU</dt><dd class="num">85 MAD <span style="color:var(--encre-2)">(BC-2026-0021, 12 juin)</span></dd>
<dt>Fournisseur</dt><dd><a href="#">Ascentech Maroc</a></dd>
<dt>Compatible</dt><dd>Otis Gen2 · Schindler 3300</dd>
</dl>
</div>
<div class="carte">
<h2>Mouvements <span style="text-transform:none;letter-spacing:0;color:var(--encre-3)">— le stock EST cette liste</span></h2>
<div class="table"><table>
<thead><tr><th>Date</th><th>Mouvement</th><th>Qté</th><th>Origine</th></tr></thead>
<tbody>
<tr><td class="num">14 juil.</td><td><span class="mvt sortie"> Sortie</span></td><td class="num">1</td><td><a href="#" class="ref num">OT-2026-0336</a> · Ahmed</td></tr>
<tr><td class="num">2 juil.</td><td><span class="mvt sortie"> Sortie</span></td><td class="num">2</td><td><a href="#" class="ref num">OT-2026-0329</a> · Fatima-Zahra</td></tr>
<tr><td class="num">12 juin</td><td><span class="mvt entree">+ Réception</span></td><td class="num">5</td><td><a href="#" class="ref num">BC-2026-0021</a> · 85 MAD/u</td></tr>
<tr><td class="num">3 mai</td><td><span class="mvt sortie"> Ajustement</span></td><td class="num">1</td><td>Inventaire — pièce endommagée (Nadia)</td></tr>
</tbody>
</table></div>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- ═══════════ 3 · BONS DE COMMANDE ═══════════ -->
<p class="note-ecran" data-note="bons" hidden><b>Intention :</b> le circuit d'achat minimal : Brouillon → Envoyé → Reçu. <b>La réception crée les mouvements d'entrée</b> (et fige le PU). Le BC préparé depuis une alerte arrive prérempli.</p>
<section class="ecran" id="bons">
<div class="app"><aside class="nav">
<div class="logo"><span class="marque"><br></span><div><b>SIOP</b></div></div>
<div class="groupe">Ressources</div>
<a href="#" class="actif"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="M21 8l-9-5-9 5v8l9 5 9-5V8zM3.3 8.3L12 13l8.7-4.7M12 13v9"/></svg>Stock &amp; achats</a>
</aside>
<div class="contenu">
<div class="topbar">
<div class="recherche"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><circle cx="11" cy="11" r="7"/><path d="m21 21-4-4"/></svg>Rechercher…</div>
<div class="compte"><span class="chip-demo">DÉMO</span><span class="avatar" style="background:var(--graf-4)">NB</span>
<div class="qui"><b>Nadia Berrada</b><br><small>Gestionnaire ▾</small></div></div>
</div>
<div class="page">
<div class="entete-page">
<h1>Bons de commande</h1>
<div class="actions"><button class="btn prim"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="M12 5v14M5 12h14"/></svg>Nouveau BC</button></div>
</div>
<div class="grille-2" style="grid-template-columns:1.1fr 1fr">
<div class="carte" style="padding:0"><div class="table"><table>
<thead><tr><th></th><th>Fournisseur</th><th>Lignes</th><th>Total</th><th>Statut</th></tr></thead>
<tbody>
<tr style="background:var(--primaire-doux)"><td class="ref num">BC-2026-0024</td><td>Ascentech Maroc</td><td class="num">2</td><td class="num">1 105 MAD</td><td><span class="st envoye">Envoyé</span></td></tr>
<tr><td class="ref num">BC-2026-0023</td><td>SchindlerParts</td><td class="num">1</td><td class="num">1 280 MAD</td><td><span class="st brouillon">Brouillon</span></td></tr>
<tr><td class="ref num">BC-2026-0021</td><td>Ascentech Maroc</td><td class="num">3</td><td class="num">1 940 MAD</td><td><span class="st recu">Reçu</span></td></tr>
<tr><td class="ref num">BC-2026-0019</td><td>Lubmaroc</td><td class="num">1</td><td class="num">850 MAD</td><td><span class="st recu">Reçu</span></td></tr>
</tbody>
</table></div></div>
<div class="panneau">
<h2 style="font-size:13px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:var(--encre-2)">BC-2026-0024 — Ascentech Maroc</h2>
<div class="table"><table>
<thead><tr><th>Pièce</th><th>Qté</th><th>PU</th><th>Total</th></tr></thead>
<tbody>
<tr><td>Contact de porte NC-31</td><td class="num">10</td><td class="num">85</td><td class="num">850</td></tr>
<tr><td>Coulisseau de guide 16 mm</td><td class="num">2</td><td class="num">127,50</td><td class="num">255</td></tr>
</tbody>
</table></div>
<div class="total"><span>Total</span><span class="num">1 105 MAD</span></div>
<div style="display:flex;gap:8px;justify-content:flex-end">
<button class="btn danger-l">Annuler le BC</button>
<button class="btn succes">Réceptionner (→ entrées de stock)</button>
</div>
<p style="font-size:12px;color:var(--encre-3)">La réception crée un mouvement d'entrée par ligne et fige le PU — le stock remonte, l'alerte s'éteint.</p>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- ═══════════ 4 · COÛTS SUR OT ═══════════ -->
<p class="note-ecran" data-note="couts-ot" hidden><b>Intention :</b> la carte « Pièces &amp; main-d'œuvre » (fiche OT validée R0) devient réelle : consommer une pièce <b>décrémente le stock et FIGE le prix</b> ; la main-d'œuvre = heures × <b>taux figé</b> de la personne (géré dans Personnes). Le coût total suit l'OT pour toujours, même si prix et taux changent ensuite.</p>
<section class="ecran" id="couts-ot">
<div class="app"><aside class="nav">
<div class="logo"><span class="marque"><br></span><div><b>SIOP</b></div></div>
<div class="groupe">Exploitation</div>
<a href="#" class="actif"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="M14.7 6.3a4.5 4.5 0 0 0-6 6L3 18v3h3l5.7-5.7a4.5 4.5 0 0 0 6-6l-2.6 2.6-2.4-2.4z"/></svg>Ordres de travail</a>
</aside>
<div class="contenu">
<div class="topbar">
<div class="recherche"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><circle cx="11" cy="11" r="7"/><path d="m21 21-4-4"/></svg>Rechercher…</div>
<div class="compte"><span class="chip-demo">DÉMO</span><span class="avatar" style="background:var(--graf-3)">AB</span>
<div class="qui"><b>Ahmed Benali</b><br><small>Technicien ▾</small></div></div>
</div>
<div class="page">
<div class="filajout"><a href="#">Ordres de travail</a> / OT-2026-0341</div>
<div class="entete-page"><h1>Bruit anormal en gaine</h1><span class="st encours">En cours</span></div>
<div class="grille-2">
<div class="carte">
<h2>Pièces &amp; main-d'œuvre</h2>
<div class="item-liste"><span class="ico"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="M21 8l-9-5-9 5v8l9 5 9-5V8z"/></svg></span>Coulisseau de guide 16 mm × 2<span class="fin num">240 MAD</span></div>
<div class="item-liste"><span class="ico"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="M21 8l-9-5-9 5v8l9 5 9-5V8z"/></svg></span>Graisse guide (cartouche) × 1<span class="fin num">85 MAD</span></div>
<div class="item-liste"><span class="ico"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 3"/></svg></span>Ahmed Benali · 1 h 30 × 120 MAD/h<span class="fin num">180 MAD</span></div>
<div class="total"><span>Coût total de l'OT</span><span class="num">505 MAD</span></div>
<div style="display:flex;gap:8px;margin-top:10px">
<button class="btn"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="M12 5v14M5 12h14"/></svg>Consommer une pièce</button>
<button class="btn"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><circle cx="12" cy="12" r="9"/><path d="M12 7v5l3 3"/></svg>Saisir du temps</button>
</div>
</div>
<div class="voile" style="border-radius:var(--rayon)">
<div class="modale" style="position:static;transform:none;width:380px">
<h3>Consommer une pièce</h3>
<div class="champ"><label>Pièce</label><div class="faux-select">Coulisseau de guide 16 mm — stock : 4 <span></span></div></div>
<div class="champ"><label for="cp-qte">Quantité</label><input id="cp-qte" value="2" class="num" style="width:90px"></div>
<div class="note-douce" style="font-size:12px;background:var(--surface-2);border-radius:8px;padding:8px 10px;color:var(--encre-2)">
Prix figé à la consommation : <b class="num">120 MAD/u</b> (dernier prix d'achat).
Le stock passera à <b class="num">2</b> — sous le seuil, une alerte partira.
</div>
<div class="pied"><button class="btn">Annuler</button><button class="btn prim">Consommer ( stock, prix figé)</button></div>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- ═══════════ 5 · STATISTIQUES ═══════════ -->
<p class="note-ecran" data-note="statistiques" hidden><b>Intention :</b> M. Bennis lit en 30 s : coûts, pannes par organe (ENFIN alimenté par les bilans codés), taux de préventif, top équipements. Palette graphique validée CVD, étiquettes directes, chiffres tabulaires.</p>
<section class="ecran" id="statistiques">
<div class="app"><aside class="nav">
<div class="logo"><span class="marque"><br></span><div><b>SIOP</b></div></div>
<div class="groupe">Pilotage</div>
<a href="#" class="actif"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="M3 3v18h18"/><rect x="7" y="12" width="3" height="6"/><rect x="12" y="8" width="3" height="10"/><rect x="17" y="5" width="3" height="13"/></svg>Statistiques</a>
<a href="#"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><circle cx="9" cy="8" r="3.5"/><path d="M2.5 20a6.5 6.5 0 0 1 13 0M17 8a3 3 0 1 1 0 .01M16.5 13.5a6 6 0 0 1 5 6"/></svg>Personnes</a>
</aside>
<div class="contenu">
<div class="topbar">
<div class="recherche"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><circle cx="11" cy="11" r="7"/><path d="m21 21-4-4"/></svg>Rechercher…</div>
<div class="compte"><span class="chip-demo">DÉMO</span><span class="avatar" style="background:var(--safran)">RB</span>
<div class="qui"><b>Rachid Bennis</b><br><small>Vue seule ▾</small></div></div>
</div>
<div class="page">
<div class="entete-page">
<h1>Statistiques</h1>
<div class="actions"><span class="select">Période : <b>12 derniers mois</b></span></div>
</div>
<div class="kpis" style="grid-template-columns:repeat(4,1fr)">
<div class="kpi"><div class="lib">Coût · juillet</div><div class="val num">18 450 <span style="font-size:14px;color:var(--encre-2)">MAD</span></div><div class="delta bon">12 % vs juin</div></div>
<div class="kpi"><div class="lib">OT clôturés · 12 mois</div><div class="val num">241</div><div class="delta neutre">dont 148 préventifs</div></div>
<div class="kpi"><div class="lib">Taux de préventif</div><div class="val num">92 %</div><div class="delta bon">grilles faites / dues</div></div>
<div class="kpi"><div class="lib">Durée moyenne de résolution</div><div class="val num">2,4 j</div><div class="delta neutre">dépannages, 12 mois</div></div>
</div>
<div class="grille-2">
<div class="carte graf">
<h2>Pannes par organe · 12 mois <span style="text-transform:none;letter-spacing:0;color:var(--encre-3)">(bilans codés)</span></h2>
<div class="barres-h">
<div class="ligne-b"><span>Portes</span><div class="fond-b"><div class="rempli" style="width:100%;background:var(--graf-1)"></div></div><span class="valeur num">34</span></div>
<div class="ligne-b"><span>Armoire cde</span><div class="fond-b"><div class="rempli" style="width:53%;background:var(--graf-1)"></div></div><span class="valeur num">18</span></div>
<div class="ligne-b"><span>Boutons</span><div class="fond-b"><div class="rempli" style="width:35%;background:var(--graf-1)"></div></div><span class="valeur num">12</span></div>
<div class="ligne-b"><span>Guides</span><div class="fond-b"><div class="rempli" style="width:26%;background:var(--graf-1)"></div></div><span class="valeur num">9</span></div>
<div class="ligne-b"><span>Treuil</span><div class="fond-b"><div class="rempli" style="width:21%;background:var(--graf-1)"></div></div><span class="valeur num">7</span></div>
</div>
</div>
<div class="carte graf">
<h2>Coûts par mois <span style="text-transform:none;letter-spacing:0;color:var(--encre-3)">(pièces + main-d'œuvre, MAD)</span></h2>
<div class="barres-h">
<div class="ligne-b"><span>Mars</span><div class="fond-b"><div class="rempli" style="width:72%;background:var(--graf-2)"></div></div><span class="valeur num">21 k</span></div>
<div class="ligne-b"><span>Avril</span><div class="fond-b"><div class="rempli" style="width:60%;background:var(--graf-2)"></div></div><span class="valeur num">17 k</span></div>
<div class="ligne-b"><span>Mai</span><div class="fond-b"><div class="rempli" style="width:100%;background:var(--graf-2)"></div></div><span class="valeur num">29 k</span></div>
<div class="ligne-b"><span>Juin</span><div class="fond-b"><div class="rempli" style="width:73%;background:var(--graf-2)"></div></div><span class="valeur num">21 k</span></div>
<div class="ligne-b"><span>Juillet</span><div class="fond-b"><div class="rempli" style="width:64%;background:var(--graf-2)"></div></div><span class="valeur num">18,5 k</span></div>
</div>
</div>
</div>
<div class="carte">
<h2>Top équipements en coût · 12 mois</h2>
<div class="table"><table>
<thead><tr><th>Appareil</th><th>Site</th><th>Dépannages</th><th>Pièces</th><th>Main-d'œuvre</th><th>Total</th></tr></thead>
<tbody>
<tr><td class="ref num">B2</td><td>Tour Atlas</td><td class="num">9</td><td class="num">6 420</td><td class="num">3 240</td><td class="num"><b>9 660 MAD</b></td></tr>
<tr><td class="ref num">A1</td><td>Résidence Al Manar</td><td class="num">6</td><td class="num">2 210</td><td class="num">1 560</td><td class="num"><b>3 770 MAD</b></td></tr>
<tr><td class="ref num">C1</td><td>Anfa Place</td><td class="num">4</td><td class="num">1 890</td><td class="num">980</td><td class="num"><b>2 870 MAD</b></td></tr>
</tbody>
</table></div>
</div>
</div>
</div>
</div>
</section>
<!-- ═══════════ 6 · TIERS ═══════════ -->
<p class="note-ecran" data-note="tiers" hidden><b>Intention :</b> l'annuaire minimal — fournisseurs de pièces et syndics/clients des sites. Un tiers se rattache aux BC (fournisseur) ou aux sites (syndic). Fiche simple, pas de CRM.</p>
<section class="ecran" id="tiers">
<div class="app"><aside class="nav">
<div class="logo"><span class="marque"><br></span><div><b>SIOP</b></div></div>
<div class="groupe">Ressources</div>
<a href="#"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="M21 8l-9-5-9 5v8l9 5 9-5V8zM3.3 8.3L12 13l8.7-4.7M12 13v9"/></svg>Stock &amp; achats</a>
<a href="#" class="actif"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="M9 21a7 7 0 1 1 6-11l6 6v3h-3l-1-1-2 1-1-2-2 1z" transform="rotate(180 12 12)"/><circle cx="9" cy="9" r="1.5"/></svg>Tiers</a>
</aside>
<div class="contenu">
<div class="topbar">
<div class="recherche"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><circle cx="11" cy="11" r="7"/><path d="m21 21-4-4"/></svg>Rechercher un tiers…</div>
<div class="compte"><span class="chip-demo">DÉMO</span><span class="avatar" style="background:var(--graf-4)">NB</span>
<div class="qui"><b>Nadia Berrada</b><br><small>Gestionnaire ▾</small></div></div>
</div>
<div class="page">
<div class="entete-page">
<h1>Tiers</h1>
<div class="actions"><button class="btn prim"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="M12 5v14M5 12h14"/></svg>Nouveau tiers</button></div>
</div>
<div class="carte" style="padding:0"><div class="table"><table>
<thead><tr><th>Nom</th><th>Type</th><th>Contact</th><th>Rattachements</th></tr></thead>
<tbody>
<tr><td><b>Ascentech Maroc</b><span class="sous">Casablanca — pièces détachées</span></td><td>Fournisseur</td><td>M. Berrini · <span class="num">05 22 34 56 78</span></td><td class="num">2 BC en cours</td></tr>
<tr><td><b>SchindlerParts</b><span class="sous">Importateur agréé</span></td><td>Fournisseur</td><td>commandes@schindlerparts.ma</td><td class="num">1 BC en cours</td></tr>
<tr><td><b>Lubmaroc</b><span class="sous">Consommables</span></td><td>Fournisseur</td><td><span class="num">05 22 11 22 33</span></td><td class="num"></td></tr>
<tr><td><b>Atlas Property Management</b><span class="sous">Syndic</span></td><td>Client / syndic</td><td>Mme Zerhouni · <span class="num">06 61 98 76 54</span></td><td>Tour Atlas</td></tr>
<tr><td><b>Syndic Al Manar</b></td><td>Client / syndic</td><td>M. Alami (gardien référent)</td><td>Résidence Al Manar</td></tr>
</tbody>
</table></div></div>
</div>
</div>
</div>
</section>
<!-- ═══════════ 7 · BIBLIOTHÈQUE ═══════════ -->
<p class="note-ecran" data-note="bibliotheque" hidden><b>Intention :</b> notices, certificats et photos — <b>rattachés</b> à un appareil ou un OT, stockés MinIO derrière FileStorage. Types fermés, taille plafonnée, aperçu léger. La carte « Documents » des fiches devient réelle.</p>
<section class="ecran" id="bibliotheque">
<div class="app"><aside class="nav">
<div class="logo"><span class="marque"><br></span><div><b>SIOP</b></div></div>
<div class="groupe">Ressources</div>
<a href="#"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="M21 8l-9-5-9 5v8l9 5 9-5V8zM3.3 8.3L12 13l8.7-4.7M12 13v9"/></svg>Stock &amp; achats</a>
<a href="#"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="M9 21a7 7 0 1 1 6-11l6 6v3h-3l-1-1-2 1-1-2-2 1z" transform="rotate(180 12 12)"/><circle cx="9" cy="9" r="1.5"/></svg>Tiers</a>
<a href="#" class="actif"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><path d="M14 2v6h6"/></svg>Fichiers</a>
</aside>
<div class="contenu">
<div class="topbar">
<div class="recherche"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><circle cx="11" cy="11" r="7"/><path d="m21 21-4-4"/></svg>Rechercher un document…</div>
<div class="compte"><span class="chip-demo">DÉMO</span><span class="avatar" style="background:var(--graf-4)">NB</span>
<div class="qui"><b>Nadia Berrada</b><br><small>Gestionnaire ▾</small></div></div>
</div>
<div class="page">
<div class="entete-page">
<h1>Bibliothèque</h1><span class="filajout">36 documents · 214 Mo</span>
<div class="actions"><button class="btn prim"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="M12 17V3M6 9l6-6 6 6M5 21h14"/></svg>Téléverser</button></div>
</div>
<div class="filtres">
<span class="select">Type : <b>Tous</b></span>
<span class="select">Rattaché à : <b>Tout le parc</b></span>
</div>
<div class="zone-photo" style="padding:22px">📁 Glissez un fichier ici — PDF, JPG, PNG · 20 Mo max · rattachez-le à un appareil ou un OT</div>
<div class="docs">
<div class="doc"><div class="vignette">📄</div><span class="type-doc">Notice</span><b>Notice Otis Gen2 Premier.pdf</b><span class="meta">Asc. A1 · 1,2 Mo · mars 2020</span></div>
<div class="doc"><div class="vignette">📄</div><span class="type-doc" style="color:var(--safran);background:var(--safran-doux)">Certificat</span><b>Certificat parachute 2026.pdf</b><span class="meta">Asc. A1 · 340 Ko · juil. 2026</span></div>
<div class="doc"><div class="vignette">🖼</div><span class="type-doc" style="color:var(--graf-3);background:var(--st-termine-fond)">Photo</span><b>photo-guide-frottement.jpg</b><span class="meta">OT-2026-0341 · 2,1 Mo · hier</span></div>
<div class="doc"><div class="vignette">📄</div><span class="type-doc">Notice</span><b>Schindler 3300 — manuel.pdf</b><span class="meta">Asc. B1 · B2 · 4,8 Mo</span></div>
</div>
<div class="carte" style="border-style:dashed;color:var(--encre-2);font-size:13px">
Ces documents nourriront l'assistant RAG en R5 (réponses citant leurs sources) — le rattachement propre commence ici.
</div>
</div>
</div>
</div>
</section>
<script>
(function(){
var onglets=document.querySelectorAll('.revue .onglets button');
var ecrans=document.querySelectorAll('.ecran');
var notes=document.querySelectorAll('.note-ecran');
onglets.forEach(function(b){b.addEventListener('click',function(){
onglets.forEach(function(x){x.setAttribute('aria-selected','false')});
b.setAttribute('aria-selected','true');
var cible=b.dataset.cible;
ecrans.forEach(function(e){e.classList.toggle('actif',e.id===cible)});
notes.forEach(function(n){n.hidden=(n.dataset.note!==cible)});
window.scrollTo({top:0});
})});
var ordre=['auto','light','dark'];var i=0;
var bt=document.getElementById('btn-theme');
bt.addEventListener('click',function(){
i=(i+1)%3;var m=ordre[i];
if(m==='auto'){document.documentElement.removeAttribute('data-theme')}
else{document.documentElement.setAttribute('data-theme',m)}
bt.textContent='Thème : '+(m==='auto'?'auto':(m==='light'?'clair':'sombre'));
});
})();
</script>
</body>
</html>