/* * SIOP V2 — styles applicatifs. * tokens.css est copié TEL QUEL depuis docs/02-design/ (source de vérité). * Les classes composants ci-dessous sont EXTRAITES de la maquette validée * (docs/02-design/maquettes/maquette-web.html) — seule adaptation : la * coquille remplit le viewport au lieu du cadre de revue 1280 px. * Règle : aucune valeur visuelle en dur — tout vient des tokens. */ @import 'tailwindcss'; @import './tokens.css'; @theme inline { --color-fond: var(--fond); --color-surface: var(--surface); --color-surface-2: var(--surface-2); --color-bordure: var(--bordure); --color-bordure-forte: var(--bordure-forte); --color-encre: var(--encre); --color-encre-2: var(--encre-2); --color-encre-3: var(--encre-3); --color-primaire: var(--primaire); --color-primaire-doux: var(--primaire-doux); --color-safran: var(--safran); --color-safran-doux: var(--safran-doux); --color-succes: var(--succes); --color-alerte: var(--alerte); --color-danger: var(--danger); --color-info: var(--info); --font-ui: var(--police-ui); --radius-carte: var(--rayon); --radius-controle: var(--rayon-controle); } /* ═══ Base (maquette §Base) ═══ */ 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; } 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; } /* ═══ Coquille applicative (plein viewport) ═══ */ .app { display: grid; grid-template-columns: 232px 1fr; min-height: 100vh; background: var(--fond); } /* 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: 0.55; font-size: 11px; color: var(--safran); } .logo b { font-size: 19px; letter-spacing: 0.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: 0.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: var(--rail) solid transparent; transition: background var(--transition); } .nav a:hover { background: rgb(255 255 255 / 0.06); color: var(--nav-encre-vif); } .nav a.actif { background: rgb(255 255 255 / 0.09); color: var(--nav-encre-vif); border-left-color: var(--safran); } .nav a[aria-disabled='true'] { opacity: 0.45; cursor: default; } .nav a .badge-nav { margin-left: auto; background: var(--prio-bloque); color: #fff; font-size: 11px; padding: 1px 7px; border-radius: var(--rayon-pastille); font-weight: 700; } .nav a .badge-release { margin-left: auto; font-size: 9.5px; letter-spacing: 0.06em; color: #6b7f9e; border: 1px solid var(--nav-bordure); padding: 1px 6px; border-radius: var(--rayon-pastille); } .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: var(--rayon-controle); padding: 7px 12px; color: var(--encre-3); font-size: 13px; } .recherche svg { width: 15px; height: 15px; } .compte { margin-left: auto; display: flex; align-items: center; gap: 10px; } .chip-demo { font-size: 11px; font-weight: 700; letter-spacing: 0.05em; color: var(--safran); background: var(--safran-doux); padding: 3px 9px; border-radius: var(--rayon-pastille); 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; text-align: left; } .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: -0.01em; text-wrap: balance; } .entete-page .actions { margin-left: auto; display: flex; gap: 8px; } /* Boutons (variants shadcn-style pilotés par ces classes) */ .btn { display: inline-flex; align-items: center; gap: 7px; padding: 8px 14px; border-radius: var(--rayon-controle); 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(0.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: 0.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: 0.04em; text-transform: uppercase; color: var(--encre-2); margin-bottom: 12px; } .grille-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; } @media (max-width: 900px) { .grille-2 { grid-template-columns: 1fr; } } /* Pastilles statut / priorité (réservées — jamais réutilisées ailleurs) */ .st { display: inline-flex; align-items: center; gap: 6px; padding: 2px 10px; border-radius: var(--rayon-pastille); 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; } .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; } } .prio.bloque { color: var(--prio-bloque); } .prio.bloque i { background: var(--prio-bloque); animation: pulse 1.4s ease-out infinite; } @media (prefers-reduced-motion: reduce) { .prio.bloque i { animation: none; } } .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); } /* ═══ Connexion ═══ */ .conn { min-height: 100vh; 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: var(--rayon-controle); 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: 0.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: var(--rayon-controle); background: var(--surface); color: var(--encre); 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); } .erreur-form { color: var(--danger); font-size: 12.5px; font-weight: 600; } /* ═══ Menu (compte / bascule démo) ═══ */ .menu { min-width: 230px; background: var(--surface); border: 1px solid var(--bordure); border-radius: var(--rayon); box-shadow: var(--ombre-menu); padding: 6px; z-index: 60; } .menu .titre-menu { padding: 7px 10px 3px; font-size: 10.5px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--encre-3); } .menu .item { display: flex; align-items: center; gap: 10px; width: 100%; padding: 7px 10px; border-radius: 7px; font-size: 13px; color: var(--encre); text-align: left; border: 0; background: none; outline: none; } .menu .item:hover, .menu .item[data-highlighted] { background: var(--primaire-doux); } .menu .item .role { margin-left: auto; font-size: 11px; color: var(--encre-2); } .menu .item svg { width: 15px; height: 15px; stroke-width: 1.75; color: var(--encre-2); } .menu .separateur { height: 1px; background: var(--bordure); margin: 6px 4px; } /* ═══ R1 — Référentiel (classes extraites de maquette-r1.html validée) ═══ */ /* Statuts d'ÉQUIPEMENT (distincts des statuts OT) */ .st.arret { color: var(--danger); background: var(--prio-bloque-fond); } .st.maintenance { color: var(--st-encours); background: var(--st-encours-fond); } /* Carte géographique — le conteneur ; Leaflet rend à l'intérieur */ .geo { position: relative; border: 1px solid var(--bordure); border-radius: var(--rayon); overflow: hidden; min-height: 320px; background: var(--surface-2); } .geo .leaflet-container { position: absolute; inset: 0; font: inherit; } /* Pin maquette (divIcon Leaflet) */ .pin-geo { width: 26px; height: 26px; border-radius: 50% 50% 50% 0; transform: rotate(-45deg) translate(4px, -4px); background: var(--primaire); border: 2px solid var(--surface); box-shadow: var(--ombre-menu); } .pin-geo::after { content: ''; position: absolute; inset: 7px; border-radius: 50%; background: var(--surface); } .pin-geo.alerte { background: var(--prio-bloque); } /* Arborescence des emplacements */ .arbre { list-style: none; padding: 0; font-size: 13.5px; } .arbre li { position: relative; padding: 7px 0 7px 26px; border-bottom: 1px solid var(--bordure); } .arbre li:last-child { border-bottom: 0; } .arbre li::before { content: ''; position: absolute; left: 8px; top: 0; bottom: 0; width: 1px; background: var(--bordure); } .arbre li::after { content: ''; position: absolute; left: 8px; top: 50%; width: 12px; height: 1px; background: var(--bordure); } .arbre li.racine { padding-left: 0; } .arbre li.racine::before, .arbre li.racine::after { display: none; } .arbre .meta { color: var(--encre-2); font-size: 12px; margin-left: 8px; } .arbre .fin { float: right; color: var(--encre-2); font-size: 12px; } /* Formulaires R1 */ .form-grille { display: grid; grid-template-columns: 1fr 1fr; gap: 12px 14px; } @media (max-width: 900px) { .form-grille { grid-template-columns: 1fr; } } .form-grille .pleine-l { grid-column: 1/-1; } .champ select { width: 100%; padding: 9px 12px; border: 1px solid var(--bordure-forte); border-radius: var(--rayon-controle); font: inherit; background: var(--surface); color: var(--encre); } .ligne-organe { display: flex; gap: 8px; align-items: center; padding: 8px 0; border-bottom: 1px solid var(--bordure); } .ligne-organe:last-of-type { border-bottom: 0; } .ligne-organe select, .ligne-organe input { padding: 8px 11px; border: 1px solid var(--bordure-forte); border-radius: var(--rayon-controle); font: inherit; background: var(--surface); color: var(--encre); } .btn-suppr { color: var(--encre-3); padding: 6px; border-radius: 6px; border: 0; background: none; } .btn-suppr:hover { color: var(--danger); background: var(--prio-bloque-fond); } /* Étiquette QR imprimable (A6 — objet papier, blanc même en thème sombre) */ .zone-impression { display: flex; gap: 24px; align-items: flex-start; flex-wrap: wrap; } .etiquette { width: 340px; background: #fff; color: #1b2534; border: 1px solid var(--bordure-forte); border-radius: 12px; padding: 22px; display: flex; flex-direction: column; gap: 12px; box-shadow: var(--ombre-menu); } .etiquette .tete { display: flex; align-items: center; gap: 10px; border-bottom: 2px solid #1b2534; padding-bottom: 10px; } .etiquette .tete .marque { display: flex; flex-direction: column; line-height: 0.55; font-size: 12px; color: #dd8a0b; } .etiquette .tete b { font-size: 20px; letter-spacing: 0.04em; } .etiquette .corps { display: flex; gap: 16px; align-items: center; } .etiquette .qr-grand { flex: none; border: 1px solid #dce3ec; border-radius: 8px; padding: 6px; background: #fff; } .etiquette h3 { font-size: 15px; font-weight: 700; margin: 0; } .etiquette .ou { font-size: 12px; color: #55647a; } .etiquette .consigne { font-size: 12.5px; background: #fdf3e3; border: 1px dashed #dd8a0b; color: #8a5a06; border-radius: 8px; padding: 8px 10px; text-align: center; font-weight: 600; } .etiquette .ref { font-size: 11px; color: #8494ab; text-align: center; font-variant-numeric: tabular-nums; } @media print { body * { visibility: hidden; } .etiquette, .etiquette * { visibility: visible; } .etiquette { position: fixed; inset: 0 auto auto 0; box-shadow: none; margin: 10mm; } } /* Modale (Radix Dialog) — style maquette */ .voile-radix { position: fixed; inset: 0; background: color-mix(in srgb, var(--encre) 32%, transparent); z-index: 70; } .modale { position: fixed; top: 10vh; left: 50%; transform: translateX(-50%); width: 460px; max-width: 94vw; max-height: 82vh; overflow-y: auto; background: var(--surface); border: 1px solid var(--bordure); border-radius: 12px; box-shadow: var(--ombre-menu); padding: 20px; display: flex; flex-direction: column; gap: 12px; z-index: 71; } .modale h3 { font-size: 15px; font-weight: 700; } .modale .pied { display: flex; justify-content: flex-end; gap: 8px; margin-top: 4px; } .note-douce { font-size: 12px; color: var(--encre-2); background: var(--surface-2); border-radius: 8px; padding: 8px 10px; } .lien-copiable { font-family: var(--police-mono); font-size: 11.5px; word-break: break-all; background: var(--surface-2); border: 1px dashed var(--bordure-forte); border-radius: 8px; padding: 8px 10px; } /* Équipes */ .equipes { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; } @media (max-width: 1000px) { .equipes { grid-template-columns: 1fr; } } .equipe { border: 1px solid var(--bordure); border-radius: var(--rayon); padding: 12px 14px; display: flex; flex-direction: column; gap: 8px; background: var(--surface); } .equipe b { font-size: 13.5px; } .equipe .zone { font-size: 12px; color: var(--encre-2); } /* Tables denses (liste ascenseurs / sites / personnes) */ .table { width: 100%; overflow-x: auto; } .table table { width: 100%; font-size: 13.5px; } .table th { font-size: 11px; letter-spacing: 0.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); } .filajout { color: var(--encre-3); font-size: 12.5px; } .filajout a { color: var(--encre-2); text-decoration: none; } .filtres { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; } .filtres select { border: 1px solid var(--bordure-forte); border-radius: var(--rayon-controle); padding: 7px 11px; font-size: 13px; background: var(--surface); color: var(--encre); } .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; } .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 .fin { margin-left: auto; display: flex; align-items: center; gap: 10px; color: var(--encre-2); font-size: 12.5px; } .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; } /* ═══ Page /design : 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: var(--rayon-controle); border: 1px solid var(--bordure); margin-bottom: 4px; }