Files
siop2/docs/02-design/maquettes/maquette-r4.html
pr-daaif 2736a2f3a1 feat(r4): maquettes HD mobile technicien — 7 écrans offline-first à valider
Design d'abord : aucune ligne de code Expo avant validation. Ma journée
(en ligne / hors-ligne côte à côte), fiche OT, clôture terrain (bilan
codé R2, garde visible, variante « en file »), scan QR des étiquettes
A6 (R1, hors-ligne inclus), fiche ascenseur, checklist du mois (coches
individuelles en file), synchro & conflits (verrou optimiste, l'humain
tranche). Tokens répliqués, bi-thème, données du parc seedé.

5 décisions soumises avec les écrans : offline-first en file, verrou
optimiste, périmètre fermé technicien, scan résolu en local, photos
compressées en file — ni audio ni géolocalisation en R4 (loi 09-08).

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

642 lines
37 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 · R4 Mobile technicien</title>
</head>
<body>
<!--
SIOP V2 — Maquettes HD de la release R4 « Mobile technicien » (design-first).
À VALIDER PAR LE RÉFÉRENT AVANT TOUT CODE EXPO (principe n°1).
Cible : l'app du TECHNICIEN (Ahmed) — offline-first, Expo Go.
La gestion reste web ; le demandeur reste sur le portail QR public (R2).
Tokens répliqués de ../tokens.css ; gabarit téléphone repris de maquette-r3
(écran portail) et étendu : tabbar, file de synchro, conflits.
Recette type (plan de releases) : mode avion en sous-sol → cocher la grille
→ retour réseau → synchro sans perdre une saisie (verrou optimiste).
-->
<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}
.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:1120px;margin:14px auto 0;padding:0 20px;color:var(--encre-2);font-size:13px}
.note-ecran b{color:var(--encre)}
/* ═══ Écrans (mobile only — pas de coquille web en R4) ═══ */
.ecran{display:none;max-width:1120px;margin:18px auto 44px;padding:0 20px}
.ecran.actif{display:block}
.tels{display:flex;gap:28px;justify-content:center;flex-wrap:wrap}
.tel{width:310px;border:1px solid var(--bordure-forte);border-radius:28px;overflow:hidden;background:var(--fond);
box-shadow:var(--ombre-menu);display:flex;flex-direction:column}
.tel .encoche{height:26px;background:var(--nav-fond);display:flex;justify-content:center;align-items:center;flex:none}
.tel .encoche i{width:70px;height:7px;border-radius:999px;background:rgb(255 255 255/.18)}
.tel .legende{flex:none;text-align:center;font-size:11.5px;font-weight:700;letter-spacing:.05em;
text-transform:uppercase;color:var(--encre-3);padding:8px;background:var(--surface-2)}
.ecran-tel{padding:14px;display:flex;flex-direction:column;gap:10px;min-height:560px}
/* Entête app */
.entete-tel{display:flex;align-items:center;gap:8px}
.entete-tel .flamme{color:var(--safran);font-size:16px}
.entete-tel b{font-size:16px;letter-spacing:.03em}
.entete-tel small{color:var(--encre-3);font-size:10.5px;margin-top:3px}
.entete-tel .fin{margin-left:auto;display:flex;align-items:center;gap:6px}
.avatar-tel{width:26px;height:26px;border-radius:50%;background:var(--st-encours);color:#fff;
display:flex;align-items:center;justify-content:center;font-size:10.5px;font-weight:700}
.sync{font-size:10.5px;font-weight:700;color:var(--st-termine);background:var(--st-termine-fond);
padding:2px 8px;border-radius:999px;white-space:nowrap}
.sync.off{color:var(--st-attente);background:var(--st-attente-fond)}
.titre-tel{font-size:17px;font-weight:800;display:flex;align-items:center;gap:8px}
.titre-tel .filet{margin-left:auto;font-size:11px;color:var(--encre-3);font-weight:600}
/* Bandeaux */
.bandeau-off{display:flex;align-items:center;gap:8px;background:var(--st-attente-fond);color:var(--st-attente);
border:1px solid currentColor;border-radius:10px;padding:8px 10px;font-size:12px;font-weight:700}
.bandeau-urgence{display:flex;align-items:center;gap:8px;background:var(--prio-bloque-fond);color:var(--prio-bloque);
border-radius:10px;padding:8px 10px;font-size:12px;font-weight:800}
.point-pulse{width:8px;height:8px;border-radius:50%;background:currentColor;flex:none}
/* Cartes OT */
.carte-ot-tel{background:var(--surface);border:1px solid var(--bordure);border-radius:12px;padding:11px 12px;
border-left:4px solid transparent}
.carte-ot-tel.bloque{border-left-color:var(--prio-bloque)}
.carte-ot-tel.haute{border-left-color:var(--prio-haute)}
.carte-ot-tel.moyenne{border-left-color:var(--prio-moyenne)}
.carte-ot-tel.basse{border-left-color:var(--prio-basse)}
.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;gap:6px}
.carte-ot-tel b{display:block;margin:3px 0 2px;font-size:14px}
.carte-ot-tel .ou{color:var(--encre-2);font-size:12px}
.st{font-size:10.5px;font-weight:700;padding:2px 8px;border-radius:999px;white-space:nowrap}
.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)}
.pastille-file{font-size:10.5px;font-weight:700;color:var(--st-attente);background:var(--st-attente-fond);
padding:2px 8px;border-radius:999px}
/* Boutons */
.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)}
.btn-tel.contour{background:var(--surface);color:var(--primaire);border:1.5px solid var(--primaire)}
.paire-boutons{display:flex;gap:8px}
.paire-boutons .btn-tel{padding:10px;font-size:13px}
/* Fiche : cartes d'info */
.carte-tel{background:var(--surface);border:1px solid var(--bordure);border-radius:12px;padding:12px;
display:flex;flex-direction:column;gap:8px}
.carte-tel h4{font-size:10.5px;letter-spacing:.07em;text-transform:uppercase;color:var(--encre-2)}
.ligne-info{display:flex;justify-content:space-between;gap:10px;font-size:12.5px}
.ligne-info span:first-child{color:var(--encre-2)}
.ligne-info b{text-align:right}
.garde{font-size:11.5px;color:var(--alerte);font-weight:600}
/* Bilan codé (selects) */
.champ-tel{display:flex;flex-direction:column;gap:4px}
.champ-tel label{font-size:11px;font-weight:700;color:var(--encre-2)}
.champ-tel label em{color:var(--danger);font-style:normal}
.select-tel{border:1.5px solid var(--bordure-forte);border-radius:9px;background:var(--surface);
padding:9px 10px;font-size:13px;color:var(--encre);display:flex;justify-content:space-between;align-items:center}
.select-tel.vide{color:var(--encre-3)}
.grille-2-tel{display:grid;grid-template-columns:1fr 1fr;gap:8px}
/* Checklist */
.progress{height:8px;border-radius:999px;background:var(--surface-2);overflow:hidden}
.progress i{display:block;height:100%;border-radius:999px;background:var(--succes);width:58%}
.check-item{display:flex;align-items:center;gap:10px;background:var(--surface);border:1px solid var(--bordure);
border-radius:10px;padding:10px 12px;font-size:13px}
.check-item .case{width:20px;height:20px;border-radius:6px;border:2px solid var(--bordure-forte);flex:none}
.check-item.fait .case{background:var(--succes);border-color:var(--succes);position:relative}
.check-item.fait .case::after{content:'✓';color:#fff;font-size:13px;font-weight:800;position:absolute;inset:0;
display:flex;align-items:center;justify-content:center}
.check-item.fait{color:var(--encre-2)}
.check-item .file-chip{margin-left:auto}
/* Scan */
.viseur{flex:1;min-height:340px;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}
/* Historique fiche ascenseur */
.hist-item{display:flex;gap:8px;align-items:baseline;font-size:12.5px;padding:7px 0;border-top:1px solid var(--bordure)}
.hist-item:first-of-type{border-top:0}
.hist-item .ref{color:var(--primaire);font-weight:700;flex:none}
.hist-item .quand{margin-left:auto;color:var(--encre-3);font-size:11px;white-space:nowrap}
/* File de synchro */
.file-item{display:flex;align-items:center;gap:10px;background:var(--surface);border:1px solid var(--bordure);
border-radius:10px;padding:10px 12px;font-size:12.5px}
.file-item .ico{width:28px;height:28px;border-radius:8px;background:var(--surface-2);display:flex;
align-items:center;justify-content:center;flex:none;font-size:14px}
.file-item .quoi b{display:block;font-size:12.5px}
.file-item .quoi span{color:var(--encre-2);font-size:11px}
.file-item .etat{margin-left:auto;font-size:10.5px;font-weight:700;padding:2px 8px;border-radius:999px;white-space:nowrap}
.etat.attente{color:var(--st-attente);background:var(--st-attente-fond)}
.etat.envoi{color:var(--info);background:var(--st-ouvert-fond)}
.etat.fait{color:var(--st-termine);background:var(--st-termine-fond)}
.etat.conflit{color:var(--danger);background:var(--prio-bloque-fond)}
.carte-conflit{background:var(--prio-bloque-fond);border:1.5px solid var(--danger);border-radius:12px;
padding:12px;display:flex;flex-direction:column;gap:8px}
.carte-conflit h4{color:var(--danger);font-size:12.5px;display:flex;gap:6px;align-items:center}
.carte-conflit p{font-size:12px;color:var(--encre)}
.carte-conflit small{font-size:11px;color:var(--encre-2)}
/* Tabbar */
.tabbar{margin-top:auto;display:flex;border-top:1px solid var(--bordure);background:var(--surface);
border-radius:0 0 0 0;padding:6px 4px 8px}
.tabbar a{flex:1;display:flex;flex-direction:column;align-items:center;gap:2px;font-size:9.5px;
font-weight:700;color:var(--encre-3);text-decoration:none;position:relative}
.tabbar a.actif{color:var(--primaire)}
.tabbar a .pic{font-size:17px;line-height:1.2}
.tabbar .badge-tab{position:absolute;top:-3px;right:calc(50% - 16px);background:var(--st-attente);
color:#fff;font-size:9px;font-weight:800;padding:0 5px;border-radius:999px}
.tabbar .badge-tab.rouge{background:var(--prio-bloque)}
/* Photos jointes */
.photos-tel{display:flex;gap:8px}
.photo-tel{width:56px;height:56px;border-radius:9px;background:var(--surface-2);border:1px solid var(--bordure);
display:flex;align-items:center;justify-content:center;font-size:19px;position:relative}
.photo-tel .file-chip{position:absolute;bottom:-6px;right:-6px}
.file-chip{font-size:9px;font-weight:800;color:var(--st-attente);background:var(--st-attente-fond);
border:1px solid currentColor;padding:0 5px;border-radius:999px}
</style>
<header class="revue">
<b>SIOP · Maquettes R4 — Mobile technicien</b>
<nav class="onglets" role="tablist" aria-label="Écrans">
<button role="tab" aria-selected="true" data-cible="jour">1 · Ma journée</button>
<button role="tab" aria-selected="false" data-cible="fiche-ot">2 · Fiche OT</button>
<button role="tab" aria-selected="false" data-cible="cloture">3 · Clôture terrain</button>
<button role="tab" aria-selected="false" data-cible="scan">4 · Scan QR</button>
<button role="tab" aria-selected="false" data-cible="ascenseur">5 · Fiche ascenseur</button>
<button role="tab" aria-selected="false" data-cible="checklist">6 · Checklist du mois</button>
<button role="tab" aria-selected="false" data-cible="synchro">7 · Synchro & conflits</button>
</nav>
<div class="droite"><button class="theme" id="btn-theme">Thème : auto</button></div>
</header>
<!-- ═══ 1 · MA JOURNÉE ═══ -->
<p class="note-ecran" data-note="jour"><b>Intention :</b> l'app s'ouvre sur les OT d'Ahmed, triés
<b>priorité puis échéance</b> — urgence « personne bloquée » toujours en tête. Le même écran vit
<b>en ligne et hors-ligne</b> : hors-ligne, rien ne disparaît, un bandeau l'assume et la tabbar
compte les saisies en file. La pastille de synchro est permanente (vert = à jour, ambre = en attente).</p>
<section class="ecran actif" id="jour">
<div class="tels">
<div class="tel">
<div class="encoche"><i></i></div>
<div class="legende">En ligne — à jour</div>
<div class="ecran-tel">
<div class="entete-tel">
<span class="flamme"></span><b>SIOP</b>
<small>Technicien</small>
<span class="fin"><span class="sync">Synchro à jour</span><span class="avatar-tel">AB</span></span>
</div>
<div class="titre-tel">Ma journée <span class="filet">jeudi 17 juil.</span></div>
<div class="bandeau-urgence"><span class="point-pulse"></span>1 personne bloquée — B2 · Tour Atlas</div>
<div class="carte-ot-tel bloque">
<div class="type-t">OT-2026-0342 · Dépannage <span class="st ouvert">Ouvert</span></div>
<b>Personne bloquée en cabine</b>
<div class="ou">Asc. B2 — Tour Atlas · Aïn Diab</div>
</div>
<div class="carte-ot-tel haute">
<div class="type-t">OT-2026-0341 · Dépannage <span class="st encours">En cours</span></div>
<b>Bruit anormal en gaine</b>
<div class="ou">Asc. A1 — Résidence Al Manar · échéance 18 juil.</div>
</div>
<div class="carte-ot-tel moyenne">
<div class="type-t">OT-2026-0336 · Préventif <span class="st ouvert">Ouvert</span></div>
<b>Contrôle mensuel — juillet</b>
<div class="ou">Asc. A2 — Résidence Al Manar · grille 0/12</div>
</div>
<div class="carte-ot-tel basse">
<div class="type-t">OT-2026-0329 · Travaux <span class="st attente">En attente</span></div>
<b>Remplacement coulisseaux</b>
<div class="ou">Asc. C1 — Anfa Place · pièce commandée (BC-2026-0024)</div>
</div>
<nav class="tabbar">
<a class="actif" href="#"><span class="pic"></span>Ma journée</a>
<a href="#"><span class="pic"></span>Scanner</a>
<a href="#"><span class="pic"></span>Préventif</a>
<a href="#"><span class="pic"></span>Synchro</a>
</nav>
</div>
</div>
<div class="tel">
<div class="encoche"><i></i></div>
<div class="legende">Hors-ligne — sous-sol</div>
<div class="ecran-tel">
<div class="entete-tel">
<span class="flamme"></span><b>SIOP</b>
<small>Technicien</small>
<span class="fin"><span class="sync off">Hors-ligne</span><span class="avatar-tel">AB</span></span>
</div>
<div class="titre-tel">Ma journée <span class="filet">jeudi 17 juil.</span></div>
<div class="bandeau-off">⚠ Hors-ligne — vos saisies partent en file et se synchroniseront au retour du réseau.</div>
<div class="carte-ot-tel haute">
<div class="type-t">OT-2026-0341 · Dépannage <span class="st encours">En cours</span></div>
<b>Bruit anormal en gaine</b>
<div class="ou">Asc. A1 — Résidence Al Manar · échéance 18 juil.</div>
</div>
<div class="carte-ot-tel moyenne">
<div class="type-t">OT-2026-0336 · Préventif <span class="st ouvert">Ouvert</span> <span class="pastille-file">2 en file</span></div>
<b>Contrôle mensuel — juillet</b>
<div class="ou">Asc. A2 — Résidence Al Manar · grille 7/12</div>
</div>
<div class="carte-ot-tel basse">
<div class="type-t">OT-2026-0329 · Travaux <span class="st attente">En attente</span></div>
<b>Remplacement coulisseaux</b>
<div class="ou">Asc. C1 — Anfa Place · pièce commandée (BC-2026-0024)</div>
</div>
<nav class="tabbar">
<a class="actif" href="#"><span class="pic"></span>Ma journée</a>
<a href="#"><span class="pic"></span>Scanner</a>
<a href="#"><span class="pic"></span>Préventif</a>
<a href="#"><span class="pic"></span>Synchro<span class="badge-tab">3</span></a>
</nav>
</div>
</div>
</div>
</section>
<!-- ═══ 2 · FICHE OT ═══ -->
<p class="note-ecran" data-note="fiche-ot" hidden><b>Intention :</b> la même machine à états que le web
(R2) — un seul <b>bouton principal</b> selon l'état, jamais de liste de transitions. Consommer une pièce
et saisir du temps reprennent les règles R3 (prix et taux <b>figés</b> annoncés avant le geste). Les photos
partent en file comme le reste. Aucune saisie n'exige le réseau.</p>
<section class="ecran" id="fiche-ot">
<div class="tels">
<div class="tel">
<div class="encoche"><i></i></div>
<div class="legende">OT en cours — actions terrain</div>
<div class="ecran-tel">
<div class="entete-tel">
<span class="flamme"></span><b> OT-2026-0341</b>
<span class="fin"><span class="sync">Synchro à jour</span></span>
</div>
<div class="titre-tel">Bruit anormal en gaine <span class="st encours">En cours</span></div>
<div class="carte-tel">
<h4>Intervention</h4>
<div class="ligne-info"><span>Équipement</span><b>Asc. A1 — Résidence Al Manar</b></div>
<div class="ligne-info"><span>Priorité</span><b style="color:var(--prio-haute)">Haute</b></div>
<div class="ligne-info"><span>Échéance</span><b>18 juillet</b></div>
<div class="ligne-info"><span>Demande liée</span><b>DEM-2026-0107 · Karim D.</b></div>
</div>
<div class="carte-tel">
<h4>Pièces & main-d'œuvre — 505 MAD</h4>
<div class="ligne-info"><span>Coulisseau 16 mm × 2</span><b class="num">240</b></div>
<div class="ligne-info"><span>Graisse guide × 1</span><b class="num">85</b></div>
<div class="ligne-info"><span>Ahmed · 1 h 30 × 120/h</span><b class="num">180</b></div>
<div class="paire-boutons">
<button class="btn-tel contour">+ Pièce</button>
<button class="btn-tel contour">+ Temps</button>
</div>
</div>
<div class="carte-tel">
<h4>Photos</h4>
<div class="photos-tel">
<span class="photo-tel">🖼</span>
<span class="photo-tel">🖼<span class="file-chip">en file</span></span>
<span class="photo-tel" style="color:var(--primaire);font-size:23px">+</span>
</div>
</div>
<button class="btn-tel vert">Clôturer l'intervention</button>
<div class="garde">Bilan incomplet : « État des portes », « Action réalisée », « Élément concerné » — la clôture ouvrira le bilan.</div>
</div>
</div>
</div>
</section>
<!-- ═══ 3 · CLÔTURE TERRAIN ═══ -->
<p class="note-ecran" data-note="cloture" hidden><b>Intention :</b> le bilan codé R2, plein écran et au
pouce : 3 champs requis (<em>*</em>), la garde reste <b>visible et bloquante</b> tant qu'ils manquent —
identique au web, mêmes référentiels administrables. Hors-ligne, « Clôturer » met la clôture <b>en
file</b> : l'OT passe localement à « Terminé (en file) » et se confirme à la synchro.</p>
<section class="ecran" id="cloture">
<div class="tels">
<div class="tel">
<div class="encoche"><i></i></div>
<div class="legende">Bilan incomplet — garde visible</div>
<div class="ecran-tel">
<div class="entete-tel"><span class="flamme"></span><b> Clôturer OT-2026-0341</b></div>
<div class="carte-tel">
<h4>Bilan d'intervention — requis pour clôturer</h4>
<div class="grille-2-tel">
<div class="champ-tel"><label>État des portes <em>*</em></label><span class="select-tel">Fonctionnelles ▾</span></div>
<div class="champ-tel"><label>Position cabine</label><span class="select-tel vide">Sélectionner ▾</span></div>
<div class="champ-tel"><label>Anomalie constatée</label><span class="select-tel">Frottement guides ▾</span></div>
<div class="champ-tel"><label>Cause extérieure</label><span class="select-tel vide">Sélectionner ▾</span></div>
<div class="champ-tel"><label>Action réalisée <em>*</em></label><span class="select-tel">Remplacement pièce ▾</span></div>
<div class="champ-tel"><label>Élément concerné <em>*</em></label><span class="select-tel vide">Sélectionner ▾</span></div>
</div>
<div class="garde">⚠ « Élément concerné » manque — la clôture restera bloquée (même garde que le web).</div>
</div>
<div class="carte-tel">
<h4>Checklist liée — 12/12 ✓</h4>
<div class="ligne-info"><span>Grille de juillet cochée sur place</span><b style="color:var(--succes)">complète</b></div>
</div>
<button class="btn-tel gris">Clôturer (bilan incomplet)</button>
</div>
</div>
<div class="tel">
<div class="encoche"><i></i></div>
<div class="legende">Complet, hors-ligne — clôture en file</div>
<div class="ecran-tel">
<div class="entete-tel"><span class="flamme"></span><b> Clôturer OT-2026-0341</b>
<span class="fin"><span class="sync off">Hors-ligne</span></span></div>
<div class="carte-tel">
<h4>Bilan d'intervention — complet</h4>
<div class="grille-2-tel">
<div class="champ-tel"><label>État des portes <em>*</em></label><span class="select-tel">Fonctionnelles ▾</span></div>
<div class="champ-tel"><label>Position cabine</label><span class="select-tel">À niveau ▾</span></div>
<div class="champ-tel"><label>Anomalie constatée</label><span class="select-tel">Frottement guides ▾</span></div>
<div class="champ-tel"><label>Cause extérieure</label><span class="select-tel">Aucune ▾</span></div>
<div class="champ-tel"><label>Action réalisée <em>*</em></label><span class="select-tel">Remplacement pièce ▾</span></div>
<div class="champ-tel"><label>Élément concerné <em>*</em></label><span class="select-tel">Guides ▾</span></div>
</div>
</div>
<button class="btn-tel vert">Clôturer — partira à la synchro</button>
<div class="bandeau-off">La clôture est enregistrée sur le téléphone. Elle sera rejouée telle quelle au retour du réseau.</div>
</div>
</div>
</div>
</section>
<!-- ═══ 4 · SCAN QR ═══ -->
<p class="note-ecran" data-note="scan" hidden><b>Intention :</b> le scanner lit le <b>QR des étiquettes
A6</b> posées en R1 (la référence de l'appareil) et ouvre la fiche — y compris <b>hors-ligne</b>, sur le
parc déjà synchronisé. En dessous de l'épaule : saisie manuelle de la référence. Aucune géolocalisation
en R4 (backlog v2, loi 09-08 : minimisation).</p>
<section class="ecran" id="scan">
<div class="tels">
<div class="tel">
<div class="encoche"><i></i></div>
<div class="legende">Scanner — QR de l'étiquette A6</div>
<div class="ecran-tel">
<div class="entete-tel"><span class="flamme"></span><b>Scanner</b>
<span class="fin"><span class="sync off">Hors-ligne</span></span></div>
<div class="viseur">
<span class="cadre-qr"></span>
<p>Visez le QR de l'étiquette de cabine</p>
</div>
<button class="btn-tel contour">Saisir la référence (A1, B2…)</button>
<nav class="tabbar">
<a href="#"><span class="pic"></span>Ma journée</a>
<a class="actif" href="#"><span class="pic"></span>Scanner</a>
<a href="#"><span class="pic"></span>Préventif</a>
<a href="#"><span class="pic"></span>Synchro<span class="badge-tab">3</span></a>
</nav>
</div>
</div>
</div>
</section>
<!-- ═══ 5 · FICHE ASCENSEUR ═══ -->
<p class="note-ecran" data-note="ascenseur" hidden><b>Intention :</b> après le scan, tout ce qu'Ahmed
doit savoir <b>devant la machine</b> : identité, statut, organes, historique des interventions (bilans
codés lisibles). Consultation seule : la création d'OT reste au dispatcher (web) et le signalement au
portail QR public (R2) — le mobile n'ajoute pas de 3ᵉ canal.</p>
<section class="ecran" id="ascenseur">
<div class="tels">
<div class="tel">
<div class="encoche"><i></i></div>
<div class="legende">Résultat du scan — Asc. A1</div>
<div class="ecran-tel">
<div class="entete-tel"><span class="flamme"></span><b> Asc. A1</b>
<span class="fin"><span class="st termine">En service</span></span></div>
<div class="titre-tel">Otis Gen2 — Résidence Al Manar</div>
<div class="carte-tel">
<h4>Identité</h4>
<div class="ligne-info"><span>Emplacement</span><b>Hall principal</b></div>
<div class="ligne-info"><span>Mise en service</span><b>mars 2019</b></div>
<div class="ligne-info"><span>Sous contrat</span><b style="color:var(--succes)">Oui — préventif mensuel</b></div>
<div class="ligne-info"><span>Gardien</span><b>M. Alami · 06 12 34 56 78</b></div>
</div>
<div class="carte-tel">
<h4>Interventions récentes</h4>
<div class="hist-item"><span class="ref">OT-0341</span> Bruit anormal — guides <span class="quand">en cours</span></div>
<div class="hist-item"><span class="ref">OT-0329</span> Portes — contact remplacé <span class="quand">2 juil.</span></div>
<div class="hist-item"><span class="ref">OT-0318</span> Préventif juin — 12/12 ✓ <span class="quand">18 juin</span></div>
<div class="hist-item"><span class="ref">OT-0303</span> Armoire cde — fusible <span class="quand">30 mai</span></div>
</div>
<div class="carte-tel">
<h4>Organes suivis</h4>
<div class="ligne-info"><span>Treuil ZAA20</span><b></b></div>
<div class="ligne-info"><span>Portes cabine S3300</span><b>2 pannes / 12 mois</b></div>
<div class="ligne-info"><span>Armoire de commande</span><b>1 panne / 12 mois</b></div>
</div>
<button class="btn-tel">Voir mes OT sur cet appareil (2)</button>
</div>
</div>
</div>
</section>
<!-- ═══ 6 · CHECKLIST DU MOIS ═══ -->
<p class="note-ecran" data-note="checklist" hidden><b>Intention :</b> la grille préventive R2, cochable
<b>au pouce et hors-ligne</b> — chaque coche part en file individuellement (pas de « tout ou rien » :
7 coches faites = 7 coches sauvées, même si le téléphone s'éteint). La progression et le statut du mois
sont ceux du serveur à la dernière synchro, assumés comme tels.</p>
<section class="ecran" id="checklist">
<div class="tels">
<div class="tel">
<div class="encoche"><i></i></div>
<div class="legende">Grille de juillet — hors-ligne, 7/12</div>
<div class="ecran-tel">
<div class="entete-tel"><span class="flamme"></span><b> Préventif — juillet</b>
<span class="fin"><span class="sync off">Hors-ligne</span></span></div>
<div class="titre-tel">Asc. A2 — grille mensuelle <span class="filet num">7/12</span></div>
<div class="progress"><i></i></div>
<div class="check-item fait"><span class="case"></span>Verrouillage portes palières</div>
<div class="check-item fait"><span class="case"></span>Contacts de porte cabine</div>
<div class="check-item fait"><span class="case"></span>Niveau d'huile du treuil</div>
<div class="check-item fait"><span class="case"></span>Jeu des coulisseaux <span class="file-chip">en file</span></div>
<div class="check-item fait"><span class="case"></span>Éclairage cabine & secours <span class="file-chip">en file</span></div>
<div class="check-item"><span class="case"></span>Parachute — essai statique</div>
<div class="check-item"><span class="case"></span>Fins de course haut/bas</div>
<div class="check-item"><span class="case"></span>Téléalarme — essai d'appel</div>
<div class="bandeau-off">2 coches en file — la grille se recale à la synchro.</div>
</div>
</div>
</div>
</section>
<!-- ═══ 7 · SYNCHRO & CONFLITS ═══ -->
<p class="note-ecran" data-note="synchro" hidden><b>Intention :</b> la file est <b>visible et honnête</b> :
chaque saisie hors-ligne y est listée, rejouée dans l'ordre au retour du réseau. Conflit (verrou
optimiste : l'OT a changé côté serveur depuis la lecture) → la file <b>s'arrête sur l'élément</b>, montre
qui a modifié quoi et quand, et l'humain tranche — rien n'est écrasé ni perdu en silence. C'est l'écran
de la recette type « mode avion en sous-sol ».</p>
<section class="ecran" id="synchro">
<div class="tels">
<div class="tel">
<div class="encoche"><i></i></div>
<div class="legende">Retour réseau — file en cours</div>
<div class="ecran-tel">
<div class="entete-tel"><span class="flamme"></span><b>Synchro</b>
<span class="fin"><span class="sync">Envoi… 2/4</span></span></div>
<div class="titre-tel">File d'attente <span class="filet">rejouée dans l'ordre</span></div>
<div class="file-item"><span class="ico"></span>
<span class="quoi"><b>Coche « Jeu des coulisseaux »</b><span>OT-2026-0336 · 14 h 21</span></span>
<span class="etat fait">envoyée</span></div>
<div class="file-item"><span class="ico"></span>
<span class="quoi"><b>Coche « Éclairage cabine »</b><span>OT-2026-0336 · 14 h 24</span></span>
<span class="etat fait">envoyée</span></div>
<div class="file-item"><span class="ico">🖼</span>
<span class="quoi"><b>Photo — guides (1,8 Mo)</b><span>OT-2026-0341 · 14 h 32</span></span>
<span class="etat envoi">envoi…</span></div>
<div class="file-item"><span class="ico">🏁</span>
<span class="quoi"><b>Clôture + bilan codé</b><span>OT-2026-0341 · 14 h 40</span></span>
<span class="etat attente">en attente</span></div>
<nav class="tabbar">
<a href="#"><span class="pic"></span>Ma journée</a>
<a href="#"><span class="pic"></span>Scanner</a>
<a href="#"><span class="pic"></span>Préventif</a>
<a class="actif" href="#"><span class="pic"></span>Synchro<span class="badge-tab">2</span></a>
</nav>
</div>
</div>
<div class="tel">
<div class="encoche"><i></i></div>
<div class="legende">Conflit — l'humain tranche</div>
<div class="ecran-tel">
<div class="entete-tel"><span class="flamme"></span><b>Synchro</b>
<span class="fin"><span class="sync off">1 conflit</span></span></div>
<div class="titre-tel">File d'attente <span class="filet">arrêtée sur le conflit</span></div>
<div class="carte-conflit">
<h4>⚠ Conflit sur OT-2026-0341</h4>
<p><b>Salma Idrissi a modifié cet OT à 14 h 38</b> (réassigné + commentaire) pendant que vous étiez hors-ligne. Votre clôture de 14 h 40 n'a <b>pas</b> été appliquée.</p>
<small>Votre saisie est conservée telle quelle dans la file — rien n'est perdu.</small>
<button class="btn-tel" style="padding:10px;font-size:13px">Revoir l'OT à jour puis rejouer</button>
<button class="btn-tel contour" style="padding:10px;font-size:13px">Abandonner ma clôture</button>
</div>
<div class="file-item"><span class="ico">🏁</span>
<span class="quoi"><b>Clôture + bilan codé</b><span>OT-2026-0341 · 14 h 40</span></span>
<span class="etat conflit">conflit</span></div>
<div class="file-item"><span class="ico">🖼</span>
<span class="quoi"><b>Photo — guides (1,8 Mo)</b><span>OT-2026-0341 · 14 h 32</span></span>
<span class="etat fait">envoyée</span></div>
<nav class="tabbar">
<a href="#"><span class="pic"></span>Ma journée</a>
<a href="#"><span class="pic"></span>Scanner</a>
<a href="#"><span class="pic"></span>Préventif</a>
<a class="actif" href="#"><span class="pic"></span>Synchro<span class="badge-tab rouge">1</span></a>
</nav>
</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>