/* ==========================================================================
   Repère Québec — Espace client
   Même direction artistique que reperequebec.ca v2 et que le scanner.
   Couleur   : vert = Repère Québec · marine = la structure · or = ce qu'on a relevé
   Forme     : les objets s'arrondissent, les traits restent droits
   Structure : le dossier se lit le long d'un rail, comme le parcours du scanner
   Densité   : l'espace sépare, la bordure est l'exception
   ========================================================================== */

@font-face {
  font-family: "Archivo";
  font-style: normal;
  font-weight: 400 800;
  font-stretch: 100% 125%;
  font-display: swap;
  src: url("/fonts/archivo-latin.woff2") format("woff2");
}

@font-face {
  font-family: "Public Sans";
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("/fonts/publicsans-latin.woff2") format("woff2");
}

@font-face {
  font-family: "Plex Mono";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("/fonts/plexmono-latin.woff2") format("woff2");
}

/* Les jetons sont ceux de la console : mêmes couleurs, mêmes courbes, mêmes
   échelles. Seules la densité et les formes changent — l'espace client est
   plus aéré et plus arrondi, parce qu'on ne l'ouvre pas huit heures par jour.
   Toute divergence de palette entre les deux fichiers est un défaut. */
:root {
  /* --- Service A · Repère Québec ----------------------------------------- */
  --qc-800: #123f2e;
  --qc-700: #17553d;
  --qc-600: #1F6A4E;
  --qc-500: #2c8564;
  --qc-100: #e7f1ec;
  --qc-050: #f3f9f6;

  /* --- Service B · Repère Sécurité ---------------------------------------- */
  --sec-800: #212f52;
  --sec-700: #2C4068;
  --sec-600: #3B5488;
  --sec-500: #5570a5;
  --sec-100: #eaeff8;
  --sec-050: #f4f7fc;

  --accent: var(--qc-600);
  --accent-fonce: var(--qc-700);
  --accent-voile: var(--qc-100);

  --marine: #0c1b2a;

  --vert: var(--qc-600);
  --vert-fonce: var(--qc-700);
  --vert-clair: var(--qc-500);
  --vert-voile: var(--qc-100);

  /* Le vert du portail ne dit pas « Repère Québec », il dit « ça va » : un
     champ calme, un dossier validé, une demande réglée. Il partage la valeur
     de --qc-600 parce que la palette n'en compte qu'un, mais le nom compte —
     c'est lui qui empêche de le tirer vers une marque le jour où une zone de
     service devra se distinguer d'un état satisfaisant. */
  --succes: var(--qc-600);

  --or: #d9a93c;
  --or-fonce: #7c5c12;
  --or-voile: #fbf3de;
  --surligneur: #fbe08f;
  --rouge: #c14b3a;
  --rouge-fonce: #8e2f21;
  --rouge-voile: #fbeae6;

  --bleu: #2f5f80;
  --bleu-fonce: #21455d;
  --bleu-voile: #e6eef4;

  /* --- Neutres ------------------------------------------------------------ */
  --n-025: #FAFBFB;
  --n-050: #F4F6F6;
  --n-100: #EBEFEF;
  --n-200: #DFE4E3;
  --n-300: #C6CFCD;
  --n-400: #9AA6A3;
  --n-500: #6C7A77;
  --n-600: #55625F;
  --n-700: #3D4A47;
  --n-900: #1B2523;

  --papier: var(--n-050);
  --blanc: #ffffff;
  --encre: #2c3b39;
  /* Ces deux-là portent du texte, pas des filets, et l'échelle de neutres
     était trop claire pour ça : --n-500 tombait à 4,48 sur blanc et 4,13 sur
     le papier, --n-400 à 2,51 et 2,32. Les notes du rail et les métadonnées
     — dates, soldes, adresses de sites — passaient donc sous le seuil AA sur
     tout le portail. Valeurs explicites, vérifiées sur les deux fonds :
     --gris 6,37/5,87 et --gris-clair 5,48/5,05. L'échelle reste intacte pour
     les bordures, où le seuil de texte ne s'applique pas. */
  --gris: #55625F;
  --gris-clair: #5F6C69;
  --trait: var(--n-200);
  --trait-fort: var(--n-300);

  --sur-marine: #a7bac7;
  --sur-marine-fort: #dbe5eb;

  --display: "Archivo", "Helvetica Neue", Arial, sans-serif;
  --texte: "Public Sans", "Helvetica Neue", Arial, sans-serif;
  --mono: "Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;

  /* --- Échelles ----------------------------------------------------------- */
  --t-xs: 0.6875rem;
  --t-s: 0.75rem;
  --t-m: 0.8125rem;
  --t-base: 0.875rem;
  --t-l: 0.9375rem;
  --t-xl: 1.0625rem;
  --t-2xl: 1.3125rem;
  --t-3xl: 1.75rem;
  --t-4xl: 2.25rem;

  --e-1: 4px;
  --e-2: 8px;
  --e-3: 12px;
  --e-4: 16px;
  --e-5: 20px;
  --e-6: 24px;
  --e-8: 32px;
  --e-10: 40px;
  --e-12: 48px;
  --e-16: 64px;

  /* L'espace client s'arrondit davantage que la console. */
  --r-xs: 6px;
  --r-s: 10px;
  --r-m: 16px;
  --r-l: 26px;
  --r-full: 999px;

  /* --- Mouvement : les mêmes courbes que la console ----------------------- */
  --sortie: cubic-bezier(0.23, 1, 0.32, 1);
  --va-vient: cubic-bezier(0.77, 0, 0.175, 1);
  --tiroir: cubic-bezier(0.32, 0.72, 0, 1);

  --d-1: 120ms;
  --d-2: 160ms;
  --d-3: 200ms;
  --d-4: 260ms;

  --barre-laterale: 272px;
  --marge-jalon: 186px;
  --ecart-jalon: 40px;
}

[data-service="quebec"] {
  --accent: var(--qc-600);
  --accent-fonce: var(--qc-700);
  --accent-voile: var(--qc-100);
}

[data-service="securite"] {
  --accent: var(--sec-600);
  --accent-fonce: var(--sec-700);
  --accent-voile: var(--sec-100);
}

* {
  box-sizing: border-box;
}

html {
  color-scheme: light;
}

body {
  margin: 0;
  background: var(--papier);
  color: var(--encre);
  font-family: var(--texte);
  font-size: 15px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

h1,
h2,
h3 {
  margin: 0;
  color: var(--marine);
  font-family: var(--display);
  font-stretch: 112%;
  letter-spacing: -0.016em;
}

p {
  margin: 0;
}

img {
  display: block;
  max-width: 100%;
  height: auto;
}

button,
input,
select,
textarea {
  font: inherit;
  color: inherit;
}

.hidden {
  display: none !important;
}

:focus-visible {
  outline: 3px solid var(--vert);
  outline-offset: 2px;
  border-radius: var(--r-xs);
}

.portal-sidebar :focus-visible {
  outline-color: var(--or);
}

.muted {
  color: var(--gris);
}

/* --- Boutons -------------------------------------------------------------- */

.primary,
.secondary,
.ghost {
  display: inline-flex;
  min-height: 46px;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 11px 20px;
  border: 1px solid transparent;
  border-radius: var(--r-s);
  font-family: var(--display);
  font-size: 0.92rem;
  font-stretch: 104%;
  font-weight: 700;
  cursor: pointer;
  transition: background-color 160ms ease, border-color 160ms ease, transform 110ms var(--sortie);
}

/* L'appui s'enfonce plutôt que de descendre : `scale` entraîne aussi le
   contenu du bouton, ce qui rend la pression physique. */
.primary:active,
.secondary:active,
.ghost:active {
  transform: scale(0.97);
}

.primary {
  background: var(--accent);
  color: var(--blanc);
}

.primary:hover {
  background: var(--accent-fonce);
}

.secondary {
  border-color: var(--trait-fort);
  background: var(--blanc);
  color: var(--marine);
}

.secondary:hover {
  border-color: var(--accent);
  color: var(--accent-fonce);
}

.ghost {
  background: transparent;
  color: var(--accent);
}

.ghost:hover {
  background: var(--accent-voile);
}

.small {
  min-height: 38px;
  padding: 8px 14px;
  font-size: 0.84rem;
}

.link-button {
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  font-size: 0.88rem;
  text-align: left;
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
}

/* --- Champs --------------------------------------------------------------- */

label {
  display: grid;
  gap: 7px;
  color: var(--marine);
  font-family: var(--display);
  font-size: 0.88rem;
  font-stretch: 104%;
  font-weight: 700;
}

input,
select,
textarea {
  width: 100%;
  min-height: 48px;
  padding: 11px 14px;
  border: 1px solid var(--trait-fort);
  border-radius: var(--r-s);
  background: var(--blanc);
  color: var(--marine);
  font-family: var(--texte);
  font-size: 0.98rem;
  font-weight: 400;
  transition: border-color 160ms ease, box-shadow 160ms ease;
}

textarea {
  min-height: auto;
  resize: vertical;
}

input::placeholder,
textarea::placeholder {
  color: #9aa7a1;
}

input:hover,
select:hover,
textarea:hover {
  border-color: var(--vert-clair);
}

input:focus,
select:focus,
textarea:focus {
  border-color: var(--vert);
  box-shadow: 0 0 0 3px rgba(27, 107, 79, 0.18);
  outline: 0;
}

input[type="file"] {
  padding: 9px 12px;
  background: var(--papier);
}

.error {
  min-height: 1.3em;
  margin: 0;
  color: var(--rouge-fonce);
  font-size: 0.88rem;
}

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

.portal-login {
  display: grid;
  min-height: 100vh;
  padding: 28px;
  place-items: center;
}

.portal-login-card {
  display: grid;
  width: min(452px, 100%);
  padding: 40px 38px 36px;
  border: 1px solid var(--trait-fort);
  border-radius: var(--r-l);
  background: var(--blanc);
  gap: 16px;
}

.portal-login-card .portal-logo {
  width: 124px;
  margin-bottom: 10px;
}

.portal-login-card h1 {
  max-width: 15ch;
  font-size: 1.7rem;
  font-weight: 800;
  line-height: 1.12;
}

.portal-login-card > .muted {
  margin-bottom: 6px;
  font-size: 0.94rem;
}

.portal-login-card .primary {
  margin-top: 4px;
}

/* --- La barre latérale : la couverture du dossier ------------------------- */

.portal-shell {
  display: grid;
  min-height: 100vh;
  grid-template-columns: var(--barre-laterale) minmax(0, 1fr);
}

.portal-sidebar {
  display: flex;
  position: sticky;
  top: 0;
  height: 100vh;
  padding: 26px 18px 22px;
  flex-direction: column;
  gap: 24px;
  background: var(--marine);
  color: var(--sur-marine);
}

.portal-marque {
  display: flex;
  align-items: center;
  margin-left: 8px;
  gap: 11px;
  color: var(--blanc);
  text-decoration: none;
}

/* Marque inversée : elle se pose directement sur le marine, sans conteneur. */
.portal-marque img {
  width: 38px;
  height: 38px;
}

.portal-marque span {
  font-family: var(--display);
  font-size: 0.95rem;
  font-stretch: 112%;
  font-weight: 700;
  letter-spacing: -0.01em;
  line-height: 1.08;
}

/* Le dossier appartient au client : son nom est le titre de la barre. */
.portal-org {
  display: grid;
  padding: 0 8px;
  gap: 4px;
}

.portal-org small {
  color: var(--sur-marine);
  font-family: var(--mono);
  font-size: 0.68rem;
}

.portal-org strong {
  color: var(--blanc);
  font-family: var(--display);
  font-size: 1.24rem;
  font-stretch: 112%;
  font-weight: 700;
  letter-spacing: -0.015em;
  line-height: 1.15;
}

/* La navigation reprend la marque en marge du site : un filet or à gauche. */
.portal-sidebar nav {
  display: grid;
  gap: 1px;
}

.portal-sidebar nav button {
  padding: 9px 12px 9px 13px;
  border: 0;
  border-left: 3px solid transparent;
  border-radius: 0 var(--r-s) var(--r-s) 0;
  background: transparent;
  color: var(--sur-marine);
  font-family: var(--texte);
  font-size: 0.93rem;
  font-weight: 600;
  text-align: left;
  cursor: pointer;
  transition: background-color 150ms ease, color 150ms ease, border-color 150ms ease;
}

.portal-sidebar nav button:hover {
  background: rgba(255, 255, 255, 0.06);
  color: var(--blanc);
}

.portal-sidebar nav button.active {
  border-left-color: var(--or);
  background: rgba(255, 255, 255, 0.08);
  color: var(--blanc);
}

.portal-user {
  display: grid;
  margin-top: auto;
  padding: 15px 8px 0;
  border-top: 1px solid rgba(255, 255, 255, 0.14);
  gap: 4px;
}

.portal-user span {
  color: var(--sur-marine-fort);
  font-size: 0.9rem;
  font-weight: 600;
}

.portal-user .link-button {
  color: var(--sur-marine);
}

.portal-user .link-button:hover {
  color: var(--blanc);
}

/* --- L'en-tête : le filet du papier à en-tête du rapport ------------------ */

.portal-main {
  min-width: 0;
}

/* `margin-inline: auto` manquait. Le plafond de 1160 px est bon — au-delà, une
   ligne de texte devient pénible à suivre — mais sans centrage le contenu
   restait collé à gauche : sur un écran de 1920, la barre latérale en prend
   272, il reste 1648, et les 488 px excédentaires s'accumulaient tous du même
   côté. Un plafond de largeur centre ce qu'il retient. */
.portal-header {
  max-width: 1160px;
  margin-inline: auto;
  padding: 40px 48px 0;
}

.portal-header h1 {
  padding-bottom: 14px;
  border-bottom: 2px solid var(--marine);
  font-size: 2.1rem;
  font-weight: 800;
  line-height: 1.06;
}

.portal-content {
  max-width: 1160px;
  margin-inline: auto;
  padding: 30px 48px 76px;
}

/* --- Le rail : la structure reprise du parcours du scanner ---------------- */

.rail {
  display: grid;
  position: relative;
  grid-template-columns: var(--marge-jalon) minmax(0, 1fr);
  column-gap: var(--ecart-jalon);
  row-gap: 46px;
}

.rail::before {
  position: absolute;
  top: 8px;
  bottom: 10px;
  left: calc(var(--marge-jalon) - 1px);
  width: 2px;
  border-radius: 999px;
  background: var(--trait);
  content: "";
}

.jalon {
  padding-right: 26px;
  text-align: right;
}

/* Les titres du rail sont courts et ferrés à droite : sans équilibrage, le
   navigateur coupait « Ce qu'on attend / de vous » ou « Ce qu'on a / produit »,
   une ligne pleine puis un orphelin. `balance` répartit les mots sur les
   lignes disponibles. */
.jalon h2 {
  font-size: 1.05rem;
  font-weight: 700;
  line-height: 1.25;
  text-wrap: balance;
}

.jalon p {
  margin-top: 6px;
  color: var(--gris-clair);
  font-size: 0.83rem;
  line-height: 1.4;
  /* Ces notes font une phrase. Ferrées à droite dans une colonne étroite,
     elles tombaient en trois lignes de longueurs très inégales ; `balance`
     les répartit. */
  text-wrap: balance;
}

.etape {
  min-width: 0;
  padding-top: 2px;
}

/* Un paragraphe suivi se lit mal au-delà d'une soixantaine de signes. Les
   cartes gardent toute la largeur — elles alignent des colonnes — mais la
   prose qu'elles contiennent est ramenée à une mesure lisible. */
.etape p,
.etape .vide p {
  max-width: 68ch;
}

/* --- Le bilan : le même objet que le score du rapport PDF ----------------- */

.bilan {
  padding: 28px 30px 26px;
  border-radius: var(--r-l);
  background: var(--marine);
}

.bilan-haut {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: 28px;
  flex-wrap: wrap;
}

.bilan-note {
  display: flex;
  align-items: baseline;
  gap: 7px;
}

.bilan-chiffre {
  color: var(--blanc);
  font-family: var(--display);
  font-size: 3.6rem;
  font-stretch: 118%;
  font-weight: 800;
  letter-spacing: -0.04em;
  line-height: 0.85;
}

.bilan-pourcent {
  color: var(--sur-marine);
  font-family: var(--display);
  font-size: 1.05rem;
  font-stretch: 104%;
  font-weight: 700;
}

.bilan-legende {
  margin-top: 8px;
  color: var(--or);
  font-family: var(--display);
  font-size: 0.88rem;
  font-stretch: 104%;
  font-weight: 700;
}

.bilan-mot {
  max-width: 32ch;
  color: var(--sur-marine-fort);
  font-size: 0.95rem;
  line-height: 1.5;
}

.bilan-mot b {
  color: var(--blanc);
  font-weight: 600;
}

.bilan .progress {
  margin-top: 22px;
  background: rgba(255, 255, 255, 0.15);
}

.bilan .progress > span {
  background: var(--vert-clair);
}

.progress {
  overflow: hidden;
  height: 9px;
  border-radius: 999px;
  background: #e2e7e1;
}

.progress > span {
  display: block;
  height: 100%;
  border-radius: 999px;
  background: var(--vert);
}

/* --- Listes réglées : le langage d'index du site --------------------------- */

.liste {
  border-top: 1px solid var(--trait);
}

.row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 20px;
  padding: 15px 0;
  border-bottom: 1px solid var(--trait);
}

.row-main {
  min-width: 0;
}

.row-main strong {
  display: block;
  color: var(--marine);
  font-family: var(--display);
  font-size: 1rem;
  font-stretch: 104%;
  font-weight: 700;
  line-height: 1.3;
}

.row-main p {
  max-width: 74ch;
  margin-top: 3px;
  color: var(--gris);
  font-size: 0.89rem;
}

.actions {
  display: flex;
  align-items: center;
  gap: 9px;
  flex-wrap: wrap;
  flex-shrink: 0;
}

.actions select,
.tache-droite select {
  width: auto;
  min-width: 168px;
  min-height: 40px;
  padding: 7px 12px;
  font-size: 0.88rem;
}

/* --- Une tâche, marquée en marge comme dans le rapport --------------------- */

.tache {
  display: grid;
  padding: 17px 0 18px 15px;
  border-bottom: 1px solid var(--trait);
  border-left: 3px solid var(--trait);
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 4px 20px;
  align-items: start;
}

.tache.prioritaire {
  border-left-color: var(--rouge);
}

.tache.attention {
  border-left-color: var(--or);
}

.tache.faite {
  border-left-color: var(--vert);
}

.tache-titre {
  color: var(--marine);
  font-family: var(--display);
  font-size: 1.04rem;
  font-stretch: 104%;
  font-weight: 700;
  line-height: 1.3;
}

.tache-pourquoi {
  max-width: 72ch;
  margin-top: 5px;
  grid-column: 1;
  color: var(--gris);
  font-size: 0.91rem;
}

.tache-meta {
  margin-top: 8px;
  grid-column: 1;
  color: var(--gris-clair);
  font-family: var(--mono);
  font-size: 0.73rem;
}

.tache-droite {
  display: flex;
  grid-row: 1 / span 3;
  grid-column: 2;
  align-items: center;
  gap: 9px;
  flex-wrap: wrap;
  justify-content: flex-end;
}

/* --- Pastilles d'état : les trois du rapport ------------------------------- */

.badge {
  display: inline-flex;
  align-items: center;
  padding: 4px 11px 5px;
  border-radius: 999px;
  background: var(--papier);
  color: var(--gris);
  font-family: var(--mono);
  font-size: 0.71rem;
  white-space: nowrap;
}

.badge.done,
.badge.implemented,
.badge.accepted,
.badge.ready,
.badge.resolved,
.badge.reviewed,
.badge.low {
  background: var(--vert-voile);
  color: var(--vert-fonce);
}

.badge.in_review,
.badge.needs_review,
.badge.medium,
.badge.processing,
.badge.requested,
.badge.waiting_client,
.badge.sent,
.badge.submitted {
  background: var(--or-voile);
  color: var(--or-fonce);
}

.badge.high,
.badge.critical,
.badge.failed,
.badge.rejected {
  background: var(--rouge-voile);
  color: var(--rouge-fonce);
}

/* --- Index à deux colonnes : le composant « 10 points » du site ------------ */

.index {
  display: grid;
  margin: 0;
  padding: 0;
  border-top: 1px solid var(--trait);
  grid-auto-flow: column;
  column-gap: 56px;
  list-style: none;
}

.index li {
  display: flex;
  align-items: baseline;
  gap: 15px;
  padding: 12px 0;
  border-bottom: 1px solid var(--trait);
}

.index-num {
  flex: 0 0 auto;
  color: var(--vert);
  font-family: var(--display);
  font-size: 0.84rem;
  font-stretch: 104%;
  font-weight: 700;
}

.index-nom {
  min-width: 0;
  flex: 1;
  color: var(--marine);
  font-family: var(--display);
  font-size: 0.98rem;
  font-stretch: 104%;
  font-weight: 600;
  letter-spacing: -0.006em;
}

/* --- Un thème de conformité ------------------------------------------------- */

.theme {
  display: grid;
  padding: 16px 0 17px;
  border-bottom: 1px solid var(--trait);
  grid-template-columns: minmax(0, 1fr) 168px 78px;
  gap: 6px 26px;
  align-items: center;
}

.theme-nom {
  color: var(--marine);
  font-family: var(--display);
  font-size: 1.02rem;
  font-stretch: 104%;
  font-weight: 700;
}

.theme-detail {
  grid-column: 1;
  color: var(--gris);
  font-size: 0.85rem;
}

.theme .progress {
  grid-row: 1 / span 2;
  grid-column: 2;
}

.theme-part {
  grid-row: 1 / span 2;
  grid-column: 3;
  color: var(--marine);
  font-family: var(--display);
  font-size: 1.3rem;
  font-stretch: 110%;
  font-weight: 800;
  line-height: 1;
  text-align: right;
}

/* --- Dépôt de document ------------------------------------------------------ */

.upload-zone {
  display: grid;
  max-width: 600px;
  padding: 22px;
  border: 1px dashed var(--trait-fort);
  border-radius: var(--r-m);
  background: var(--blanc);
  gap: 16px;
}

.upload-zone .primary {
  justify-self: start;
}

/* --- Bandeau d'attention ----------------------------------------------------- */

.notice {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 22px;
  margin-bottom: 30px;
  padding: 16px 20px;
  border-left: 3px solid var(--or);
  border-radius: var(--r-s);
  background: var(--or-voile);
}

.notice strong {
  color: var(--marine);
  font-family: var(--display);
  font-size: 1rem;
  font-stretch: 104%;
  font-weight: 700;
}

.notice p {
  max-width: 72ch;
  margin-top: 3px;
  color: var(--or-fonce);
  font-size: 0.9rem;
}

/* --- État vide : une phrase, un filet, rien de plus --------------------------- */

.vide {
  padding: 20px 0 4px;
  border-top: 1px solid var(--trait);
}

.vide strong {
  display: block;
  color: var(--marine);
  font-family: var(--display);
  font-size: 1.05rem;
  font-stretch: 104%;
  font-weight: 700;
}

.vide p {
  max-width: 56ch;
  margin-top: 4px;
  color: var(--gris);
  font-size: 0.92rem;
}

/* --- Panneau : réservé aux blocs qui gagnent à être cadrés -------------------- */

.panel {
  padding: 22px 24px;
  border: 1px solid var(--trait);
  border-radius: var(--r-m);
  background: var(--blanc);
}

/* --- Fiche compte ------------------------------------------------------------- */

.account-details {
  display: grid;
  border-top: 1px solid var(--trait);
}

.account-details > div {
  display: grid;
  padding: 13px 0;
  border-bottom: 1px solid var(--trait);
  gap: 2px;
}

.account-details small {
  color: var(--gris);
  font-family: var(--display);
  font-size: 0.8rem;
  font-stretch: 104%;
  font-weight: 600;
}

.account-details strong {
  color: var(--marine);
  font-family: var(--display);
  font-size: 1.02rem;
  font-stretch: 104%;
  font-weight: 700;
}

/* --- Conversation --------------------------------------------------------------- */

.support-card {
  cursor: pointer;
  transition: background-color 150ms ease;
}

.support-card:hover {
  background: #f7f9f6;
}

.message {
  padding: 15px 18px;
  border-radius: var(--r-m);
  background: var(--papier);
}

.message + .message {
  margin-top: 10px;
}

.message.equipe {
  background: var(--vert-voile);
}

.message strong {
  color: var(--marine);
  font-family: var(--display);
  font-size: 0.94rem;
  font-stretch: 104%;
  font-weight: 700;
}

.message p {
  margin: 5px 0 0;
  white-space: pre-wrap;
}

.message small {
  display: block;
  margin-top: 8px;
  color: var(--gris-clair);
  font-family: var(--mono);
  font-size: 0.72rem;
}

/* --- Fenêtre modale --------------------------------------------------------------- */

dialog {
  width: min(680px, calc(100% - 28px));
  padding: 0;
  border: 1px solid var(--trait-fort);
  border-radius: var(--r-l);
  background: var(--blanc);
  color: var(--encre);
}

dialog::backdrop {
  background: rgba(7, 18, 29, 0.62);
}

#portal-dialog-content {
  max-height: min(72vh, 640px);
  padding: 28px;
  overflow-y: auto;
}

#portal-dialog-content h2 {
  padding-bottom: 12px;
  margin-bottom: 20px;
  border-bottom: 2px solid var(--marine);
  font-size: 1.32rem;
  font-weight: 700;
}

.dialog-actions {
  display: flex;
  padding: 15px 28px;
  border-top: 1px solid var(--trait);
  justify-content: flex-end;
  background: #fbfcfa;
  border-radius: 0 0 calc(var(--r-l) - 1px) calc(var(--r-l) - 1px);
}

.stack {
  display: grid;
  gap: 16px;
}

/* --- Mesures : ce que les attributs `style=` prétendaient faire -----------
   Neuf attributs `style=` traînaient dans le portail. La CSP les ignore tous
   depuis toujours : les formulaires s'étalaient sur toute la largeur du
   conteneur — 90 caractères par ligne — et les boutons d'envoi s'étiraient
   d'un bord à l'autre. Rien ne cassait, d'où la longévité : la page restait
   valide, elle était seulement mal composée.

   Ces classes disent ce que les attributs annonçaient, dans une feuille que
   le navigateur applique. Les gouttières ne sont pas reprises : trois
   formulaires réclamaient 14, 16 et 18 px sans qu'aucune raison ne distingue
   les trois. Ils prennent celle de `.stack`. */
.mesure-form { max-inline-size: 600px; }
.mesure-bloc { max-inline-size: 680px; }
.bouton-debut { justify-self: start; }
.fil-messages { margin-block-end: 22px; }
.mfa-activation { margin-block-start: 18px; }

/* --- Notification transitoire -------------------------------------------------- */

.portal-toast {
  position: fixed;
  right: 24px;
  bottom: 24px;
  z-index: 60;
  max-width: min(380px, calc(100% - 48px));
  padding: 13px 18px;
  border-radius: var(--r-s);
  background: var(--marine);
  color: var(--blanc);
  font-weight: 600;
  box-shadow: 0 12px 30px rgba(12, 27, 42, 0.24);
}

.portal-toast.error {
  background: var(--rouge-fonce);
}

/* --- Adaptations ---------------------------------------------------------------- */

@media (max-width: 1120px) {
  :root {
    --marge-jalon: 132px;
    --ecart-jalon: 28px;
  }

  .theme {
    grid-template-columns: minmax(0, 1fr) 120px 68px;
  }
}

@media (max-width: 900px) {
  .portal-shell {
    grid-template-columns: 1fr;
  }

  /* La bande de navigation prévoit déjà `overflow-x: auto`, mais elle ne
     défilait jamais : un enfant de grille garde `min-width: auto`, donc la
     piste `1fr` s'élargissait jusqu'à la largeur du contenu au lieu de le
     contraindre. Le portail entier dépassait alors l'écran sur téléphone —
     toutes les pages, pas seulement celles-ci. Deux déclarations rendent la
     contrainte effective. */
  .portal-shell > * {
    min-inline-size: 0;
  }

  .portal-sidebar {
    position: sticky;
    top: 0;
    z-index: 30;
    height: auto;
    padding: 14px 0 0;
    gap: 12px;
  }

  .portal-marque {
    margin-left: 20px;
  }

  .portal-marque img {
    width: 32px;
    height: 32px;
  }

  .portal-org {
    padding: 0 20px;
  }

  .portal-org small {
    display: none;
  }

  .portal-org strong {
    font-size: 1.08rem;
  }

  /* Une bande de navigation qui défile, plutôt qu'une grille de boutons. */
  .portal-sidebar nav {
    display: flex;
    padding: 0 20px;
    overflow-x: auto;
    gap: 4px;
    scrollbar-width: none;
  }

  .portal-sidebar nav::-webkit-scrollbar {
    display: none;
  }

  .portal-sidebar nav button {
    padding: 9px 13px 11px;
    border-left: 0;
    border-bottom: 3px solid transparent;
    border-radius: var(--r-s) var(--r-s) 0 0;
    white-space: nowrap;
  }

  .portal-sidebar nav button.active {
    border-bottom-color: var(--or);
  }

  .portal-user {
    display: none;
  }

  .portal-header {
    padding: 26px 20px 0;
  }

  .portal-header h1 {
    font-size: 1.66rem;
  }

  .portal-content {
    padding: 24px 20px 60px;
  }

  /* Le rail se replie : les jalons passent au-dessus de leur contenu. */
  .rail {
    grid-template-columns: minmax(0, 1fr);
    row-gap: 34px;
  }

  .rail::before {
    display: none;
  }

  .jalon {
    display: flex;
    align-items: baseline;
    padding-right: 0;
    padding-bottom: 4px;
    gap: 12px;
    text-align: left;
  }

  .jalon p {
    display: none;
  }

  .etape {
    margin-top: -22px;
  }

  .index {
    grid-auto-flow: row;
  }

  .theme {
    grid-template-columns: minmax(0, 1fr) 64px;
  }

  .theme .progress {
    grid-row: 3;
    grid-column: 1 / -1;
    margin-top: 6px;
  }

  .theme-part {
    grid-row: 1;
    grid-column: 2;
  }

  .bilan {
    padding: 24px 22px 22px;
  }

  .bilan-haut {
    align-items: flex-start;
    flex-direction: column;
    gap: 20px;
  }
}

@media (max-width: 620px) {
  body {
    font-size: 14.5px;
  }

  .portal-login-card {
    padding: 30px 24px 28px;
  }

  .row,
  .notice {
    align-items: flex-start;
    flex-direction: column;
    gap: 12px;
  }

  .tache {
    grid-template-columns: minmax(0, 1fr);
  }

  .tache-droite {
    grid-row: auto;
    grid-column: 1;
    margin-top: 12px;
    justify-content: flex-start;
  }

  .bilan-chiffre {
    font-size: 3.1rem;
  }

  .portal-toast {
    right: 16px;
    bottom: 16px;
    left: 16px;
    max-width: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  * {
    transition: none !important;
  }
}

/* Une précision qui porte sur la liste au-dessus, pas sur la section. */
.note-liste {
  max-width: 66ch;
  margin-top: 14px;
  color: var(--gris-clair);
  font-size: 0.85rem;
  line-height: 1.5;
}

.progression-mini {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 14px;
  margin-bottom: 8px;
}

.progression-mini b {
  color: var(--marine);
  font-family: var(--display);
  font-size: 1.3rem;
  font-stretch: 110%;
  font-weight: 800;
  line-height: 1;
}

.progression-mini small {
  color: var(--gris);
  font-size: 0.85rem;
}

/* --- Vérification en deux étapes du portail client ------------------------ */
.mfa-box {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  padding: 16px;
  border: 1px solid var(--trait-fort);
  border-radius: var(--r-m);
  gap: 16px;
  background: var(--papier);
}
.mfa-box p { margin: 6px 0 0; }
.mfa-status {
  flex: 0 0 auto;
  padding: 5px 9px;
  border: 1px solid var(--trait-fort);
  border-radius: 999px;
  font-size: 0.76rem;
  font-weight: 700;
}
.mfa-status.active { border-color: var(--vert); color: var(--vert); }
.mfa-enrollment {
  display: grid;
  padding: 16px;
  border: 1px solid var(--trait-fort);
  border-radius: var(--r-m);
  background: var(--papier);
  gap: 10px;
}
.mfa-enrollment p { margin: 0; }
.mfa-secret {
  display: block;
  padding: 12px;
  border: 1px solid var(--trait);
  border-radius: var(--r-s);
  overflow-wrap: anywhere;
  background: var(--blanc);
  font-family: var(--mono);
  font-size: 0.88rem;
  letter-spacing: 0.07em;
}
.mfa-link { text-decoration: none; }
.recovery-codes {
  display: grid;
  margin: 14px 0;
  padding: 14px;
  border: 1px solid var(--trait-fort);
  border-radius: var(--r-m);
  grid-template-columns: 1fr 1fr;
  gap: 8px;
  background: var(--papier);
}
.recovery-codes code { font-family: var(--mono); font-size: 0.82rem; }
.mfa-disable-form { margin-top: 18px; }
@media (max-width: 560px) {
  .recovery-codes { grid-template-columns: 1fr; }
  .mfa-box { flex-direction: column; }
}

/* Repère Sécurité — espace client
 *
 * Ce bloc n'utilisait aucun jeton `--sec-*` : tout y était codé en dur, et il
 * avait dérivé vers le vert. Le liseré de « Correction recommandée » était un
 * #1b6b4f unique dans tout le code, à un cheveu du vert Repère Québec. Le
 * client voyait donc l'identité Loi 25 sur sa page Sécurité, pendant que la
 * console interne affichait correctement le pétrole — deux services de la
 * même maison qui ne se ressemblaient que du côté qu'il ne voyait pas.
 *
 * Les gris de l'en-tête tiraient eux aussi vers le vert (#dbe3e0, #a8bbb4).
 * Ils penchent maintenant vers le pétrole, pour que la teinte du service se
 * lise jusque dans les neutres.
 *
 * Les couleurs de sévérité ne sont pas des jetons de service : rouge, ambre
 * et jaune disent le risque, pas la marque, et restent donc littérales. La
 * sévérité ne repose jamais sur elles seules — la pastille porte son libellé
 * en toutes lettres. */
.portal-security-head{background:var(--marine);color:#fff;border-radius:22px;padding:26px;margin-bottom:16px}.portal-security-head h2{font-size:32px;margin:4px 0 8px}.portal-security-head>p{color:#cfd9e8;max-width:720px}.portal-security-score{display:flex;align-items:baseline;gap:7px;margin-top:22px;flex-wrap:wrap}.portal-security-score strong{font-size:48px}.portal-security-score span{color:#9fb0c6}.portal-security-score small{width:100%;color:#9fb0c6}.portal-security-stats{display:grid;grid-template-columns:repeat(4,1fr);gap:10px;margin-bottom:18px}.portal-security-stat{background:#fff;border:1px solid #e3e7ee;border-radius:14px;padding:15px;display:grid;gap:3px}.portal-security-stat strong{font-size:25px}.portal-security-stat span{font-size:12px;color:#6b727e}.portal-security-stat.critical strong{color:#9c2f29}.portal-security-stat.high strong{color:#99560b}.portal-security-stat.medium strong{color:#7d6400}.portal-security-findings{display:grid;gap:12px}.portal-security-finding{background:#fff;border:1px solid #e3e7ee;border-radius:16px;padding:17px}.portal-security-finding h3{margin:10px 0 7px}.portal-severity{border-radius:999px;padding:4px 8px;font-size:11px;font-weight:800;text-transform:uppercase;margin-right:8px}.portal-severity.critical{background:#fee9e7;color:#9c2f29}.portal-severity.high{background:#fff0df;color:#99560b}.portal-severity.medium{background:#fff7d8;color:#7d6400}.portal-severity.low,.portal-severity.info{background:var(--sec-100);color:var(--sec-700)}.portal-remediation{background:var(--sec-050);border-left:3px solid var(--sec-600);border-radius:8px;padding:10px 12px;margin-top:12px}.portal-remediation p{margin:4px 0 0}@media(max-width:720px){.portal-security-stats{grid-template-columns:repeat(2,1fr)}.portal-security-head h2{font-size:27px}}

/* ==========================================================================
   Retour au toucher — même règle que la console
   L'espace client est surtout consulté sur téléphone : le survol collé y est
   plus gênant qu'ailleurs, et l'appui doit toujours répondre.
   ========================================================================== */

/* Rétablit l'intention de l'auteur : cet écart était écrit en attribut
   `style`, donc bloqué par la CSP et jamais appliqué. */
.progress-espace {
  margin-bottom: var(--e-6);
}

@media (prefers-reduced-motion: reduce) {
  * {
    transition-duration: var(--d-1) !important;
    animation-duration: var(--d-1) !important;
    animation-delay: 0ms !important;
    scroll-behavior: auto !important;
  }

  *,
  *::before,
  *::after {
    transition-property: color, background-color, border-color, box-shadow, opacity, fill, stroke !important;
  }

  *:active {
    transform: none !important;
  }
}

/* Sans pointeur fin, le navigateur allume `:hover` au premier toucher et le
   laisse allumé jusqu'au toucher suivant. L'espace client se consulte surtout
   au téléphone : on annule donc ces états plutôt que de les laisser collés. */
@media (hover: none) {
  .primary:hover { background: var(--accent); }
  .secondary:hover { border-color: var(--trait-fort); color: var(--marine); }
  .ghost:hover { background: transparent; }
  .portal-sidebar nav button:hover { background: transparent; color: inherit; }
  .portal-user .link-button:hover { color: inherit; }
  .support-card:hover { background: inherit; }
  input:hover,
  select:hover,
  textarea:hover { border-color: var(--trait-fort); }
}

/* ==========================================================================
   Le verdict — la phrase qui répond avant les chiffres
   L'utilisateur n'est pas technicien : il veut savoir si ça va, et si quelque
   chose lui est demandé. Le pourcentage vient après.
   ========================================================================== */

.verdict {
  padding: var(--e-5) var(--e-6);
  margin-bottom: var(--e-6);
  border: 1px solid var(--trait);
  border-left: 4px solid var(--trait-fort);
  border-radius: var(--r-m);
  background: var(--blanc);
}

.verdict strong {
  display: block;
  margin-bottom: 4px;
  color: var(--marine);
  font-family: var(--display);
  font-size: 1.12rem;
  font-stretch: 106%;
  letter-spacing: -0.012em;
}

.verdict p {
  color: var(--gris);
  font-size: 0.95rem;
  line-height: 1.5;
}

.verdict.est-critique { border-left-color: var(--rouge); background: var(--rouge-voile); }
.verdict.est-attente { border-left-color: var(--or-fonce); background: var(--or-voile); }
.verdict.est-fait { border-left-color: var(--vert); background: var(--vert-voile); }

/* La barre d'un thème porte l'état du thème, pas toujours le vert : une barre
   verte à 0 % sur un thème en échec serait un contresens. */
.theme.est-critique .progress > span { background: var(--rouge); }
.theme.est-attente .progress > span { background: var(--or-fonce); }
.theme.est-fait .progress > span { background: var(--vert); }

.theme.est-critique .theme-part { color: var(--rouge-fonce); }
.theme.est-attente .theme-part { color: var(--or-fonce); }

/* ==========================================================================
   REPÈRE MAINTENANCE — l'espace des demandes

   Le client se pose une seule question en arrivant : « est-ce qu'on attend
   quelque chose de moi ? ». Un seul statut y répond oui, et lui seul porte
   l'accent. Les six autres restent calmes.

   Aucun rouge : le rouge doit signifier que quelque chose ne va pas, et une
   demande d'entretien ne va jamais mal. « Annulée » et « Refusée » sont les
   jetons les plus gris de la série, pas les plus alarmants.

   Chaque jeton porte une pastille dont la forme change — pleine, creuse,
   barrée : la couleur n'est jamais seule à porter l'information.

   Bronze plutôt que vert ou indigo : trois familles de teintes séparées se
   distinguent d'un coup d'œil. Le doré décoratif existant reste réservé aux
   ornements ; les deux ne partagent jamais un même bloc.
   ========================================================================== */

.espace-maintenance {
  --mnt: #8A5A2B;
  --mnt-fonce: #6d4620;
  --mnt-voile: #f4ece2;
  --mnt-papier: #faf6f1;
}

.mnt-etat {
  display: inline-flex;
  align-items: center;
  padding: 4px 11px 5px;
  border-radius: 999px;
  border: 1px solid transparent;
  background: var(--papier);
  color: var(--gris);
  font-family: var(--texte);
  font-size: 0.76rem;
  font-weight: 600;
  white-space: nowrap;
}
/* Pas de pastille ronde devant le libellé. La couleur porte ici sur toute la
   surface de l'étiquette — un aplat teinté, pas un point — et l'état se lit
   de toute façon en toutes lettres. Un rond coloré n'ajoutait rien à
   « Planifiée » qu'un aplat ne dise mieux. */
.mnt-etat.in_progress { background: var(--bleu-voile); color: var(--bleu-fonce); }
.mnt-etat.waiting_client {
  background: var(--mnt-voile, #f4ece2);
  color: var(--mnt-fonce, #6d4620);
  border-color: #a6743f;
  font-weight: 700;
}
.mnt-etat.done { background: var(--vert-voile); color: var(--vert-fonce); }
.mnt-etat.cancelled,
.mnt-etat.declined { background: var(--trait); color: var(--gris); }


/* Une ligne de demande : la référence ancre, le sujet porte, l'état conclut. */
.mnt-demande {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 6px 16px;
  align-items: center;
  inline-size: 100%;
  padding: 16px 18px;
  border: 1px solid var(--trait);
  border-radius: 4px;
  background: var(--blanc);
  text-align: start;
  font: inherit;
  color: inherit;
  cursor: pointer;
  transition: border-color 160ms var(--sortie, ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .mnt-demande:hover { border-color: var(--trait-fort); }
}
.mnt-demande:active { transform: scale(0.995); }
.mnt-demande-titre { display: grid; gap: 3px; min-inline-size: 0; }
.mnt-demande-titre strong { font-size: 1rem; overflow-wrap: anywhere; }
.mnt-demande-meta {
  font-size: 0.82rem;
  color: var(--gris);
  font-variant-numeric: tabular-nums;
}
.mnt-numero {
  font-family: var(--mono);
  font-size: 0.78rem;
  color: var(--gris);
}

/* --- Fiche --------------------------------------------------------------- */

.mnt-faits-client {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 16px 22px;
  padding: 18px 0;
  border-block: 1px solid var(--trait);
}
.mnt-faits-client > div { display: grid; gap: 4px; min-inline-size: 0; }
.mnt-faits-client dt {
  font-size: 0.72rem;
  font-weight: 660;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--gris);
}
.mnt-faits-client dd { margin: 0; font-size: 0.95rem; overflow-wrap: anywhere; }

.mnt-echange { display: grid; gap: 14px; }
.mnt-bulle {
  display: grid;
  gap: 6px;
  padding: 14px 16px;
  border: 1px solid var(--trait);
  border-radius: 4px;
  background: var(--blanc);
}
.mnt-bulle.equipe {
  border-left: 3px solid var(--mnt, #8A5A2B);
  background: var(--mnt-papier, #faf6f1);
}
.mnt-bulle-tete {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 12px;
  align-items: baseline;
  font-size: 0.8rem;
  color: var(--gris);
}
.mnt-bulle-tete strong { color: var(--encre); font-size: 0.88rem; }
.mnt-bulle p { margin: 0; white-space: pre-wrap; overflow-wrap: anywhere; }

.mnt-piece {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 13px 16px;
  border: 1px solid var(--trait);
  border-radius: 4px;
}
.mnt-piece-nom { display: grid; gap: 2px; min-inline-size: 0; }
.mnt-piece-nom strong { font-size: 0.92rem; overflow-wrap: anywhere; }
.mnt-piece-meta { font-size: 0.78rem; color: var(--gris); }

/* Le champ de réponse et le dépôt de fichier tiennent la pleine largeur sur
   téléphone : c'est là que le client écrit le plus souvent. */
.mnt-formulaire { display: grid; gap: 14px; max-inline-size: 640px; }
.mnt-formulaire textarea { min-block-size: 120px; }

.mnt-retour {
  min-block-size: 40px;
  margin-block-end: 22px;
}

@media (max-width: 640px) {
  /* La carte passe en une colonne : sans cette contrainte, le jeton d'état
     s'étirerait sur toute la largeur et cesserait de se lire comme un jeton. */
  .mnt-demande { grid-template-columns: 1fr; }
  .mnt-demande .mnt-etat { justify-self: start; }
  .mnt-faits-client { grid-template-columns: 1fr 1fr; }
  .mnt-piece { flex-direction: column; align-items: flex-start; }
  .mnt-piece button { inline-size: 100%; }
}

@media (max-width: 400px) {
  .mnt-faits-client { grid-template-columns: 1fr; }
}

@media (prefers-reduced-motion: reduce) {
  .mnt-demande { transition-duration: 1ms; }
  .mnt-demande:active { transform: none; }
}

/* --- Sites, forfait et travaux réalisés ----------------------------------- */

.mnt-site-client,
.mnt-banque,
.mnt-travail {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 6px 16px;
  align-items: center;
  padding: 16px 18px;
  border: 1px solid var(--trait);
  border-radius: 4px;
  background: var(--blanc);
}

/* Une banque échue ou épuisée reste affichée — elle a couvert du travail, et
   la retirer effacerait cet historique — mais elle cesse de se présenter
   comme une réserve disponible. */
.mnt-etat.active { background: var(--vert-voile); color: var(--vert-fonce); }
.mnt-etat.exhausted,
.mnt-etat.expired { background: var(--trait); color: var(--gris); }

.mnt-travail { grid-template-columns: 1fr; }
.mnt-travail-detail {
  margin: 0;
  font-size: 0.92rem;
  color: var(--encre);
  overflow-wrap: anywhere;
}

/* Le forfait : ce qui reste d'abord, parce que c'est la question. Le
   dépassement se dit en une phrase, sans rouge ni alarme — c'est un sujet de
   conversation commerciale, pas un incident. */
.mnt-forfait {
  display: grid;
  gap: 8px;
  margin-block-start: 16px;
  padding: 18px 20px;
  border: 1px solid var(--trait);
  border-left: 3px solid var(--mnt, #8A5A2B);
  border-radius: 4px;
  background: var(--mnt-papier, #faf6f1);
}
.mnt-forfait-titre {
  margin: 0;
  font-size: 0.72rem;
  font-weight: 660;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--mnt-fonce, #6d4620);
}
.mnt-forfait-reste { margin: 0; display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.mnt-forfait-reste strong {
  font-size: 1.6rem;
  font-weight: 700;
  color: var(--encre);
  letter-spacing: -0.015em;
  font-variant-numeric: tabular-nums;
}
.mnt-forfait-reste span { font-size: 0.9rem; color: var(--gris); }
.mnt-forfait-pied { margin: 0; font-size: 0.85rem; color: var(--gris); }

.mnt-forfait-barre {
  block-size: 8px;
  border-radius: 999px;
  background: var(--blanc);
  border: 1px solid var(--trait);
  overflow: hidden;
}
.mnt-forfait-barre > span {
  display: block;
  block-size: 100%;
  inline-size: 0;
  border-radius: inherit;
  background: var(--mnt, #8A5A2B);
  transition: inline-size 320ms var(--sortie, ease-out);
}

@media (max-width: 640px) {
  .mnt-site-client,
  .mnt-banque { grid-template-columns: 1fr; }
  .mnt-site-client .mnt-etat,
  .mnt-banque .mnt-etat { justify-self: start; }
}

@media (prefers-reduced-motion: reduce) {
  .mnt-forfait-barre > span { transition-duration: 1ms; }
}

/* ==========================================================================
   Le mur — accueil de l'espace client

   Une composition d'aplats jointifs, sans gouttière ni coin arrondi : la
   couleur occupe des surfaces entières et les frontières se font par contact.
   Un seul champ profond — ce qui attend le client — et autour, des zones qui
   portent chacune une donnée et une seule.

   Sur fond clair l'indigo descend (600, 700) ; sur fond sombre il monte (300).
   Un même pas ne peut pas servir les deux.
   ========================================================================== */
.mur {
  display: grid;
  grid-template-columns: 1.62fr 1fr;
  border-radius: var(--r-l);
  overflow: hidden;
}

.zone {
  display: flex;
  flex-direction: column;
  min-inline-size: 0;
  padding: 32px 34px;
  color: inherit;
  text-decoration: none;
}

.zone-etiq {
  font-family: var(--display);
  font-size: 10.5px;
  font-weight: 700;
  letter-spacing: 0.19em;
  text-transform: uppercase;
}

/* --- le champ dominant --- */
.z-vous {
  grid-row: span 2;
  background: var(--marine);
  color: #fff;
}
.z-vous .zone-etiq { color: #8fa8c8; }
.z-vous-compte {
  display: flex;
  align-items: baseline;
  gap: 18px;
  margin-block-start: 16px;
}
.z-vous-compte b {
  font-family: var(--display);
  font-size: clamp(56px, 7vw, 92px);
  font-weight: 800;
  letter-spacing: -0.05em;
  line-height: 0.8;
  color: var(--or);
}
.z-vous-compte span {
  font-family: var(--display);
  font-size: 18px;
  font-weight: 640;
  line-height: 1.2;
  max-inline-size: 16ch;
  color: #dce6f0;
}
.z-vous ul {
  margin: 30px 0 0;
  padding: 0;
  list-style: none;
}
.z-vous li {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 20px;
  align-items: center;
  padding: 15px 0;
  border-block-start: 1px solid rgba(255, 255, 255, 0.17);
}
.z-vous li b {
  display: block;
  font-family: var(--display);
  font-size: 16px;
  font-weight: 670;
}
.z-vous li span {
  display: block;
  margin-block-start: 3px;
  font-size: 13.5px;
  line-height: 1.4;
  color: #b6c6d6;
}
.z-vous li a {
  padding: 9px 16px;
  border-radius: 3px;
  background: var(--or);
  color: #2b2007;
  font-family: var(--display);
  font-size: 12.5px;
  font-weight: 700;
  text-decoration: none;
  white-space: nowrap;
}
.z-vous-repos {
  margin-block-start: 30px;
  font-size: 15.5px;
  line-height: 1.55;
  color: #d6ece0;
  max-inline-size: 40ch;
}
/* Le champ calme garde sa hauteur — il tient les deux zones de service en
   face — mais il n'a qu'une phrase à dire. Sans centrage, cette phrase se
   tassait en haut et laissait un grand vide sous elle. Un espace réparti se
   lit comme du calme ; un espace tombé en bas se lit comme un oubli. */
/* `est-fait` est le même état, atteint par l'autre chemin : la conformité ne
   compte pas ce qui reste, elle constate que plus rien ne manque. Un seul jeu
   de déclarations pour les deux — deux copies finissent toujours par diverger
   d'une teinte. */
.z-vous.est-calme,
.z-vous.est-fait {
  background: var(--succes);
  justify-content: center;
}
.z-vous.est-calme .zone-etiq,
.z-vous.est-calme .z-vous-compte,
.z-vous.est-calme .z-vous-repos { flex: none; }
.z-vous.est-calme .z-vous-compte { margin-block-start: 14px; }
/* 11 px sur le vert : la teinte d'origine donnait 4,58, le ratio le plus serré
   du portail. Elle ne servait qu'à l'accueil ; elle habille maintenant l'état
   calme de cinq écrans, et une marge de huit centièmes n'est pas une marge à
   cette échelle-là. Remontée à 5,02 — l'étiquette reste plus sourde que le
   texte qu'elle surmonte, personne ne verra la différence. */
.z-vous.est-calme .zone-etiq,
.z-vous.est-fait .zone-etiq { color: #cfe8dc; }
.z-vous.est-calme .z-vous-compte b { color: #fff; }
.z-vous.est-calme .z-vous-compte span { color: #d6ece0; }

/* --- les services : teintes claires --- */
.z-serv { justify-content: space-between; }
.z-serv h2 {
  margin-block-start: 9px;
  font-size: 20px;
  font-weight: 700;
  letter-spacing: -0.018em;
  color: var(--marine);
}
.z-serv .suite {
  margin-block-start: 20px;
  font-family: var(--display);
  font-size: 13px;
  font-weight: 660;
}
.z-qc { background: var(--qc-100, #e7f1ec); }
.z-qc .zone-etiq, .z-qc .suite { color: var(--qc-700, #17553d); }
.z-mnt { background: var(--mnt-100, #f4ece2); }
.z-mnt .zone-etiq, .z-mnt .suite { color: var(--mnt-700, #6d4620); }
.z-sec {
  grid-column: 1 / -1;
  background: var(--sec-100);
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 24px;
  align-items: center;
  padding: 24px 34px;
}
.z-sec .zone-etiq { color: var(--sec-600); }
.z-sec b {
  display: block;
  margin-block-start: 8px;
  font-family: var(--display);
  font-size: 18px;
  font-weight: 690;
  color: var(--marine);
}
.z-sec p {
  margin-block-start: 6px;
  font-size: 14px;
  line-height: 1.5;
  color: var(--sec-700);
  max-inline-size: 60ch;
}

/* --- l'anneau : une proportion se lit mieux qu'elle ne se calcule --------
   `stroke-dasharray` est un attribut de présentation SVG, pas un attribut
   style= : la CSP l'accepte. L'arc porte le RESTANT, pas le consommé. */
.anneau { display: flex; align-items: center; gap: 18px; margin-block-start: 18px; }
.anneau svg { flex: none; inline-size: 88px; block-size: 88px; transform: rotate(-90deg); }
/* Les couleurs de trait étaient définies uniquement dans les zones du mur.
   Hors du mur — dans le solde des heures — le cercle n'avait donc aucune
   couleur et l'anneau se rendait invisible : présent dans le DOM, absent à
   l'écran. Un défaut vaut mieux qu'une règle qui suppose son contexte. */
.anneau .piste { fill: none; stroke-width: 9; stroke: var(--trait); }
.anneau .arc { fill: none; stroke-width: 9; stroke-linecap: round; stroke: var(--mnt-600, #8A5A2B); }
.z-qc .anneau .piste { stroke: #cbe2d6; }
.z-qc .anneau .arc { stroke: var(--qc-600, #1F6A4E); }
.z-mnt .anneau .piste { stroke: #e6d5c1; }
.z-mnt .anneau .arc { stroke: var(--mnt-600, #8A5A2B); }
.anneau-txt { min-inline-size: 0; }
.anneau-txt .v {
  font-family: var(--display);
  font-size: 30px;
  font-weight: 750;
  letter-spacing: -0.03em;
  line-height: 1;
}
.z-qc .anneau-txt .v { color: var(--qc-700, #17553d); }
.z-mnt .anneau-txt .v { color: var(--mnt-700, #6d4620); }
.anneau-txt .sur { font-family: var(--mono); font-size: 19px; color: var(--gris); }
.anneau-txt .n { margin-block-start: 6px; font-size: 13.5px; line-height: 1.45; color: var(--gris); }

/* Le survol ne s'adresse qu'aux zones qui mènent quelque part. Dans les
   bandeaux de section, une zone de service est un constat, pas un lien : la
   voir s'assombrir sous le curseur lui promettait un clic qui n'existe pas. */
@media (hover: hover) and (pointer: fine) {
  a.z-serv, .z-vous li a { transition: filter 0.18s ease-out; }
  a.z-serv:hover { filter: brightness(0.98); }
  .z-vous li a:hover { filter: brightness(1.1); }
}
.zone a:focus-visible, .z-serv:focus-visible { outline: 3px solid var(--or); outline-offset: -6px; }

@media (max-width: 900px) {
  .mur { grid-template-columns: 1fr; border-radius: var(--r-m); }
  .zone { padding: 24px 20px; }
  .z-vous { grid-row: auto; }
  .z-sec { grid-column: auto; grid-template-columns: 1fr; }
}

/* --- Le solde des heures --------------------------------------------------
   Trois banques donnaient trois lignes identiques, et le total — la seule
   chose que le client vient vérifier — n'apparaissait nulle part. L'anneau
   porte désormais le solde de l'ensemble ; le détail suit, en retrait, avec
   l'échéance de chaque banque parce que c'est elle qui décide de l'ordre
   dans lequel elles se consomment. */
.mnt-solde {
  border: 1px solid var(--trait);
  border-radius: 4px;
  background: var(--blanc);
  overflow: hidden;
}

.mnt-solde-tete {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  flex-wrap: wrap;
  padding: 22px 24px;
}

.mnt-solde-tete .anneau { margin-block-start: 0; }

.mnt-solde-echeance {
  max-inline-size: 26ch;
  margin: 0;
  color: var(--gris);
  font-size: 13.5px;
  line-height: 1.45;
  text-align: end;
}

.mnt-solde-detail {
  margin: 0;
  padding: 0;
  list-style: none;
  border-block-start: 1px solid var(--trait);
}

.mnt-solde-detail li {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto auto;
  gap: 4px 18px;
  align-items: baseline;
  padding: 13px 24px;
  border-block-end: 1px solid var(--trait);
}
.mnt-solde-detail li:last-child { border-block-end: 0; }

.mnt-solde-nom {
  font-family: var(--display);
  font-size: 14.5px;
  font-weight: 640;
  min-inline-size: 0;
}

.mnt-solde-offert {
  font-family: var(--texte);
  font-size: 12.5px;
  font-weight: 400;
  color: var(--mnt-700, #6d4620);
}

.mnt-solde-reste,
.mnt-solde-fin {
  font-family: var(--mono);
  font-size: 11.5px;
  font-variant-numeric: tabular-nums;
  color: var(--gris);
  white-space: nowrap;
}

@media (max-width: 640px) {
  .mnt-solde-tete { justify-content: flex-start; }
  .mnt-solde-echeance { text-align: start; max-inline-size: none; }
  .mnt-solde-detail li {
    grid-template-columns: minmax(0, 1fr) auto;
    row-gap: 6px;
  }
  .mnt-solde-fin { grid-column: 1 / -1; }
}

/* --- Le carnet ------------------------------------------------------------
   L'objet de la vitrine Maintenance, ramené dans le compte du client. La
   bande couvre douze mois : un mois où l'on est intervenu se teinte, et son
   intensité suit le temps passé. Une liste seule ne montrait pas la
   régularité — or c'est elle que le client paie tous les mois. */
.carnet {
  border: 1px solid var(--trait);
  border-radius: 4px;
  background: var(--blanc);
  overflow: hidden;
}

.carnet-bande {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: 3px;
  padding: 20px 22px 10px;
}

.carnet-barre {
  block-size: 26px;
  border-radius: 2px;
  background: var(--mnt-600, #8A5A2B);
}
.carnet-barre.est-faible { background: #e0c9ad; }
.carnet-barre.est-vide { background: #eef0f0; }

.carnet-legende {
  display: flex;
  justify-content: space-between;
  padding: 0 22px 18px;
  font-family: var(--mono);
  font-size: 11px;
  color: var(--gris-clair);
}

.carnet-lignes {
  margin: 0;
  padding: 0;
  list-style: none;
  border-block-start: 1px solid var(--trait);
}

.carnet-ligne {
  display: grid;
  grid-template-columns: 92px minmax(0, 1fr) auto;
  gap: 4px 16px;
  align-items: baseline;
  padding: 14px 22px;
  border-block-end: 1px solid var(--trait);
}
.carnet-ligne:last-child { border-block-end: 0; }

.carnet-date,
.carnet-duree {
  font-family: var(--mono);
  font-size: 11.5px;
  font-variant-numeric: tabular-nums;
  color: var(--gris);
  white-space: nowrap;
}

.carnet-fait { display: grid; gap: 3px; min-inline-size: 0; }
.carnet-fait strong { font-family: var(--display); font-size: 15px; font-weight: 640; }
.carnet-fait span { font-size: 13.5px; line-height: 1.45; color: var(--gris); }
.carnet-ou { font-family: var(--mono); font-size: 11.5px; color: var(--gris-clair); }

@media (max-width: 640px) {
  .carnet-bande { gap: 2px; padding-inline: 18px; }
  .carnet-barre { block-size: 20px; }
  .carnet-ligne {
    grid-template-columns: minmax(0, 1fr) auto;
    padding-inline: 18px;
  }
  .carnet-date { grid-column: 1 / -1; }
}

/* Une intervention antérieure à la banque reste listée — elle a eu lieu — mais
   ne colore aucune case de la bande. Sans marque, le client compte trois
   lignes pour un mois teinté et cherche l'erreur. */
.carnet-ligne.est-hors-fenetre .carnet-date,
.carnet-ligne.est-hors-fenetre .carnet-fait strong { color: var(--gris); }
.carnet-hors {
  display: block;
  margin-block-start: 3px;
  font-family: var(--texte);
  font-size: 11px;
  font-variant-numeric: normal;
  color: var(--gris-clair);
  white-space: nowrap;
}

/* ==========================================================================
   Le bandeau — le mur, en tête d'une section

   L'accueil est un mur : il occupe tout l'écran, parce qu'il n'a rien d'autre
   à dire. Une section, elle, a une liste à montrer. Elle garde donc la langue
   du mur sans en prendre la place : des aplats jointifs, sans gouttière ni
   coin arrondi entre eux, la couleur sur des surfaces entières plutôt que sur
   des points, et une seule donnée par zone.

   Le champ dominant pose partout la même question — « est-ce qu'on attend
   quelque chose de moi ? » — et sa teinte est sa réponse. La zone qui lui fait
   face porte la mesure du dossier, jamais un second appel à l'action : deux
   urgences côte à côte n'en font plus aucune.
   ========================================================================== */
.mur-bandeau {
  grid-template-columns: 1.62fr 1fr;
  margin-block-end: 34px;
}

/* Le mur de l'accueil fait courir son champ sur deux rangées : deux zones de
   service lui font face. Un bandeau n'en a qu'une. Sans cette remise à zéro,
   le champ s'étirait sur deux rangées au-dessus d'une case vide, et la moitié
   basse du bandeau restait blanche. */
.mur-bandeau .zone { grid-row: auto; }

/* --- le champ dominant, quand il porte une phrase plutôt qu'un compte ------
   La conformité ne répond pas « combien » mais « est-ce que ça va ». Le grand
   nombre n'a alors rien à afficher : c'est la phrase qui devient l'objet, à
   l'échelle où le nombre se lisait. */
.z-vous-dit { margin-block-start: 16px; }
.z-vous-dit b {
  display: block;
  font-family: var(--display);
  font-size: clamp(26px, 3.1vw, 38px);
  font-weight: 760;
  letter-spacing: -0.03em;
  line-height: 1.08;
  color: #fff;
}
.z-vous-dit p {
  margin-block-start: 14px;
  font-size: 15.5px;
  line-height: 1.55;
  max-inline-size: 42ch;
  color: #d6e2ec;
}

/* --- les teintes du champ -------------------------------------------------
   Chaque teinte renomme TOUS les textes qu'elle recouvre, jamais le seul
   fond. Une règle qui ne nomme que le conteneur laisse en place les couleurs
   de la teinte précédente — c'est ainsi qu'on obtient du blanc sur du blanc
   le jour où le conteneur change de couleur.

   Rouge et bronze ne sont pas des marques ici : le bronze de Maintenance vit
   dans `.espace-maintenance`, et ces deux teintes-ci ne servent qu'à dire
   « à corriger » et « en cours de vérification ». */
.z-vous.est-critique { background: var(--rouge-fonce); justify-content: center; }
.z-vous.est-critique .zone-etiq { color: #f0c4bb; }
.z-vous.est-critique .z-vous-dit p { color: #f7ded8; }

/* L'étiquette est à 11 px : mesurée sur le bronze, la teinte d'abord retenue
   donnait 4,56 — au-dessus du seuil, mais d'un cheveu, et c'est le genre de
   marge qu'un rendu de police un peu plus fin efface. Remontée à 4,91, elle
   reste plus sourde que le texte courant, comme sur les autres teintes. */
.z-vous.est-attente { background: var(--or-fonce); justify-content: center; }
.z-vous.est-attente .zone-etiq { color: #f4e4bb; }
.z-vous.est-attente .z-vous-dit p { color: #f7ecc9; }

.z-vous.est-fait .z-vous-dit p { color: #d6ece0; }

/* --- une zone qui porte un compte, pas une proportion ---------------------
   L'anneau dit une part ; un nombre de demandes en traitement n'en est pas
   une. Lui en dessiner un obligerait à inventer un dénominateur. */
.z-nombre {
  display: flex;
  align-items: baseline;
  gap: 14px;
  margin-block-start: 18px;
}
.z-nombre b {
  font-family: var(--display);
  font-size: 46px;
  font-weight: 780;
  letter-spacing: -0.04em;
  line-height: 0.9;
}
.z-nombre span {
  font-size: 13.5px;
  line-height: 1.4;
  max-inline-size: 18ch;
}
.z-qc .z-nombre b { color: var(--qc-700, #17553d); }
.z-qc .z-nombre span,
.z-qc .z-rien { color: var(--qc-800, #123f2e); }

/* Une zone sans donnée le dit en toutes lettres. Un aplat vide se lit comme
   un défaut de chargement, et un zéro qu'on n'a jamais mesuré est un
   mensonge : ici il n'y a rien à mesurer, pas zéro. */
.z-rien {
  margin-block-start: 18px;
  font-size: 14.5px;
  line-height: 1.5;
  max-inline-size: 34ch;
}

@media (max-width: 900px) {
  .mur-bandeau { grid-template-columns: 1fr; margin-block-end: 26px; }
}
