/* ==========================================================================
   CloudFive — état des services. Direction « Le filet ».

   Même direction artistique que cf-panel.css et que cloudfive.fr/v6, et pour
   la même raison : le site a corrigé trois fois la même erreur (.stats en
   v8.3, .socle-offres, .universe) avec à chaque fois le même commentaire —
   « on garde la structure, on retire le contenant ». Cette page part donc de
   l'arrivée de cette trajectoire :

     - aucune carte, aucune ombre sur un bloc statique
     - DEUX épaisseurs de filet, jamais trois
     - la typographie fait la hiérarchie
     - un seul accent orange par écran
     - le chiffre en grand, son unité en petit et en gris
     - rayons 16 / 10 / 8, courbe cubic-bezier(0.16, 1, 0.3, 1)
     - appui à scale(0.97) sur tout ce qui se presse

   DEUX THÈMES DANS UN SEUL FICHIER. Les panels existants ont chacun leur
   feuille (cf-panel.css clair, cf-v6.css graphite) parce qu'on choisit à la
   construction. Ici le visiteur choisit, et la bascule doit être instantanée :
   un seul jeu de classes, les jetons redéfinis sous [data-theme]. Les valeurs
   sombres sont celles de cf-v6.css, au jeton près, pour que les trois
   interfaces restent la même famille.

   Écrite à la main, servie localement : pas de Tailwind par CDN. Le brain a
   déjà mis Fastly/GitHub en bogon ; un visiteur derrière le /24 se serait
   retrouvé avec une page nue — et une page d'état illisible pendant une
   attaque, c'est l'inverse du but.
   ========================================================================== */

/* --- Poppins, servi par cette machine -------------------------------------
   Exactement les fichiers de cloudfive.fr/v6, copies dans /opt/cf-assets.
   Passer par Google Fonts ferait dependre d'un tiers la page qu'on ouvre
   precisement quand quelque chose est deja casse, et imposerait une
   banniere de consentement. 4 x 11 Ko, mis en cache une semaine. */

@font-face { font-family: 'Poppins'; font-style: normal; font-weight: 400; font-display: swap;
             src: url('/assets/fonts/poppins-400.woff2') format('woff2'); }
@font-face { font-family: 'Poppins'; font-style: normal; font-weight: 500; font-display: swap;
             src: url('/assets/fonts/poppins-500.woff2') format('woff2'); }
@font-face { font-family: 'Poppins'; font-style: normal; font-weight: 600; font-display: swap;
             src: url('/assets/fonts/poppins-600.woff2') format('woff2'); }
@font-face { font-family: 'Poppins'; font-style: normal; font-weight: 700; font-display: swap;
             src: url('/assets/fonts/poppins-700.woff2') format('woff2'); }

:root {
  /* --- Clair : les valeurs RELEVEES sur cloudfive.fr/v6 ----------------
     Rien ici n'est approche. Chaque valeur est lue dans la feuille du site,
     pour que passer de cloudfive.fr a cette page ne se voie pas. Les seuls
     jetons en plus sont les etats (panne, degrade, inconnu), que le site
     vitrine n'a pas besoin de nommer.

     Les triplets --*-rgb existent parce que la barre d'en-tete du site est
     translucide : rgba(var(--bg-rgb), 0.86). Sans eux, pas de flou. */
  --bg:          #FAFAFA;
  --bg-rgb:      250, 250, 250;
  --bg-warm:     #FCFCFC;
  --surface:     #FFFFFF;
  --surface-rgb: 255, 255, 255;
  --surface-2:   #FCFCFC;
  --raised:      #FFFFFF;
  --chip:        #F4F4F5;
  --papier:      #F6F2EE;

  --ink:         #111113;
  --ink-rgb:     17, 17, 19;
  --on-ink:      #FFFFFF;
  --muted:       #76767B;
  --faint:       #6F6F78;
  --ghost:       #C4C4C9;

  /* Deux epaisseurs. Pas trois. */
  --line:        rgba(17, 17, 19, 0.10);
  --line-soft:   rgba(17, 17, 19, 0.06);

  --cf:          #f96e1e;
  --cf-fill:     #f96e1e;
  --cf-ink:      #d95c0f;   /* l'orange des qu'il se pose en TEXTE */
  --cf-press:    #d95c0f;
  --cf-lite:     #ff8f3c;
  --cf-wash:     rgba(249, 110, 30, 0.08);
  --cf-04:       rgba(249, 110, 30, 0.04);
  --cf-08:       rgba(249, 110, 30, 0.08);
  --cf-12:       rgba(249, 110, 30, 0.12);
  --cf-line:     rgba(249, 110, 30, 0.22);

  --ok:          #2FB85D;
  --ok-ink:      #1E8B45;
  --ok-wash:     rgba(47, 184, 93, 0.12);
  --danger:      #D2384A;
  --danger-wash: rgba(210, 56, 74, 0.11);
  --warn:        #C8881A;
  --warn-wash:   rgba(200, 136, 26, 0.13);
  --info:        #3A5BC7;
  --vide:        rgba(17, 17, 19, 0.09);   /* barre de jour sans mesure */
  /* Les « -ink » : la couleur d'état quand elle se pose en TEXTE. Le vert et
     l'ambre purs tombent sous 3:1 sur blanc, même en 54 px. */
  --warn-ink:    #A86F0E;
  --info-wash:   rgba(58, 91, 199, 0.11);
  --lead:        #55555C;   /* le chapeau du héros du site, plus soutenu que --muted */
  --ombre-carte: 0 10px 24px rgba(17, 12, 46, 0.05);
  --ombre-hero:  0 24px 60px -44px rgba(17, 17, 19, 0.30);

  --r-media:     16px;
  --r-btn:       10px;
  --r-chip:      8px;
  --r-pill:      10px;

  --ease:        cubic-bezier(0.16, 1, 0.3, 1);
  --gutter:      56px;
  --max:         1180px;   /* la colonne du site, au pixel */
  --max-large:   1320px;   /* console d'administration : tableaux larges */

  color-scheme: light;
}

/* --- Sombre : les jetons de cf-v6.css, variante console graphite -------
   Règle de confort tenue de la charte : le fond n'est jamais noir, le texte
   n'est jamais blanc pur. C'est l'écart entre les deux qui fatigue, pas la
   teinte. */
:root[data-theme="dark"] {
  --bg:          #111113;
  --bg-rgb:      17, 17, 19;
  --bg-warm:     #151416;
  --surface:     #1A1A1D;
  --surface-rgb: 26, 26, 29;
  --surface-2:   #161618;
  --raised:      #252528;
  --chip:        #252528;
  --papier:      #1E1D20;

  --ink:         #F4F4F5;
  --ink-rgb:     244, 244, 245;
  --on-ink:      #111113;
  --muted:       #A1A1A8;
  --faint:       #8A8A92;
  --ghost:       #4A4A50;

  --line:        rgba(255, 255, 255, 0.10);
  --line-soft:   rgba(255, 255, 255, 0.06);

  --cf-ink:      #FF8F3C;   /* sur fond sombre c'est le clair qui porte le texte */
  --cf-press:    #E0621A;
  --cf-wash:     rgba(249, 110, 30, 0.14);
  --cf-04:       rgba(249, 110, 30, 0.07);
  --cf-08:       rgba(249, 110, 30, 0.14);
  --cf-12:       rgba(249, 110, 30, 0.21);
  --cf-line:     rgba(249, 110, 30, 0.34);

  /* Desatures : ils ne doivent pas rivaliser avec l'orange. */
  --ok:          #3DCB6E;
  --ok-ink:      #3DCB6E;
  --ok-wash:     rgba(61, 203, 110, 0.16);
  --danger:      #E05F6B;
  --danger-wash: rgba(224, 95, 107, 0.15);
  --warn:        #D9A43B;
  --warn-wash:   rgba(217, 164, 59, 0.15);
  --info:        #6E8FEF;
  --vide:        rgba(255, 255, 255, 0.09);
  --warn-ink:    #D9A43B;
  --info-wash:   rgba(110, 143, 239, 0.15);
  --lead:        #A1A1A8;
  --ombre-carte: 0 10px 24px rgba(0, 0, 0, 0.22);
  --ombre-hero:  0 24px 60px -44px rgba(0, 0, 0, 0.60);

  color-scheme: dark;
}

/* Sans choix explicite, on suit le système. Le garde :not([data-theme]) est
   indispensable : sans lui, un visiteur qui a CHOISI le clair sur une machine
   en mode sombre se verrait imposer le sombre malgré son choix.

   ⚠️ Ce bloc répète la palette de :root[data-theme="dark"], faute de
   sélecteur CSS capable de réunir « attribut » et « media query ». Les deux
   DOIVENT rester identiques — une dérive donne une page sombre à moitié
   claire selon la façon dont le visiteur est arrivé au sombre.
   `python3 verifier-themes.py` compare les deux blocs et échoue sinon. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #111113; --bg-rgb: 17, 17, 19; --bg-warm: #151416;
    --surface: #1A1A1D; --surface-rgb: 26, 26, 29; --surface-2: #161618;
    --raised: #252528; --chip: #252528; --papier: #1E1D20;
    --ink: #F4F4F5; --ink-rgb: 244, 244, 245; --on-ink: #111113;
    --muted: #A1A1A8; --faint: #8A8A92; --ghost: #4A4A50;
    --line: rgba(255, 255, 255, 0.10); --line-soft: rgba(255, 255, 255, 0.06);
    --cf-ink: #FF8F3C; --cf-press: #E0621A; --cf-wash: rgba(249, 110, 30, 0.14);
    --cf-04: rgba(249, 110, 30, 0.07); --cf-08: rgba(249, 110, 30, 0.14);
    --cf-12: rgba(249, 110, 30, 0.21); --cf-line: rgba(249, 110, 30, 0.34);
    --ok: #3DCB6E; --ok-ink: #3DCB6E; --ok-wash: rgba(61, 203, 110, 0.16);
    --danger: #E05F6B; --danger-wash: rgba(224, 95, 107, 0.15);
    --warn: #D9A43B; --warn-wash: rgba(217, 164, 59, 0.15);
    --info: #6E8FEF; --vide: rgba(255, 255, 255, 0.09);
    --warn-ink: #D9A43B; --info-wash: rgba(110, 143, 239, 0.15); --lead: #A1A1A8;
    --ombre-carte: 0 10px 24px rgba(0, 0, 0, 0.22);
    --ombre-hero: 0 24px 60px -44px rgba(0, 0, 0, 0.60);
    color-scheme: dark;
  }
}

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: 'Poppins', ui-sans-serif, system-ui, -apple-system, sans-serif;
  font-size: 15px;
  font-weight: 400;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  /* Pas de transition sur body : la bascule de thème la ferait traîner sur
     toute la page. Les couleurs changent d'un coup, c'est plus net. */
}

/* --- Typographie --------------------------------------------------------
   Échelle INTÉRIEURE : un titre de page d'état ne crie pas. L'accueil du
   site monte à 86px, pas une page de supervision. */

h1, h2, h3, h4 {
  margin: 0; color: var(--ink);
  font-weight: 500; letter-spacing: -0.035em; line-height: 1.12;
}
h1 { font-size: clamp(27px, 3vw, 37px); }
h2 { font-size: clamp(20px, 2.1vw, 25px); }
h3 { font-size: 17px; letter-spacing: -0.015em; }
h4 { font-size: 15px; letter-spacing: -0.01em; font-weight: 500; }

p { margin: 0; color: var(--muted); }
.lead { font-size: 15.5px; line-height: 1.55; color: var(--muted); max-width: 70ch; }
.small { font-size: 13px; color: var(--faint); }
.tiny  { font-size: 11.5px; color: var(--faint); letter-spacing: 0.04em; }

a { color: var(--cf-ink); text-decoration: none; transition: color 200ms var(--ease); }
a:hover { color: var(--cf); }

/* Ce qui fait qu'un tableau a l'air réglé. */
td, th, input, select, .num, .val, .unite { font-variant-numeric: tabular-nums; }
.mono, code, pre {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-variant-numeric: tabular-nums;
}

:focus-visible {
  outline: 2px solid var(--cf);
  outline-offset: 2px;
  border-radius: 4px;
}

.sr {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}

/* --- Mise en page -------------------------------------------------------- */

.wrap { width: 100%; max-width: var(--max); margin-inline: auto; padding-inline: var(--gutter); }
.wrap--large { max-width: var(--max-large); }
/* padding-BLOCK et non le raccourci `padding` : ces classes se portent
   toujours avec .wrap, et un raccourci de même spécificité déclaré plus bas
   remettait padding-left/right à 0 — la gouttière disparaissait et le
   contenu touchait les deux bords de l'écran, à toutes les largeurs. */
.rubrique { padding-block: clamp(28px, 3vw, 44px); }
.fil { border-top: 1px solid var(--line); }
.fil-doux { border-top: 1px solid var(--line-soft); }

/* --- En-tête -------------------------------------------------------------
   La barre de cloudfive.fr/v6, à l'identique : 66 px de haut, fond
   translucide flouté, filet doux en bas, marque à gauche, onglets soulignés
   d'un trait orange, bascule de thème à droite. Les mesures sont relevées
   dans la feuille du site, pas estimées — c'est ce qui fait qu'on ne sent
   pas la frontière entre le site et cette page.

   La barre est pleine largeur (comme le site), le contenu reste dans sa
   colonne : c'est voulu, l'en-tête appartient au site, le tableau de bord
   appartient à la page. */

.hd { position: sticky; top: 0; z-index: 60; }

.hd-bar {
  background: rgba(var(--bg-rgb), 0.86);
  backdrop-filter: saturate(180%) blur(20px);
  -webkit-backdrop-filter: saturate(180%) blur(20px);
  border-bottom: 1px solid var(--line-soft);
  transition: border-color 260ms var(--ease);
}
/* Collée, la barre affirme son filet ; au repos elle se fond dans la page. */
.hd.colle .hd-bar { border-bottom-color: var(--line); }

.hd-in {
  display: flex; align-items: center;
  height: 66px;
  padding-inline: clamp(20px, 2.6vw, 40px);
  gap: clamp(16px, 2.4vw, 36px);
}

.hd-gauche { display: flex; align-items: center; gap: 14px; flex: none; }
.hd-brand { display: inline-flex; align-items: center; gap: 9px; }
.hd-brand img { display: block; width: 56px; height: 32px; object-fit: contain; }
.hd-mot {
  font-weight: 600; font-size: 14.5px; letter-spacing: 0.09em; line-height: 1;
  color: var(--ink); text-transform: uppercase; padding-top: 1px;
  white-space: nowrap;
}
.hd-mot b { font-weight: 600; color: var(--cf); }

/* Le nom de CE site, séparé de la marque par un filet vertical : on est sur
   un sous-domaine de CloudFive, pas sur la vitrine, et la barre doit le dire
   sans qu'on ait à lire le titre. */
.hd-sous {
  font-size: 13.5px; color: var(--faint); white-space: nowrap;
  padding-left: 14px; border-left: 1px solid var(--line);
}

.hd-nav { display: flex; align-items: center; gap: clamp(2px, 0.6vw, 10px); }
.hd-tab {
  position: relative; display: inline-flex; align-items: center;
  padding: 22px 10px; line-height: 1;
  font-size: 14px; font-weight: 500; color: var(--muted);
  transition: color 200ms ease;
}
/* Le trait orange sous l'onglet : 3 px, arrondi en haut, il POUSSE depuis le
   centre. C'est la signature de la barre du site. */
.hd-tab::after {
  content: ''; position: absolute; left: 10px; right: 10px; bottom: 0;
  height: 3px; border-radius: 3px 3px 0 0; background: var(--cf);
  transform: scaleX(0); transform-origin: center;
  transition: transform 260ms var(--ease);
}
.hd-tab:hover { color: var(--ink); }
.hd-tab:hover::after { transform: scaleX(1); }
.hd-tab.on { color: var(--cf); }
.hd-tab.on::after { transform: scaleX(1); }
.hd-tab.on:hover { color: var(--cf-ink); }
.hd-tab:focus-visible { outline: 2px solid var(--cf); outline-offset: -4px; }

.hd-right { display: flex; align-items: center; gap: 10px; margin-left: auto; }

.hd-connexion {
  display: inline-flex; align-items: center; gap: 8px;
  height: 36px; padding: 0 14px 0 12px;
  font-size: 13.5px; font-weight: 500; color: var(--ink);
  border: 1px solid var(--line); border-radius: var(--r-btn);
  background: var(--surface); white-space: nowrap;
  transition: border-color 200ms ease, color 200ms ease,
              transform 160ms var(--ease);
}
.hd-connexion svg { width: 16px; height: 16px; color: var(--muted); flex: none; }
.hd-connexion:hover { border-color: var(--cf); color: var(--cf-ink); }
.hd-connexion:hover svg { color: var(--cf); }
.hd-connexion:active { transform: scale(0.97); }

.hd-login { font-size: 13px; color: var(--muted); }
.hd-login b { color: var(--ink); font-weight: 500; }

/* --- Bascule de thème ----------------------------------------------------
   Deux icônes, une seule visible, aux mesures du bouton du site : 36 × 34.
   Pas de libellé — l'icône dit tout, et un mot en plus déséquilibrerait la
   barre. */

.hd-theme {
  display: inline-flex; align-items: center; justify-content: center; flex: none;
  width: 36px; height: 34px; padding: 0;
  border: 1px solid var(--line); border-radius: var(--r-btn);
  background: var(--surface); color: var(--faint); cursor: pointer;
  transition: border-color 200ms ease, color 200ms ease,
              transform 160ms var(--ease);
}
.hd-theme:hover { border-color: rgba(var(--ink-rgb), 0.22); color: var(--ink); }
.hd-theme:active { transform: scale(0.97); }
.hd-theme svg { width: 16px; height: 16px; display: block; }
.hd-theme .soleil { display: none; }
:root[data-theme="dark"] .hd-theme .lune { display: none; }
:root[data-theme="dark"] .hd-theme .soleil { display: block; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .hd-theme .lune { display: none; }
  :root:not([data-theme="light"]) .hd-theme .soleil { display: block; }
}

/* --- Le bandeau du haut -------------------------------------------------
   Celui du site (13 px, orange plein, un point blanc, un lien souligné), mais
   seulement quand un incident est ouvert : affiché en permanence, il ne
   voudrait plus rien dire le jour où il compte. Les couleurs sont FIXES dans
   les deux thèmes, comme l'orange du site — un rouge éclairci pour le sombre
   ne tiendrait plus le blanc. */

.haut { background: #f96e1e; color: #fff; font-size: 13px; line-height: 1.4; }
.haut--panne       { background: #C63042; }
.haut--maintenance { background: #3A5BC7; }
.haut-in { display: flex; align-items: center; gap: 14px; min-height: 35px; padding-block: 8px; }
.haut-pt {
  flex: none; width: 6px; height: 6px; border-radius: 50%;
  background: #fff; opacity: 0.85;
}
.haut-tx { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.haut-tx b { font-weight: 600; }
.haut a {
  flex: none; color: #fff; font-weight: 500; white-space: nowrap;
  border-bottom: 1px solid rgba(255, 255, 255, 0.5);
}
.haut a:hover { color: #fff; border-bottom-color: #fff; }

/* --- Le héros -------------------------------------------------------------
   La carte d'accueil de cloudfive.fr/v6, relevée sur la page : rayon 16,
   filet --line, ombre longue et très diffuse, la photo du datacenter fondue
   à droite (même masque, même désaturation), le verdict à gauche et les
   repères chiffrés dans la bande translucide du bas.

   Un peu plus large que la colonne de contenu, comme sur le site : le héros
   déborde, le reste s'aligne. */

.hero-st {
  position: relative; overflow: hidden;
  width: calc(100% - 2 * clamp(12px, 2.5vw, 36px)); max-width: var(--max);
  margin: 18px auto 0;
  padding-top: clamp(34px, 4.4vw, 64px);
  background: var(--surface);
  border: 1px solid var(--line); border-radius: var(--r-media);
  box-shadow: var(--ombre-hero);
}

.hero-st-fond {
  position: absolute; inset: 0 0 0 42%; overflow: hidden; pointer-events: none;
}
.hero-st-fond img {
  display: block; width: 100%; height: 100%; max-width: none;
  object-fit: cover; object-position: 60% 40%;
  filter: saturate(0.55) brightness(1.04);
  -webkit-mask-image:
    linear-gradient(90deg, transparent 0%, rgba(0,0,0,0.03) 10%, rgba(0,0,0,0.12) 20%,
                    rgba(0,0,0,0.30) 30%, rgba(0,0,0,0.55) 40%, rgba(0,0,0,0.80) 52%,
                    rgba(0,0,0,0.95) 64%, #000 78%),
    linear-gradient(180deg, #000 0%, #000 55%, rgba(0,0,0,0.85) 72%,
                    rgba(0,0,0,0.50) 88%, transparent 100%);
  -webkit-mask-composite: source-in;
          mask-image:
    linear-gradient(90deg, transparent 0%, rgba(0,0,0,0.03) 10%, rgba(0,0,0,0.12) 20%,
                    rgba(0,0,0,0.30) 30%, rgba(0,0,0,0.55) 40%, rgba(0,0,0,0.80) 52%,
                    rgba(0,0,0,0.95) 64%, #000 78%),
    linear-gradient(180deg, #000 0%, #000 55%, rgba(0,0,0,0.85) 72%,
                    rgba(0,0,0,0.50) 88%, transparent 100%);
          mask-composite: intersect;
}
:root[data-theme="dark"] .hero-st-fond img { filter: saturate(0.95); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .hero-st-fond img { filter: saturate(0.95); }
}

.hero-st-in {
  position: relative; z-index: 2;
  max-width: calc(620px + 2 * clamp(24px, 3.4vw, 48px));
  padding: 0 clamp(24px, 3.4vw, 48px) 4px;
}
.hero-st h1 {
  max-width: 17ch;
  font-size: clamp(34px, 4.6vw, 56px); font-weight: 500;
  letter-spacing: -0.04em; line-height: 1.06; text-wrap: balance;
}
/* Le mot fort, coloré comme « français » sur le site — mais de la couleur
   de l'ÉTAT : sur cette page, la couleur est l'information. */
.hero-st .hi { color: var(--ok-ink); }
.hero-st[data-etat="degrade"] .hi     { color: var(--warn-ink); }
.hero-st[data-etat="panne"] .hi       { color: var(--danger); }
.hero-st[data-etat="maintenance"] .hi { color: var(--info); }
.hero-st[data-etat="inconnu"] .hi,
.hero-st[data-etat="pause"] .hi,
.hero-st[data-etat="perime"] .hi      { color: var(--muted); }

.hero-st .lead {
  max-width: 46ch; margin-top: 18px;
  font-size: clamp(16px, 1.45vw, 19px); line-height: 1.6; color: var(--lead);
}
.hero-st-meta { margin-top: 22px; font-size: 13px; color: var(--faint); }
.hero-st-meta .vif { color: var(--ink); font-variant-numeric: tabular-nums; }

/* La pastille au-dessus du titre : la puce des tuiles du site (11,5 px,
   capitales espacées, rayon 8), en couleur d'état. */
.puce {
  display: inline-flex; align-items: center; gap: 8px;
  margin-bottom: 18px; padding: 5px 10px 5px 9px;
  border-radius: var(--r-chip); border: 1px solid transparent;
  font-size: 11.5px; font-weight: 500; letter-spacing: 0.06em; text-transform: uppercase;
  background: var(--ok-wash); color: var(--ok-ink);
}
.puce i { width: 7px; height: 7px; border-radius: 50%; background: currentColor; flex: none; }
.puce--degrade     { background: var(--warn-wash);   color: var(--warn-ink); }
.puce--panne       { background: var(--danger-wash); color: var(--danger); }
.puce--maintenance { background: var(--info-wash);   color: var(--info); }
.puce--inconnu, .puce--pause, .puce--perime { background: var(--chip); color: var(--muted); }

/* La lumière qui court sur le bord de la carte — la signature du héros de
   cloudfive.fr/v6, au degré près (conic-gradient masqué en anneau, 11 s par
   tour). Le site fait tourner un trait orange et un trait vert ; ici le
   second prend la couleur de l'ÉTAT : il passe au rouge pendant une panne.
   Les navigateurs ne l'animent pas dans un onglet caché, elle ne coûte rien
   sur un écran laissé ouvert. */
@property --cf-tour { syntax: '<angle>'; inherits: false; initial-value: 0deg; }
@keyframes cfTour { to { --cf-tour: 360deg; } }

.hero-st { --tour-etat: rgba(47, 184, 93, 0.70); }
.hero-st[data-etat="degrade"]     { --tour-etat: rgba(217, 164, 59, 0.80); }
.hero-st[data-etat="panne"]       { --tour-etat: rgba(224, 72, 88, 0.85); }
.hero-st[data-etat="maintenance"] { --tour-etat: rgba(110, 143, 239, 0.80); }
.hero-st[data-etat="inconnu"],
.hero-st[data-etat="pause"],
.hero-st[data-etat="perime"]      { --tour-etat: rgba(140, 140, 150, 0.55); }

.hero-st::before,
.hero-st::after {
  content: ''; position: absolute; inset: -1px; z-index: 4;
  border-radius: inherit; padding: 1.5px; pointer-events: none;
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
          mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
          mask-composite: exclude;
}
.hero-st::after {
  background: conic-gradient(from var(--cf-tour), transparent 0deg, transparent 300deg,
              rgba(249, 110, 30, 0.9) 326deg, transparent 338deg, transparent 360deg);
}
.hero-st::before {
  padding: 2px;
  background: conic-gradient(from calc(var(--cf-tour) + 180deg), transparent 0deg,
              transparent 312deg, var(--tour-etat) 332deg, transparent 342deg, transparent 360deg);
}
@media (prefers-reduced-motion: no-preference) {
  .hero-st::before, .hero-st::after { animation: cfTour 11s linear infinite; }
}
@media (prefers-reduced-motion: reduce) {
  .hero-st::before, .hero-st::after { display: none; }
}

/* --- Les repères ---------------------------------------------------------
   La bande du bas du héros du site : translucide, floutée, filet doux au
   dessus, quatre colonnes séparées par des filets verticaux. Le chiffre en
   grand, son unité en petit et en gris. */

.reperes {
  position: relative; z-index: 3;
  margin-top: clamp(28px, 3.4vw, 48px);
  padding: 0 clamp(24px, 3.4vw, 48px);
  background: rgba(var(--surface-rgb), 0.72);
  -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px);
  border-top: 1px solid var(--line-soft);
}
.reperes-grille { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); }
.repere { padding: 24px 28px 26px 0; min-width: 0; }
.repere + .repere { padding-left: 28px; border-left: 1px solid var(--line-soft); }
.repere-top { display: flex; align-items: center; gap: 12px; }
.repere-n {
  font-size: clamp(28px, 2.6vw, 37.5px); font-weight: 500;
  letter-spacing: -0.045em; line-height: 1; color: var(--ink);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.repere-n i {
  font-style: normal; font-size: 0.42em; margin-left: 3px;
  letter-spacing: 0; color: var(--faint);
}
.repere-n--ok    { color: var(--ok-ink); }
.repere-n--panne { color: var(--danger); }
.repere-pouls {
  flex: none; width: 9px; height: 9px; border-radius: 50%;
  background: var(--ok); box-shadow: 0 0 0 1.5px var(--ok-wash);
}
.repere-l { margin-top: 8px; font-size: 14.5px; color: var(--ink); line-height: 1.4; }
.repere-sub { margin-top: 3px; font-size: 12.5px; color: var(--lead); line-height: 1.5; }
.repere-go { color: var(--cf-ink); border-bottom: 1px solid var(--cf-line); }
.repere-go:hover { color: var(--cf); border-bottom-color: var(--cf); }

@keyframes pulseStat {
  0%   { box-shadow: 0 0 0 0 rgba(47, 184, 93, 0.4); }
  70%  { box-shadow: 0 0 0 11px rgba(47, 184, 93, 0); }
  100% { box-shadow: 0 0 0 0 rgba(47, 184, 93, 0); }
}
/* Le lent travelling de la photo, une seule fois : une page d'état reste
   parfois ouverte des heures sur un écran, une animation infinie y
   chaufferait le processeur pour rien. */
@keyframes travelling {
  from { transform: scale(1.02) translate3d(0, 0, 0); }
  to   { transform: scale(1.09) translate3d(-1.5%, 1.2%, 0); }
}
@media (prefers-reduced-motion: no-preference) {
  .hero-st-fond img { animation: travelling 26s cubic-bezier(0.2, 0.6, 0.2, 1) both; }
  .repere-pouls,
  .puce--ok i { animation: pulseStat 2.6s infinite; }
  /* L'entrée ne se joue qu'au premier affichage : la mise à jour en place
     (classe .rafraichi) remplace le texte sans le refaire monter. */
  :root:not(.rafraichi) .hero-st-in > * { animation: monte 600ms var(--ease) both; }
  :root:not(.rafraichi) .hero-st-in > :nth-child(2) { animation-delay: 50ms; }
  :root:not(.rafraichi) .hero-st-in > :nth-child(3) { animation-delay: 100ms; }
  :root:not(.rafraichi) .hero-st-in > :nth-child(4) { animation-delay: 150ms; }
  :root:not(.rafraichi) .reperes { animation: monte 600ms var(--ease) 180ms both; }
}

/* --- Bandeau de chiffres -------------------------------------------------
   Repris de cloudfive.fr/v6 : pas de boîte, deux filets, des séparateurs
   verticaux. Le chiffre avant son libellé. */

.stats {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  border-top: 1px solid var(--line); border-bottom: 1px solid var(--line);
}
.stat { padding: 20px 0 20px 22px; border-left: 1px solid var(--line-soft); }
.stat:first-child { padding-left: 0; border-left: 0; }
.stat-n { font-size: clamp(27px, 2.8vw, 34px); font-weight: 500; letter-spacing: -0.04em; line-height: 1; }
.unite { font-size: 14px; color: var(--faint); margin-left: 3px; letter-spacing: 0; }
.stat-l { margin-top: 7px; font-size: 12.5px; color: var(--faint); }
.stat--ok .stat-n { color: var(--ok); }
.stat--danger .stat-n { color: var(--danger); }
.stat--cf .stat-n { color: var(--cf-ink); }

/* --- Titres de section ----------------------------------------------------
   L'échelle des h2 du site (« Le panel que vous ouvrirez tous les jours. ») :
   une phrase, un point final, pas de capitales. */

.sec-tete { margin-bottom: 22px; }
.sec-tete h2 {
  max-width: 24ch; font-size: clamp(26px, 2.9vw, 36px);
  letter-spacing: -0.035em; line-height: 1.1; text-wrap: balance;
}
.sec-tete .lead { margin-top: 10px; max-width: 62ch; color: var(--lead); }
.sec-tete--ligne {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 10px 20px; flex-wrap: wrap;
}
.sec-tete--ligne h2 { max-width: none; }
.lien-fleche { font-size: 14px; font-weight: 500; color: var(--cf-ink); white-space: nowrap; }
.lien-fleche span { display: inline-block; transition: transform 220ms var(--ease); }
.lien-fleche:hover span { transform: translateX(3px); }

#services { padding-top: clamp(44px, 5.4vw, 76px); }
#incidents { padding-top: clamp(26px, 3vw, 40px); padding-bottom: 0; }

/* --- Une carte par famille de services --------------------------------------
   Les cartes du site : surface blanche, filet doux, rayon 16, ombre courte.
   Repliable — sauf la première, celle du site et de l'espace client, qu'on
   veut voir sans cliquer. */

.cartes-g { display: grid; gap: 12px; }
.carte-g {
  background: var(--surface);
  border: 1px solid var(--line-soft); border-radius: var(--r-media);
  box-shadow: var(--ombre-carte);
  transition: border-color 220ms var(--ease);
}
.carte-g:hover { border-color: var(--line); }
.carte-g-tete {
  display: flex; align-items: center; gap: 12px;
  width: 100%; padding: 18px 22px; margin: 0;
  background: none; border: 0; border-radius: var(--r-media);
  color: inherit; font: inherit; text-align: left;
}
button.carte-g-tete { cursor: pointer; }
.carte-g-tete h3 {
  font-size: 16.5px; letter-spacing: -0.015em; min-width: 0;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  transition: color 200ms ease;
}
button.carte-g-tete:hover h3 { color: var(--cf-ink); }
.carte-g-n { margin-left: auto; font-size: 13px; color: var(--faint); white-space: nowrap; }
.carte-g-chev {
  flex: none; width: 16px; height: 16px; color: var(--faint);
  transition: transform 260ms var(--ease);
}
.carte-g[data-ouvert="0"] .carte-g-chev { transform: rotate(-90deg); }
.carte-g[data-ouvert="0"] .carte-g-corps { display: none; }
.carte-g-corps { padding: 2px 22px 14px; border-top: 1px solid var(--line-soft); }

/* --- Incidents en cours : la carte, avec le trait de 3 px en tête que le
   site pose sur ses panneaux — ici dans la couleur de l'impact. --- */

.carte-inc {
  margin-bottom: 12px; padding: 20px 22px;
  background: var(--surface);
  border: 1px solid var(--line-soft); border-top: 3px solid var(--warn);
  border-radius: var(--r-media); box-shadow: var(--ombre-carte);
}
.carte-inc--panne { border-top-color: var(--danger); }
.carte-inc--info  { border-top-color: var(--info); }
.carte-inc-tete { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; }
.carte-inc-tete h2 { flex: 1 1 auto; min-width: 0; font-size: 18px; letter-spacing: -0.02em; }
.carte-inc .maj-item::before { outline-color: var(--surface); }

/* --- Liste en carte (incidents clos) --- */

.carte-liste {
  background: var(--surface);
  border: 1px solid var(--line-soft); border-radius: var(--r-media);
  box-shadow: var(--ombre-carte); overflow: hidden;
}
.carte-liste-l {
  display: grid; grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center; gap: 14px; padding: 14px 22px;
  border-top: 1px solid var(--line-soft);
}
.carte-liste-l:first-child { border-top: 0; }
.carte-liste-t { font-size: 14.5px; color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.carte-liste-q { font-size: 12.5px; color: var(--faint); white-space: nowrap; font-variant-numeric: tabular-nums; }
.carte-liste--vide p { padding: 22px; font-size: 14px; color: var(--muted); max-width: 72ch; }

/* --- La légende des couleurs du damier, une fois pour toute la page --- */

.legende {
  display: flex; flex-wrap: wrap; gap: 8px 22px;
  margin-top: 16px; font-size: 12px; color: var(--faint);
}
.legende span { display: inline-flex; align-items: center; gap: 7px; }
.legende .jour {
  display: block; flex: none; width: 10px; height: 10px; min-width: 0;
  border-radius: 3px; transition: none;
}
.legende .jour:hover { opacity: 1; transform: none; }

.compo {
  display: grid;
  grid-template-columns: minmax(130px, 1.1fr) minmax(0, 2.4fr) auto;
  align-items: center; gap: 18px;
  padding: 11px 0; border-top: 1px solid var(--line-soft);
}
.compo:first-child { border-top: 0; }
.compo-nom { display: flex; align-items: center; gap: 9px; min-width: 0; }
.compo-nom span {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  font-size: 14.5px; color: var(--ink);
}
.compo-nom a { color: var(--ink); }
.compo-nom a:hover { color: var(--cf-ink); }
.compo-taux { font-size: 13px; color: var(--muted); white-space: nowrap; }

.pt {
  flex: none; width: 8px; height: 8px; border-radius: 50%;
  background: var(--ok);
}
.pt--panne    { background: var(--danger); }
.pt--degrade  { background: var(--warn); }
.pt--pause    { background: var(--ghost); }
.pt--inconnu  { background: var(--ghost); }

/* --- Le damier des 90 jours ---------------------------------------------
   Une barre par jour. Des flex plutôt qu'une grille : la dernière barre
   touche le bord droit quel que soit le nombre de jours réellement mesurés,
   donc « aujourd'hui » est toujours au même endroit. */

/* Un seul enfant de grille, légende comprise : laisser sortir deux éléments
   créait une quatrième colonne dans .compo et éjectait le taux sous la ligne. */
.damier-bloc { min-width: 0; }
.damier { display: flex; gap: 2px; align-items: stretch; height: 30px; min-width: 0; }
.jour {
  flex: 1 1 0; min-width: 2px; border-radius: 2px;
  background: var(--ok);
  transition: opacity 140ms var(--ease), transform 140ms var(--ease);
}
.jour--vide    { background: var(--vide); }
.jour--panne   { background: var(--danger); }
.jour--degrade { background: var(--warn); }
.jour:hover { opacity: 0.72; transform: scaleY(1.12); }
.damier-leg {
  display: flex; justify-content: space-between;
  margin-top: 7px; font-size: 11.5px; color: var(--faint);
}
/* L'échelle de temps, une fois par groupe, alignée sur la colonne du damier :
   posée hors grille, « aujourd'hui » se collerait au bord droit de la page
   et non au-dessus de la dernière barre. */
.compo--echelle { padding: 2px 0 2px; border-top: 0; }
.compo--echelle .damier-leg { margin-top: 0; }
.compo--echelle .damier-leg span:nth-child(2) { color: var(--ghost); }

/* Sur mobile, 90 barres de 2px font une bouillie grise : on n'en montre que
   30, et on le dit — une échelle qui annonce 90 jours quand on en voit 30
   serait un mensonge discret mais réel. */
.hors-etroit { display: none; }
@media (max-width: 760px) {
  .jour--hors-mobile { display: none; }
  .hors-etroit { display: inline; }
  .compo--echelle .damier-leg span:first-child,
  .compo--echelle .damier-leg span:last-child { display: none; }
}

/* --- Courbe de temps de réponse -----------------------------------------
   SVG en ligne, tracé plein + aplat très léger. Pas de grille : deux filets
   suffisent à situer, et une grille ferait une troisième épaisseur. */

.courbe { position: relative; width: 100%; }
.courbe svg { display: block; width: 100%; height: auto; }
.courbe-trace { fill: none; stroke: var(--cf); stroke-width: 1.6; stroke-linejoin: round; stroke-linecap: round; vector-effect: non-scaling-stroke; }
.courbe-aplat { fill: var(--cf-wash); stroke: none; }
.courbe-axe { stroke: var(--line); stroke-width: 1; vector-effect: non-scaling-stroke; }
.courbe-leg { display: flex; justify-content: space-between; margin-top: 8px; font-size: 11.5px; color: var(--faint); }
.courbe-vide { padding: 26px 0; text-align: center; color: var(--faint); font-size: 13px; }

/* Gris et non orange : la charte veut UN seul accent orange par écran, et
   dix-huit micro-courbes orange en feraient dix-huit. L'orange est réservé à
   l'action principale de la page ; le rouge reste pour ce qui est tombé. */
.spark { display: block; width: 92px; height: 24px; }
.spark path { fill: none; stroke: var(--ghost); stroke-width: 1.4; vector-effect: non-scaling-stroke; }
.spark.spark--panne path { stroke: var(--danger); }

/* --- Étiquettes ---------------------------------------------------------- */

.tag {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 9px; border-radius: var(--r-chip);
  font-size: 12px; font-weight: 500; letter-spacing: 0.01em;
  background: var(--ok-wash); color: var(--ok);
}
.tag--panne   { background: var(--danger-wash); color: var(--danger); }
.tag--degrade { background: var(--warn-wash); color: var(--warn); }
.tag--cf      { background: var(--cf-wash); color: var(--cf-ink); }
.tag--info    { background: var(--info-wash); color: var(--info); }

/* --- Incidents -----------------------------------------------------------
   Une colonne de temps à gauche, un filet vertical, le récit à droite.
   C'est une chronologie : la structure doit se lire avant le texte. */

.incident { padding: 18px 0; border-top: 1px solid var(--line-soft); }
.incident:first-child { border-top: 0; }
.incident-tete { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; }
.incident-tete h1,
.incident-tete h2,
.incident-tete h3 { flex: 1 1 auto; min-width: 0; }
.incident-quand { font-size: 12.5px; color: var(--faint); white-space: nowrap; }
.maj { position: relative; margin-top: 14px; padding-left: 20px; }
.maj::before {
  content: ""; position: absolute; left: 3px; top: 4px; bottom: 4px;
  width: 1px; background: var(--line);
}
.maj-item { position: relative; padding: 0 0 13px 0; }
.maj-item:last-child { padding-bottom: 0; }
.maj-item::before {
  content: ""; position: absolute; left: -20px; top: 7px;
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--ghost); outline: 3px solid var(--bg);
}
.maj-item--actif::before { background: var(--cf); }
.maj-etat { font-size: 12.5px; font-weight: 500; color: var(--ink); }
.maj-texte { font-size: 14px; color: var(--muted); margin-top: 2px; }
.maj-quand { font-size: 11.5px; color: var(--faint); margin-top: 3px; }

/* --- Boutons -------------------------------------------------------------
   Appui à scale(0.97) sur tout ce qui se presse : c'est dans la charte, et
   c'est ce qui donne l'impression que l'interface répond. */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  padding: 9px 17px; border-radius: var(--r-btn);
  border: 1px solid transparent; background: var(--cf-fill); color: #fff;
  font: inherit; font-size: 14px; font-weight: 500; line-height: 1.2;
  cursor: pointer; text-decoration: none;
  transition: background 180ms var(--ease), color 180ms var(--ease),
              border-color 180ms var(--ease), transform 140ms var(--ease);
}
.btn:hover { background: #e8631a; color: #fff; }
.btn:active { transform: scale(0.97); }
.btn-quiet { background: transparent; border-color: var(--line); color: var(--ink); }
.btn-quiet:hover { background: var(--cf-wash); border-color: var(--ghost); color: var(--ink); }
.btn-danger { background: transparent; border-color: var(--danger); color: var(--danger); }
.btn-danger:hover { background: var(--danger-wash); color: var(--danger); }
.btn-sm { padding: 6px 12px; font-size: 13px; }
.btn[disabled], .btn[aria-disabled="true"] { opacity: 0.5; pointer-events: none; }

/* --- Formulaires ---------------------------------------------------------- */

.champ { display: block; margin-bottom: 15px; }
.champ > span { display: block; font-size: 12.5px; color: var(--muted); margin-bottom: 5px; }
.champ .small { margin-top: 5px; display: block; }
input[type=text], input[type=password], input[type=number], input[type=url],
input[type=email], select, textarea {
  width: 100%; padding: 9px 12px;
  border: 1px solid var(--line); border-radius: var(--r-btn);
  background: var(--raised); color: var(--ink);
  font: inherit; font-size: 14px;
  transition: border-color 180ms var(--ease), box-shadow 180ms var(--ease);
}
input:focus, select:focus, textarea:focus {
  outline: none; border-color: var(--cf);
  box-shadow: 0 0 0 3px var(--cf-wash);
}
textarea { min-height: 92px; resize: vertical; line-height: 1.55; }
.duo { display: grid; grid-template-columns: 1fr 1fr; gap: 0 18px; }
.trio { display: grid; grid-template-columns: repeat(3, 1fr); gap: 0 18px; }
@media (max-width: 640px) { .duo, .trio { grid-template-columns: 1fr; } }

.bascule { display: flex; align-items: center; gap: 9px; cursor: pointer; font-size: 14px; }
.bascule input { width: auto; margin: 0; accent-color: var(--cf); }

/* --- Tableaux ------------------------------------------------------------- */

.liste { width: 100%; border-collapse: collapse; }
.liste th {
  text-align: left; font-size: 11.5px; font-weight: 500; letter-spacing: 0.05em;
  text-transform: uppercase; color: var(--faint);
  padding: 0 14px 9px 0; border-bottom: 1px solid var(--line);
}
.liste td { padding: 12px 14px 12px 0; border-bottom: 1px solid var(--line-soft); font-size: 14px; vertical-align: middle; }
.liste tr:last-child td { border-bottom: 0; }
.liste .droite, .liste th.droite { text-align: right; padding-right: 0; }
/* Une colonne alignée à droite n'a pas de marge à droite : sans marge à
   GAUCHE, son titre vient toucher celui de la colonne précédente, et on lit
   « RÉPONSE6 H ». */
.liste th.droite, .liste td.droite { padding-left: 18px; }
.liste td.droite + td, .liste th.droite + th { padding-left: 18px; }
.scroll-x { overflow-x: auto; -webkit-overflow-scrolling: touch; }

/* --- Messages ------------------------------------------------------------- */

.flash {
  display: flex; align-items: flex-start; gap: 10px;
  padding: 11px 15px; margin-bottom: 18px;
  border-radius: var(--r-btn); border: 1px solid var(--line);
  font-size: 14px; color: var(--ink);
}
.flash--ok { border-color: color-mix(in srgb, var(--ok) 40%, transparent); background: var(--ok-wash); }
.flash--err { border-color: color-mix(in srgb, var(--danger) 40%, transparent); background: var(--danger-wash); }
.vide { padding: 34px 0; text-align: center; color: var(--faint); font-size: 14px; }

/* --- Pied ----------------------------------------------------------------
   Celui du site, raccourci : la bande marque + une phrase + deux actions,
   trois colonnes de liens, la ligne légale. Le point vert de .pied-pt existe
   déjà sur cloudfive.fr/v6, où il est décoratif ; ici il dit l'état réel. */

.pied { margin-top: 12px; }

.pied-haut {
  display: grid; grid-template-columns: auto 1fr auto;
  gap: 24px 40px; align-items: center;
  padding: clamp(32px, 4vw, 52px) 0 clamp(24px, 3vw, 36px);
  border-top: 1px solid var(--line);
}
.pied-marque { display: inline-flex; align-items: center; gap: 10px; color: var(--ink); }
.pied-marque:hover { color: var(--ink); }
.pied-marque img { display: block; width: 56px; height: 32px; object-fit: contain; }
.pied-marque span {
  font-weight: 600; font-size: 14.5px; letter-spacing: 0.09em;
  text-transform: uppercase;
}
.pied-marque span b { color: var(--cf); font-weight: 600; }
.pied-phrase { margin: 0; font-size: 14.5px; color: var(--muted); max-width: 52ch; }
.pied-actions { display: flex; gap: 8px; }
/* Les boutons du site sont plus grands que ceux de la console : ici on est
   dans le pied public, on reprend sa taille. */
.pied-actions .btn { font-size: 15px; padding: 12px 26px; }

.pied-grille {
  display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 24px 28px; padding: clamp(28px, 3.4vw, 44px) 0;
  border-top: 1px solid var(--line-soft);
}
.pied-col h4 {
  margin: 0 0 12px; font-size: 11.5px; font-weight: 500;
  letter-spacing: 0.09em; text-transform: uppercase; color: var(--faint);
}
.pied-col a {
  display: block; padding: 5px 0; font-size: 14px; line-height: 1.35;
  color: var(--ink); overflow-wrap: anywhere;
  transition: color 160ms ease;
}
.pied-col a:hover { color: var(--cf); }

.pied-bas {
  display: flex; justify-content: space-between; align-items: center;
  gap: 16px 28px; flex-wrap: wrap;
  padding: 20px 0 44px; border-top: 1px solid var(--line-soft);
  font-size: 12.5px; color: var(--faint);
}
.pied-legal, .pied-info { display: flex; flex-wrap: wrap; gap: 6px 18px; align-items: center; }
.pied-legal a { color: var(--muted); }
.pied-legal a:hover { color: var(--ink); }
.pied-info span { display: inline-flex; align-items: center; gap: 7px; }
.pied-pt {
  width: 6px; height: 6px; border-radius: 50%; flex: none;
  background: var(--ok); box-shadow: 0 0 0 3px var(--ok-wash);
}
.pied-pt--degrade { background: var(--warn);   box-shadow: 0 0 0 3px var(--warn-wash); }
.pied-pt--panne   { background: var(--danger); box-shadow: 0 0 0 3px var(--danger-wash); }
.pied-pt--inconnu,
.pied-pt--pause,
.pied-pt--perime  { background: var(--ghost);  box-shadow: none; }
.pied-pt--maintenance { background: var(--info); box-shadow: 0 0 0 3px var(--info-wash); }

/* --- Connexion ------------------------------------------------------------ */

.connexion { min-height: 72vh; display: grid; place-items: center; padding: 40px var(--gutter); }
.connexion form { width: 100%; max-width: 340px; }
.connexion h1 { font-size: 25px; margin-bottom: 6px; }
.connexion .lead { margin-bottom: 24px; font-size: 14px; }

/* --- Apparition ----------------------------------------------------------
   Discrète et une seule fois : une page d'état se consulte en urgence, elle
   ne doit pas faire attendre. */

@media (prefers-reduced-motion: no-preference) {
  .apparait { animation: monte 520ms var(--ease) both; }
  .apparait:nth-child(2) { animation-delay: 40ms; }
  .apparait:nth-child(3) { animation-delay: 80ms; }
  .apparait:nth-child(4) { animation-delay: 120ms; }
}
@keyframes monte {
  from { opacity: 0; transform: translateY(8px); }
  to   { opacity: 1; transform: none; }
}

/* --- Infobulle du damier -------------------------------------------------- */

#bulle {
  position: fixed; z-index: 80; pointer-events: none;
  padding: 7px 11px; border-radius: var(--r-chip);
  border: 1px solid var(--line);
  background: var(--surface); color: var(--ink);
  font-size: 12.5px; line-height: 1.45; white-space: nowrap;
  box-shadow: 0 6px 22px rgba(0, 0, 0, 0.14);
  opacity: 0; transform: translateY(4px);
  transition: opacity 140ms var(--ease), transform 140ms var(--ease);
}
#bulle.on { opacity: 1; transform: none; }
#bulle b { font-weight: 500; }
#bulle .small { display: block; margin-top: 1px; }

/* --- Étroit ---------------------------------------------------------------- */

@media (max-width: 820px) {
  :root { --gutter: 22px; }
  .hd-in { padding-inline: 16px; gap: 10px; }
  .hd-gauche { gap: 10px; }
  .hd-sous { display: none; }
  .hd-nav { gap: 0; }
  .hd-tab { padding: 22px 8px; font-size: 13.5px; }
  .hd-tab::after { left: 8px; right: 8px; }
  /* Comme sur le site : le bouton garde son icone, perd son libelle. */
  .hd-connexion { padding: 0 9px; }
  .hd-connexion span { display: none; }
  .hd-connexion svg { width: 18px; height: 18px; }
  .pied-haut { grid-template-columns: 1fr; }
  .pied-grille { grid-template-columns: 1fr 1fr; }

  /* Le héros passe en une colonne : la photo n'a plus la place de se fondre
     à côté du texte, elle disparaît (et, chargée en lazy, n'est même pas
     téléchargée). Les repères passent en deux par deux. */
  .hero-st-fond { display: none; }
  .reperes-grille { grid-template-columns: 1fr 1fr; }
  .repere { padding: 18px 16px 20px 0; }
  .repere + .repere { padding-left: 16px; }
  .repere:nth-child(3) { padding-left: 0; border-left: 0; }
  .repere:nth-child(n+3) { border-top: 1px solid var(--line-soft); }
  .carte-g-tete { padding: 16px 16px; gap: 10px; }
  .carte-g-corps { padding: 2px 16px 12px; }
  .carte-inc { padding: 18px 16px; }
  .carte-liste-l { grid-template-columns: minmax(0, 1fr) auto; padding: 13px 16px; }
  .carte-liste-l .tag { grid-column: 1 / -1; justify-self: start; }
  .stat { padding-left: 16px; }

  /* Deux lignes : le nom et son taux côte à côte, le damier dessous sur
     toute la largeur. Viser `.damier` ne suffit plus — il est désormais
     dans `.damier-bloc`, et c'est LUI l'enfant de la grille ; la règle
     d'avant ne s'appliquait donc à rien et le damier, coincé en colonne
     « auto », débordait de l'écran. */
  .compo { grid-template-columns: minmax(0, 1fr) auto; gap: 7px 14px; }
  .compo-nom  { grid-column: 1; }
  .compo-taux { grid-column: 2; text-align: right; }
  .compo .damier-bloc { grid-column: 1 / -1; order: 3; }

  .compo--echelle { grid-template-columns: 1fr; }
  .compo--echelle > span { display: none; }
  .compo--echelle .damier-leg { grid-column: 1 / -1; }
}
@media (max-width: 480px) {
  .hd-mot { display: none; }
  .pied-actions { flex-wrap: wrap; }
  .stats { grid-template-columns: 1fr 1fr; }
  .stat:nth-child(3) { padding-left: 0; border-left: 0; }
}

/* --- Historique ------------------------------------------------------------
   Le même héros, en plus court, puis les incidents en cartes regroupées par
   mois. Un incident clos garde un trait de tête neutre : la couleur est
   réservée à ce qui est en cours. */

.hero-st--court { padding-top: clamp(30px, 3.6vw, 52px); }
.hero-st--court:not(:has(.reperes)) { padding-bottom: clamp(30px, 3.6vw, 48px); }
.reperes-grille--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.hero-st .puce--neutre { background: var(--cf-wash); color: var(--cf-ink); }
.hero-st--court .hi { color: var(--cf); }

.mois + .mois { margin-top: clamp(28px, 3vw, 40px); }
.mois-titre {
  margin: 0 0 12px; font-size: 12px; font-weight: 500;
  letter-spacing: 0.09em; text-transform: uppercase; color: var(--faint);
}
.carte-inc--neutre { border-top-color: var(--line); }
.tag--neutre { background: var(--chip); color: var(--muted); }
.carte-inc-tete h3 { flex: 1 1 auto; min-width: 0; font-size: 16.5px; letter-spacing: -0.015em; }
.carte-inc-auto { margin-top: 6px; }
.en-cours { font-weight: 500; color: var(--danger); }

@media (max-width: 820px) {
  .reperes-grille--3 { grid-template-columns: 1fr 1fr; }
  .reperes-grille--3 .repere:nth-child(3) { grid-column: 1 / -1; }
}

/* --- Abonnement aux incidents ----------------------------------------------- */

.ab-retour { margin-bottom: 18px; }
.ab-carte {
  display: grid; gap: 24px; max-width: 720px; padding: clamp(20px, 3vw, 32px);
  background: var(--surface); border: 1px solid var(--line-soft); border-radius: var(--r-media);
  box-shadow: var(--ombre-carte);
}
.ab-carte fieldset { border: 0; margin: 0; padding: 0; }
.ab-carte legend { font-size: 15px; font-weight: 500; color: var(--ink); margin-bottom: 12px; }
.ab-choix { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.ab-choix legend { grid-column: 1 / -1; }
.ab-option {
  display: flex; gap: 12px; align-items: flex-start; padding: 14px 16px; cursor: pointer;
  border: 1px solid var(--line); border-radius: var(--r-btn); transition: border-color 180ms var(--ease);
}
.ab-option:has(input:checked) { border-color: var(--cf); background: var(--cf-wash); }
.ab-option input { margin-top: 4px; accent-color: var(--cf); }
.ab-option b { display: block; font-weight: 500; color: var(--ink); }
.ab-option i { display: block; font-style: normal; font-size: 13px; color: var(--muted); margin-top: 2px; }
.ab-option--off { opacity: 0.55; cursor: not-allowed; }
.ab-champ label { display: block; font-size: 13px; color: var(--muted); margin-bottom: 7px; }
.ab-champ input {
  width: 100%; height: 46px; padding: 0 14px; font: inherit; font-size: 15px; color: var(--ink);
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--r-btn); outline: none;
}
.ab-champ input:focus { border-color: var(--cf); box-shadow: 0 0 0 3px var(--cf-wash); }
.ab-champ .small { margin-top: 8px; }
.ab-familles { display: flex; flex-wrap: wrap; gap: 8px 10px; }
.ab-familles legend { width: 100%; }
.ab-case {
  display: inline-flex; align-items: center; gap: 8px; padding: 8px 12px; cursor: pointer;
  border: 1px solid var(--line); border-radius: var(--r-chip); font-size: 14px;
}
.ab-case input { accent-color: var(--cf); }
.ab-btn { justify-self: start; height: 46px; padding: 0 26px; }
.ab-flux {
  display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap;
  max-width: 720px; margin-top: 18px; padding: 18px 20px;
  border: 1px solid var(--line-soft); border-radius: var(--r-media);
}
.ab-flux b { display: block; font-weight: 500; }
.ab-flux span { display: block; font-size: 13.5px; color: var(--muted); margin-top: 2px; }
@media (max-width: 640px) { .ab-choix { grid-template-columns: 1fr; } }
