.dashboard-final {
  min-height: 100vh;
  color: var(--color-text-primary);
  /* Shell en colonne : la navbar prend sa hauteur, la vue active occupe le reste.
     Permet à la vue moyen terme de tenir dans le viewport (zéro scroll de page). */
  display: flex;
  flex-direction: column;
}

/* La barre d'application vit dans le composant .ds-navbar (navbar.css). */

/* ── Carte 1 (KPI objectif) en BLANC : hero KPI, seule carte inversée ── */
.ds-kpi-card--hero {
  background: var(--color-text-primary);   /* blanc */
}

.ds-kpi-card--hero .ds-kpi-card__eyebrow,
.ds-kpi-card--hero .ds-kpi-card__name,
.ds-kpi-card--hero .ds-kpi-card__value,
.ds-kpi-card--hero .ds-kpi-card__target,
.ds-kpi-card--hero .ds-kpi-card__meta {
  color: var(--color-surface);   /* texte sombre sur fond blanc — inclut __name (sinon blanc sur blanc) */
}

.ds-kpi-card--hero .ds-kpi-card__divider {
  border-color: color-mix(in srgb, var(--color-surface) 15%, transparent);
}

.ds-kpi-card--hero .ds-delta {
  color: var(--color-surface);
  background: color-mix(in srgb, var(--color-surface) 8%, transparent);
}

/* Conteneur de page : largeur max + centré (la grille). */
.dashboard-final__page {
  max-width: var(--grid-max-width);
  width: 100%;   /* remplit jusqu'à max-width (sinon, en flex-column, margin-inline:auto rétrécit
                    la page au contenu → la To-do faisait 363px au lieu de la largeur de grille). */
  margin-inline: auto;
  padding-inline: var(--grid-page-padding);
  padding-block: var(--space-32) var(--grid-page-padding);   /* gap navbar→grille resserré (48 jugé trop) — symétrique avec le bas */
  /* Grille VERTICALE : rangée KPI compacte (auto) + rangée contenu à hauteur définie
     (≥ token, grandit si le contenu déborde). Rythme vertical stable, vide ou rempli,
     sans forcer 100vh. */
  display: grid;
  grid-template-rows: auto minmax(var(--grid-row-content-height), auto);
  gap: var(--grid-gutter);
}

/* Barre de navigation (tabs). */
.dashboard-final__nav {
  display: flex;
}

/* ── Ligne des 4 cartes : sur la grille DS (.ds-grid) — chaque carte = span 3 (4×3=12). ── */

/* Les cartes réutilisées : pas de marge propre (l'espacement vient de la grille). */
.dashboard-final__kpi-row > * {
  margin: 0;
  width: auto;            /* neutralise la largeur fixe des composants → la colonne de grille pilote */
}

/* La carte « Jalon actif » n'a pas de marge haute ici (elle vit dans une grille, pas sous une timeline).
   La bande KPI long terme est un contexte COMPACT : les 3 tuiles y sont à --kpi-card-summary-padding (16).
   Le jalon rejoint ce padding pour que les 4 cadres aient le MÊME inset (cohérence de bande).
   Son rythme interne (eyebrow→titre→stepper) reste canonique — on n'aligne que le cadre. */
.dashboard-final .ds-jalon-active {
  margin-top: 0;
  --jalon-active-padding: var(--kpi-card-summary-padding);
}

/* État vide dans une tuile KPI compacte : l'empty-state est dimensionné pour un stage
   autonome (padding-block 64 = +128px) → il gonfle la tuile à ~306px et casse le rythme
   (réf = tuiles fines ~150px en haut, gros contenu en bas). On le rend compact + centré. */
.dashboard-final__kpi-row .ds-empty-state {
  padding-block: 0;
  gap: var(--space-8);
  max-width: none;
}

.dashboard-final__kpi-row .ds-empty-state__icon {
  width: var(--space-32);
  height: var(--space-32);
  margin-bottom: 0;
}

.dashboard-final__kpi-row > *:has(.ds-empty-state) {
  display: flex;
  flex-direction: column;
  justify-content: center;
}

/* ── Vues commutables (onglets) : une page par vue, une seule visible. ──
   Le [hidden] natif ne suffit pas : .dashboard-final__page force display:grid
   (gagne sur hidden). On rétablit donc explicitement display:none. */
.dashboard-final__page[hidden] {
  display: none;
}

/* La vue moyen terme occupe la hauteur restante sous la navbar et n'excède jamais le
   viewport : pas de scroll de page (Principe 5). Le seul défilement possible est interne
   au rail (liste de jalons) si les jalons débordent — la carte cadence reste visible. */
.dashboard-final__page--moyen {
  flex: 1;
  min-height: 0;
  overflow: hidden;
  grid-template-rows: minmax(0, 1fr);
}

/* La rangée remplit la page ; les deux colonnes s'étirent à la même hauteur (v4). */
.dashboard-final__moyen-row {
  align-items: stretch;
  min-height: 0;
}

/* CONTEXTE (col-4) : rail puis carte cadence empilés en haut (enquillés). Le rail épouse
   ses jalons (pas de void) et scrolle en interne s'il déborde ; la cadence reste visible. */
.dashboard-final__moyen-side {
  display: flex;
  flex-direction: column;
  gap: var(--grid-gutter);
  min-height: 0;
}
.dashboard-final__moyen-side .ds-timeline {
  display: flex;
  flex-direction: column;
  flex: 0 1 auto;   /* hauteur naturelle, rétrécit seulement si la colonne déborde */
  min-height: 0;
}
.dashboard-final__moyen-side .ds-timeline__list {
  height: auto;
  min-height: 0;
  overflow-y: auto;
}
/* La carte cadence garde sa taille, collée juste sous le rail (pas étirée, pas déplacée). */
.dashboard-final__moyen-heatmap {
  max-width: none;
  flex: none;
}
/* Le popover au survol s'ouvre À DROITE de la grille (pas dessous ni dessus) : dans le
   dashboard la carte est près du bas d'une vue clippée (overflow:hidden) → sous la grille il
   tombait hors cadre, et par-dessus il masquait le calendrier. À droite il reste visible sans
   rien cacher. */
.dashboard-final__moyen-heatmap .ds-heatmap-popover {
  top: 0;
  bottom: auto;
  left: 100%;
  right: auto;
  margin-left: var(--space-12);
}

/* Détail du jalon = CARTE DÉFINIE (fidèle v4 : bord + ombre + padding). */
.dashboard-final__detail-card {
  display: flex;
  background: var(--card-background);
  border: var(--card-border-defined);
  border-radius: var(--card-radius);
  box-shadow: var(--card-shadow-defined);
  padding: var(--card-padding);
}
.dashboard-final__detail-card .ds-jalon-detail {
  flex: 1;
  display: flex;
  flex-direction: column;
}

/* Desktop : asymétrie SUR la grille 12 col — rail = 3 colonnes, détail = 9 (gouttière système).
   Les cartes KPI absorbent le mou pour remplir la hauteur du détail (v4 : cartes hautes). */
@media (min-width: 1025px) {
  .dashboard-final__moyen-row > .ds-col-4 { grid-column: span 3; }
  .dashboard-final__moyen-row > .ds-col-8 { grid-column: span 9; }
  .dashboard-final__detail-card .ds-jalon-detail__section + .ds-jalon-detail__section { flex: 1; }
  .dashboard-final__detail-card .ds-jalon-detail__kpi-grid { flex: 1; }
  .dashboard-final__detail-card .ds-jalon-detail__kpi-grid .ds-kpi-card { display: flex; flex-direction: column; }
  .dashboard-final__detail-card .ds-jalon-detail__kpi-grid .ds-kpi-card__metric { flex: 1; }
}

/* Empilé (≤1024) : rail + détail pleine largeur, flux naturel (le viewport-fill ne tient
   plus quand les colonnes s'empilent → on relâche la contrainte de hauteur). */
@media (max-width: 1024px) {
  .dashboard-final__page--moyen {
    flex: none;
    overflow: visible;
    grid-template-rows: auto;
  }
  .dashboard-final__moyen-row > .ds-col-4,
  .dashboard-final__moyen-row > .ds-col-8 { grid-column: 1 / -1; }
  .dashboard-final__moyen-side { grid-template-rows: none; }
  .dashboard-final__moyen-side .ds-timeline__list {
    flex: none;
    overflow-y: visible;
  }
  /* Empilé : la carte cadence est pleine largeur → un popover à droite (left:100%) déborderait
     le viewport. On l'ancre au bord droit de la carte (s'ouvre vers la gauche, dans le cadre). */
  .dashboard-final__moyen-heatmap .ds-heatmap-popover {
    left: auto;
    right: 0;
    margin-left: 0;
  }
}

/* ── Vue TO-DO : exécution. Barre jalon + liste 3 blocs (En cours/À faire/Terminé) ↔ Board. ──
   La rangée épouse son contenu (comme moyen terme) : pas de hauteur réservée. */
.dashboard-final__page--todo {
  grid-template-rows: auto;
}

/* Pile verticale : barre jalon → validation → corps. RYTHME CONSTANT (24 partout,
   identique au gap entre blocs de statut) → pas de mélange 16/24. */
.dashboard-final__todo {
  display: flex;
  flex-direction: column;
  gap: var(--space-24);
}

/* ── Barre de jalons (milestone tabs) : carte pleine largeur, pills scrollables. ── */
.dashboard-final__jalonbar {
  display: flex;
  gap: var(--space-4);
  padding: var(--space-8);
  background: var(--card-background);
  border: var(--card-border-defined);
  border-radius: var(--card-radius);
  box-shadow: var(--card-shadow-defined);
  overflow-x: auto;
}

.dashboard-final__jalonpill {
  display: inline-flex;
  flex-shrink: 0;
  align-items: center;
  gap: var(--space-8);
  padding: var(--space-8) var(--space-12);
  background: none;
  border: none;
  border-radius: var(--radius-md);
  color: var(--color-text-muted);
  font-size: var(--type-body-md-size);
  font-weight: var(--font-weight-medium);
  cursor: pointer;
  transition: var(--motion-transition-default);
}

.dashboard-final__jalonpill:hover {
  color: var(--color-text-secondary);
  background: var(--color-surface-raised);
}

.dashboard-final__jalonpill.is-active {
  color: var(--color-text-primary);
  background: var(--color-surface-raised);
}

.dashboard-final__jalonpill-name {
  white-space: nowrap;
}

.dashboard-final__jalonpill-dot {
  flex-shrink: 0;
  width: var(--space-8);
  height: var(--space-8);
  border-radius: var(--radius-full);
}

/* Jalon en cours = dot orange (statut actif, DS §900). Validé = dot neutre. */
.dashboard-final__jalonpill-dot.is-active {
  background: var(--color-accent-primary);
}

.dashboard-final__jalonpill-dot.is-done {
  background: var(--color-text-muted);
}

.dashboard-final__jalonpill-count {
  color: var(--color-text-muted);
  font-size: var(--type-caption-size);
  font-variant-numeric: tabular-nums;
}

/* ── Ligne validation : drapeau + VALIDATION · {jalon} : {critère} + Valider. ──
   Pas de séparateur/padding propre : le gap de section (24) uniforme fait la respiration. */
.dashboard-final__validation {
  display: flex;
  align-items: center;
  gap: var(--space-16);
}

.dashboard-final__validation-text {
  flex: 1;
  min-width: 0;
  margin: 0;
}

.dashboard-final__validation-label {
  display: inline-flex;
  align-items: center;
  gap: var(--space-8);
  color: var(--color-text-primary);
  font-weight: var(--font-weight-semibold);
  letter-spacing: var(--letter-spacing-label);
}

.dashboard-final__validation-icon {
  flex-shrink: 0;
  width: var(--space-16);
  height: var(--space-16);
  stroke-width: var(--icon-stroke-width);
}

.dashboard-final__validation-crit {
  color: var(--color-text-secondary);
}

.dashboard-final__validation-empty {
  color: var(--color-text-muted);
}

.dashboard-final__validation-btn {
  flex-shrink: 0;
}

/* ── Toolbar : bascule Liste/Board (icônes), en absolu top-right → alignée sur le 1er bloc. ── */
.dashboard-final__todo-bodywrap {
  position: relative;
}

.dashboard-final__todo-toolbar {
  position: absolute;
  top: 0;
  right: 0;
  z-index: 1;
  display: flex;
  justify-content: flex-end;
}

.dashboard-final__todo-toolbar .ds-tabs-segmented__tab {
  display: inline-flex;
  align-items: center;
  gap: var(--space-4);
}

.dashboard-final__toggle-icon {
  width: var(--space-16);
  height: var(--space-16);
  stroke-width: var(--icon-stroke-width-bold);
}

/* ── Liste : 3 CARTES séparées (une par bloc), chacune = composant task-list (table-stage). ── */
.dashboard-final__todo-card:not(:last-child) {
  margin-bottom: var(--space-16);
}

/* Titre de tâche = medium (comme le legacy .task-name 500), pas regular. */
.dashboard-final__todo-card .ds-row-title {
  font-weight: var(--font-weight-medium);
}

/* Rapprocher badge + tâches + sous-tâches du bord gauche : le composant met margin-left 32 sur le
   status-heading et 16 de padding inline sur les cellules → trop d'inset. On réduit dans le contexte todo. */
.dashboard-final__todo-card .ds-table__status-heading {
  margin-left: 0;
}

.dashboard-final__todo-card .ds-table td {
  padding-inline: var(--space-8);
}

/* Bloc cible de dépôt (drag inter-carte) : surface levée = zone d'accueil claire. */
.dashboard-final__todo-group.is-drop-target .ds-table--nested tbody {
  background: var(--color-surface-raised);
}

/* Tâche/sous-tâche terminée : titre atténué + barré (fait = ça recule, cohérent timeline §802). */
.nested-group__task.is-done .ds-row-title,
.ds-row-title.is-done {
  color: var(--color-text-muted);
  text-decoration: line-through;
}

/* Compteur de sous-tâches accolé au titre (déjà type-caption). */
.ds-row-subcount {
  flex-shrink: 0;
  color: var(--color-text-muted);
}

/* Chevron sans sous-tâche : garde la place (alignement) mais icône masquée + non cliquable. */
.ds-disclosure.is-empty {
  cursor: default;
}

.ds-disclosure.is-empty .ds-disclosure__icon {
  opacity: 0;
}

/* ── Board (Kanban) : 3 colonnes de flux sur la grille DS (ds-col-4 ×3). ──
   Colonnes transparentes (pas de cadre) → les cartes sont le seul niveau de surface
   (jamais de carte dans une carte). */
.dashboard-final__kanban-col {
  display: flex;
  flex-direction: column;
  gap: var(--kanban-head-gap);
}

.dashboard-final__kanban-head {
  display: flex;
  align-items: center;
  gap: var(--space-8);
}

.dashboard-final__kanban-count {
  color: var(--color-text-muted);
}

.dashboard-final__kanban-list {
  display: flex;
  flex-direction: column;
  gap: var(--kanban-card-gap);
  min-height: var(--kanban-list-min-height);
}

/* Carte = tuile définie (liftable au drag), compacte. */
.dashboard-final__kanban-card {
  display: flex;
  flex-direction: column;
  gap: var(--kanban-card-inner-gap);
  padding: var(--kanban-card-padding);
  background: var(--kanban-card-background);
  border: var(--kanban-card-border);
  border-radius: var(--kanban-card-radius);
  box-shadow: var(--kanban-card-shadow);
  cursor: grab;
}

/* Tête de carte : titre + actions (⋯/×) révélées au survol, à droite. */
.dashboard-final__kanban-cardhead {
  display: flex;
  align-items: flex-start;
  gap: var(--space-8);
}

.dashboard-final__kanban-title {
  flex: 1;
  min-width: 0;
  margin: 0;
  color: var(--color-text-primary);
  font-weight: var(--font-weight-medium);
}

.dashboard-final__kanban-card.is-done .dashboard-final__kanban-title {
  color: var(--color-text-muted);
}

/* Actions de carte : en flux (pas absolu comme dans la table), masquées au repos. */
.dashboard-final__kanban-actions {
  position: static;
  flex-shrink: 0;
  opacity: 0;
}

.dashboard-final__kanban-card:hover .dashboard-final__kanban-actions,
.dashboard-final__kanban-card:focus-within .dashboard-final__kanban-actions {
  opacity: 1;
}

/* Méta : progression sous-tâches (atténuée). */
.dashboard-final__kanban-meta {
  display: flex;
  align-items: baseline;
  gap: var(--kanban-meta-gap);
}

.dashboard-final__kanban-progress {
  flex-shrink: 0;
  color: var(--color-text-muted);
}

/* Le « + Ajouter… » du kanban : pleine largeur de colonne, sous les cartes. */
.dashboard-final__kanban-add {
  justify-content: flex-start;
}

/* Carte en cours de déplacement : estompée (fantôme suivant le curseur). */
.dashboard-final__kanban-card.is-dragging {
  opacity: var(--opacity-dragging);
  cursor: grabbing;
}

/* Colonne cible de dépôt : surface levée = zone d'accueil claire (sans accent réservé au CTA). */
.dashboard-final__kanban-list.is-drop-target {
  background: var(--color-surface-raised);
  border-radius: var(--card-radius);
  box-shadow: inset 0 0 0 var(--border-width-default) var(--color-border-strong);
}

/* ── Édition inline (ajout / renommage) : champ borderless qui garde le look de la row (pas un gros ds-input). ── */
.dashboard-final__todo-input {
  flex: 1;
  width: 100%;
  min-width: 0;
  padding: 0;
  color: var(--color-text-primary);
  font: inherit;
  background: transparent;
  border: none;
  outline: none;
}

/* Row d'ajout en édition : reprend l'inline ghost (« + » + champ) → rythme identique à « Ajouter une action… ». */
.dashboard-final__todo-editing {
  display: inline-flex;
  align-items: center;
  gap: var(--empty-inline-gap);
  width: 100%;
}

/* ── Panneau détail = panneau latéral DROITE (comme le legacy .side-panel). ──
   Pas de backdrop : le dashboard reste visible et cliquable. DS neutre (pas d'orange). */
.dashboard-final__taskpanel-overlay {
  position: fixed;
  inset: 0;
  z-index: var(--z-overlay);
  pointer-events: none;   /* wrapper jamais bloquant */
}

.dashboard-final__taskpanel {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  display: flex;
  flex-direction: column;
  width: min(var(--taskpanel-width), 42vw);
  padding: var(--space-32) var(--space-24);
  background: var(--color-surface);
  border-left: var(--border-subtle);
  box-shadow: var(--shadow-lg);
  pointer-events: auto;   /* le panneau est interactif */
  overflow-y: auto;
}

.dashboard-final__taskpanel-close {
  position: absolute;
  top: var(--space-16);
  right: var(--space-16);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--space-32);
  height: var(--space-32);
  padding: 0;
  color: var(--color-text-muted);
  background: transparent;
  border: none;
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: var(--motion-transition-default);
}

.dashboard-final__taskpanel-close:hover {
  color: var(--color-text-primary);
  background: var(--button-ghost-background-hover);
}

/* Corps : rythme groupé (titre→champ tight, section→section aéré). */
.dashboard-final__taskpanel-body {
  display: flex;
  flex-direction: column;
  gap: var(--space-section-gap);
  flex: 1;
}

.dashboard-final__taskpanel-section {
  display: flex;
  flex-direction: column;
  gap: var(--space-label-gap);
}

/* Label de section : uniforme (type-data-label). Pas de couleur propre → cohérent avec « Checklist ». */
.dashboard-final__taskpanel-label { }

/* Statut = pastille compacte (select inline auto-large), pas un champ pleine largeur. */
.dashboard-final__taskpanel-statusrow {
  display: flex;
}
.dashboard-final__taskpanel-statusselect {
  width: auto;
}
.dashboard-final__taskpanel-statusselect .ds-select {
  width: auto;
  height: auto;
  padding-block: var(--space-4);
  padding-inline: var(--space-8) var(--space-24);
  font-size: var(--type-caption-size);
  line-height: var(--type-caption-line);
  border-radius: var(--radius-full);
}

/* Titre = héros du panneau (h2), collé au statut au-dessus (marge négative du gap section). */
.dashboard-final__taskpanel-title {
  margin: 0;
}

.dashboard-final__taskpanel-field {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.dashboard-final__taskpanel-jalon {
  color: var(--color-text-primary);
}

.dashboard-final__taskpanel-checkhead {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
}

.dashboard-final__taskpanel-checkcount {
  color: var(--color-text-muted);
}

.dashboard-final__taskpanel-subs {
  display: flex;
  flex-direction: column;
  gap: var(--space-element-gap);
  margin-top: var(--space-element-gap);
}

.dashboard-final__taskpanel-sub {
  display: flex;
  align-items: center;
  gap: var(--space-8);
}

.dashboard-final__taskpanel-sub .ds-checkbox {
  flex: 1;
  min-width: 0;
}

.dashboard-final__taskpanel-sub .ds-row-action {
  flex-shrink: 0;
  opacity: 0;
}

.dashboard-final__taskpanel-sub:hover .ds-row-action,
.dashboard-final__taskpanel-sub:focus-within .ds-row-action {
  opacity: 1;
}

.dashboard-final__taskpanel-subadd {
  display: flex;
  align-items: center;
  gap: var(--space-8);
}

.dashboard-final__taskpanel-subaddicon {
  flex-shrink: 0;
  width: var(--checkbox-size-round);
  color: var(--color-text-muted);
  text-align: center;
}

/* Zone destructive : épinglée en bas, séparée par un filet. */
.dashboard-final__taskpanel-danger {
  margin-top: var(--space-section-gap);
  padding-top: var(--space-24);
  border-top: var(--border-subtle);
}

/* ── Rangée du bas : sur la grille DS — graphique span 8 + SMART span 4. ── */

/* Les composants ont une largeur propre : on la neutralise, la colonne de grille pilote. */
.dashboard-final__bottom-row > * {
  width: auto;
  max-width: none;
}

/* Le graphique remplit la hauteur de sa colonne. */
.dashboard-final__bottom-row .ds-chart-card {
  height: 100%;
}

/* Reflow responsive — le span est une décision de vue. Breakpoints alignés sur la grille DS. */
@media (max-width: 1024px) {
  /* Grille à 8 col : KPI 2 par ligne (span 4), rangée du bas empilée pleine largeur. */
  .dashboard-final__kpi-row > * { grid-column: span 4; }
  .dashboard-final__bottom-row > * { grid-column: 1 / -1; }
}

@media (max-width: 600px) {
  /* Grille à 4 col : tout en pleine largeur + marge de page resserrée. */
  .dashboard-final__page,
  .ds-navbar__inner { padding-inline: var(--grid-page-padding-mobile); }
  .dashboard-final__kpi-row > * { grid-column: 1 / -1; }
}
