mirror of
https://github.com/siop-spelev/siop2.git
synced 2026-08-08 12:41:54 +00:00
docs(r0): kickoff SIOP V2 — vision, cadrage, charte graphique, maquettes HD
Refondation design-first du projet SIOP (v1 gelée) : - Playbook 00-vision (charte projet, personas, benchmark Atlas) - Playbook 01-cadrage (releases R0→R5 + DoD, user-story map, exigences, risques) - Playbook 02-design : charte graphique, tokens.css bi-thème (palettes analytics validées CVD/contraste par script), maquettes HD navigables (7 écrans dont démo-login DEMO_MODE, bilan codé, portail QR, mobile) Prochaine étape : validation des maquettes par le référent avant tout code. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
79
docs/02-design/charte-graphique.md
Normal file
79
docs/02-design/charte-graphique.md
Normal file
@@ -0,0 +1,79 @@
|
||||
# Charte graphique — SIOP V2
|
||||
|
||||
> **Rôle de ce document (playbook)** : fixer l'identité visuelle AVANT le code. Toute
|
||||
> valeur visuelle vit dans [`tokens.css`](tokens.css) (source de vérité, importée telle
|
||||
> quelle par l'application) ; ce document explique les **choix** et leurs raisons.
|
||||
> Règle absolue : aucun style codé en dur hors tokens — c'est ce qui a rendu la v1 « flottante ».
|
||||
|
||||
## 1. Positionnement
|
||||
|
||||
SIOP est un **outil de travail professionnel** pour ascensoristes : sobre, dense sans être
|
||||
étouffant, lisible en plein soleil sur un chantier comme au bureau. Le monde visuel est
|
||||
celui du métier — acier, cabine, signalisation de sécurité — pas celui d'une app grand
|
||||
public. Deux thèmes (clair/sombre) au même niveau de soin.
|
||||
|
||||
## 2. Couleur
|
||||
|
||||
| Token | Valeur (clair) | Rôle & justification |
|
||||
| --- | --- | --- |
|
||||
| `--encre` | `#1B2534` | Texte principal — un « noir acier » à biais bleu, jamais de noir pur |
|
||||
| `--bleu-treuil` | `#1F4FB8` | **Primaire** (actions, liens, focus) — bleu de vêtement de travail, profond et désaturé, volontairement distinct du bleu néon par défaut des frameworks |
|
||||
| `--safran` | `#DD8A0B` | **Accent de marque** — safran marocain / gilet haute visibilité. Parcimonieux : logo, rail actif de navigation, moments de marque. Jamais pour un statut |
|
||||
| Fonds | `#F5F7FA` / surfaces `#FFFFFF` | Acier clair, biais froid assumé |
|
||||
| Sombre | fond `#0F1622`, surface `#182234` | « Machinerie de nuit » — pas une simple inversion |
|
||||
|
||||
**Statuts (réservés, jamais réutilisés ailleurs)** : Ouvert `bleu`, En cours `indigo`,
|
||||
En attente `ambre`, Terminé `vert`, Annulé `gris`. Priorités : **Personne bloquée**
|
||||
(rouge vif + pastille animée — la seule animation d'alerte de l'app), Haute `rouge`,
|
||||
Moyenne `ambre`, Basse `verte`. Toujours pastille/pictogramme + libellé, jamais la couleur seule.
|
||||
|
||||
**Palettes graphiques (analytics) — validées par script (CVD, contraste, bande de
|
||||
luminosité)** :
|
||||
|
||||
- Clair : `#3B69D6 · #DD8A0B · #1F9E8E · #8A63D2` (ordre fixe, jamais recyclé ; étiquettes
|
||||
directes obligatoires — le safran passe sous 3:1 sur blanc).
|
||||
- Sombre : `#5580E4 · #C7820A · #26A896 · #9673DE` (repas dédiés, pas d'inversion automatique).
|
||||
|
||||
## 3. Typographie
|
||||
|
||||
- **UI & titres : Manrope** (géométrique-humaniste, OFL, auto-hébergée — jamais de CDN).
|
||||
Titres en 600/700, `text-wrap: balance`. Les maquettes HTML approximent avec Avenir Next
|
||||
(présent sur macOS) en attendant l'app.
|
||||
- **Données : chiffres tabulaires** (`font-variant-numeric: tabular-nums`) partout où des
|
||||
nombres s'alignent (tables, KPI, coûts).
|
||||
- Échelle : 12 / 13 / 14 (base) / 16 / 20 / 24 / 32. Libellés en capitales : 11 px,
|
||||
`letter-spacing: 0.06em`.
|
||||
|
||||
## 4. Forme & espace
|
||||
|
||||
- Grille d'espacement **4 px** ; densité « bureau » (tables 40 px/ligne) mais cibles
|
||||
tactiles ≥ 44 px sur mobile.
|
||||
- Rayons : 10 px (cartes), 8 px (contrôles), 999 px (pastilles).
|
||||
- Élévation discrète : bordures d'abord (`--bordure`), ombre légère seulement au survol/menus.
|
||||
- **Motif signature « rail »** : l'élément actif de la navigation porte un rail vertical
|
||||
safran de 3 px (la cage d'ascenseur) — c'est LE geste identitaire, utilisé nulle part ailleurs.
|
||||
|
||||
## 5. Iconographie & logo
|
||||
|
||||
- **Lucide**, trait 1,75 px, 16–20 px dans l'UI.
|
||||
- Logotype : « SIOP » en Manrope 700 + marque **▲▼** (montée/descente cabine) safran sur
|
||||
encre. Favicon = la marque seule.
|
||||
|
||||
## 6. Mouvement
|
||||
|
||||
Fonctionnel uniquement : transitions 120–160 ms (`ease-out`) sur survol/ouverture ;
|
||||
`prefers-reduced-motion` respecté ; **une seule** animation continue autorisée — la
|
||||
pastille « personne bloquée ».
|
||||
|
||||
## 7. Ton rédactionnel
|
||||
|
||||
Français métier, direct, sans jargon système : « Clôturer l'intervention », pas
|
||||
« Soumettre le formulaire ». Les erreurs disent quoi faire (« La checklist est incomplète :
|
||||
traitez chaque tâche »), jamais « Erreur 400 ». Vocabulaire du carnet : OT, bilan, organe,
|
||||
grille du mois.
|
||||
|
||||
## 8. Application
|
||||
|
||||
`tokens.css` est copié tel quel dans `apps/web` (et mappé vers la config Tailwind/shadcn).
|
||||
La page `/design` de l'app (R0) expose tous les tokens et composants — c'est la référence
|
||||
vivante des revues pixel.
|
||||
821
docs/02-design/maquettes/maquette-web.html
Normal file
821
docs/02-design/maquettes/maquette-web.html
Normal file
@@ -0,0 +1,821 @@
|
||||
<!doctype html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>SIOP V2 — Maquettes haute-fidélité</title>
|
||||
</head>
|
||||
<body>
|
||||
<!--
|
||||
SIOP V2 — Maquettes HD (R0, phase design).
|
||||
Source de vérité des valeurs : ../tokens.css (répliquées ici pour l'autonomie du fichier).
|
||||
7 écrans navigables + bascule clair/sombre. À valider par le référent AVANT tout code.
|
||||
-->
|
||||
<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>
|
||||
|
||||
<!-- ═══════════ BARRE DE REVUE ═══════════ -->
|
||||
<header class="revue">
|
||||
<b>SIOP V2 · Maquettes HD</b>
|
||||
<nav class="onglets" role="tablist" aria-label="Écrans">
|
||||
<button role="tab" aria-selected="true" data-cible="connexion">1 · Connexion</button>
|
||||
<button role="tab" aria-selected="false" data-cible="dashboard">2 · Tableau de bord</button>
|
||||
<button role="tab" aria-selected="false" data-cible="liste-ot">3 · Ordres de travail</button>
|
||||
<button role="tab" aria-selected="false" data-cible="fiche-ot">4 · Fiche OT</button>
|
||||
<button role="tab" aria-selected="false" data-cible="ascenseur">5 · Fiche ascenseur</button>
|
||||
<button role="tab" aria-selected="false" data-cible="portail">6 · Portail demandeur</button>
|
||||
<button role="tab" aria-selected="false" data-cible="mobile">7 · Mobile technicien</button>
|
||||
</nav>
|
||||
<div class="droite"><button class="theme" id="btn-theme">Thème : auto</button></div>
|
||||
</header>
|
||||
|
||||
<!-- ═══════════ 1 · CONNEXION ═══════════ -->
|
||||
<p class="note-ecran" data-note="connexion"><b>Intention :</b> première impression sobre ; le <b>mode démonstration</b> (demande DX du référent) permet d'entrer dans n'importe quel rôle en 1 clic — visible uniquement quand <code>DEMO_MODE=true</code>.</p>
|
||||
<section class="ecran actif" id="connexion">
|
||||
<div class="app pleine"><div class="conn">
|
||||
<div class="carte-conn">
|
||||
<div class="logo">
|
||||
<span class="marque">▲<br>▼</span>
|
||||
<div><b>SIOP</b><small>Maintenance d'ascenseurs</small></div>
|
||||
</div>
|
||||
<div class="champ"><label for="m-email">Email</label><input id="m-email" placeholder="prenom.nom@spelev.ma"></div>
|
||||
<div class="champ"><label for="m-mdp">Mot de passe</label><input id="m-mdp" type="password" placeholder="••••••••"></div>
|
||||
<button class="btn prim" style="justify-content:center">Se connecter</button>
|
||||
<div class="sep">Mode démonstration</div>
|
||||
<div class="demo-liste">
|
||||
<button><span class="avatar">SI</span> Salma Idrissi <span class="role">Dispatchrice</span></button>
|
||||
<button><span class="avatar" style="background:var(--graf-3)">AB</span> Ahmed Benali <span class="role">Technicien</span></button>
|
||||
<button><span class="avatar" style="background:var(--graf-4)">NB</span> Nadia Berrada <span class="role">Gestionnaire</span></button>
|
||||
<button><span class="avatar" style="background:var(--st-annule)">KD</span> Karim Doukkali <span class="role">Demandeur</span></button>
|
||||
<button><span class="avatar" style="background:var(--safran)">RB</span> R. Bennis <span class="role">Vue seule</span></button>
|
||||
</div>
|
||||
<div style="text-align:center"><span class="chip-demo">DEMO_MODE=true — absent en production</span></div>
|
||||
</div>
|
||||
</div></div>
|
||||
</section>
|
||||
|
||||
<!-- ═══════════ 2 · TABLEAU DE BORD ═══════════ -->
|
||||
<p class="note-ecran" data-note="dashboard" hidden><b>Intention :</b> Salma lit la situation en 10 s. L'urgence « personne bloquée » est <b>impossible à manquer</b> (bandeau + pastille animée — seule animation continue de l'app). KPI en chiffres tabulaires, graphiques aux couleurs validées (CVD).</p>
|
||||
<section class="ecran" id="dashboard">
|
||||
<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"><rect x="3" y="3" width="7" height="9" rx="1"/><rect x="14" y="3" width="7" height="5" rx="1"/><rect x="14" y="12" width="7" height="9" rx="1"/><rect x="3" y="16" width="7" height="5" rx="1"/></svg>Tableau de bord</a>
|
||||
<a href="#"><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<span class="badge-nav">1</span></a>
|
||||
<a href="#"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="M8 10h8M8 14h5M21 12a9 9 0 1 1-4-7.5"/></svg>Demandes</a>
|
||||
<a href="#"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><rect x="3" y="4" width="18" height="18" rx="2"/><path d="M16 2v4M8 2v4M3 10h18"/></svg>Préventif</a>
|
||||
<div class="groupe">Parc</div>
|
||||
<a href="#"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><rect x="6" y="2" width="12" height="20" rx="2"/><path d="M10 7l2-2 2 2M10 17l2 2 2-2"/></svg>Ascenseurs</a>
|
||||
<a href="#"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="M20 10c0 6-8 12-8 12S4 16 4 10a8 8 0 1 1 16 0z"/><circle cx="12" cy="10" r="3"/></svg>Sites</a>
|
||||
<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 & 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>
|
||||
<div class="groupe">Pilotage</div>
|
||||
<a href="#"><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 un OT, un ascenseur, un site… ⌘K</div>
|
||||
<span class="chip-urgence"><span class="point-pulse"></span>1 personne bloquée</span>
|
||||
<div class="compte"><span class="chip-demo">DÉMO</span><span class="avatar">SI</span>
|
||||
<div class="qui"><b>Salma Idrissi</b><br><small>Dispatchrice ▾</small></div></div>
|
||||
</div>
|
||||
<div class="page">
|
||||
<div class="bandeau-urgence">
|
||||
<span class="point-pulse"></span>
|
||||
<div><b>Personne bloquée — Tour Atlas, ascenseur B2</b> (Casablanca)<br>
|
||||
<span class="depuis">Signalé il y a 4 min par le gardien · aucune intervention en cours</span></div>
|
||||
<div style="margin-left:auto"><button class="btn prim">Créer l'OT d'urgence</button></div>
|
||||
</div>
|
||||
<div class="kpis">
|
||||
<div class="kpi"><div class="lib">OT ouverts</div><div class="val num">12</div><div class="delta neutre">dont 5 en cours</div></div>
|
||||
<div class="kpi alarme"><div class="lib">En retard</div><div class="val num">3</div><div class="delta mauvais">+2 cette semaine</div></div>
|
||||
<div class="kpi"><div class="lib">Préventif · juillet</div>
|
||||
<div class="anneau">
|
||||
<svg width="46" height="46" viewBox="0 0 46 46" role="img" aria-label="78 pour cent">
|
||||
<circle cx="23" cy="23" r="19" fill="none" stroke="var(--graf-grille)" stroke-width="6"/>
|
||||
<circle cx="23" cy="23" r="19" fill="none" stroke="var(--primaire)" stroke-width="6"
|
||||
stroke-dasharray="93 120" stroke-linecap="round" transform="rotate(-90 23 23)"/>
|
||||
</svg>
|
||||
<div><div class="val num" style="font-size:22px">78 %</div><div class="delta bon">32 / 41 grilles</div></div>
|
||||
</div></div>
|
||||
<div class="kpi"><div class="lib">Demandes à traiter</div><div class="val num">4</div><div class="delta neutre">la + ancienne : 2 h</div></div>
|
||||
<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>
|
||||
<div class="grille-2">
|
||||
<div class="carte graf">
|
||||
<h2>OT par statut</h2>
|
||||
<div class="barres-h">
|
||||
<div class="ligne-b"><span>Ouvert</span><div class="fond-b"><div class="rempli" style="width:58%;background:var(--st-ouvert)"></div></div><span class="valeur num">7</span></div>
|
||||
<div class="ligne-b"><span>En cours</span><div class="fond-b"><div class="rempli" style="width:42%;background:var(--st-encours)"></div></div><span class="valeur num">5</span></div>
|
||||
<div class="ligne-b"><span>En attente</span><div class="fond-b"><div class="rempli" style="width:17%;background:var(--st-attente)"></div></div><span class="valeur num">2</span></div>
|
||||
<div class="ligne-b"><span>Terminé (30 j)</span><div class="fond-b"><div class="rempli" style="width:100%;background:var(--st-termine)"></div></div><span class="valeur num">34</span></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="carte graf">
|
||||
<h2>Pannes par organe · 12 mois</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>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 class="ligne-b"><span>Parachute</span><div class="fond-b"><div class="rempli" style="width:15%;background:var(--graf-1)"></div></div><span class="valeur num">5</span></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="carte">
|
||||
<h2>Interventions récentes</h2>
|
||||
<div class="table"><table>
|
||||
<thead><tr><th>N°</th><th>Objet</th><th>Équipement</th><th>Priorité</th><th>Statut</th><th>Assignés</th></tr></thead>
|
||||
<tbody>
|
||||
<tr><td class="ref num">OT-2026-0341</td><td>Bruit anormal en gaine</td><td>Asc. A1<span class="sous">Résidence Al Manar</span></td><td><span class="prio haute"><i></i>Haute</span></td><td><span class="st encours">En cours</span></td><td><div class="avatars"><span class="avatar">AB</span></div></td></tr>
|
||||
<tr><td class="ref num">OT-2026-0339</td><td>Grille du mois — juillet</td><td>Asc. C1<span class="sous">Anfa Place</span></td><td><span class="prio basse"><i></i>Basse</span></td><td><span class="st ouvert">Ouvert</span></td><td><div class="avatars"><span class="avatar" style="background:var(--graf-3)">FA</span></div></td></tr>
|
||||
<tr><td class="ref num">OT-2026-0336</td><td>Remplacement contact porte</td><td>Asc. B2<span class="sous">Tour Atlas</span></td><td><span class="prio moyenne"><i></i>Moyenne</span></td><td><span class="st attente">En attente</span></td><td><div class="avatars"><span class="avatar">AB</span><span class="avatar" style="background:var(--graf-3)">FA</span></div></td></tr>
|
||||
<tr><td class="ref num">OT-2026-0332</td><td>Réglage nivellement cabine</td><td>Asc. A1<span class="sous">Résidence Al Manar</span></td><td><span class="prio basse"><i></i>Basse</span></td><td><span class="st termine">Terminé</span></td><td><div class="avatars"><span class="avatar" style="background:var(--graf-3)">FA</span></div></td></tr>
|
||||
</tbody>
|
||||
</table></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ═══════════ 3 · LISTE OT ═══════════ -->
|
||||
<p class="note-ecran" data-note="liste-ot" hidden><b>Intention :</b> table dense « bureau » (40 px/ligne), filtres en une rangée, l'OT « personne bloquée » porte une <b>strie rouge</b> + pastille animée. Références cliquables, sites en sous-texte.</p>
|
||||
<section class="ecran" id="liste-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="#"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><rect x="3" y="3" width="7" height="9" rx="1"/><rect x="14" y="3" width="7" height="5" rx="1"/><rect x="14" y="12" width="7" height="9" rx="1"/><rect x="3" y="16" width="7" height="5" rx="1"/></svg>Tableau de bord</a>
|
||||
<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<span class="badge-nav">1</span></a>
|
||||
<a href="#"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="M8 10h8M8 14h5M21 12a9 9 0 1 1-4-7.5"/></svg>Demandes</a>
|
||||
<a href="#"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><rect x="3" y="4" width="18" height="18" rx="2"/><path d="M16 2v4M8 2v4M3 10h18"/></svg>Préventif</a>
|
||||
<div class="groupe">Parc</div>
|
||||
<a href="#"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><rect x="6" y="2" width="12" height="20" rx="2"/><path d="M10 7l2-2 2 2M10 17l2 2 2-2"/></svg>Ascenseurs</a>
|
||||
<a href="#"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="M20 10c0 6-8 12-8 12S4 16 4 10a8 8 0 1 1 16 0z"/><circle cx="12" cy="10" r="3"/></svg>Sites</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>
|
||||
<span class="chip-urgence"><span class="point-pulse"></span>1 personne bloquée</span>
|
||||
<div class="compte"><span class="chip-demo">DÉMO</span><span class="avatar">SI</span>
|
||||
<div class="qui"><b>Salma Idrissi</b><br><small>Dispatchrice ▾</small></div></div>
|
||||
</div>
|
||||
<div class="page">
|
||||
<div class="entete-page">
|
||||
<h1>Ordres de travail</h1>
|
||||
<div class="actions"><button class="btn prim"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="M12 5v14M5 12h14"/></svg>Nouvel OT</button></div>
|
||||
</div>
|
||||
<div class="filtres">
|
||||
<span class="select">Statut : <b>Actifs</b> ▾</span>
|
||||
<span class="select">Type : <b>Tous</b> ▾</span>
|
||||
<span class="select">Priorité : <b>Toutes</b> ▾</span>
|
||||
<span class="select">Assigné : <b>Tous</b> ▾</span>
|
||||
<span style="color:var(--encre-3);font-size:12.5px;margin-left:auto" class="num">14 résultats</span>
|
||||
</div>
|
||||
<div class="carte" style="padding:0"><div class="table"><table>
|
||||
<thead><tr><th>N°</th><th>Objet</th><th>Équipement · Site</th><th>Type</th><th>Priorité</th><th>Statut</th><th>Assignés</th><th>Échéance</th></tr></thead>
|
||||
<tbody>
|
||||
<tr class="ligne-bloque"><td class="ref num">OT-2026-0342</td><td><b>Personne bloquée en cabine</b></td><td>Asc. B2<span class="sous">Tour Atlas, Casablanca</span></td><td>Dépannage</td><td><span class="prio bloque"><i></i>Personne bloquée</span></td><td><span class="st ouvert">Ouvert</span></td><td>—</td><td><b>immédiat</b></td></tr>
|
||||
<tr><td class="ref num">OT-2026-0341</td><td>Bruit anormal en gaine</td><td>Asc. A1<span class="sous">Résidence Al Manar, Mohammedia</span></td><td>Dépannage</td><td><span class="prio haute"><i></i>Haute</span></td><td><span class="st encours">En cours</span></td><td><div class="avatars"><span class="avatar">AB</span></div></td><td class="num">15 juil.</td></tr>
|
||||
<tr><td class="ref num">OT-2026-0339</td><td>Grille du mois — juillet</td><td>Asc. C1<span class="sous">Anfa Place, Casablanca</span></td><td>Maintenance</td><td><span class="prio basse"><i></i>Basse</span></td><td><span class="st ouvert">Ouvert</span></td><td><div class="avatars"><span class="avatar" style="background:var(--graf-3)">FA</span></div></td><td class="num">31 juil.</td></tr>
|
||||
<tr><td class="ref num">OT-2026-0338</td><td>Grille du mois — juillet</td><td>Asc. A1<span class="sous">Résidence Al Manar, Mohammedia</span></td><td>Maintenance</td><td><span class="prio basse"><i></i>Basse</span></td><td><span class="st encours">En cours</span></td><td><div class="avatars"><span class="avatar">AB</span></div></td><td class="num">31 juil.</td></tr>
|
||||
<tr><td class="ref num">OT-2026-0336</td><td>Remplacement contact de porte</td><td>Asc. B2<span class="sous">Tour Atlas, Casablanca</span></td><td>Dépannage</td><td><span class="prio moyenne"><i></i>Moyenne</span></td><td><span class="st attente">En attente</span></td><td><div class="avatars"><span class="avatar">AB</span><span class="avatar" style="background:var(--graf-3)">FA</span></div></td><td class="num">18 juil.</td></tr>
|
||||
<tr><td class="ref num">OT-2026-0335</td><td>Ampoule cabine grillée</td><td>Asc. D3<span class="sous">Clinique Andalous, Mohammedia</span></td><td>Travaux</td><td><span class="prio basse"><i></i>Basse</span></td><td><span class="st ouvert">Ouvert</span></td><td>—</td><td class="num">22 juil.</td></tr>
|
||||
<tr><td class="ref num">OT-2026-0332</td><td>Réglage nivellement cabine</td><td>Asc. A1<span class="sous">Résidence Al Manar, Mohammedia</span></td><td>Dépannage</td><td><span class="prio basse"><i></i>Basse</span></td><td><span class="st termine">Terminé</span></td><td><div class="avatars"><span class="avatar" style="background:var(--graf-3)">FA</span></div></td><td class="num">12 juil.</td></tr>
|
||||
</tbody>
|
||||
</table></div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ═══════════ 4 · FICHE OT ═══════════ -->
|
||||
<p class="note-ecran" data-note="fiche-ot" hidden><b>Intention :</b> tout le carnet SPELEV sur un écran — activité chronologique, <b>bilan codé 6 champs</b> (requis marqués, clôture bloquée sinon), coûts pièces + main-d'œuvre, assignation en 1 clic.</p>
|
||||
<section class="ecran" id="fiche-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="#"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><rect x="3" y="3" width="7" height="9" rx="1"/><rect x="14" y="3" width="7" height="5" rx="1"/><rect x="14" y="12" width="7" height="9" rx="1"/><rect x="3" y="16" width="7" height="5" rx="1"/></svg>Tableau de bord</a>
|
||||
<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>
|
||||
<a href="#"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="M8 10h8M8 14h5M21 12a9 9 0 1 1-4-7.5"/></svg>Demandes</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">SI</span>
|
||||
<div class="qui"><b>Salma Idrissi</b><br><small>Dispatchrice ▾</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 class="actions">
|
||||
<button class="btn ghost">En attente</button>
|
||||
<button class="btn danger-l">Annuler</button>
|
||||
<button class="btn succes">Clôturer l'intervention</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="grille-2">
|
||||
<div class="carte">
|
||||
<h2>Intervention</h2>
|
||||
<dl class="infos">
|
||||
<dt>N°</dt><dd class="num">OT-2026-0341 · Dépannage</dd>
|
||||
<dt>Équipement</dt><dd><a href="#">Ascenseur A1 — Otis Gen2</a></dd>
|
||||
<dt>Site</dt><dd>Résidence Al Manar, Mohammedia</dd>
|
||||
<dt>Priorité</dt><dd><span class="prio haute"><i></i>Haute</span></dd>
|
||||
<dt>Échéance</dt><dd class="num">15 juillet 2026</dd>
|
||||
<dt>Assignés</dt><dd style="display:flex;align-items:center;gap:8px">
|
||||
<span class="avatars"><span class="avatar">AB</span></span> Ahmed Benali
|
||||
<button class="btn ghost" style="padding:3px 8px;font-size:12px">+ Assigner</button></dd>
|
||||
<dt>Demande liée</dt><dd><a href="#" class="num">DEM-2026-0107</a> — Karim Doukkali (gardien)</dd>
|
||||
</dl>
|
||||
</div>
|
||||
<div class="carte">
|
||||
<h2>Activité</h2>
|
||||
<ul class="chrono">
|
||||
<li class="fait"><b>Ahmed Benali</b> a démarré l'intervention<br><span class="quand">aujourd'hui · 09 h 41</span></li>
|
||||
<li class="fait">Commentaire d'Ahmed : « Frottement guide côté gaine, contrôle des coulisseaux en cours. »<br><span class="quand">aujourd'hui · 10 h 05</span></li>
|
||||
<li class="fait"><b>Salma Idrissi</b> a assigné Ahmed Benali<br><span class="quand">hier · 16 h 22</span></li>
|
||||
<li>OT créé depuis la demande <span class="num">DEM-2026-0107</span><br><span class="quand">hier · 16 h 20</span></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="grille-2">
|
||||
<div class="carte">
|
||||
<h2>Bilan d'intervention <span style="color:var(--encre-3);text-transform:none;letter-spacing:0">— requis pour clôturer</span></h2>
|
||||
<div class="bilan">
|
||||
<div class="champ-b"><label>État des portes <em>*</em></label><div class="faux-select">Fonctionnement normal <span>▾</span></div></div>
|
||||
<div class="champ-b"><label>Position cabine</label><div class="faux-select">Entre deux niveaux <span>▾</span></div></div>
|
||||
<div class="champ-b"><label>Anomalie constatée</label><div class="faux-select">Frottement mécanique <span>▾</span></div></div>
|
||||
<div class="champ-b"><label>Cause extérieure</label><div class="faux-select vide">Sélectionner… <span>▾</span></div></div>
|
||||
<div class="champ-b"><label>Action réalisée <em>*</em></label><div class="faux-select">Réglage <span>▾</span></div></div>
|
||||
<div class="champ-b"><label>Élément concerné <em>*</em></label><div class="faux-select vide">Sélectionner… <span>▾</span></div></div>
|
||||
</div>
|
||||
<p style="margin-top:12px;font-size:12.5px;color:var(--alerte)">⚠ « Élément concerné » manquant — la clôture restera bloquée.</p>
|
||||
</div>
|
||||
<div style="display:flex;flex-direction:column;gap:16px">
|
||||
<div class="carte">
|
||||
<h2>Pièces & 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 × 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)<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</span><span class="num">505 MAD</span></div>
|
||||
</div>
|
||||
<div class="carte">
|
||||
<h2>Documents</h2>
|
||||
<div class="item-liste"><span class="ico"><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></span>photo-guide-frottement.jpg<span class="fin">2,1 Mo · <a href="#" style="color:var(--primaire)">↓</a></span></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ═══════════ 5 · FICHE ASCENSEUR ═══════════ -->
|
||||
<p class="note-ecran" data-note="ascenseur" hidden><b>Intention :</b> l'identité de l'appareil (l'« ID Appareil » du carnet), ses <b>organes</b>, son historique, ses documents et son <b>étiquette QR</b> imprimable — tout au même endroit.</p>
|
||||
<section class="ecran" id="ascenseur">
|
||||
<div class="app"><aside class="nav">
|
||||
<div class="logo"><span class="marque">▲<br>▼</span><div><b>SIOP</b></div></div>
|
||||
<div class="groupe">Parc</div>
|
||||
<a href="#" class="actif"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><rect x="6" y="2" width="12" height="20" rx="2"/><path d="M10 7l2-2 2 2M10 17l2 2 2-2"/></svg>Ascenseurs</a>
|
||||
<a href="#"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="M20 10c0 6-8 12-8 12S4 16 4 10a8 8 0 1 1 16 0z"/><circle cx="12" cy="10" r="3"/></svg>Sites</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">SI</span>
|
||||
<div class="qui"><b>Salma Idrissi</b><br><small>Dispatchrice ▾</small></div></div>
|
||||
</div>
|
||||
<div class="page">
|
||||
<div class="filajout"><a href="#">Ascenseurs</a> / Ascenseur A1</div>
|
||||
<div class="entete-page">
|
||||
<h1>Ascenseur A1 — Otis Gen2 Premier</h1>
|
||||
<span class="st termine">En service</span>
|
||||
<div class="actions">
|
||||
<button class="btn"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><rect x="3" y="3" width="8" height="8" rx="1"/><rect x="13" y="3" width="8" height="8" rx="1"/><rect x="3" y="13" width="8" height="8" rx="1"/><path d="M13 13h3v3h-3zM19 13h2v2h-2zM13 19h2v2h-2zM18 18h3v3h-3z"/></svg>Étiquette QR</button>
|
||||
<button class="btn prim"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="M12 5v14M5 12h14"/></svg>Nouvel OT</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="grille-3">
|
||||
<div class="carte" style="grid-column:span 2">
|
||||
<h2>Identité</h2>
|
||||
<dl class="infos">
|
||||
<dt>N° de série</dt><dd class="num">OT-2020-4521</dd>
|
||||
<dt>Marque · modèle</dt><dd>Otis — Gen2 Premier</dd>
|
||||
<dt>Mise en service</dt><dd class="num">15 mars 2020</dd>
|
||||
<dt>Site</dt><dd><a href="#">Résidence Al Manar</a> — Bd Hassan II, Mohammedia</dd>
|
||||
<dt>Contrat préventif</dt><dd><span class="st termine">Actif</span> · premier contrôle effectué</dd>
|
||||
<dt>Charge · niveaux</dt><dd class="num">630 kg · 8 niveaux</dd>
|
||||
</dl>
|
||||
</div>
|
||||
<div class="carte">
|
||||
<h2>Étiquette cabine</h2>
|
||||
<div class="qr">
|
||||
<svg width="86" height="86" viewBox="0 0 86 86" role="img" aria-label="QR code de l'ascenseur A1">
|
||||
<rect width="86" height="86" fill="#fff"/>
|
||||
<g fill="#1b2534">
|
||||
<rect x="8" y="8" width="20" height="20"/><rect x="58" y="8" width="20" height="20"/><rect x="8" y="58" width="20" height="20"/>
|
||||
<rect x="12" y="12" width="12" height="12" fill="#fff"/><rect x="62" y="12" width="12" height="12" fill="#fff"/><rect x="12" y="62" width="12" height="12" fill="#fff"/>
|
||||
<rect x="15" y="15" width="6" height="6"/><rect x="65" y="15" width="6" height="6"/><rect x="15" y="65" width="6" height="6"/>
|
||||
<rect x="34" y="10" width="4" height="4"/><rect x="42" y="10" width="8" height="4"/><rect x="34" y="18" width="4" height="8"/><rect x="46" y="18" width="4" height="4"/>
|
||||
<rect x="10" y="34" width="4" height="4"/><rect x="18" y="34" width="8" height="4"/><rect x="30" y="34" width="4" height="8"/><rect x="42" y="34" width="4" height="4"/>
|
||||
<rect x="50" y="34" width="4" height="8"/><rect x="58" y="38" width="8" height="4"/><rect x="70" y="34" width="4" height="4"/>
|
||||
<rect x="34" y="46" width="8" height="4"/><rect x="46" y="46" width="4" height="4"/><rect x="58" y="50" width="4" height="4"/><rect x="66" y="46" width="8" height="4"/>
|
||||
<rect x="34" y="58" width="4" height="8"/><rect x="42" y="62" width="8" height="4"/><rect x="58" y="58" width="8" height="8"/><rect x="70" y="70" width="6" height="6"/>
|
||||
<rect x="42" y="70" width="4" height="6"/><rect x="50" y="70" width="4" height="4"/>
|
||||
</g>
|
||||
</svg>
|
||||
<div style="font-size:12.5px;color:var(--encre-2)">Collée en cabine.<br>Scan gardien → signalement prérempli.<br>Scan technicien → cette fiche.</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="grille-2">
|
||||
<div class="carte">
|
||||
<h2>Organes</h2>
|
||||
<div class="item-liste"><span class="ico"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><rect x="4" y="3" width="16" height="18" rx="1"/><path d="M12 3v18"/></svg></span>Portes cabine — Fermator 40/10<span class="fin"><span class="st attente">Surveillance</span></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="8"/><circle cx="12" cy="12" r="3"/><path d="M12 4v2M12 18v2M4 12h2M18 12h2"/></svg></span>Treuil — Gen2 gearless<span class="fin"><span class="st termine">Bon état</span></span></div>
|
||||
<div class="item-liste"><span class="ico"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><path d="M12 3v12M6 9l6 6 6-6"/><path d="M5 21h14"/></svg></span>Parachute — essai juillet ✓<span class="fin"><span class="st termine">Conforme</span></span></div>
|
||||
<div class="item-liste"><span class="ico"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor"><rect x="5" y="4" width="14" height="16" rx="1"/><path d="M9 8h6M9 12h6M9 16h3"/></svg></span>Armoire de commande — MCS 220<span class="fin"><span class="st termine">Bon état</span></span></div>
|
||||
</div>
|
||||
<div style="display:flex;flex-direction:column;gap:16px">
|
||||
<div class="carte">
|
||||
<h2>Historique récent</h2>
|
||||
<ul class="chrono">
|
||||
<li class="fait"><span class="num">OT-2026-0341</span> · Bruit en gaine — <span class="st encours">En cours</span><br><span class="quand">ouvert hier</span></li>
|
||||
<li class="fait"><span class="num">OT-2026-0338</span> · Grille du mois juillet — <span class="st encours">En cours</span><br><span class="quand">généré le 1ᵉʳ juillet</span></li>
|
||||
<li class="fait"><span class="num">OT-2026-0332</span> · Nivellement cabine — <span class="st termine">Terminé</span><br><span class="quand">12 juillet · bilan : Réglage / Guides</span></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="carte">
|
||||
<h2>Documents</h2>
|
||||
<div class="item-liste"><span class="ico"><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></span>Notice Otis Gen2 Premier.pdf<span class="fin">1,2 Mo · <a href="#" style="color:var(--primaire)">↓</a></span></div>
|
||||
<div class="item-liste"><span class="ico"><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></span>Certificat parachute 2026.pdf<span class="fin">340 Ko · <a href="#" style="color:var(--primaire)">↓</a></span></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ═══════════ 6 · PORTAIL DEMANDEUR ═══════════ -->
|
||||
<p class="note-ecran" data-note="portail" hidden><b>Intention :</b> Karim (gardien, aucune formation) arrive ici en scannant le QR : équipement <b>prérempli</b>, un seul choix critique (« personne bloquée ? »), suivi sans jargon (Reçu → En cours → Résolu).</p>
|
||||
<section class="ecran" id="portail">
|
||||
<div class="app pleine"><div style="background:var(--fond);min-height:640px">
|
||||
<div class="portail">
|
||||
<div class="logo" style="color:var(--encre);padding:0">
|
||||
<span class="marque">▲<br>▼</span><div><b style="font-size:19px">SIOP</b><small style="color:var(--encre-2)">Signalement — Résidence Al Manar</small></div>
|
||||
</div>
|
||||
<div class="carte" style="display:flex;flex-direction:column;gap:12px">
|
||||
<div style="display:flex;align-items:center;gap:10px;background:var(--primaire-doux);border-radius:8px;padding:10px 12px;font-size:13px">
|
||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="var(--primaire)" stroke-width="1.75"><rect x="6" y="2" width="12" height="20" rx="2"/><path d="M10 7l2-2 2 2M10 17l2 2 2-2"/></svg>
|
||||
<b>Ascenseur A1 — hall principal</b> <span style="color:var(--encre-2)">(détecté par le QR)</span>
|
||||
</div>
|
||||
<div class="gros-toggle"><b>Une personne est-elle bloquée dans la cabine ?</b><span class="interrupteur" role="switch" aria-checked="false" aria-label="Personne bloquée"></span></div>
|
||||
<div class="champ"><label for="m-desc">Décrivez le problème</label>
|
||||
<input id="m-desc" placeholder="Ex. : la porte ne se ferme plus au 3ᵉ étage"></div>
|
||||
<div class="zone-photo">📷 Ajouter une photo (facultatif)</div>
|
||||
<button class="btn prim" style="justify-content:center;padding:11px">Envoyer le signalement</button>
|
||||
</div>
|
||||
<div class="carte">
|
||||
<h2>Mes signalements</h2>
|
||||
<div class="item-liste" style="align-items:flex-start"><div>
|
||||
<b>Porte bloquée au 3ᵉ étage</b><span class="sous num">DEM-2026-0107 · hier</span>
|
||||
<div class="suivi-simple">
|
||||
<span class="etape fait">✓ Reçu</span><span class="lien-e"></span>
|
||||
<span class="etape fait">Intervention en cours</span><span class="lien-e"></span>
|
||||
<span class="etape">Résolu</span>
|
||||
</div></div>
|
||||
</div>
|
||||
<div class="item-liste" style="align-items:flex-start"><div>
|
||||
<b>Voyant cabine éteint</b><span class="sous num">DEM-2026-0093 · 2 juil.</span>
|
||||
<div class="suivi-simple">
|
||||
<span class="etape fait">✓ Reçu</span><span class="lien-e"></span>
|
||||
<span class="etape fait">✓ Intervention</span><span class="lien-e"></span>
|
||||
<span class="etape fait">✓ Résolu</span>
|
||||
</div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div></div>
|
||||
</section>
|
||||
|
||||
<!-- ═══════════ 7 · MOBILE ═══════════ -->
|
||||
<p class="note-ecran" data-note="mobile" hidden><b>Intention :</b> Ahmed au sous-sol, gants, sans réseau — gros boutons (≥ 44 px), état de synchro toujours visible, grille du mois en 2 taps, clôture bloquée tant que la grille n'est pas complète.</p>
|
||||
<section class="ecran" id="mobile">
|
||||
<div class="app pleine" style="border:0;background:transparent"><div class="tels">
|
||||
<div class="tel"><div class="encoche"><i></i></div>
|
||||
<div class="ecran-tel">
|
||||
<h3>Mes interventions <span class="sync">⟳ à jour</span></h3>
|
||||
<div class="carte-ot-tel" style="border-left:3px solid var(--prio-haute)">
|
||||
<div class="type-t">Dépannage <span class="prio haute"><i></i>Haute</span></div>
|
||||
<b>Bruit anormal en gaine</b>
|
||||
<div class="ou">Asc. A1 · Résidence Al Manar</div>
|
||||
</div>
|
||||
<div class="carte-ot-tel">
|
||||
<div class="type-t">Maintenance <span class="prio basse"><i></i>Basse</span></div>
|
||||
<b>Grille du mois — juillet</b>
|
||||
<div class="ou">Asc. A1 · Résidence Al Manar</div>
|
||||
</div>
|
||||
<div class="carte-ot-tel">
|
||||
<div class="type-t">Dépannage <span class="prio moyenne"><i></i>Moyenne</span></div>
|
||||
<b>Contact de porte</b>
|
||||
<div class="ou">Asc. B2 · Tour Atlas</div>
|
||||
</div>
|
||||
<div style="margin-top:auto"><button class="btn-tel">▣ Scanner un ascenseur</button></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tel"><div class="encoche"><i></i></div>
|
||||
<div class="ecran-tel">
|
||||
<h3>Grille du mois <span class="sync off">⟳ hors-ligne · 2 en attente</span></h3>
|
||||
<div style="font-size:12.5px;color:var(--encre-2)">OT-2026-0338 · Asc. A1 · <b class="num" style="color:var(--encre)">2/4 traitées</b></div>
|
||||
<div class="carte" style="padding:4px 14px">
|
||||
<div class="check"><span class="coche ok">✓</span>Jeu et fixation des portes</div>
|
||||
<div class="check"><span class="coche na">–</span>Éclairage de secours <span class="qui-fait">N-A</span></div>
|
||||
<div class="check"><span class="coche"></span>Niveau d'huile du treuil</div>
|
||||
<div class="check"><span class="coche"></span>Essai parachute (juillet)</div>
|
||||
</div>
|
||||
<div class="paire-boutons"><span class="btn-choix actif">Fait</span><span class="btn-choix">Non applicable</span></div>
|
||||
<div style="margin-top:auto;display:flex;flex-direction:column;gap:8px">
|
||||
<button class="btn-tel gris" disabled>Clôturer (grille incomplète)</button>
|
||||
<div style="text-align:center;font-size:11.5px;color:var(--encre-3)">Vos coches partiront à la prochaine synchro</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tel"><div class="encoche"><i></i></div>
|
||||
<div class="ecran-tel" style="padding:10px">
|
||||
<h3 style="padding:4px 4px 0">Scanner</h3>
|
||||
<div class="viseur"><div class="cadre-qr"></div><p>Visez le QR collé en cabine</p></div>
|
||||
<button class="btn-tel vert">Ascenseur A1 reconnu → ouvrir la fiche</button>
|
||||
</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>
|
||||
156
docs/02-design/tokens.css
Normal file
156
docs/02-design/tokens.css
Normal file
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
* SIOP V2 — Design tokens (source de vérité visuelle)
|
||||
* Importé tel quel par apps/web ; les maquettes HD l'utilisent aussi.
|
||||
* Règle : AUCUNE valeur visuelle codée en dur hors de ce fichier.
|
||||
* Thèmes : clair par défaut, sombre via @media + surcharge [data-theme].
|
||||
*/
|
||||
|
||||
:root {
|
||||
/* ——— Marque ——— */
|
||||
--primaire: #1f4fb8; /* bleu-treuil : actions, liens, focus */
|
||||
--primaire-actif: #1a439c;
|
||||
--primaire-doux: #eaf0fb; /* fonds de sélection/hover primaires */
|
||||
--safran: #dd8a0b; /* accent de marque — parcimonieux */
|
||||
--safran-doux: #fdf3e3;
|
||||
|
||||
/* ——— Neutres (acier, biais froid) ——— */
|
||||
--fond: #f5f7fa;
|
||||
--surface: #ffffff;
|
||||
--surface-2: #eef2f7; /* en-têtes de table, zones repliées */
|
||||
--bordure: #dce3ec;
|
||||
--bordure-forte: #b9c4d4;
|
||||
--encre: #1b2534; /* texte principal */
|
||||
--encre-2: #55647a; /* texte secondaire */
|
||||
--encre-3: #8494ab; /* placeholder, désactivé */
|
||||
|
||||
/* ——— Statuts OT (réservés) ——— */
|
||||
--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;
|
||||
|
||||
/* ——— Priorités (réservées) ——— */
|
||||
--prio-bloque: #d92626; --prio-bloque-fond: #fdeaea; /* personne bloquée */
|
||||
--prio-haute: #d92626;
|
||||
--prio-moyenne: #b96f07;
|
||||
--prio-basse: #178a50;
|
||||
--prio-aucune: #8494ab;
|
||||
|
||||
/* ——— Sémantique générale ——— */
|
||||
--succes: #178a50;
|
||||
--alerte: #b96f07;
|
||||
--danger: #d92626;
|
||||
--info: #3d6fe0;
|
||||
|
||||
/* ——— Palette graphique (analytics, ordre FIXE, validée CVD) ——— */
|
||||
--graf-1: #3b69d6;
|
||||
--graf-2: #dd8a0b;
|
||||
--graf-3: #1f9e8e;
|
||||
--graf-4: #8a63d2;
|
||||
--graf-grille: #e6ebf2;
|
||||
|
||||
/* ——— Typographie ——— */
|
||||
--police-ui: "Manrope", "Avenir Next", "Segoe UI Variable", system-ui, sans-serif;
|
||||
--police-mono: "SF Mono", ui-monospace, "Cascadia Mono", monospace;
|
||||
--t-11: 11px; --t-12: 12px; --t-13: 13px; --t-14: 14px;
|
||||
--t-16: 16px; --t-20: 20px; --t-24: 24px; --t-32: 32px;
|
||||
|
||||
/* ——— Forme & espace (grille 4 px) ——— */
|
||||
--e-1: 4px; --e-2: 8px; --e-3: 12px; --e-4: 16px; --e-5: 20px; --e-6: 24px; --e-8: 32px;
|
||||
--rayon: 10px; /* cartes */
|
||||
--rayon-controle: 8px; /* inputs, boutons */
|
||||
--rayon-pastille: 999px;
|
||||
--ombre-menu: 0 8px 24px rgb(16 30 54 / 0.14);
|
||||
--rail: 3px; /* motif signature : rail actif safran */
|
||||
|
||||
/* ——— Mouvement ——— */
|
||||
--transition: 140ms ease-out;
|
||||
}
|
||||
|
||||
/* ——— Thème sombre (« machinerie de nuit », pas une inversion) ——— */
|
||||
@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;
|
||||
|
||||
--ombre-menu: 0 8px 24px rgb(0 0 0 / 0.45);
|
||||
}
|
||||
}
|
||||
|
||||
/* Le sélecteur de thème de l'app doit GAGNER dans les deux sens. */
|
||||
: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;
|
||||
--ombre-menu: 0 8px 24px rgb(16 30 54 / 0.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;
|
||||
--ombre-menu: 0 8px 24px rgb(0 0 0 / 0.45);
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
:root { --transition: 0ms; }
|
||||
}
|
||||
Reference in New Issue
Block a user