/* ===========================================================
   NUANCIER.CSS — surcharges spécifiques au nuancier
   Étend games.css.
   =========================================================== */


/* ===========================================================
   0. SURCHARGE DU FOND EN MODE CLAIR
   Un nuancier exige un fond neutre pour ne pas teinter la
   perception des couleurs. Le mode sombre reste inchangé.
   =========================================================== */

/* Override : nuancier sur fond blanc pur en mode clair (les fonds crème
   de games.css faussent la perception des couleurs). Le mode sombre garde
   le bleu nuit profond. */

:root:not([data-theme="dark"]) {
  --color-bg: #ffffff;
  --color-surface: #ffffff;
  --color-border: rgba(26, 26, 26, 0.10);
  --color-border-strong: rgba(26, 26, 26, 0.28);
}

[data-theme="dark"] {
  /* Surface plus sombre que le fond pour distinguer les cartes */
  --color-surface: #243149;
  /* Bordures plus visibles sur fond sombre */
  --color-border: rgba(184, 196, 217, 0.15);
  --color-border-strong: rgba(184, 196, 217, 0.30);
}

html,
body {
  background: var(--color-bg);
}


/* ===========================================================
   1. AJUSTEMENTS DE LAYOUT
   =========================================================== */

.nuancier-main {
  flex: 1;
}

.view {
  display: none;
  animation: fadeUp 300ms cubic-bezier(0.2, 0, 0, 1) backwards;
}

.view.is-active {
  display: block;
}

.view-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  flex-wrap: wrap;
  gap: var(--space-md);
  margin-bottom: var(--space-lg);
  padding-bottom: var(--space-md);
  border-bottom: 1px solid var(--color-border);
}

/* Variante : view-header avec une action à droite (Sprint 8 UX).
   Le bouton "Ajouter aux favoris" est placé en bout de ligne, sur la
   même ligne que les sous-onglets en desktop. */
.view-header--with-action {
  align-items: center;
}

.view-header--with-action .sub-tabs {
  flex: 1 1 auto;
}

.ds-header-fav-add {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2xs, 4px);
  flex-shrink: 0;
  white-space: nowrap;
}

.ds-header-fav-add .ds-fav-star {
  color: var(--color-text-soft);
}

.section-heading {
  font-family: var(--font-display);
  font-size: 1.5rem;
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: 1.1;
}

.block-heading {
  font-family: var(--font-display);
  font-size: 1rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  margin-bottom: var(--space-xs);
}

.block-sub {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--color-text-faint);
  margin-left: var(--space-xs);
}


/* ===========================================================
   2. ONGLETS DE NAVIGATION

   Sprint 2.0 : la barre d'onglets principale est désormais cachée.
   Toute la navigation passe par la home (cf. section 2quater) et le
   bouton Home du header. Les .tab-btn restent dans le DOM (et reçoivent
   toujours .click() programmatique depuis le router des blocs home)
   mais ne sont plus affichées visuellement. Les styles ci-dessous sont
   conservés pour le mode "barre revisible" éventuel (et pour les
   sous-onglets internes qui en héritent indirectement). */

.tabs-row {
  display: none;
}

/* Styles legacy conservés (au cas où on rebascule la barre visible) */
.tab-btn {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--color-text-soft);
  padding: var(--space-sm) var(--space-md);
  background: transparent;
  border: none;
  border-bottom: 2px solid transparent;
  cursor: pointer;
  white-space: nowrap;
  margin-bottom: -1px;
  transition: color var(--t-fast), border-color var(--t-fast);
}

.tab-btn:hover {
  color: var(--color-text);
}

.tab-btn.is-active {
  color: var(--color-text);
  border-bottom-color: var(--color-text);
}


/* ===========================================================
   2quater. PAGE D'ACCUEIL (Sprint 2.0)

   Cartes pleines couleur Polychromie 1931 (Le Corbusier). Chaque
   section a sa famille chromatique : Importer (crème), Explorer
   (verts), Analyser (bleus), Créer (terres rouges). Texte ton sur
   ton tiré de la même palette pour garantir l'AA WCAG.

   Le bloc Importer est lui-même la drop-zone : clic ou drag & drop
   déclenchent l'import puis basculent vers view-import.
   =========================================================== */

#view-home {
  max-width: 1100px;
  margin: 0 auto;
}

.home-intro {
  margin-bottom: var(--space-xl);
}

.home-title {
  font-family: var(--font-display);
  font-size: clamp(2.5rem, 6vw, 3.75rem);
  font-weight: 500;
  line-height: 1.05;
  margin: 0 0 var(--space-sm);
  color: var(--color-text);
}

.home-lead {
  font-family: var(--font-display);
  font-size: 1.25rem;
  line-height: 1.5;
  color: var(--color-text-soft);
  max-width: 60ch;
  margin: 0;
}

.home-section {
  margin-bottom: var(--space-xl);
}

.home-section-title {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.18em;
  color: var(--color-text-faint);
  margin: 0 0 var(--space-md);
}

/* Grilles : 1 colonne (Importer en solo), 2 cols, 3 cols */
.home-cards {
  display: grid;
  gap: var(--space-md);
}

.home-cards--2 {
  grid-template-columns: repeat(2, 1fr);
}

.home-cards--3 {
  grid-template-columns: repeat(3, 1fr);
}

@media (max-width: 800px) {
  .home-cards--2,
  .home-cards--3 {
    grid-template-columns: 1fr;
  }
}

/* Carte cliquable (bouton)
   - Hauteur minimum pour avoir du volume "à la Coolors"
   - Fond plein, texte ton sur ton, pas de bordure
   - Hover : translateY (-2px) + ombre douce */
.home-card {
  position: relative;
  display: block;
  width: 100%;
  min-height: 220px;
  padding: 0;
  background: transparent;
  border: none;
  border-radius: var(--radius-md);
  cursor: pointer;
  text-align: left;
  font: inherit;
  color: inherit;
  overflow: hidden;
  transition: transform 200ms ease, box-shadow 200ms ease;
}

.home-card:hover {
  transform: translateY(-2px);
  box-shadow: 0 8px 20px rgba(0, 0, 0, 0.08);
}

.home-card:active {
  transform: translateY(0);
}

.home-card:focus-visible {
  outline: 2px solid var(--color-text);
  outline-offset: 3px;
}

.home-card-body {
  padding: clamp(20px, 3vw, 32px);
  display: flex;
  flex-direction: column;
  gap: 12px;
  height: 100%;
  min-height: inherit;
}

.home-card-icon {
  flex: 0 0 auto;
  width: 36px;
  height: 36px;
  margin-bottom: 4px;
}

.home-card-icon svg {
  width: 100%;
  height: 100%;
  display: block;
}

.home-card-title {
  font-family: var(--font-display);
  font-size: clamp(1.6rem, 3vw, 2.1rem);
  font-weight: 500;
  line-height: 1.05;
  margin: 0;
}

.home-card--import .home-card-title {
  font-size: clamp(2rem, 4vw, 2.6rem);
}

.home-card-desc {
  font-family: var(--font-display);
  font-size: 1rem;
  line-height: 1.45;
  margin: 0;
  flex: 1 1 auto;
}

.home-card-cta {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.14em;
  margin: 0;
}

.home-card-cta span {
  display: inline-block;
  transition: transform 200ms ease;
}

.home-card:hover .home-card-cta span {
  transform: translateX(4px);
}

/* === COULEURS POLYCHROMIE 1931 par section ===
   Toutes les valeurs sont prises dans le nuancier Salubra Le
   Corbusier — voir app.js, palette "Polychromie 1931". */

/* Importer (crème ocrée) — texte terre sombre, ratio 10.5 (AA) */
.home-card--import {
  background: #fff1ce;
  color: #47332c;
}
.home-card--import .home-card-desc { color: #5d3833; }

/* Importer — état dragover */
.home-card--import.is-dragging {
  background: #f8d5b0;
  outline: 2px dashed #47332c;
  outline-offset: -8px;
}

/* Explorer — verts du clair au saturé */
.home-card--explore-1 { background: #e2e7dc; color: #2c695a; }
.home-card--explore-1 .home-card-desc { color: #2c695a; }

.home-card--explore-2 { background: #cad8cd; color: #2c695a; }
.home-card--explore-2 .home-card-desc { color: #2c695a; }

.home-card--explore-3 { background: #cede9f; color: #2c695a; }
.home-card--explore-3 .home-card-desc { color: #2c695a; }

/* Analyser — bleus distincts */
.home-card--analyser-1 { background: #bccccf; color: #4e6498; }
.home-card--analyser-1 .home-card-desc { color: #4e6498; }

.home-card--analyser-2 { background: #96b4c9; color: #47332c; }
.home-card--analyser-2 .home-card-desc { color: #47332c; }

/* Créer — terres rouges */
.home-card--creer-1 { background: #fadec3; color: #811c35; }
.home-card--creer-1 .home-card-desc { color: #811c35; }

.home-card--creer-2 { background: #f4cab6; color: #811c35; }
.home-card--creer-2 .home-card-desc { color: #811c35; }


/* ===========================================================
   2bis. EXPLORER — bandeau couleur active + sous-onglets
   =========================================================== */

.explore-header {
  margin-bottom: var(--space-lg);
}

.active-color-bar {
  display: flex;
  align-items: center;
  gap: var(--space-md);
  flex-wrap: wrap;
  padding: var(--space-md);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  margin-bottom: var(--space-md);
}

.active-color-label {
  font-family: var(--font-mono);
  font-size: 0.65rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--color-text-faint);
  flex-shrink: 0;
}

.active-color-bar .color-input-group {
  flex-shrink: 0;
}

.active-color-bar .hsl-display {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  color: var(--color-text-soft);
  flex: 1;
  min-width: 120px;
}

.btn-send-comparison {
  flex-shrink: 0;
  font-family: var(--font-mono);
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

/* Sprint 2.0 : bandeau compact 2-col à gauche, occupe ~50% de la largeur.
   Utilisé dans Variations et Roue chromatique. */
.active-color-bar--compact {
  display: grid;
  grid-template-columns: auto auto;
  gap: var(--space-lg);
  align-items: center;
  width: max-content;
  max-width: 100%;
  margin-bottom: var(--space-lg);
}

.active-color-bar--compact .active-color-field {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.active-color-bar--compact .active-color-label {
  flex-shrink: 0;
}

.active-color-bar--compact .color-input-group {
  flex-shrink: 0;
}

.active-color-bar--compact .active-color-meta {
  display: flex;
  align-items: center;
  gap: var(--space-md);
}

.active-color-bar--compact .hsl-display {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  color: var(--color-text-soft);
  white-space: nowrap;
}

@media (max-width: 700px) {
  .active-color-bar--compact {
    grid-template-columns: 1fr;
    width: 100%;
  }
}

/* Sprint 2.0 : cartes empilées de la vue Variations
   (Variations, Mélangeur, Harmonies) — chaque carte est nette,
   séparée par un fond/border, et compose son contenu de blocs. */
.explore-card {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-lg);
  margin-bottom: var(--space-lg);
}

.explore-card-header {
  margin-bottom: var(--space-md);
  padding-bottom: var(--space-sm);
  border-bottom: 1px solid var(--color-border);
}

.explore-card-title {
  font-family: var(--font-display);
  font-size: 1.4rem;
  font-weight: 500;
  margin: 0 0 4px;
  color: var(--color-text);
}

.explore-card-desc {
  font-family: var(--font-display);
  font-size: 0.9rem;
  line-height: 1.5;
  color: var(--color-text-soft);
  margin: 0;
}

.explore-card .variation-block:last-child,
.explore-card .harmony-block:last-child {
  margin-bottom: 0;
}

/* Sprint 2.0 : header Palettes utilise simplement .view-header
   (même structure que Composants : titre + sub-tabs sur la même ligne).
   Aucun modificateur n'est nécessaire. */

/* Sprint 2.0 : description de la roue, pleine largeur */
.wheel-intro {
  max-width: none;
  margin-bottom: var(--space-lg);
}

/* Sprint 2.0 : verdict d'accessibilité dans Comparer */
.cmp-a11y-block {
  margin-top: var(--space-lg);
}

.ds-a11y-warn {
  font-family: var(--font-mono);
  font-size: 0.8125rem;
  padding: var(--space-md);
  background: color-mix(in srgb, var(--color-warning, #c47b00) 10%, transparent);
  border: 1px solid color-mix(in srgb, var(--color-warning, #c47b00) 30%, transparent);
  border-radius: var(--radius-sm);
  color: var(--color-text);
}

[data-theme="dark"] .ds-a11y-warn {
  background: color-mix(in srgb, var(--color-warning, #ffb74d) 12%, transparent);
  border-color: color-mix(in srgb, var(--color-warning, #ffb74d) 35%, transparent);
}

/* Sous-onglets internes à Explorer */
.sub-tabs {
  display: flex;
  gap: var(--space-xs);
  border-bottom: 1px solid var(--color-border);
  overflow-x: auto;
  scrollbar-width: none;
}

.sub-tabs::-webkit-scrollbar { display: none; }

.sub-tab-btn {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--color-text-soft);
  padding: var(--space-sm) var(--space-md);
  background: transparent;
  border: none;
  border-bottom: 2px solid transparent;
  cursor: pointer;
  white-space: nowrap;
  margin-bottom: -1px;
  transition: color var(--t-fast), border-color var(--t-fast);
}

.sub-tab-btn:hover {
  color: var(--color-text);
}

.sub-tab-btn.is-active {
  color: var(--color-accent);
  border-bottom-color: var(--color-accent);
}

.sub-view {
  display: none;
  margin-top: var(--space-md);
}

.sub-view.is-active {
  display: block;
}


/* ===========================================================
   2ter. RESPONSIVE MOBILE
   =========================================================== */

@media (max-width: 600px) {
  /* Onglets principaux : labels plus courts via JS ? Non — on garde tels quels,
     le scroll horizontal fait son travail mais on réduit le padding */
  .tab-btn {
    font-size: 0.7rem;
    padding: var(--space-sm) var(--space-sm);
    letter-spacing: 0.05em;
  }

  /* Bandeau couleur active : on empile */
  .active-color-bar {
    flex-direction: column;
    align-items: stretch;
    gap: var(--space-sm);
  }
  .active-color-bar .hsl-display { min-width: 0; }
  .btn-send-comparison { align-self: flex-start; }
}


/* ===========================================================
   3. FILTRES (catégorie)
   =========================================================== */

.filter-group {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  flex-wrap: wrap;
}

.filter-group .level-label {
  margin-bottom: 0;
}

.filter-group .mode-row {
  margin-bottom: 0;
}


/* ===========================================================
   4. GRILLE DE PALETTES
   =========================================================== */

.palettes-grid {
  display: grid;
  gap: var(--space-lg);
}

.palette {
  padding: var(--space-md);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  transition: border-color var(--t-fast);
}

.palette:hover {
  border-color: var(--color-border-strong);
}

.palette-header {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--space-sm);
  margin-bottom: var(--space-xs);
}

.palette-meta {
  display: flex;
  align-items: baseline;
  gap: var(--space-sm);
  white-space: nowrap;
}

.palette-export-btn {
  font-family: var(--font-mono);
  font-size: 0.65rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--color-text-soft);
  padding: 2px var(--space-sm);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  background: transparent;
  cursor: pointer;
  transition: border-color var(--t-fast), color var(--t-fast);
}

.palette-export-btn:hover {
  border-color: var(--color-border-strong);
  color: var(--color-text);
}

.palette-name {
  font-family: var(--font-display);
  font-size: 1rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  margin: 0;
}

.palette-category {
  font-family: var(--font-mono);
  font-size: 0.65rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--color-text-faint);
  white-space: nowrap;
}

.palette-desc {
  font-family: var(--font-display);
  font-size: 0.85rem;
  color: var(--color-text-soft);
  margin-bottom: var(--space-md);
  line-height: 1.5;
}

.palette-swatches {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(72px, 1fr));
  gap: var(--space-xs);
}

.palette-source {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  color: var(--color-text-faint);
  line-height: 1.5;
  margin-top: var(--space-sm);
  padding-top: var(--space-sm);
  border-top: 1px solid var(--color-border);
}

.palette-source-label {
  text-transform: uppercase;
  letter-spacing: 0.1em;
  font-size: 0.6rem;
  margin-right: var(--space-xs);
  color: var(--color-text-faint);
}

.palette-source a {
  color: var(--color-text-soft);
  text-decoration: none;
  border-bottom: 1px dotted var(--color-border-strong);
  transition: color var(--t-fast), border-color var(--t-fast);
}

.palette-source a:hover {
  color: var(--color-accent);
  border-bottom-color: var(--color-accent);
}

.palette-status {
  display: block;
  margin-top: 2px;
  font-style: italic;
  font-size: 0.65rem;
  color: var(--color-text-faint);
}


/* ===========================================================
   5. SWATCHES (échantillons)
   =========================================================== */

.swatch {
  aspect-ratio: 1 / 1;
  border-radius: var(--radius-sm);
  cursor: pointer;
  position: relative;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  padding: var(--space-xs);
  transition: transform var(--t-fast);
}

.swatch:hover {
  transform: translateY(-2px);
}

.swatch-label {
  font-family: var(--font-mono);
  font-size: 0.65rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  /* Par défaut sur couleur claire : label sombre */
  background: rgba(0, 0, 0, 0.8);
  color: #fff;
  padding: 2px 6px;
  border-radius: var(--radius-sm);
  opacity: 0;
  transition: opacity var(--t-fast);
  pointer-events: none;
  text-transform: uppercase;
}

/* Sur couleur sombre : label clair pour contraster */
.swatch.is-dark .swatch-label {
  background: rgba(255, 255, 255, 0.92);
  color: #1a1a1a;
}

.swatch:hover .swatch-label {
  opacity: 1;
}

.swatch-row {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(64px, 1fr));
  gap: var(--space-xs);
}

.swatch-row--large {
  grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
  gap: var(--space-sm);
}

.swatch-row--large .swatch {
  aspect-ratio: 4 / 3;
}

.swatch-row--large .swatch-label {
  opacity: 1;
}


/* ===========================================================
   6. VARIATIONS / HARMONIES — saisie couleur
   =========================================================== */

.color-input-group {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  flex-wrap: wrap;
}

.color-input-group input[type="color"] {
  width: 40px;
  height: 40px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  cursor: pointer;
  padding: 2px;
  background: var(--color-surface);
}

.color-input-group input[type="color"]:hover {
  border-color: var(--color-border-strong);
}

.color-input-group input[type="text"] {
  font-family: var(--font-mono);
  font-size: 0.85rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  padding: var(--space-sm) var(--space-md);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  background: var(--color-surface);
  color: var(--color-text);
  width: 110px;
  text-transform: uppercase;
}

.color-input-group input[type="text"]:focus {
  outline: none;
  border-color: var(--color-text);
}

.hsl-display {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--color-text-faint);
}

.variation-block,
.harmony-block {
  margin-bottom: var(--space-lg);
}

.harmony-desc {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--color-text-faint);
  margin-bottom: var(--space-sm);
}

/* Mélangeur : se distingue visuellement des variations standards */
.mixer-block {
  margin-top: var(--space-xl);
  padding-top: var(--space-lg);
  border-top: 1px solid var(--color-border);
}

.mixer-controls {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: var(--space-md);
  margin-bottom: var(--space-md);
  padding: var(--space-md);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
}

.mixer-input {
  grid-column: span 4;
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
  min-width: 0;
}

@media (max-width: 768px) {
  .mixer-input { grid-column: span 12; }
}

.mixer-input .level-label {
  margin-bottom: 0;
}


/* ===========================================================
   7. COMPARAISON
   =========================================================== */

.comparison-actions {
  display: flex;
  gap: var(--space-sm);
}

.comparison-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: var(--space-sm);
  min-height: 280px;
}

.comparison-card {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  overflow: hidden;
  background: var(--color-surface);
  transition: border-color var(--t-fast);
}

.comparison-card:hover {
  border-color: var(--color-border-strong);
}

.comparison-swatch-wrap {
  position: relative;
}

.comparison-swatch {
  height: 160px;
  cursor: pointer;
  position: relative;
}

.comparison-swatch::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, transparent 60%, rgba(0, 0, 0, 0.1));
  pointer-events: none;
}

.comparison-swatch-wrap input[type="color"] {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  cursor: pointer;
  border: none;
}

.comparison-info {
  padding: var(--space-sm) var(--space-md) var(--space-md);
  font-family: var(--font-mono);
  font-size: 0.7rem;
  line-height: 1.6;
}

.comparison-info .hex-value {
  display: block;
  font-size: 0.95rem;
  font-weight: 700;
  color: var(--color-text);
  margin-bottom: var(--space-sm);
  cursor: pointer;
  letter-spacing: 0.03em;
}

.comparison-info .hex-value:hover {
  color: var(--color-accent);
}

.comparison-info .meta-row {
  display: flex;
  gap: var(--space-sm);
  align-items: baseline;
  padding: 1px 0;
}

.comparison-info .meta-label {
  flex: 0 0 42px;
  color: var(--color-text-faint);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-size: 0.6rem;
}

.comparison-info .meta-val {
  flex: 1;
  color: var(--color-text-soft);
  font-size: 0.7rem;
  letter-spacing: 0.02em;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.comparison-info .meta-val--name {
  font-style: italic;
  color: var(--color-text-faint);
}

.comparison-remove {
  position: absolute;
  top: var(--space-xs);
  right: var(--space-xs);
  width: 24px;
  height: 24px;
  border-radius: var(--radius-pill);
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  font-family: var(--font-mono);
  font-size: 0.9rem;
  line-height: 1;
  color: var(--color-text);
  cursor: pointer;
  opacity: 0;
  transition: opacity var(--t-fast);
  z-index: 2;
}

.comparison-card:hover .comparison-remove {
  opacity: 1;
}

.comparison-remove:hover {
  border-color: var(--color-accent);
  color: var(--color-accent);
}

.empty-state {
  grid-column: 1 / -1;
  text-align: center;
  padding: var(--space-xl) var(--space-md);
  font-family: var(--font-mono);
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--color-text-faint);
}


/* ===========================================================
   8. TOAST
   =========================================================== */

.toast {
  position: fixed;
  bottom: var(--space-lg);
  left: 50%;
  transform: translateX(-50%) translateY(20px);
  background: var(--color-text);
  color: var(--color-bg);
  padding: var(--space-sm) var(--space-md);
  border-radius: var(--radius-sm);
  font-family: var(--font-mono);
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  opacity: 0;
  transition: opacity var(--t-med), transform var(--t-med);
  pointer-events: none;
  z-index: 100;
}

.toast.is-visible {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}


/* ===========================================================
   9. PIED DE PAGE
   =========================================================== */

.rules-sources {
  margin-top: var(--space-xl);
  padding-top: var(--space-md);
  border-top: 1px solid var(--color-border);
  text-align: center;
}


/* ===========================================================
   9bis. PARSER MULTI-FORMAT (vue Comparaison)
   =========================================================== */

.color-parser {
  margin-bottom: var(--space-lg);
  padding: var(--space-md);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
}

.color-parser .level-label {
  display: block;
  margin-bottom: var(--space-sm);
}

.parser-row {
  display: flex;
  gap: var(--space-sm);
  align-items: stretch;
}

.parser-input {
  flex: 1;
  font-family: var(--font-mono);
  font-size: 0.85rem;
  padding: var(--space-sm) var(--space-md);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  background: var(--color-bg);
  color: var(--color-text);
  min-width: 0;
}

.parser-input::placeholder {
  color: var(--color-text-faint);
  font-style: italic;
}

.parser-input:focus {
  outline: none;
  border-color: var(--color-text);
}

.parser-feedback {
  margin-top: var(--space-xs);
  font-family: var(--font-mono);
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  min-height: 1.2em;
  color: var(--color-text-faint);
  transition: color var(--t-fast);
}

.parser-feedback--success {
  color: var(--color-success);  /* vert validé */
}

.parser-feedback--preview {
  color: var(--color-text-soft);
}

.parser-feedback--error {
  color: var(--color-accent);
}

[data-theme="dark"] .parser-feedback--success {
  color: #6FBC8F;
}


/* ===========================================================
   9ter. MATRICE DE CONTRASTE WCAG
   =========================================================== */

.contrast-matrix-wrap {
  margin-top: var(--space-xl);
  padding-top: var(--space-lg);
  border-top: 1px solid var(--color-border);
}

.contrast-matrix-wrap.is-hidden {
  display: none;
}

.matrix-header {
  margin-bottom: var(--space-md);
}

.matrix-scroll {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: thin;
}

.contrast-matrix {
  border-collapse: separate;
  border-spacing: 2px;
  font-family: var(--font-mono);
  width: 100%;
  min-width: 320px;
}

.contrast-matrix th,
.contrast-matrix td {
  padding: 0;
  vertical-align: middle;
  text-align: center;
}

/* Coin vide en haut à gauche */
.matrix-corner {
  width: 32px;
  height: 32px;
}

/* Têtes : petits swatches en haut et à gauche */
.matrix-head {
  width: 32px;
  height: 32px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--color-border);
}

.matrix-head--row {
  /* Têtes de ligne — même style */
}

/* Cellules de la matrice */
.matrix-cell {
  width: 96px;
  height: 64px;
  border-radius: var(--radius-sm);
  padding: var(--space-xs) var(--space-sm);
  display: table-cell;
  position: relative;
  font-weight: 700;
}

/* Pour aligner correctement le contenu dans la cellule table */
.matrix-cell .matrix-ratio,
.matrix-cell .matrix-grade {
  display: block;
  line-height: 1.2;
}

.matrix-ratio {
  font-size: 1.1rem;
  letter-spacing: 0.02em;
}

.matrix-grade {
  font-size: 0.6rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  opacity: 0.85;
  margin-top: 2px;
}

/* Diagonale (couleur sur elle-même) */
.matrix-cell--diag {
  background: transparent;
  color: var(--color-text-faint);
  font-size: 0.9rem;
  border: 1px dashed var(--color-border);
}

/* Indicateur de niveau — petit point en haut à droite */
.matrix-cell:not(.matrix-cell--diag)::before {
  content: '';
  position: absolute;
  top: 4px;
  right: 4px;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  box-shadow: 0 0 0 1px rgba(255,255,255,0.6);
}

.matrix-cell--aaa::before   { background: var(--color-success); }
.matrix-cell--aa::before    { background: #ADD036; }
.matrix-cell--large::before { background: #FBEE3B; }
.matrix-cell--fail::before  { background: var(--color-error); }

/* Niveaux : pas de couleur de fond imposée — l'aperçu vient du
   style inline (texte d'une couleur sur fond de l'autre). */
.matrix-cell--aaa,
.matrix-cell--aa,
.matrix-cell--large,
.matrix-cell--fail {
  /* placeholders */
}

/* Légende */
.matrix-legend {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-md);
  margin-top: var(--space-md);
  font-family: var(--font-mono);
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--color-text-soft);
}

.legend-item {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  white-space: nowrap;
}

@media (max-width: 700px) {
  .matrix-legend {
    flex-direction: column;
    gap: var(--space-sm);
  }
}

.legend-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  border: 1px solid var(--color-border);
}

.legend-dot--aaa  { background: var(--color-success); border-color: var(--color-success); }
.legend-dot--aa   { background: #ADD036; border-color: #ADD036; }
.legend-dot--large{ background: #FBEE3B; border-color: #d4c731; }
.legend-dot--fail { background: var(--color-error); border-color: var(--color-error); }


/* ===========================================================
   9ter. MODAL D'EXPORT
   =========================================================== */

.export-modal {
  width: min(100%, 640px);
  max-height: min(90vh, 720px);
  position: relative;
}

.export-close {
  position: absolute;
  top: var(--space-md);
  right: var(--space-md);
  width: 32px;
  height: 32px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--color-border);
  background: transparent;
  font-family: var(--font-mono);
  font-size: 1.1rem;
  line-height: 1;
  color: var(--color-text-soft);
  cursor: pointer;
  transition: border-color var(--t-fast), color var(--t-fast);
}

.export-close:hover {
  border-color: var(--color-border-strong);
  color: var(--color-text);
}

.export-palette-name {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--color-text-soft);
  margin-bottom: var(--space-lg);
}

.export-format-row {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  flex-wrap: wrap;
  margin-bottom: var(--space-md);
}

.export-format-row .level-label {
  margin-bottom: 0;
}

.export-format-row .mode-row {
  margin-bottom: 0;
}

.export-code-wrap {
  margin: 0 0 var(--space-md);
  padding: var(--space-md);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  font-family: var(--font-mono);
  font-size: 0.8rem;
  line-height: 1.6;
  color: var(--color-text);
  overflow-x: auto;
  overflow-y: auto;
  max-height: 360px;
  white-space: pre;
}

.export-code-wrap code {
  font-family: inherit;
  font-size: inherit;
  background: none;
  padding: 0;
}

/* En mode sombre, surface plus claire que le fond pour bien marquer le bloc de code */
[data-theme="dark"] .export-code-wrap {
  background: rgba(255, 255, 255, 0.03);
}


/* ===========================================================
   9quater. FAVORIS — boutons étoile et vue Favoris
   =========================================================== */

/* Bouton étoile sur les cartes de palette */
.palette-fav-btn {
  font-family: var(--font-display);
  font-size: 1rem;
  line-height: 1;
  padding: 2px 6px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--color-text-soft);
  cursor: pointer;
  transition: color var(--t-fast), border-color var(--t-fast);
}

.palette-fav-btn:hover {
  border-color: var(--color-border-strong);
  color: var(--color-text);
}

.palette-fav-btn.is-fav {
  color: var(--color-accent);
  border-color: var(--color-accent);
}

/* Bouton étoile sur les inputs couleur (Variations, Harmonies) */
.color-fav-btn {
  font-family: var(--font-display);
  font-size: 1.25rem;
  line-height: 1;
  width: 40px;
  height: 40px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  background: var(--color-surface);
  color: var(--color-text-soft);
  cursor: pointer;
  transition: color var(--t-fast), border-color var(--t-fast);
}

.color-fav-btn:hover {
  border-color: var(--color-border-strong);
  color: var(--color-text);
}

.color-fav-btn.is-fav {
  color: var(--color-accent);
  border-color: var(--color-accent);
}

/* Version compacte dans les cartes de comparaison */
.color-fav-btn--small {
  width: 26px;
  height: 26px;
  font-size: 1rem;
  padding: 0;
}

/* Ligne hex + étoile dans les cartes de comparaison */
.comparison-info .hex-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-sm);
  margin-bottom: var(--space-sm);
}


/* Vue Favoris — actions */
.favorites-actions {
  display: flex;
  gap: var(--space-sm);
  flex-wrap: wrap;
}

/* Sections (Palettes / Couleurs) */
.favorites-section {
  margin-bottom: var(--space-xl);
}

.favorites-section .block-heading {
  margin-bottom: var(--space-md);
  padding-bottom: var(--space-sm);
  border-bottom: 1px solid var(--color-border);
}

/* Grille des couleurs favorites — proche des cartes de comparaison */
.fav-colors-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: var(--space-sm);
}

.fav-color-card {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  overflow: hidden;
  background: var(--color-surface);
  transition: border-color var(--t-fast);
}

.fav-color-card:hover {
  border-color: var(--color-border-strong);
}

.fav-color-swatch {
  height: 120px;
  cursor: pointer;
  position: relative;
}

.fav-color-swatch::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, transparent 60%, rgba(0, 0, 0, 0.08));
  pointer-events: none;
}

.fav-color-remove {
  position: absolute;
  top: var(--space-xs);
  right: var(--space-xs);
  width: 24px;
  height: 24px;
  border-radius: var(--radius-pill);
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  font-family: var(--font-mono);
  font-size: 0.9rem;
  line-height: 1;
  color: var(--color-text);
  cursor: pointer;
  opacity: 0;
  transition: opacity var(--t-fast), border-color var(--t-fast), color var(--t-fast);
  z-index: 2;
}

.fav-color-card:hover .fav-color-remove {
  opacity: 1;
}

.fav-color-remove:hover {
  border-color: var(--color-accent);
  color: var(--color-accent);
}

.fav-color-info {
  padding: var(--space-sm) var(--space-md) var(--space-md);
  font-family: var(--font-mono);
  font-size: 0.7rem;
  line-height: 1.6;
}

.fav-color-info .hex-value {
  font-size: 0.95rem;
  font-weight: 700;
  color: var(--color-text);
  margin-bottom: var(--space-sm);
  cursor: pointer;
  letter-spacing: 0.03em;
}

.fav-color-info .hex-value:hover {
  color: var(--color-accent);
}

.fav-color-info .meta-row {
  display: flex;
  gap: var(--space-sm);
  align-items: baseline;
  padding: 1px 0;
}

.fav-color-info .meta-label {
  flex: 0 0 42px;
  color: var(--color-text-faint);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-size: 0.6rem;
}

.fav-color-info .meta-val {
  flex: 1;
  color: var(--color-text-soft);
  font-size: 0.7rem;
  letter-spacing: 0.02em;
}

.fav-color-info .meta-val--name {
  font-style: italic;
  color: var(--color-text-faint);
}


/* ----- Favoris : Design Systems sauvegardés ----------------------

   Carte d'aperçu d'un DS : 4 swatches en bandeau (primaire, secondaire,
   fond clair, fond sombre), nom + date en dessous, deux actions. */

.fav-ds-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: var(--space-md);
}

.fav-ds-card {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  overflow: hidden;
  background: var(--color-surface);
  transition: border-color var(--t-fast);
}

.fav-ds-card:hover {
  border-color: var(--color-border-strong);
}

/* Bandeau de 4 swatches en hauteur fixe, sans gap (look "palette nue"). */
.fav-ds-swatches {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  height: 88px;
}

.fav-ds-swatch {
  height: 100%;
}

.fav-ds-info {
  padding: var(--space-sm) var(--space-md);
  border-bottom: 1px solid var(--color-border);
}

.fav-ds-name {
  font-family: var(--font-display);
  font-size: var(--text-base);
  font-weight: 600;
  color: var(--color-text);
  line-height: 1.3;
}

.fav-ds-date {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--color-text-soft);
  margin-top: 2px;
}

.fav-ds-actions {
  display: flex;
  gap: var(--space-xs);
  padding: var(--space-sm) var(--space-md);
}


/* ===========================================================
   9sexies. ROUE CHROMATIQUE
   =========================================================== */

:root {
  --wheel-oog: #d4d0c8;  /* gris cendré pour zones hors gamut sRGB */
}

[data-theme="dark"] {
  --wheel-oog: #2a2d34;
}

.view-desc {
  font-family: var(--font-display);
  font-size: 0.9rem;
  color: var(--color-text-soft);
  margin: 0 0 var(--space-md);
  max-width: 60ch;
  line-height: 1.5;
}

.wheel-layout {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: var(--space-xl);
  align-items: start;
}

.wheel-stage {
  grid-column: span 6;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-md);
  aspect-ratio: 1 / 1;
}

.wheel-svg {
  width: 100%;
  height: 100%;
  cursor: pointer;
  touch-action: none;
  user-select: none;
  -webkit-user-select: none;
}

.wheel-svg .wheel-main-point {
  cursor: grab;
  filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.18));
}

.wheel-svg:active .wheel-main-point {
  cursor: grabbing;
}

.wheel-controls {
  grid-column: span 6;
  display: flex;
  flex-direction: column;
  gap: var(--space-lg);
  min-width: 0;
}

@media (max-width: 900px) {
  .wheel-stage,
  .wheel-controls { grid-column: span 12; }
}

.wheel-control-group {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
}

.wheel-control-group .level-label {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  margin-bottom: 0;
}

.wheel-value {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  font-weight: 700;
  color: var(--color-text);
  text-transform: none;
  letter-spacing: 0.02em;
}

.wheel-slider {
  -webkit-appearance: none;
  appearance: none;
  width: 100%;
  height: 4px;
  background: var(--color-border);
  border-radius: var(--radius-pill);
  outline: none;
  cursor: pointer;
}

.wheel-slider::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: var(--color-text);
  border: 2px solid var(--color-bg);
  cursor: grab;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
}

.wheel-slider::-webkit-slider-thumb:active {
  cursor: grabbing;
}

.wheel-slider::-moz-range-thumb {
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: var(--color-text);
  border: 2px solid var(--color-bg);
  cursor: grab;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
}

.wheel-hint {
  font-family: var(--font-mono);
  font-size: 0.65rem;
  color: var(--color-text-faint);
  font-style: italic;
  line-height: 1.5;
  margin-top: var(--space-xs);
}

/* Sur petits écrans : la roue passe au-dessus des contrôles
   (géré par span-12 ci-dessus). Centrage du SVG. */
@media (max-width: 900px) {
  .wheel-stage {
    max-width: 360px;
    margin: 0 auto;
  }
}


/* ===========================================================
   9septies. DEPUIS IMAGE
   =========================================================== */

.image-extractor {
  display: flex;
  flex-direction: column;
  gap: var(--space-lg);
}

/* Zone de dépôt */
.image-drop-zone {
  position: relative;
  border: 2px dashed var(--color-border-strong);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  transition: border-color var(--t-fast), background var(--t-fast);
  min-height: 220px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.image-drop-zone.is-dragging {
  border-color: var(--color-accent);
  background: var(--color-bg);
}

.image-drop-content {
  text-align: center;
  padding: var(--space-xl);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-sm);
}

.image-drop-text {
  font-family: var(--font-display);
  font-size: 1.1rem;
  color: var(--color-text);
  margin: 0;
}

.image-drop-hint {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--color-text-faint);
  margin: 0;
}

.image-drop-formats {
  font-family: var(--font-mono);
  font-size: 0.65rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--color-text-faint);
  margin: var(--space-sm) 0 0;
}

/* Aperçu de l'image chargée */
.image-preview-wrap {
  position: relative;
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-md);
}

.image-preview {
  max-width: 100%;
  max-height: 320px;
  border-radius: var(--radius-sm);
  display: block;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
}

.image-replace-btn {
  position: absolute;
  top: var(--space-md);
  right: var(--space-md);
  font-family: var(--font-mono);
  font-size: 0.65rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--color-text);
  background: rgba(255, 255, 255, 0.92);
  padding: var(--space-xs) var(--space-sm);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  cursor: pointer;
  backdrop-filter: blur(6px);
  transition: background var(--t-fast);
}

.image-replace-btn:hover {
  background: rgba(255, 255, 255, 1);
}

[data-theme="dark"] .image-replace-btn {
  color: var(--color-text);
  background: rgba(20, 24, 32, 0.92);
}

/* Contrôles */
.image-controls {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-lg);
  align-items: center;
  justify-content: space-between;
  padding: var(--space-md);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
}

.image-control-group {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
}

.image-control-group .level-label {
  margin-bottom: 0;
}

.image-status {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--color-text-faint);
}

/* Résultats : deux palettes */
.image-results {
  display: flex;
  flex-direction: column;
  gap: var(--space-lg);
}

.image-palette-block {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
}

.image-palette-header {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  flex-wrap: wrap;
  gap: var(--space-sm);
  margin-bottom: var(--space-xs);
}

.image-send-btn {
  flex-shrink: 0;
}


/* ===========================================================
   PROPOSITION DESIGN SYSTEM (Sprint 5A)
   Carte affichée sous les palettes extraites pour proposer un
   mapping primary/secondary/bg/tempérament et permettre la
   création du DS en un clic.
   =========================================================== */

.ds-proposal {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
  padding: var(--space-lg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  margin-top: var(--space-lg);
}

.ds-proposal-header {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  flex-wrap: wrap;
  gap: var(--space-sm);
}

.ds-proposal-source {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
}

.ds-proposal-source-label {
  font-size: var(--text-xs);
  color: var(--color-text-muted);
  margin-right: var(--space-2xs);
}

.ds-proposal-mapping {
  display: grid;
  grid-template-columns: auto 32px 1fr;
  gap: var(--space-xs) var(--space-md);
  align-items: center;
}

.ds-proposal-role {
  font-size: var(--text-sm);
  color: var(--color-text);
}

.ds-proposal-swatch {
  width: 28px;
  height: 28px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--color-border);
  flex-shrink: 0;
}

.ds-proposal-value {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  color: var(--color-text);
}

.ds-proposal-value-detail {
  font-family: var(--font-sans);
  font-size: var(--text-xs);
  color: var(--color-text-muted);
  margin-left: var(--space-xs);
}

.ds-proposal-warnings {
  display: flex;
  flex-direction: column;
  gap: var(--space-2xs, 4px);
  padding: var(--space-sm) var(--space-md);
  background: color-mix(in srgb, var(--color-warning, #B45309) 8%, transparent);
  border-left: 3px solid var(--color-warning, #B45309);
  border-radius: var(--radius-sm);
  font-size: var(--text-sm, 14px);
  color: var(--color-text);
}

.ds-proposal-warnings p {
  margin: 0;
}

.ds-proposal-actions {
  display: flex;
  gap: var(--space-sm);
  align-items: center;
}

.ds-proposal-alternates {
  margin-top: var(--space-md);
  padding-top: var(--space-md);
  border-top: 1px dashed var(--color-border);
}

.ds-proposal-alt-title {
  font-size: var(--text-sm);
  font-weight: 600;
  color: var(--color-text);
  margin: 0 0 var(--space-2xs);
}

.ds-proposal-alt-hint {
  font-size: var(--text-xs);
  color: var(--color-text-muted);
  margin: 0 0 var(--space-sm);
}

.ds-proposal-alt-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
}

.ds-proposal-alt-row {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  flex-wrap: wrap;
}

.ds-proposal-alt-swatch {
  width: 24px;
  height: 24px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--color-border);
  flex-shrink: 0;
}

.ds-proposal-alt-hex {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  color: var(--color-text);
  min-width: 80px;
}

.ds-proposal-alt-actions {
  display: flex;
  gap: var(--space-2xs);
  flex-wrap: wrap;
}


/* ===========================================================
   APERÇU D'IMPORT JSON (Sprint 7)
   Affiché quand le JSON a des warnings ou n'est pas un format
   Nuancier v1 propre. Réutilise la grammaire visuelle de
   .ds-proposal mais avec un usage transactionnel (importer/annuler)
   plutôt qu'éditable.
   =========================================================== */

.ds-import-preview {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
  padding: var(--space-lg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  margin-top: var(--space-lg);
}

.ds-import-preview-summary {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
  font-size: var(--text-sm);
  color: var(--color-text);
}

.ds-import-preview-summary-row {
  display: flex;
  gap: var(--space-sm);
  align-items: baseline;
}

.ds-import-preview-summary-label {
  font-weight: 600;
  min-width: 140px;
  flex-shrink: 0;
}

.ds-import-preview-summary-value {
  font-family: var(--font-mono);
  color: var(--color-text-muted);
}

.ds-import-preview-warnings {
  display: flex;
  flex-direction: column;
  gap: var(--space-2xs, 4px);
  padding: var(--space-sm) var(--space-md);
  background: color-mix(in srgb, var(--color-warning, #B45309) 8%, transparent);
  border-left: 3px solid var(--color-warning, #B45309);
  border-radius: var(--radius-sm);
  font-size: var(--text-sm, 14px);
  color: var(--color-text);
}

.ds-import-preview-warnings p {
  margin: 0;
}

.ds-import-preview-actions {
  display: flex;
  gap: var(--space-sm);
  align-items: center;
}


/* ===========================================================
   9octies. DEPUIS CSS
   Réutilise au max les styles de la vue Image (.image-drop-zone, etc.)
   =========================================================== */

.css-extractor {
  display: flex;
  flex-direction: column;
  gap: var(--space-lg);
}

/* Le bloc loaded — affiche le nom du fichier et les stats */
.css-loaded-wrap {
  width: 100%;
  padding: var(--space-md) var(--space-lg);
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
}

.css-loaded-info {
  text-align: center;
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
}

.css-loaded-name {
  font-family: var(--font-mono);
  font-size: 0.9rem;
  font-weight: 700;
  color: var(--color-text);
  word-break: break-all;
}

.css-loaded-stats {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--color-text-faint);
}

/* code inline dans la description de la vue */
.view-desc code {
  font-family: var(--font-mono);
  font-size: 0.85em;
  background: var(--color-surface);
  padding: 1px 5px;
  border-radius: 3px;
  border: 1px solid var(--color-border);
  color: var(--color-text);
}


/* ===========================================================
   9quinquies. GÉNÉRATEUR PLEIN ÉCRAN
   =========================================================== */

/* La vue elle-même : par défaut elle vit dans .app comme les autres,
   mais quand le body a la classe d'activation, on la prend en plein écran */
.view-generator {
  display: none;
}

.view-generator.is-active {
  display: flex;
  flex-direction: column;
}

/* Mode plein écran : cache l'interface du site, libère toute la fenêtre */
body.generator-fullscreen-active .header,
body.generator-fullscreen-active .tabs-row,
body.generator-fullscreen-active .rules-sources {
  display: none !important;
}

body.generator-fullscreen-active .app {
  padding: 0;
  max-width: none;
  height: 100vh;
  height: 100dvh;
  min-height: 0;
}

body.generator-fullscreen-active main {
  flex: 1;
  display: flex;
  min-height: 0;
}

body.generator-fullscreen-active .view-generator.is-active {
  flex: 1;
  position: relative;
  height: 100vh;
  height: 100dvh;
}

/* La scène : 5 colonnes côte à côte qui remplissent l'espace */
.generator-stage {
  flex: 1;
  display: flex;
  flex-direction: row;
  height: 100%;
  outline: none;
}

.gen-col {
  flex: 1;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: flex-grow 0.25s ease;
  cursor: default;
  min-width: 0;
}

.gen-col:hover {
  flex-grow: 1.05;
}

/* Centre les infos et actions de chaque colonne */
.gen-col-inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-lg);
  padding: var(--space-md);
  opacity: 0.7;
  transition: opacity var(--t-fast);
}

.gen-col:hover .gen-col-inner {
  opacity: 1;
}

/* Code hex au centre de la colonne — gros et lisible */
.gen-col-hex {
  font-family: var(--font-mono);
  font-size: 1.4rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  cursor: pointer;
  color: #1a1a1a;
  user-select: all;
  padding: var(--space-xs) var(--space-sm);
  border-radius: var(--radius-sm);
  transition: background var(--t-fast);
}

.gen-col.is-dark .gen-col-hex {
  color: #f5f5f5;
}

.gen-col-hex:hover {
  background: rgba(255, 255, 255, 0.2);
}

.gen-col.is-dark .gen-col-hex:hover {
  background: rgba(0, 0, 0, 0.25);
}

/* Boutons d'action sous le hex — verrou et favori */
.gen-col-actions {
  display: flex;
  gap: var(--space-sm);
}

.gen-col-btn {
  width: 38px;
  height: 38px;
  border-radius: var(--radius-pill);
  border: 1.5px solid rgba(26, 26, 26, 0.3);
  background: transparent;
  font-family: var(--font-display);
  font-size: 1rem;
  line-height: 1;
  color: #1a1a1a;
  cursor: pointer;
  transition: all var(--t-fast);
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.gen-col-btn:hover {
  background: rgba(255, 255, 255, 0.4);
}

.gen-col.is-dark .gen-col-btn {
  border-color: rgba(245, 245, 245, 0.4);
  color: #f5f5f5;
}

.gen-col.is-dark .gen-col-btn:hover {
  background: rgba(0, 0, 0, 0.3);
}

/* État verrouillé : bouton plein, plus visible */
.gen-col-btn.is-locked {
  background: rgba(26, 26, 26, 0.85);
  color: #f5f5f5;
  border-color: rgba(26, 26, 26, 0.85);
}

.gen-col.is-dark .gen-col-btn.is-locked {
  background: rgba(245, 245, 245, 0.9);
  color: #1a1a1a;
  border-color: rgba(245, 245, 245, 0.9);
}

/* Favori actif : étoile rouge brique */
.gen-col-btn.is-fav {
  color: var(--color-accent);
  border-color: var(--color-accent);
}

/* Barre de contrôles flottante en bas */
.generator-controls {
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: var(--space-md) var(--space-lg);
  gap: var(--space-md);
  background: linear-gradient(180deg, transparent, rgba(0, 0, 0, 0.18));
  pointer-events: none;
  z-index: 10;
}

.generator-controls > * {
  pointer-events: auto;
}

.generator-exit-btn {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: #1a1a1a;
  background: rgba(255, 255, 255, 0.85);
  padding: var(--space-sm) var(--space-md);
  border: 1px solid rgba(26, 26, 26, 0.15);
  border-radius: var(--radius-sm);
  cursor: pointer;
  backdrop-filter: blur(6px);
  transition: background var(--t-fast);
}

.generator-exit-btn:hover {
  background: rgba(255, 255, 255, 0.95);
}

.generator-hint {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: #1a1a1a;
  background: rgba(255, 255, 255, 0.75);
  padding: var(--space-sm) var(--space-md);
  border-radius: var(--radius-sm);
  backdrop-filter: blur(6px);
  white-space: nowrap;
}

.generator-hint kbd {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  background: rgba(26, 26, 26, 0.85);
  color: #f5f5f5;
  padding: 1px 6px;
  border-radius: 3px;
  margin: 0 2px;
  font-weight: 700;
}

.generator-actions {
  display: flex;
  gap: var(--space-sm);
}

.generator-actions .btn-ghost {
  background: rgba(255, 255, 255, 0.85);
  color: #1a1a1a;
  backdrop-filter: blur(6px);
  border-color: rgba(26, 26, 26, 0.15);
}

.generator-actions .btn-ghost:hover {
  background: rgba(255, 255, 255, 0.95);
  color: #1a1a1a;
}

/* Par défaut : label complet visible, label court caché (inversé en mobile) */
#generator-save .label-full  { display: inline; }
#generator-save .label-short { display: none; }

/* Sur petits écrans : colonnes deviennent rangées, contrôles en haut */
@media (max-width: 700px) {
  .generator-stage {
    flex-direction: column;
  }

  .gen-col {
    flex: 1;
    min-height: 0;
  }

  .gen-col-inner {
    flex-direction: row;
    gap: var(--space-md);
    opacity: 1;
  }

  .gen-col-hex {
    font-size: 1.1rem;
  }

  /* Contrôles en haut sur mobile (sinon ils chevauchent les couleurs en bas) */
  .generator-controls {
    top: 0;
    bottom: auto;
    flex-wrap: wrap;
    gap: var(--space-sm);
    padding: var(--space-sm);
    background: linear-gradient(180deg, rgba(0, 0, 0, 0.18), transparent);
  }

  .generator-hint {
    display: none; /* pas de clavier sur mobile, raccourcis inutiles */
  }

  /* Étiquette plus courte du bouton Sauvegarder sur mobile */
  #generator-save .label-full { display: none; }
  #generator-save .label-short { display: inline; }
}


/* ===========================================================
   10. RESPONSIVE
   =========================================================== */

@media (max-width: 700px) {
  .view-header {
    flex-direction: column;
    align-items: stretch;
  }

  .swatch-row {
    grid-template-columns: repeat(auto-fill, minmax(52px, 1fr));
  }

  .swatch-row--large {
    grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
  }

  .palette-swatches {
    grid-template-columns: repeat(auto-fill, minmax(56px, 1fr));
  }
}


/* ===========================================================
   FICHE COULEUR — drawer latéral (desktop) / plein écran (mobile)
   =========================================================== */

.color-card-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0);
  pointer-events: none;
  transition: background var(--t-base);
  z-index: 90;
}

.color-card-backdrop:not(.hidden) {
  pointer-events: auto;
}

.color-card {
  position: fixed;
  top: 0;
  right: 0;
  width: 380px;
  max-width: 100vw;
  height: 100vh;
  background: var(--color-bg);
  border-left: 1px solid var(--color-border);
  box-shadow: -8px 0 24px rgba(0, 0, 0, 0.06);
  display: flex;
  flex-direction: column;
  transform: translateX(100%);
  transition: transform var(--t-base);
  z-index: 100;
  overflow-y: auto;
}

.color-card:not(.hidden) {
  transform: translateX(0);
}

.color-card.hidden {
  pointer-events: none;
}

.color-card-header {
  display: flex;
  justify-content: flex-end;
  padding: var(--space-sm) var(--space-md);
}

.color-card-close {
  background: none;
  border: none;
  font-size: 1.6rem;
  line-height: 1;
  color: var(--color-text);
  cursor: pointer;
  padding: 4px 10px;
  border-radius: var(--radius-sm);
  transition: background var(--t-fast);
}

.color-card-close:hover {
  background: var(--color-surface);
}

.color-card-swatch {
  width: 100%;
  height: 200px;
  flex-shrink: 0;
}

.color-card-body {
  padding: var(--space-lg) var(--space-md) var(--space-xl);
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
}

.cc-hex-block {
  text-align: center;
}

.cc-hex-title {
  font-family: var(--font-mono);
  font-size: 1.5rem;
  font-weight: 700;
  margin: 0;
  letter-spacing: 0.02em;
  color: var(--color-text);
}

.cc-css-name {
  font-family: var(--font-mono);
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--color-text-faint);
  margin: var(--space-xs) 0 0;
}

.cc-actions-primary {
  display: flex;
  gap: var(--space-sm);
  align-items: center;
}

.cc-btn-copy {
  flex: 1;
  padding: var(--space-sm) var(--space-md);
  font-size: 0.85rem;
}

.cc-fav-btn {
  width: 44px;
  height: 44px;
  flex-shrink: 0;
  font-size: 1.2rem;
}

.cc-formats {
  display: flex;
  flex-direction: column;
  gap: 1px;
  background: var(--color-border);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  overflow: hidden;
}

.cc-format-row {
  display: grid;
  grid-template-columns: 80px 1fr auto;
  align-items: center;
  gap: var(--space-sm);
  padding: var(--space-sm) var(--space-md);
  background: var(--color-bg);
}

.cc-format-label {
  font-family: var(--font-mono);
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--color-text-faint);
}

.cc-format-value {
  font-family: var(--font-mono);
  font-size: 0.8rem;
  color: var(--color-text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.cc-format-copy {
  background: none;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  width: 28px;
  height: 28px;
  cursor: pointer;
  font-size: 0.9rem;
  color: var(--color-text-faint);
  transition: all var(--t-fast);
  padding: 0;
}

.cc-format-copy:hover {
  border-color: var(--color-text);
  color: var(--color-text);
}

.cc-actions-secondary {
  display: flex;
  gap: var(--space-sm);
}

.cc-actions-secondary .btn-ghost {
  flex: 1;
  font-size: 0.75rem;
  padding: var(--space-sm);
}

/* Mode plein écran sur mobile : la fiche prend toute la place */
@media (max-width: 700px) {
  .color-card {
    width: 100vw;
    max-width: 100vw;
    border-left: none;
    box-shadow: none;
  }

  .color-card-swatch {
    height: 240px;
  }

  /* Sur mobile on remplace le × par une flèche retour à gauche */
  .color-card-header {
    justify-content: flex-start;
    padding: var(--space-md);
    border-bottom: 1px solid var(--color-border);
  }

  .color-card-close::before {
    content: '← Retour';
    font-family: var(--font-mono);
    font-size: 0.8rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
  }

  .color-card-close {
    font-size: 0;  /* cache le × original */
    padding: var(--space-xs) var(--space-sm);
  }
}


/* ============================================================
   DESIGN SYSTEM — vue dédiée

   Toutes les classes sont préfixées `.ds-` (ou `#ds-` pour les IDs).

   Ce bloc consomme massivement le DS partagé du projet (games.css) :
   - tokens : --space-*, --color-*, --radius-*, --font-*, --t-*
   - composants : .btn, .btn-ghost, .btn-small (utilisés directement
                  dans le HTML généré par le JS, pas redéfinis ici)

   Les classes définies ci-dessous ne couvrent que ce qui est
   spécifique au module (grille de primitifs, panneau a11y, aperçu
   isolé, etc.) et n'a pas d'équivalent dans games.css.

   Code JS : dossier ds/
   ============================================================ */

/* ----- Utilitaires de mise en page des zones de contrôles ------
   Règle universelle des sous-modules DS :
   - Les SELECTS (menus déroulants) vont sur une ligne en haut,
     3 max par ligne. Au-delà, deux lignes en regroupant par sens.
   - Les autres contrôles (sliders, inputs, radios) sont empilés
     en dessous.

   Usage :
     <div class="ds-controls-row">    <!-- 3 selects max -->
       <div class="ds-control-group">...</div>
       <div class="ds-control-group">...</div>
       <div class="ds-control-group">...</div>
     </div>
     <div class="ds-controls-stack">  <!-- le reste -->
       <div class="ds-control-group">...slider...</div>
     </div>

   Une cellule isolée occupe 1/3 (cohérence universelle), pas la
   pleine largeur — c'est volontaire pour qu'on retrouve toujours
   le même alignement de la 1ère colonne entre sous-modules. */

.ds-controls-row {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-md) var(--space-lg);
}

.ds-controls-row + .ds-controls-row {
  margin-top: var(--space-md);
}

.ds-controls-stack {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
  margin-top: var(--space-lg);
}

/* Sous tablette, les selects empilent. */
@media (max-width: 768px) {
  .ds-controls-row {
    grid-template-columns: 1fr;
  }
}


/* ----- Zone A : contrôles d'entrée -----------------------------
   Grille 12 colonnes : 3 sections symétriques de marque.
   - Couleurs de marque (Primaire + Secondaire)   → span 4
   - Mode clair (Fond + Tempérament des neutres)  → span 4
   - Mode sombre (Fond + Texte, toujours déplié)  → span 4
   Les actions globales (toggle Aperçu Clair/Sombre, bouton Favoris)
   sont dans la zone CM, séparée et placée AVANT C1 (tokens
   sémantiques) puisque c'est elle qui pilote ce qu'on y voit. */

.ds-controls {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: var(--space-lg);
  padding: var(--space-lg) 0;
  border-top: 1px solid var(--color-border);
  border-bottom: 1px solid var(--color-border);
  margin-bottom: var(--space-lg);
}

/* Fieldsets thématiques. On garde fieldset/legend pour l'accessibilité,
   mais sans bordure visible. */
.ds-control-section {
  grid-column: span 4;
  border: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
  min-width: 0;
}

@media (max-width: 1100px) {
  .ds-control-section { grid-column: span 6; }
}
@media (max-width: 768px) {
  .ds-control-section { grid-column: span 12; }
}

/* Titre de section : reste reconnaissable en caps mais lisible */
.ds-control-section-title {
  display: block;
  font-family: var(--font-display);
  font-size: var(--text-sm);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--color-text-soft);
  padding: 0 0 var(--space-xs) 0;
  border-bottom: 1px solid var(--color-border);
}

/* Groupe label + contrôle */
.ds-control-group {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
}

/* Label d'un input — lisible, contraste plein, casse normale */
.ds-control-label {
  font-family: var(--font-display);
  font-size: var(--text-base);
  font-weight: 600;
  color: var(--color-text);
  line-height: 1.4;
}

/* Hint sous un contrôle — discret mais lisible (AA) */
.ds-control-hint {
  font-family: var(--font-display);
  font-size: var(--text-sm);
  color: var(--color-text-soft);
  line-height: 1.5;
}

/* Ligne horizontale dans un groupe : color-picker + hex + auto */
.ds-control-row {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
}

/* ----- Inputs spécifiques ---------------------------------------
   On ne style que ce qui n'existe pas dans games.css : le color picker
   natif et le champ hex monospace. Les boutons standard utilisent .btn,
   .btn-ghost, .btn-small directement dans le HTML. */

.ds-color-input {
  width: 32px;
  height: 32px;
  padding: 0;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  background: transparent;
  cursor: pointer;
  flex-shrink: 0;
}
.ds-color-input::-webkit-color-swatch-wrapper { padding: 2px; }
.ds-color-input::-webkit-color-swatch { border: none; border-radius: 2px; }
.ds-color-input:disabled { cursor: not-allowed; opacity: 0.5; }

.ds-hex-input {
  flex: 1;
  min-width: 0;
  font-family: var(--font-mono);
  font-size: var(--text-base);
  padding: var(--space-xs) var(--space-sm);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--color-text);
  transition: border-color var(--t-fast);
}
.ds-hex-input:focus {
  outline: none;
  border-color: var(--color-text);
}
.ds-hex-input:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/* Checkbox + label inline, cohérent avec .controls-hint */
.ds-checkbox-label {
  display: inline-flex;
  align-items: center;
  gap: var(--space-xs);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--color-text-soft);
  cursor: pointer;
  user-select: none;
}
.ds-checkbox-label input[type="checkbox"] {
  margin: 0;
  cursor: pointer;
}

/* Select natif stylé sobrement, cohérent avec les hex inputs */
.ds-select {
  font-family: var(--font-display);
  font-size: var(--text-base);
  padding: var(--space-xs) var(--space-sm);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--color-text);
  cursor: pointer;
  transition: border-color var(--t-fast);
  flex: 1;
  min-width: 0;
}
.ds-select:focus {
  outline: none;
  border-color: var(--color-text);
}

/* Segmented control Clair/Sombre — style cohérent avec .mode-toggle.
   Un seul fond, deux états (actif / inactif). */
.ds-segmented {
  display: inline-flex;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  overflow: hidden;
}
.ds-segmented-btn {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  padding: var(--space-xs) var(--space-md);
  background: transparent;
  color: var(--color-text-soft);
  border: none;
  cursor: pointer;
  transition: background-color var(--t-fast), color var(--t-fast);
}
.ds-segmented-btn:not(:last-child) {
  border-right: 1px solid var(--color-border);
}
.ds-segmented-btn:hover {
  color: var(--color-text);
}
.ds-segmented-btn.is-active {
  background: var(--color-text);
  color: var(--color-bg);
}


/* ----- Zone CM : actions globales (Aperçu / Favoris / Exporter) -----

   Ligne horizontale entre tokens sémantiques (C1) et a11y/preview.
   Le segmented à gauche, les deux boutons à droite, avec un espace
   souple entre. Sur mobile, l'ensemble passe en wrap naturel. */

.ds-actions {
  display: flex;
  align-items: center;
  gap: var(--space-md);
  padding: var(--space-md) 0;
  border-top: 1px solid var(--color-border);
  border-bottom: 1px solid var(--color-border);
  margin: var(--space-lg) 0;
  flex-wrap: wrap;
}

.ds-actions-group {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
}

.ds-actions-label {
  font-family: var(--font-display);
  font-size: var(--text-sm);
  font-weight: 500;
  color: var(--color-text-soft);
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

/* Spacer flex qui pousse les boutons à droite tant qu'il y a la place,
   et se réduit à 0 quand l'ensemble doit wrapper. */
.ds-actions-spacer {
  flex: 1 1 auto;
  min-width: var(--space-md);
}

.ds-fav-star {
  display: inline-block;
  margin-right: 0.25em;
  color: var(--color-text-soft);
}


/* ----- Zone B : grille des primitifs (7 familles × 11 paliers) ----- */

.ds-primitives {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
  margin-bottom: var(--space-xl);
}

.ds-scale-row {
  display: grid;
  grid-template-columns: 80px repeat(11, 1fr);
  gap: 2px;
  align-items: stretch;
}

.ds-scale-step-label {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--color-text-faint);
  text-align: center;
  padding: var(--space-xs) 0;
}

.ds-scale-label {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  color: var(--color-text);
  display: flex;
  align-items: center;
  padding-right: var(--space-sm);
}

.ds-swatch {
  aspect-ratio: 1;
  border-radius: var(--radius-sm);
  cursor: pointer;
  position: relative;
  display: flex;
  align-items: flex-end;
  justify-content: center;
  padding: 4px;
  transition: transform var(--t-fast);
}
.ds-swatch:hover {
  transform: scale(1.05);
  z-index: 1;
}

.ds-swatch-hex {
  font-family: var(--font-mono);
  font-size: 0.55rem;
  color: rgba(255, 255, 255, 0.85);
  text-shadow: 0 1px 1px rgba(0, 0, 0, 0.5);
  opacity: 0;
  transition: opacity var(--t-fast);
}
.ds-swatch:hover .ds-swatch-hex {
  opacity: 1;
}
.ds-swatch.is-dark-bg .ds-swatch-hex {
  color: rgba(255, 255, 255, 0.85);
}
.ds-swatch.is-light-bg .ds-swatch-hex {
  color: rgba(0, 0, 0, 0.7);
  text-shadow: none;
}


/* ----- Zone C1 : tokens sémantiques ----- */

.ds-semantics {
  margin-bottom: var(--space-xl);
}

.ds-block-heading {
  font-family: var(--font-display);
  font-size: 1.25rem;
  font-weight: 500;
  margin-bottom: var(--space-md);
}

.ds-semantics-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: var(--space-lg);
}

.ds-sem-category {
  display: flex;
  flex-direction: column;
}

.ds-sem-cat-title {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--color-text-faint);
  margin-bottom: var(--space-sm);
  padding-bottom: var(--space-xs);
  border-bottom: 1px solid var(--color-border);
}

.ds-sem-row {
  display: grid;
  grid-template-columns: 24px 1fr auto auto;
  gap: var(--space-sm);
  align-items: center;
  padding: var(--space-xs) 0;
  font-family: var(--font-mono);
  font-size: var(--text-sm);
}

.ds-sem-swatch {
  width: 20px;
  height: 20px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--color-border);
}
.ds-sem-swatch.has-alpha {
  background-image:
    linear-gradient(45deg, #ccc 25%, transparent 25%),
    linear-gradient(-45deg, #ccc 25%, transparent 25%),
    linear-gradient(45deg, transparent 75%, #ccc 75%),
    linear-gradient(-45deg, transparent 75%, #ccc 75%);
  background-size: 8px 8px;
  background-position: 0 0, 0 4px, 4px -4px, -4px 0;
}

.ds-sem-name {
  color: var(--color-text);
}

.ds-sem-ref {
  color: var(--color-text-soft);
  font-size: var(--text-xs);
}

/* Badge WCAG : AA / AAA / fail */
.ds-sem-badge {
  font-family: var(--font-mono);
  font-size: 0.6rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  padding: 2px 6px;
  border-radius: var(--radius-sm);
  font-weight: 600;
}
.ds-sem-badge.is-aa {
  background: color-mix(in srgb, var(--color-success) 15%, transparent);
  color: var(--color-success);
}
.ds-sem-badge.is-aaa {
  background: color-mix(in srgb, var(--color-success) 20%, transparent);
  color: var(--color-success);
}
.ds-sem-badge.is-fail {
  background: color-mix(in srgb, var(--color-error) 15%, transparent);
  color: var(--color-error);
}


/* ----- Zone C2 : aperçu visuel isolé ----- */
/* Les couleurs sont injectées en CSS variables --dsp-* en inline
   sur le conteneur. La zone est totalement isolée du thème courant. */

.ds-preview-mode-label {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--color-text-faint);
  margin-bottom: var(--space-sm);
}

.ds-preview-frame {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  overflow: hidden;
  margin-bottom: var(--space-xl);
}

.ds-preview-page {
  padding: var(--space-lg) var(--space-xl);
  background: var(--dsp-bg-page);
  color: var(--dsp-text-default);
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
  font-family: var(--font-display);
}

.ds-preview-header {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
}

.ds-preview-h1 {
  font-size: 1.75rem;
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: 1.2;
  color: var(--dsp-text-default);
}

.ds-preview-lead {
  font-size: 0.9375rem;
  line-height: 1.6;
  color: var(--dsp-text-muted);
}

.ds-preview-card {
  background: var(--dsp-bg-surface);
  border: 1px solid var(--dsp-border-default);
  border-radius: var(--radius-md);
  padding: var(--space-md);
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
}

.ds-preview-h2 {
  font-size: var(--text-md);
  font-weight: 600;
  color: var(--dsp-text-default);
}

.ds-preview-body {
  font-size: var(--text-base);
  line-height: 1.6;
  color: var(--dsp-text-muted);
}

.ds-preview-muted {
  font-size: 0.8125rem;
  color: var(--dsp-text-subtle);
}

.ds-preview-link {
  color: var(--dsp-text-link);
  text-decoration: underline;
  text-decoration-color: var(--dsp-border-default);
}

.ds-preview-actions {
  display: flex;
  gap: var(--space-sm);
  flex-wrap: wrap;
}

/* Boutons d'aperçu isolés — ils ne peuvent pas hériter de .btn parce
   que les couleurs viennent des --dsp-* (couleurs du DS généré).
   On reproduit la structure (taille/typo) mais avec les vars locales. */
.ds-preview-btn {
  font-family: var(--font-display);
  font-size: var(--text-base);
  font-weight: 500;
  padding: var(--space-xs) var(--space-md);
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: background-color var(--t-fast);
}
.ds-preview-btn--primary {
  background: var(--dsp-primary);
  color: var(--dsp-text-on-primary);
  border-color: var(--dsp-primary);
}
.ds-preview-btn--primary:hover { background: var(--dsp-primary-hover); }
.ds-preview-btn--primary:active { background: var(--dsp-primary-active); }
.ds-preview-btn--secondary {
  background: transparent;
  color: var(--dsp-secondary);
  border-color: var(--dsp-secondary);
}
.ds-preview-btn--secondary:hover {
  background: var(--dsp-secondary);
  color: var(--dsp-text-on-secondary);
}
.ds-preview-btn--ghost {
  background: transparent;
  color: var(--dsp-text-default);
}
.ds-preview-btn--ghost:hover {
  background: var(--dsp-bg-muted);
}
.ds-preview-btn:focus-visible {
  outline: 2px solid var(--dsp-border-focus);
  outline-offset: 2px;
}

/* Champ de saisie dans l'aperçu */
.ds-preview-input-row {
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.ds-preview-input-label {
  font-size: var(--text-sm);
  color: var(--dsp-text-muted);
}
.ds-preview-input {
  font-family: inherit;
  font-size: var(--text-base);
  padding: var(--space-xs) var(--space-sm);
  background: var(--dsp-bg-surface);
  border: 1px solid var(--dsp-border-default);
  border-radius: var(--radius-sm);
  color: var(--dsp-text-default);
}
.ds-preview-input:focus {
  outline: none;
  border-color: var(--dsp-border-focus);
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--dsp-border-focus) 30%, transparent);
}

/* Chips d'état — un seul bloc partagé, mapping data-state vers vars */
.ds-preview-states {
  display: flex;
  gap: var(--space-xs);
  flex-wrap: wrap;
}
.ds-preview-chip {
  font-size: var(--text-sm);
  font-weight: 500;
  padding: 4px 10px;
  border-radius: var(--radius-pill);
  border: 1px solid var(--dsp-chip-color, transparent);
  background: var(--dsp-chip-bg, transparent);
  color: var(--dsp-chip-color, currentColor);
}
.ds-preview-chip[data-state="success"] { --dsp-chip-color: var(--dsp-success); --dsp-chip-bg: var(--dsp-success-subtle); }
.ds-preview-chip[data-state="warning"] { --dsp-chip-color: var(--dsp-warning); --dsp-chip-bg: var(--dsp-warning-subtle); }
.ds-preview-chip[data-state="error"]   { --dsp-chip-color: var(--dsp-error);   --dsp-chip-bg: var(--dsp-error-subtle); }
.ds-preview-chip[data-state="info"]    { --dsp-chip-color: var(--dsp-info);    --dsp-chip-bg: var(--dsp-info-subtle); }

/* Stack de surfaces */
.ds-preview-stack {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-sm);
}
.ds-preview-stack-item {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
}
.ds-preview-stack-label {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--dsp-text-subtle);
}
.ds-preview-elevated,
.ds-preview-subtle {
  padding: var(--space-md);
  border-radius: var(--radius-sm);
  border: 1px solid var(--dsp-border-default);
  font-size: 0.8125rem;
  color: var(--dsp-text-muted);
}
.ds-preview-elevated { background: var(--dsp-bg-elevated); }
.ds-preview-subtle   { background: var(--dsp-bg-subtle); }


/* ----- Zone C3 : panneau accessibilité ----- */

.ds-a11y {
  margin-bottom: var(--space-xl);
  padding-top: var(--space-lg);
  border-top: 1px solid var(--color-border);
}

.ds-a11y-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-md);
  flex-wrap: wrap;
  margin-bottom: var(--space-md);
}

.ds-a11y-header-actions {
  display: flex;
  gap: var(--space-sm);
  flex-wrap: wrap;
}

.ds-a11y-summary {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  color: var(--color-text-soft);
  margin-bottom: var(--space-md);
}

.ds-a11y-allgood {
  font-family: var(--font-mono);
  font-size: 0.8125rem;
  padding: var(--space-md);
  background: color-mix(in srgb, var(--color-success) 8%, transparent);
  border: 1px solid color-mix(in srgb, var(--color-success) 25%, transparent);
  border-radius: var(--radius-sm);
  color: var(--color-text);
}
[data-theme="dark"] .ds-a11y-allgood {
  background: color-mix(in srgb, var(--color-success) 10%, transparent);
  border-color: color-mix(in srgb, var(--color-success) 30%, transparent);
}

.ds-a11y-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
}

.ds-a11y-item {
  display: grid;
  grid-template-columns: 1fr auto;
  grid-template-areas:
    "line action"
    "swatches action";
  gap: var(--space-xs) var(--space-md);
  align-items: center;
  padding: var(--space-md);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
}

.ds-a11y-line {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  flex-wrap: wrap;
  font-family: var(--font-mono);
  font-size: var(--text-sm);
}
.ds-a11y-line:first-of-type { grid-area: line; }
.ds-a11y-line--swatches { grid-area: swatches; }

.ds-a11y-fg, .ds-a11y-bg, .ds-a11y-hex {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  color: var(--color-text);
}
.ds-a11y-on {
  color: var(--color-text-soft);
}
.ds-a11y-level {
  font-family: var(--font-mono);
  font-size: 0.6rem;
  letter-spacing: 0.05em;
  padding: 1px 5px;
  border-radius: 2px;
  font-weight: 600;
  background: color-mix(in srgb, var(--color-error) 15%, transparent);
  color: var(--color-error);
}

.ds-a11y-swatch {
  display: inline-block;
  width: 18px;
  height: 18px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--color-border);
}

.ds-a11y-ratio {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  font-weight: 600;
}
.ds-a11y-ratio.is-fail { color: var(--color-error); }
.ds-a11y-ratio.is-ok   { color: var(--color-success); }

.ds-a11y-arrow {
  color: var(--color-text-faint);
  margin: 0 var(--space-xs);
}
.ds-a11y-target {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--color-text-faint);
}

.ds-a11y-actions {
  grid-area: action;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: var(--space-xs);
}

.ds-a11y-hint {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  font-style: italic;
  color: var(--color-text-faint);
  text-align: right;
  max-width: 200px;
}


/* ----- Responsive ----- */

@media (max-width: 880px) {
  .ds-scale-row {
    grid-template-columns: 60px repeat(11, 1fr);
  }
  .ds-a11y-item {
    grid-template-columns: 1fr;
    grid-template-areas: "line" "swatches" "action";
  }
  .ds-a11y-actions { align-items: flex-start; }
  .ds-a11y-hint { text-align: left; max-width: none; }
}


/* ===========================================================
   DESIGN SYSTEM — Sous-module ESPACEMENTS (A2)

   Préfixe .ds-spacing-* pour éviter toute collision avec le
   sous-module Couleurs (.ds-*).
   =========================================================== */

#sub-ds-spacing {
  display: none;
}
#sub-ds-spacing.is-active {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: var(--space-lg) var(--space-md);
  padding-top: var(--space-md);
}

/* ----- Zone SA : contrôles ----- */

/* Le container occupe toute la ligne ; sa structure interne
   est gérée par les utilitaires .ds-controls-row à l'intérieur
   du <fieldset>. */
.ds-spacing-controls {
  grid-column: span 12;
}

/* ----- Zone SB : visualisation de l'échelle ----- */

.ds-spacing-scale {
  grid-column: span 12;
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
  background: var(--color-surface);
  padding: var(--space-md);
  border-radius: 8px;
  border: 1px solid var(--color-border);
}

.ds-spacing-row {
  display: grid;
  grid-template-columns: 72px 1fr 96px;
  align-items: center;
  gap: var(--space-md);
  min-height: 28px;
}

.ds-spacing-row-label {
  font-family: var(--font-mono);
  font-size: var(--text-md);
  color: var(--color-text-soft);
  text-align: right;
}

.ds-spacing-row-bar-wrap {
  display: flex;
  align-items: center;
  height: 16px;
}
.ds-spacing-row-bar {
  height: 100%;
  background: var(--color-accent);
  border-radius: 2px;
  min-width: 2px;
  /* Transition douce lors d'un changement de baseUnit ou de rythme. */
  transition: width 120ms ease-out;
}

.ds-spacing-row-value {
  font-family: var(--font-mono);
  font-size: var(--text-md);
  color: var(--color-text);
  text-align: left;
}

/* ----- Responsive ----- */

@media (max-width: 600px) {
  .ds-spacing-row {
    grid-template-columns: 48px 1fr 64px;
    gap: var(--space-sm);
  }
}


/* ===========================================================
   DESIGN SYSTEM — Spacing : aperçu en contexte (Zone SC)

   Toutes les saynètes consomment --dsp-space-*, injectées sur
   #ds-spacing-preview par dsSpacingRenderPreview().

   On reste en gamme neutre (gris/surfaces) : on est sur l'onglet
   Espacements, pas Couleurs. Les "espaces" doivent être lisibles
   sans que les saynètes elles-mêmes attirent l'œil par leurs
   couleurs.
   =========================================================== */

.ds-spacing-preview {
  grid-column: span 12;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: 8px;
  padding: var(--space-md);
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
}

.ds-spacing-preview-label {
  font-size: var(--text-md);
  font-weight: 600;
  color: var(--color-text-soft);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.ds-spacing-preview-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: var(--space-md);
}

.ds-spacing-preview-card {
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: 6px;
  padding: var(--space-md);
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
}

.ds-spacing-preview-caption {
  font-family: var(--font-mono);
  font-size: var(--text-base);
  color: var(--color-text-faint);
}


/* ----- Saynète 1 : Dense (formulaire) ----- */

/*
   Les "espaces de la maquette" utilisent --dsp-space-* (variables
   injectées). Les "rendus visuels" (couleurs, traits, hauteurs)
   utilisent --color-* / --text-* / px en dur — ce n'est pas l'objet
   de cette zone.

   Pour qu'on VOIE l'espace md (par exemple), il faut que les
   éléments adjacents aient un contraste visuel. D'où l'usage de
   surfaces gris clair pour les inputs et les blocs.
*/
.dsp-form {
  display: flex;
  flex-direction: column;
  gap: var(--dsp-space-sm);
}
.dsp-form-row {
  display: flex;
  align-items: center;
  gap: var(--dsp-space-md);
  /* Padding visualise sm = padding interne de ligne */
  padding: var(--dsp-space-xs) 0;
}
.dsp-form-label {
  flex: 0 0 80px;
  font-size: var(--text-md);
  color: var(--color-text-soft);
}
.dsp-form-input {
  flex: 1;
  height: 24px;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: 3px;
}
.dsp-form-actions {
  display: flex;
  justify-content: flex-end;
  gap: var(--dsp-space-sm);
  margin-top: var(--dsp-space-md);
}


/* ----- Saynète 2 : Carte (composant) ----- */

.dsp-card {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: 4px;
  /* Le padding du composant utilise md/lg : ce sont les paliers
     les plus structurants pour les cartes. */
  padding: var(--dsp-space-lg);
  display: flex;
  flex-direction: column;
  gap: var(--dsp-space-md);
}
.dsp-card-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  /* Padding bottom + bordure pour matérialiser la séparation entête/corps */
  padding-bottom: var(--dsp-space-sm);
  border-bottom: 1px solid var(--color-border);
}
.dsp-card-title {
  width: 50%;
  height: 12px;
  background: var(--color-text);
  opacity: 0.6;
  border-radius: 2px;
}
.dsp-card-meta {
  width: 60px;
  height: 8px;
  background: var(--color-text-faint);
  border-radius: 2px;
}
.dsp-card-body {
  display: flex;
  flex-direction: column;
  gap: var(--dsp-space-xs);
}
.dsp-line {
  height: 8px;
  background: var(--color-border-strong);
  border-radius: 2px;
}
.dsp-line-full  { width: 100%; }
.dsp-line-short { width: 60%; }

.dsp-card-footer {
  display: flex;
  justify-content: flex-end;
  /* Margin top = lg pour bien séparer le footer du body */
  margin-top: var(--dsp-space-sm);
}


/* ----- Saynète 3 : Layout (sections) ----- */

.dsp-layout {
  display: flex;
  flex-direction: column;
  /* gap entre sections = xl : c'est le palier "respiration de page" */
  gap: var(--dsp-space-xl);
  /* Padding interne du layout = 2xl en haut/bas pour simuler une
     section de page web réelle */
  padding: var(--dsp-space-lg) 0;
}
.dsp-section {
  display: flex;
  flex-direction: column;
  /* gap interne = md : entre titre et contenu d'une section */
  gap: var(--dsp-space-md);
}
.dsp-section-title {
  width: 40%;
  height: 14px;
  background: var(--color-text);
  opacity: 0.7;
  border-radius: 2px;
}
.dsp-section-block {
  height: 40px;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: 4px;
}


/* ----- Boutons partagés ----- */

.dsp-btn {
  display: inline-block;
  /* Padding utilise sm (vertical) et md (horizontal) — règle classique :
     un bouton est ~2x plus large que haut côté padding. */
  padding: var(--dsp-space-sm) var(--dsp-space-md);
  font-size: var(--text-md);
  border-radius: 4px;
  border: 1px solid transparent;
  /* Largeur fixe pour la version sans label (Saynète 2) */
  min-width: 72px;
  min-height: 32px;
}
.dsp-btn-primary {
  background: var(--color-text);
  color: var(--color-bg);
}
.dsp-btn-ghost {
  background: transparent;
  border-color: var(--color-border-strong);
  color: var(--color-text-soft);
}


/* ----- Responsive ----- */

@media (max-width: 700px) {
  .ds-spacing-preview-grid {
    grid-template-columns: 1fr;
  }
}


/* ===========================================================
   DESIGN SYSTEM — Sous-module TYPOGRAPHIE (A1)

   Préfixe .ds-typo-* pour les éléments structurels (TA, TB, TC).
   Préfixe .dst-* pour les éléments à l'intérieur de l'aperçu
   (TC) — ils consomment les variables --dsf-* (font stacks) et
   --dst-size-*/--dst-lh-*/--dst-ls-* (échelle).
   =========================================================== */

#sub-ds-typography {
  display: none;
}
#sub-ds-typography.is-active {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: var(--space-lg) var(--space-md);
  padding-top: var(--space-md);
}

/* ===========================================================
   ZONES-CYCLES — Typo découpée en deux sections distinctes,
   chacune réalisant un cycle "choix → rendu" autonome.

   Une zone = un <section class="ds-typo-zone"> qui contient un
   titre <h3 class="ds-typo-zone-title"> puis les conteneurs
   internes (controls, scale, preview, conventions) en flux flex
   vertical. Les conteneurs internes n'ont plus leur propre
   fond/bordure/radius — c'est la zone qui porte la "carte".
   =========================================================== */

.ds-typo-zone {
  /* Le sous-onglet #sub-ds-typography est en grid 12 col ; chaque
     zone occupe toute la largeur. */
  grid-column: span 12;
  display: flex;
  flex-direction: column;
  gap: var(--space-lg);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: 8px;
  padding: var(--space-lg);
}

.ds-typo-zone-title {
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-weight: 600;
  color: var(--color-text);
  margin: 0;
  /* Filet sous le titre pour signaler la frontière entre titre de
     zone et contenu de la zone. */
  padding-bottom: var(--space-sm);
  border-bottom: 1px solid var(--color-border);
}

/* ----- Zone TA : contrôles ----- */

/* Le container est désormais enfant d'une .ds-typo-zone qui est en
   flex column ; il prend la largeur de la zone naturellement. Plus
   de fond/bordure : c'est la zone qui porte le contenant visuel. */
.ds-typo-controls {
  /* (rien de spécifique — la structure interne est portée par
     .ds-control-section / .ds-controls-row à l'intérieur) */
}

.ds-typo-custom-input {
  margin-top: var(--space-xs);
  width: 100%;
  padding: var(--space-xs) var(--space-sm);
  font-family: var(--font-mono);
  font-size: var(--text-md);
  background: var(--color-bg);
  color: var(--color-text);
  border: 1px solid var(--color-border);
  border-radius: 4px;
}
.ds-typo-custom-input:focus {
  outline: 2px solid var(--color-accent);
  outline-offset: 1px;
}


/* ----- Zone TB : échelle nue -----
   Disposition horizontale : un palier = une "colonne" empilée verticalement
   [échantillon Ag / nom / valeurs], les 8 paliers alignés sur une seule
   rangée. L'œil compare la hiérarchie de gauche à droite en un coup
   d'œil, sans rien dérouler. Les échantillons sont alignés sur la base
   (alphabétique) pour que la progression des tailles soit lisible. */

.ds-typo-scale {
  /* La carte visuelle est portée par .ds-typo-zone parent. Ici on
     ne gère que la disposition horizontale des 8 paliers. */
  display: flex;
  flex-direction: row;
  align-items: flex-end;
  /* flex-end aligne le bas des cellules : comme chaque cellule a son
     échantillon en haut, les libellés monospace s'alignent en bas. */
  justify-content: space-between;
  gap: var(--space-md);
  /* Si la largeur disponible est trop courte, on laisse le navigateur
     contraindre les colonnes (chaque palier reste lisible jusqu'à xs).
     Un overflow-x: auto serait pire qu'un wrap, donc on garde nowrap
     et on s'appuie sur flex-shrink des cellules. */
  overflow-x: auto;
}

.ds-typo-row {
  /* Une "row" devient en fait une CELLULE de la rangée horizontale,
     mais on garde le nom pour ne pas casser le JS et la persistance. */
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
  gap: var(--space-xs);
  flex: 1 1 0;
  min-width: 0;
  /* Pas de bordure entre cellules : la disposition parle d'elle-même.
     Un ancien :last-child supprimait la bordure du bas en mode vertical,
     plus pertinent ici. */
  border-bottom: none;
  padding-bottom: 0;
}

.ds-typo-row-label {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  color: var(--color-text-soft);
  /* Centré pour matcher l'échantillon au-dessus. */
  text-align: center;
}

.ds-typo-row-sample {
  /* font-family / font-size / line-height / letter-spacing
     sont injectés en inline-style par dsTypoRenderScale */
  color: var(--color-text);
  /* En layout horizontal, on autorise le débordement vertical mais on
     coupe l'horizontal — un Ag rend deux glyphes, c'est court. */
  white-space: nowrap;
  /* Plus de min-height : on veut que la rangée fasse la hauteur de la
     plus grosse cellule (4xl), donc on laisse line-height décider. */
}

.ds-typo-row-meta {
  /* Pile verticale serrée des trois valeurs (px / rem / lh), centrée
     sous le libellé. Avec le ratio compact, ces valeurs sont
     suffisamment courtes pour ne pas casser la largeur de cellule. */
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1px;
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--color-text-faint);
  line-height: 1.3;
}
.ds-typo-row-px  { color: var(--color-text); }
.ds-typo-row-rem,
.ds-typo-row-lh  { color: var(--color-text-faint); }

/* Sur écrans étroits, on tolère un scroll horizontal plutôt qu'un
   collapse vertical : la promesse de "tout sur une ligne" tient,
   au prix d'un scroll si vraiment l'espace manque. */
@media (max-width: 700px) {
  .ds-typo-scale {
    overflow-x: auto;
  }
  .ds-typo-row {
    flex: 0 0 auto;
    min-width: 80px;
  }
}


/* ----- Zone TC : aperçu en contexte ----- */

.ds-typo-preview {
  /* Carte portée par la zone parente — ici juste la mise en colonne
     du label + grille interne. */
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
}

.ds-typo-preview-label {
  font-family: var(--font-display);
  font-size: var(--text-md);
  font-weight: 600;
  color: var(--color-text-soft);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.ds-typo-preview-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(340px, 1fr));
  gap: var(--space-md);
}

.ds-typo-preview-card {
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: 6px;
  padding: var(--space-md);
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
}

.ds-typo-preview-caption {
  font-family: var(--font-mono);
  font-size: var(--text-base);
  color: var(--color-text-faint);
}


/* ----- Saynète 1 : Article ----- */

/*
   Les styles ci-dessous consomment les variables --dsf-* (font stacks)
   et --dst-size-*/-lh-*/-ls-* (échelle) injectées par dsTypoRenderPreview.

   Convention :
   - h1 = 3xl (display)
   - h2 = xl  (display)
   - lead = lg (body) — sous-titre/intro
   - body = base (body) — texte courant
   - link = base + couleur accent
   - caption = xs (body) — note de bas
*/
.dst-h1 {
  font-family: var(--dsf-display);
  font-size: var(--dst-size-3xl);
  line-height: var(--dst-lh-3xl);
  letter-spacing: var(--dst-ls-3xl);
  font-weight: 700;
  color: var(--color-text);
  margin: 0;
}
.dst-h2 {
  font-family: var(--dsf-display);
  font-size: var(--dst-size-xl);
  line-height: var(--dst-lh-xl);
  letter-spacing: var(--dst-ls-xl);
  font-weight: 600;
  color: var(--color-text);
  margin: var(--space-sm) 0 0 0;
}
.dst-lead {
  font-family: var(--dsf-body);
  font-size: var(--dst-size-lg);
  line-height: var(--dst-lh-lg);
  letter-spacing: var(--dst-ls-lg);
  color: var(--color-text-soft);
  margin: 0;
}
.dst-body {
  font-family: var(--dsf-body);
  font-size: var(--dst-size-base);
  line-height: var(--dst-lh-base);
  letter-spacing: var(--dst-ls-base);
  color: var(--color-text);
  margin: 0;
}
.dst-caption {
  font-family: var(--dsf-body);
  font-size: var(--dst-size-xs);
  line-height: var(--dst-lh-xs);
  letter-spacing: var(--dst-ls-xs);
  color: var(--color-text-faint);
  margin: var(--space-xs) 0 0 0;
}
.dst-link {
  color: var(--color-accent);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.dst-code {
  font-family: var(--font-mono);
  font-size: 0.9em;
  background: var(--color-surface);
  padding: 1px 4px;
  border-radius: 3px;
}


/* ----- Saynète 2 : UI / composant ----- */

.dst-ui-toolbar {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-md);
  padding-bottom: var(--space-sm);
  border-bottom: 1px solid var(--color-border);
}
.dst-ui-title {
  font-family: var(--dsf-display);
  font-size: var(--dst-size-lg);
  line-height: var(--dst-lh-lg);
  letter-spacing: var(--dst-ls-lg);
  font-weight: 600;
  color: var(--color-text);
}
.dst-ui-meta {
  font-family: var(--dsf-body);
  font-size: var(--dst-size-xs);
  line-height: var(--dst-lh-xs);
  letter-spacing: var(--dst-ls-xs);
  color: var(--color-text-faint);
}

.dst-ui-card {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: 4px;
  padding: var(--space-md);
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
}
.dst-ui-card-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-sm);
}
.dst-ui-card-title {
  font-family: var(--dsf-display);
  font-size: var(--dst-size-base);
  line-height: var(--dst-lh-base);
  letter-spacing: var(--dst-ls-base);
  font-weight: 600;
  color: var(--color-text);
  margin: 0;
}
.dst-ui-badge {
  font-family: var(--dsf-body);
  font-size: var(--dst-size-xs);
  line-height: 1;
  letter-spacing: 0.02em;
  background: var(--color-accent);
  color: var(--color-bg);
  padding: 2px 6px;
  border-radius: 3px;
  font-weight: 700;
}
.dst-ui-card-body {
  font-family: var(--dsf-body);
  font-size: var(--dst-size-sm);
  line-height: var(--dst-lh-sm);
  letter-spacing: var(--dst-ls-sm);
  color: var(--color-text-soft);
  margin: 0;
}
.dst-ui-card-footer {
  display: flex;
  justify-content: flex-end;
  gap: var(--space-xs);
}
.dst-ui-btn-primary,
.dst-ui-btn-ghost {
  font-family: var(--dsf-body);
  font-size: var(--dst-size-sm);
  line-height: 1;
  font-weight: 500;
  padding: 8px 12px;
  border-radius: 4px;
  border: 1px solid transparent;
  cursor: pointer;
}
.dst-ui-btn-primary {
  background: var(--color-text);
  color: var(--color-bg);
}
.dst-ui-btn-ghost {
  background: transparent;
  border-color: var(--color-border-strong);
  color: var(--color-text-soft);
}

.dst-ui-form {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
}
.dst-ui-label {
  font-family: var(--dsf-body);
  font-size: var(--dst-size-sm);
  line-height: 1.4;
  letter-spacing: var(--dst-ls-sm);
  color: var(--color-text-soft);
  font-weight: 500;
}
.dst-ui-input {
  font-family: var(--dsf-body);
  font-size: var(--dst-size-base);
  line-height: 1.4;
  padding: 6px 8px;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: 3px;
  color: var(--color-text);
}
.dst-ui-hint {
  font-family: var(--dsf-body);
  font-size: var(--dst-size-xs);
  line-height: var(--dst-lh-xs);
  letter-spacing: var(--dst-ls-xs);
  color: var(--color-text-faint);
}


/* ----- Responsive ----- */

@media (max-width: 700px) {
  .ds-typo-preview-grid {
    grid-template-columns: 1fr;
  }
  /* Note : la zone TB (.ds-typo-scale / .ds-typo-row) gère elle-même
     son responsive via overflow-x dans son bloc principal — pas de
     règle dédiée ici. */
}


/* ===========================================================
   DESIGN SYSTEM — Sous-module FORMES (A3 + A4)

   Préfixe .ds-shapes-* pour tous les éléments du sous-module
   (FA contrôles, FB radius, FC bordures, FD ombres).
   =========================================================== */

#sub-ds-shapes {
  display: none;
}
#sub-ds-shapes.is-active {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: var(--space-lg) var(--space-md);
  padding-top: var(--space-md);
}

/* ----- Titre de section pour les sous-modules de Formes ----- */

/* Le conteneur des Espacements (sous-module fusionné dans Formes)
   occupe toute la ligne. Le contenu interne suit ses propres règles
   .ds-spacing-* déjà définies plus haut. */
.ds-shapes-spacing {
  grid-column: span 12;
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
}

/* Chaque sous-section (Radius, Bordures, Ombres) a éventuellement
   un titre court, mono-uppercase pour rester cohérent avec le ton
   utilitaire du DS. */
.ds-shapes-section-title {
  font-family: var(--font-display);
  font-size: var(--text-md);
  font-weight: 600;
  color: var(--color-text-soft);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin-bottom: var(--space-sm);
}


/* ----- Header de section : titre + Default à droite ----- */

/* Chaque zone FB/FC/FD a son propre header :
   - titre à gauche
   - étiquette "Default" + <select> à droite (paliers actifs seulement) */
.ds-shapes-section-header {
  display: flex;
  align-items: center;
  gap: var(--space-md);
  margin-bottom: var(--space-md);
}
.ds-shapes-section-header .ds-shapes-section-title {
  margin-bottom: 0;
}

/* Nom textuel d'un palier dans une cellule (radius / border / shadow).
   Sous-titre court, en mono pour rappeler qu'il sert de clé de token. */
.ds-shapes-cell-name {
  font-family: var(--font-mono);
  font-size: var(--text-md);
  color: var(--color-text);
}


/* ----- Zone FB : radius nu ----- */

.ds-shapes-radius {
  grid-column: span 12;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: 8px;
  padding: var(--space-md);
}

.ds-shapes-radius-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
  gap: var(--space-md);
}

.ds-shapes-radius-cell {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-sm);
  padding: var(--space-sm);
  border-radius: 4px;
  border: 1px solid transparent;
}

/* Indication "ceci est cliquable" : reset des styles button natifs,
   pointeur main, transition douce au survol. */
.ds-shapes-selectable {
  appearance: none;
  background: transparent;
  font: inherit;
  color: inherit;
  cursor: pointer;
  transition: border-color 150ms ease-out, background 150ms ease-out, transform 150ms ease-out;
}
.ds-shapes-selectable:hover {
  border-color: var(--color-border-strong);
  background: color-mix(in srgb, var(--color-accent) 3%, transparent);
}
.ds-shapes-selectable:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

/* État SÉLECTIONNÉ : le palier choisi comme standard par l'utilisateur. */
.ds-shapes-selectable.is-selected {
  border-color: var(--color-accent);
  background: color-mix(in srgb, var(--color-accent) 8%, transparent);
}
.ds-shapes-selectable.is-selected:hover {
  /* Empêche le hover d'écraser le visuel sélectionné. */
  background: color-mix(in srgb, var(--color-accent) 10%, transparent);
}

/* Petite indication sous les contrôles : "Cliquez pour..." */
.ds-shapes-hint {
  font-family: var(--font-display);
  font-size: var(--text-sm);
  color: var(--color-text-soft);
  font-style: italic;
  margin: 0 0 var(--space-sm) 0;
}

.ds-shapes-radius-swatch {
  width: 88px;
  height: 88px;
  background: var(--color-text);
  /* border-radius injecté en inline-style par le render. */
}

.ds-shapes-radius-value {
  font-family: var(--font-mono);
  font-size: var(--text-base);
  color: var(--color-text-faint);
}


/* ----- Zone FC : bordures ----- */

.ds-shapes-borders {
  grid-column: span 12;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: 8px;
  padding: var(--space-md);
}

.ds-shapes-borders-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: var(--space-md);
}

.ds-shapes-borders-cell {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-sm);
  padding: var(--space-sm);
  border-radius: 4px;
  border: 1px solid transparent;
}

.ds-shapes-borders-swatch {
  width: 88px;
  height: 56px;
  background: var(--color-bg);
  border-color: var(--color-text);
  /* border-width, border-style, border-radius injectés en inline-style. */
}

.ds-shapes-borders-value {
  font-family: var(--font-mono);
  font-size: var(--text-base);
  color: var(--color-text-faint);
}


/* ----- Zone FD : ombres ----- */

.ds-shapes-shadows {
  grid-column: span 12;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: 8px;
  padding: var(--space-md);
}

/* Stratégie d'affichage des ombres :
   1. Le swatch est BLANC avec une bordure très pâle — c'est l'objet
      "carte qui flotte". Le palier 'none' reste visible grâce à
      cette bordure.
   2. Le fond de la grille est légèrement plus FONCÉ que la surface
      (et que le swatch) — c'est le "sol" sur lequel l'objet projette
      son ombre. Sans ce contraste subtil, une ombre de blanc-sur-blanc
      se confond avec le fond et reste invisible.
   3. Padding généreux en bas pour laisser respirer l'ombre du palier xl. */
.ds-shapes-shadows-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
  gap: var(--space-md);
  padding: var(--space-lg) var(--space-md) calc(var(--space-lg) + var(--space-sm));
  margin-top: var(--space-sm);
  background: color-mix(in srgb, var(--color-text) 4%, var(--color-surface));
  border-radius: 6px;
}

.ds-shapes-shadows-cell {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-md);
  padding: var(--space-sm);
  border-radius: 4px;
  border: 1px solid transparent;
}

.ds-shapes-shadows-swatch {
  width: 88px;
  height: 88px;
  /* Swatch BLANC : l'ombre est le seul indice de profondeur, ce qui
     met en valeur la différence entre paliers. La bordure très pâle
     reste perceptible même quand box-shadow vaut "none". */
  background: var(--color-surface);
  border: 1px solid color-mix(in srgb, var(--color-text) 8%, transparent);
  /* box-shadow + border-radius injectés en inline-style. */
}



/* ===========================================================
   DESIGN SYSTEM — Sous-module MOUVEMENT

   Section dans l'onglet Formes : 1 select (Tempo) + une zone
   d'aperçu avec 3 démos visuelles qui rendent perceptible la
   vitesse choisie. Les démos consomment les variables scopées
   --dsmot-fast / --dsmot-base / --dsmot-slow injectées en
   inline-style sur le conteneur par dsMotionRenderPreview.
   Lorsque le tempo change, les variables se mettent à jour
   et toutes les transitions suivent automatiquement.

   Préfixe interne : .dsmot-* (Design System Motion).
   =========================================================== */

.ds-shapes-motion {
  grid-column: span 12;
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
}

.ds-motion-preview {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: 8px;
  padding: var(--space-md);
}

.ds-motion-preview-label {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  color: var(--color-text-soft);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin-bottom: var(--space-md);
}

.ds-motion-preview-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: var(--space-md);
}

.ds-motion-preview-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
  /* La carte porte aussi .ds-shapes-selectable : padding pour offrir
     une zone cliquable confortable, et bord arrondi cohérent. */
  padding: var(--space-sm);
  border-radius: 4px;
  border: 1px solid transparent;
}

.ds-motion-preview-caption {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--color-text-faint);
  text-transform: uppercase;
}

/* ----- Démo 1 : bouton (utilise --dsmot-fast) ----- */

/* Un bouton sobre qui change de couleur et se soulève très
   légèrement au survol. La transition utilise la durée "fast" :
   on doit sentir une réaction quasi-instantanée mais douce. */
.dsmot-btn {
  appearance: none;
  border: 1px solid var(--color-border);
  background: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-display);
  font-size: var(--text-base);
  padding: var(--space-sm) var(--space-md);
  border-radius: 6px;
  cursor: pointer;
  transition:
    background var(--dsmot-fast, 150ms) ease-out,
    color      var(--dsmot-fast, 150ms) ease-out,
    transform  var(--dsmot-fast, 150ms) ease-out,
    box-shadow var(--dsmot-fast, 150ms) ease-out;
}
/* Hover s'applique au survol direct, OU au survol de la carte parente
   (puisqu'elle est cliquable). */
.dsmot-btn:hover,
.ds-motion-preview-card:hover .dsmot-btn {
  background: var(--color-accent);
  color: var(--color-bg);
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12);
}
.dsmot-btn-label {
  pointer-events: none;
}

/* ----- Démo 2 : carte qui se révèle (utilise --dsmot-base) ----- */

/* Une carte avec un fond qui glisse depuis le bas au survol.
   Utilise la durée "base" — la transition standard pour les
   changements d'état d'un composant. */
.dsmot-card {
  position: relative;
  width: 100%;
  height: 70px;
  border-radius: 8px;
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  overflow: hidden;
  cursor: pointer;
}
.dsmot-card-front,
.dsmot-card-back {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-display);
  font-size: var(--text-base);
  transition: transform var(--dsmot-base, 250ms) cubic-bezier(0.4, 0, 0.2, 1);
}
.dsmot-card-front {
  color: var(--color-text);
}
.dsmot-card-back {
  background: var(--color-accent);
  color: var(--color-bg);
  transform: translateY(100%);
}
.dsmot-card-back::before {
  content: "Réagi";
  font-family: var(--font-display);
}
.dsmot-card:hover .dsmot-card-front,
.ds-motion-preview-card:hover .dsmot-card-front {
  transform: translateY(-100%);
}
.dsmot-card:hover .dsmot-card-back,
.ds-motion-preview-card:hover .dsmot-card-back {
  transform: translateY(0);
}

/* ----- Démo 3 : tiroir qui glisse (utilise --dsmot-slow) ----- */

/* Un tiroir qui se déploie sur la largeur au survol. Utilise la
   durée "slow" — pour les changements de structure (ouvrir un
   panneau, transition d'écran). */
.dsmot-drawer {
  position: relative;
  width: 100%;
  height: 70px;
  border-radius: 8px;
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  overflow: hidden;
  cursor: pointer;
}
.dsmot-drawer-trigger {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-display);
  font-size: var(--text-base);
  color: var(--color-text);
  z-index: 1;
}
.dsmot-drawer-panel {
  position: absolute;
  inset: 0;
  background: var(--color-accent);
  transform: translateX(-100%);
  transition: transform var(--dsmot-slow, 400ms) cubic-bezier(0.4, 0, 0.2, 1);
}
.dsmot-drawer:hover .dsmot-drawer-panel,
.ds-motion-preview-card:hover .dsmot-drawer-panel {
  transform: translateX(0);
}
.dsmot-drawer:hover .dsmot-drawer-trigger,
.ds-motion-preview-card:hover .dsmot-drawer-trigger {
  color: var(--color-bg);
}



/* ===========================================================
   DESIGN SYSTEM — Typographie : zone TD (Conventions)
   =========================================================== */

.ds-typo-conventions {
  /* Carte portée par .ds-typo-zone parent. Ici on ne fait que la
     disposition flex column pour empiler les contrôles puis l'aperçu
     avant/après. */
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
}

.ds-typo-section-title {
  font-family: var(--font-display);
  font-size: var(--text-md);
  font-weight: 600;
  color: var(--color-text-soft);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.ds-typo-conventions-intro {
  font-family: var(--font-body, var(--font-display));
  font-size: var(--text-base);
  color: var(--color-text-soft);
  margin: 0;
  max-width: 720px;
  line-height: 1.5;
}

/* 2 fieldsets côte à côte : Titres / Texte courant */
.ds-typo-conventions-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-md) var(--space-lg);
}

@media (max-width: 720px) {
  .ds-typo-conventions-grid {
    grid-template-columns: 1fr;
  }
}

/* ----- Aperçu avant/après ----- */

.ds-typo-conventions-preview {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-md);
  margin-top: var(--space-sm);
}

.ds-typo-conventions-col {
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: 6px;
  padding: var(--space-md);
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
}

.ds-typo-conventions-col-title {
  font-family: var(--font-mono);
  font-size: var(--text-base);
  color: var(--color-text-faint);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.ds-typo-conventions-sample {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
}

.ds-typo-conventions-sample-title {
  font-family: var(--dsf-display, var(--font-display));
  font-size: var(--text-xl, 1.25rem);
  font-weight: 700;
  color: var(--color-text);
  /* text-transform et letter-spacing sont injectés en inline-style
     côté "après" (titleTokens), pas appliqués au "avant". */
  line-height: 1.3;
}

.ds-typo-conventions-sample-body {
  font-family: var(--dsf-body, var(--font-display));
  font-size: var(--text-md);
  line-height: 1.55;
  color: var(--color-text);
  margin: 0;
}


/* ----- Responsive ----- */

@media (max-width: 700px) {
  .ds-typo-conventions-preview {
    grid-template-columns: 1fr;
  }
}


/* ===========================================================
   DESIGN SYSTEM — Sous-onglet EXPORTER

   Sous-vue centralisant le récapitulatif des choix utilisateur et
   permettant de télécharger le CSS final. Structure verticale,
   pas de grille 12 colonnes (la mise en page est éditoriale plus
   que technique).

   Préfixe : .ds-export-*
   =========================================================== */

#sub-ds-export {
  display: none;
}
#sub-ds-export.is-active {
  display: flex;
  flex-direction: column;
  gap: var(--space-lg);
  padding-top: var(--space-md);
}

/* ----- Bandeau du haut : titre + bouton télécharger ----- */

.ds-export-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-md);
  flex-wrap: wrap;
  padding: var(--space-md);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: 8px;
}

.ds-export-header-info {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

/* Sprint 8 : conteneur des boutons d'action du header
   (Télécharger + Pack projet). */
.ds-export-header-actions {
  display: flex;
  gap: var(--space-sm);
  align-items: center;
  flex-wrap: wrap;
}

/* Sprint 8 : onglets de format (CSS / JSON / Tailwind v3 / v4 / shadcn).
   Réutilise la convention .mode-btn déjà stylée dans le projet. */
.ds-export-format-tabs {
  display: flex;
  gap: var(--space-xs);
  flex-wrap: wrap;
  padding: var(--space-sm) 0;
  border-bottom: 1px solid var(--color-border);
  margin-bottom: var(--space-md);
}

.ds-export-title {
  font-family: var(--font-display);
  font-size: var(--text-lg);
  font-weight: 600;
  color: var(--color-text);
  margin: 0;
}

.ds-export-subtitle {
  font-family: var(--font-display);
  font-size: var(--text-sm);
  color: var(--color-text-soft);
  margin: 0;
}

/* Titre des sections internes (Récap, Aperçu) */
.ds-export-section-title {
  font-family: var(--font-display);
  font-size: var(--text-md);
  font-weight: 600;
  color: var(--color-text-soft);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin: 0 0 var(--space-sm) 0;
}

/* ----- Section "Récapitulatif" ----- */

.ds-export-summary {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: 8px;
  padding: var(--space-md);
}

.ds-export-summary-table {
  width: 100%;
  border-collapse: collapse;
  font-family: var(--font-display);
  font-size: var(--text-sm);
  color: var(--color-text);
}

.ds-export-summary-table th,
.ds-export-summary-table td {
  text-align: left;
  padding: var(--space-xs) var(--space-sm);
  vertical-align: top;
}

/* En-tête de section dans le tableau (regroupement visuel) */
.ds-export-summary-section th {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--color-text-faint);
  padding-top: var(--space-md);
  padding-bottom: var(--space-xs);
  font-weight: normal;
  border-bottom: 1px solid var(--color-border);
}
.ds-export-summary-section:first-child th {
  padding-top: 0;
}

.ds-export-summary-label {
  width: 40%;
  color: var(--color-text-soft);
}

.ds-export-summary-value {
  width: 60%;
  font-family: var(--font-mono);
  color: var(--color-text);
}

/* ----- Section "Aperçu du CSS" ----- */

.ds-export-preview {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: 8px;
  padding: var(--space-md);
}

.ds-export-preview-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-md);
  margin-bottom: var(--space-sm);
}

.ds-export-preview-header .ds-export-section-title {
  margin: 0;
}

.ds-export-code {
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  border-radius: 4px;
  padding: var(--space-md);
  max-height: 400px;
  overflow: auto;
  margin: 0;
}

.ds-export-code code {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--color-text);
  line-height: 1.5;
  white-space: pre;
}
