/* UI components — Eco Autumn, rounded, desktop-first */

.ui-stack {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.ui-stack--sm {
  gap: var(--space-3);
}

/* Liste sans puces ni marge ni padding — utile pour les <ul> qui servent
   uniquement à grouper sémantiquement des éléments mis en page autrement. */
.ui-list-bare {
  list-style: none;
  margin: 0;
  padding: 0;
}

.ui-label {
  display: block;
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--color-text);
  margin-bottom: var(--space-2);
}

.ui-field {
  margin-bottom: var(--space-4);
}

.ui-field:last-child {
  margin-bottom: 0;
}

.ui-input,
.ui-select,
.ui-textarea {
  width: 100%;
  max-width: 32rem;
  padding: 10px 14px;
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border);
  background: var(--color-surface);
  color: var(--color-text);
  transition: border-color 0.15s, box-shadow 0.15s;
}

.ui-input:hover:not(:disabled),
.ui-select:hover:not(:disabled),
.ui-textarea:hover:not(:disabled) {
  border-color: var(--color-accent-brown);
}

.ui-input:disabled,
.ui-select:disabled,
.ui-textarea:disabled {
  opacity: 0.55;
  cursor: not-allowed;
  background: var(--color-bg);
}

/* Valeurs affichées dans un formulaire mais non saisissables (ex. produit courant) */
.ui-input--static {
  cursor: default;
  background: var(--color-bg);
  user-select: text;
}

.ui-input--static:hover {
  border-color: var(--color-border);
}

.ui-input--error,
.ui-select--error,
.ui-textarea--error {
  border-color: var(--color-danger);
}

.ui-error {
  font-size: 0.8125rem;
  color: var(--color-danger);
  margin-top: var(--space-2);
}

.ui-hint {
  font-size: 0.8125rem;
  color: var(--color-text-muted);
  margin-top: var(--space-2);
}

.ui-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: 10px 20px;
  border-radius: var(--radius-md);
  border: 1px solid transparent;
  font-weight: 600;
  cursor: pointer;
  text-decoration: none;
  transition: background 0.15s, border-color 0.15s;
}

button.ui-btn {
  font: inherit;
  appearance: none;
  -webkit-appearance: none;
}

.ui-btn:disabled {
  opacity: 0.55;
  cursor: not-allowed;
}

/* Opt-in guard : grise visuellement le submit d'un <form data-guard-submit>
   tant qu'un champ required est vide ou qu'un type/pattern n'est pas
   respecté. `:has(:invalid)` combine la validation HTML5 native au feedback
   visuel. Navigateurs sans `:has()` (legacy) : la règle est ignorée et le
   bouton reste actif, la validation HTML5 prendra le relais au submit. */
form[data-guard-submit]:has(:invalid) button[type="submit"],
form[data-guard-submit]:has(:invalid) input[type="submit"] {
  opacity: 0.5;
  cursor: not-allowed;
  pointer-events: none;
}

.ui-btn--primary {
  background: var(--color-primary);
  color: var(--color-on-primary);
}

.ui-btn--primary:hover:not(:disabled) {
  background: var(--color-primary-hover);
}

.ui-btn--compact {
  padding: 6px 12px;
  font-size: 0.875rem;
}

.ui-btn--block {
  width: 100%;
  justify-content: center;
  box-sizing: border-box;
}

.ui-btn--secondary {
  background: transparent;
  color: var(--color-primary-hover);
  border-color: var(--color-border);
}

.ui-btn--secondary:hover:not(:disabled) {
  background: var(--color-primary-soft);
}

.ui-btn--ghost {
  background: transparent;
  color: var(--color-text);
  border-color: var(--color-border);
}

.ui-btn--ghost:hover:not(:disabled) {
  background: var(--color-primary-soft);
}

.ui-btn--danger {
  background: var(--color-danger);
  color: var(--color-on-primary);
}

.ui-btn--danger:hover:not(:disabled) {
  filter: brightness(0.95);
}

/* Variante "outline" : bordure + texte rouge, fond transparent. Moins
   agressive visuellement que .ui-btn--danger (fond plein). Utilisée pour
   les actions destructives dans les tableaux et à côté des actions neutres. */
.ui-btn--danger-outline {
  border-color: var(--color-danger);
  color: var(--color-danger);
  background: transparent;
}

.ui-btn--danger-outline:hover:not(:disabled) {
  background: rgba(185, 28, 28, 0.08);
  color: var(--color-danger);
}

.ui-btn--success {
  background: var(--color-success);
  color: var(--color-on-primary);
  border-color: transparent;
}

.ui-btn--success:hover:not(:disabled) {
  filter: brightness(1.05);
}

/* Liste catalogue produits : en-tête + zone tableau scrollable. */
.catalog-product-list-page {
  display: flex;
  flex-direction: column;
}

/* Remplit la hauteur visible sous l'en-tête de page : le tableau défile à
   l'intérieur. La colonne `p-main` passe en flex pour la page qui le demande
   (`body.catalog-product-list-body`) ; l'ancienne marge verticale figée
   (7,75 rem) ignorait la hauteur réelle de l'en-tête (lot 2 b). */
.catalog-product-list-body .p-main {
  display: flex;
  flex-direction: column;
  min-height: calc(100dvh - 3.25rem);
}

.catalog-product-list-page--fill {
  flex: 1 1 0;
  min-height: 0;
  overflow: hidden;
}

.catalog-product-list-page--fill .catalog-product-list-page__header,
.catalog-product-list-page--fill .catalog-product-list-page__page-title {
  flex: 0 0 auto;
}

.catalog-product-list-page__header-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
}

.catalog-product-list-page__nav {
  flex: 1 1 12rem;
  min-width: 0;
}

.catalog-product-list-page__search .ui-input,
.catalog-product-list-page__filters .ui-input {
  width: 100%;
}

.catalog-product-list-page__filter-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(14rem, 1fr));
  gap: 0 var(--space-4);
  align-items: end;
}

.catalog-product-list-page__bulk-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
  align-items: center;
}

.catalog-product-list-page__toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-3);
  overflow: visible;
  position: relative;
  z-index: 2;
}

.catalog-product-list-page__toolbar .catalog-product-list-page__filters {
  flex: 1 1 100%;
  min-width: 0;
}

.catalog-product-list-page__search-row {
  display: flex;
  align-items: flex-end;
  gap: var(--space-3);
  width: 100%;
}

.catalog-product-list-page__search-row .catalog-product-list-page__search {
  flex: 1 1 auto;
  min-width: 0;
}

.catalog-product-list-page__search {
  width: 100%;
}

.ui-input--search-prominent {
  font-size: 1rem;
  padding: var(--space-3) var(--space-4);
}

.catalog-product-list-page__filter-zone {
  margin-top: var(--space-3);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.catalog-product-list-page__filter-zone-label {
  font-size: var(--text-xs, 0.75rem);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--color-text-muted);
}

.filter-chip-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
}

.filter-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: 0.25rem 0.65rem;
  border-radius: 999px;
  font-size: 0.8125rem;
  font-weight: 500;
  text-decoration: none;
  color: var(--color-text);
  background: color-mix(in srgb, var(--color-primary) 12%, var(--color-surface));
  border: 1px solid color-mix(in srgb, var(--color-primary) 28%, var(--color-border));
}

.filter-chip:hover {
  border-color: var(--color-primary);
}

.filter-chip__dismiss {
  opacity: 0.65;
  line-height: 1;
}

.filter-chip-row__clear {
  font-size: 0.875rem;
  margin-left: var(--space-1);
}

.filter-popover-wrap {
  position: relative;
}

.filter-popover {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  z-index: var(--z-dropdown);
  min-width: 14rem;
  padding: var(--space-2) 0;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-sm);
}

.filter-popover[hidden] {
  display: none;
}

.filter-popover__types {
  margin: 0;
  padding: 0;
  list-style: none;
}

.filter-popover__type {
  display: block;
  width: 100%;
  padding: var(--space-2) var(--space-3);
  background: transparent;
  border: 0;
  font: inherit;
  font-size: var(--text-sm, 0.875rem);
  text-align: left;
  cursor: pointer;
  color: inherit;
}

.filter-popover__type:hover,
.filter-popover__type:focus-visible {
  background: var(--color-surface-hover);
}

.filter-popover__value-panel {
  padding: var(--space-3);
  min-width: 16rem;
}

.filter-popover__value-panel[hidden] {
  display: none;
}

.filter-popover__panel[hidden] {
  display: none;
}

.filter-popover__actions {
  display: flex;
  justify-content: flex-end;
  gap: var(--space-2);
  margin-top: var(--space-3);
}

/* Popover filtres 2 colonnes (survol catégorie → valeurs scrollables). */
.filter-popover--split {
  min-width: 28rem;
  max-width: min(36rem, 95vw);
  padding: 0;
}

.filter-popover__split {
  display: grid;
  grid-template-columns: minmax(9rem, 11rem) 1fr;
  min-height: 12rem;
}

.filter-popover--split .filter-popover__types {
  margin: 0;
  padding: var(--space-1) 0;
  list-style: none;
  border-right: 1px solid var(--color-border);
}

.filter-popover--split .filter-popover__type {
  display: block;
  width: 100%;
  padding: var(--space-2) var(--space-3);
  background: transparent;
  border: 0;
  font: inherit;
  font-size: var(--text-sm, 0.875rem);
  text-align: left;
  cursor: pointer;
  color: inherit;
}

.filter-popover--split .filter-popover__type:hover,
.filter-popover--split .filter-popover__type:focus-visible,
.filter-popover--split .filter-popover__type--active {
  background: var(--color-surface-hover);
}

.filter-popover__values-scroll {
  position: relative;
  min-height: 12rem;
  max-height: min(16rem, 50vh);
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}

.filter-popover--split .filter-popover__panel {
  padding: var(--space-1) 0;
}

.filter-popover--split .filter-popover__panel[hidden] {
  display: none;
}

.filter-popover__value-list {
  margin: 0;
  padding: 0;
  list-style: none;
}

.filter-popover__value {
  display: block;
  width: 100%;
  padding: var(--space-2) var(--space-3);
  background: transparent;
  border: 0;
  font: inherit;
  font-size: var(--text-sm, 0.875rem);
  text-align: left;
  cursor: pointer;
  color: inherit;
}

.filter-popover__value:hover,
.filter-popover__value:focus-visible {
  background: var(--color-surface-hover);
}

.filter-popover__panel .ui-input[data-filter-value-input] {
  margin: var(--space-2) var(--space-3);
  width: calc(100% - var(--space-6));
}

.filter-popover__field-label {
  display: block;
  margin: var(--space-2) var(--space-3) 0;
  font-size: var(--fs-sm);
  font-weight: 600;
}

.filter-popover__hint {
  margin: 0 var(--space-3);
  color: var(--color-text-muted);
  font-size: var(--fs-sm);
}

.filter-popover__panel .filter-popover__actions {
  margin: var(--space-2) var(--space-3);
}

/* Page activités portail fournisseur.
   La page défile comme une page ordinaire. Elle était verrouillée à la hauteur de
   l'écran (100dvh − 8.5rem) : le tableau n'y recevait que ce que laissaient les
   filtres et les boutons, soit 2 px sur un PC Windows à 150 % (audit zoom du
   25/09/2026). C'est désormais sa zone de défilement qui se borne à un écran
   (`__table-scroll`). */
.portal-activities-page {
  display: flex;
  flex-direction: column;
}

.portal-activities-page__header {
  flex: 0 0 auto;
}

.portal-activities-page__table-card {
  display: flex;
  flex-direction: column;
}

.portal-activities-htmx-shell {
  position: relative;
}

.portal-activities-htmx-loading {
  position: absolute;
  inset: 0;
  z-index: 3;
  display: none;
  align-items: center;
  justify-content: center;
  background: color-mix(in srgb, var(--color-surface) 72%, transparent);
  border-radius: inherit;
  pointer-events: none;
}

/* Voile de liste (sites, fournisseurs) : même rendu que le catalogue,
   sans reprendre le shell flex de la page produits. */
.ui-htmx-overlay-shell {
  position: relative;
}

.ui-htmx-overlay-shell > .portal-activities-htmx-loading.htmx-indicator.htmx-request {
  display: flex;
}

.ui-htmx-overlay-shell > .portal-activities-htmx-loading.htmx-request ~ [aria-live="polite"] {
  opacity: 0.55;
  pointer-events: none;
  transition: opacity var(--duration-fast, 0.15s) var(--ease-out, ease-out);
}

.portal-activities-htmx-shell #portal-activities-loading.htmx-indicator.htmx-request {
  display: flex;
}

.portal-activities-htmx-shell > #portal-activities-results {
  display: flex;
  flex-direction: column;
}

.portal-activities-htmx-shell #portal-activities-loading.htmx-request ~ #portal-activities-results {
  opacity: 0.55;
  pointer-events: none;
  transition: opacity var(--duration-fast, 0.15s) var(--ease-out, ease-out);
}

.portal-certificates-htmx-shell {
  position: relative;
}

.portal-certificates-htmx-shell #portal-certificates-loading.htmx-indicator.htmx-request {
  display: flex;
}

.portal-certificates-htmx-shell #portal-certificates-loading.htmx-request ~ #certs-results {
  opacity: 0.55;
  pointer-events: none;
  transition: opacity var(--duration-fast, 0.15s) var(--ease-out, ease-out);
}

.portal-attributes-htmx-shell {
  position: relative;
}

.portal-attributes-htmx-shell #portal-attributes-loading.htmx-indicator.htmx-request {
  display: flex;
}

.portal-attributes-htmx-shell #portal-attributes-loading.htmx-request ~ #portal-attributes-results {
  opacity: 0.55;
  pointer-events: none;
  transition: opacity var(--duration-fast, 0.15s) var(--ease-out, ease-out);
}

.portal-sites-htmx-shell {
  position: relative;
}

.portal-sites-htmx-shell #portal-sites-loading.htmx-indicator.htmx-request {
  display: flex;
}

.portal-sites-htmx-shell #portal-sites-loading.htmx-request ~ #portal-sites-results {
  opacity: 0.55;
  pointer-events: none;
  transition: opacity var(--duration-fast, 0.15s) var(--ease-out, ease-out);
}

/* Page « Détails du produit » : même principe que la page activités, la page
   défile et le tableau se borne à un écran (voir `.portal-activities-page`). */
.portal-attributes-page {
  display: flex;
  flex-direction: column;
}

.portal-attributes-page__table-card {
  display: flex;
  flex-direction: column;
}

.portal-attributes-htmx-shell > #portal-attributes-results {
  display: flex;
  flex-direction: column;
}

.portal-attributes-results {
  display: flex;
  flex-direction: column;
}

.portal-attributes-results__grid {
  display: flex;
  flex-direction: column;
}

.portal-attributes-page__table-body {
  display: flex;
  flex-direction: column;
}

.portal-attributes-page__table-scroll {
  width: 100%;
  overflow: auto;
  scrollbar-gutter: stable;
  -webkit-overflow-scrolling: touch;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface);
}

.portal-attr-grid__table thead tr {
  background: var(--color-primary-soft);
}

.portal-attr-grid__table tbody tr {
  background: var(--color-surface);
}

.portal-activities-results {
  display: flex;
  flex-direction: column;
}

.portal-activities-page__toolbar {
  flex: 0 0 auto;
  margin-bottom: var(--space-3);
}

.portal-activities-page__filters-search {
  width: 100%;
  margin: 0;
}

.portal-activities-page__site-select {
  min-width: 11rem;
  max-width: 16rem;
}

.portal-activities-row-site {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
}

.portal-activities-row-site-form {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  margin: 0;
}

.portal-activities-row-site-form__select {
  flex: 1 1 10rem;
  min-width: 10rem;
  max-width: 14rem;
}

.portal-activities-row-site__pending-badge {
  flex: 0 0 auto;
}

.portal-activities-page__filters {
  width: 100%;
}

.portal-activities-page__search-row {
  display: flex;
  align-items: flex-end;
  gap: var(--space-3);
  width: 100%;
}

.portal-activities-page__search {
  flex: 1 1 auto;
  min-width: 0;
}

.portal-activities-page__filter-zone {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin-top: var(--space-3);
}

.portal-activities-page__filter-zone-header {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
}

.portal-activities-page__filter-controls {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
}

.portal-activities-page__filter-chips {
  margin-top: 0;
}

.portal-activities-page__filter-zone-label {
  font-size: var(--text-xs, 0.75rem);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--color-text-muted);
}

.portal-activities-page__toolbar-actions {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.portal-activities-page__bulk-bar {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin-top: var(--space-3);
}

/* Dès qu'une ligne est cochée, la barre d'action groupée (Activités et Détails du
   produit) reste collée en bas de l'écran : le tableau n'est plus enfermé dans la
   hauteur de l'écran, et la barre qui le suit sortirait du champ. Le bouton d'envoi
   n'est actif qu'avec une sélection (portal_activities_selection.js et
   portal_attributes_selection.js). */
.portal-activities-page__bulk-bar:has(#portal-bulk-submit:enabled),
.portal-attr-grid__bulk-bar:has(#portal-bulk-submit:enabled) {
  position: sticky;
  bottom: 0;
  z-index: var(--z-sticky);
  margin-inline: calc(-1 * var(--space-6));
  padding: var(--space-3) var(--space-6) calc(var(--space-3) + var(--portal-submit-room, 0px));
  border-top: 1px solid var(--color-border);
  background: var(--color-surface);
}

/* Collée, la barre n'a plus besoin de son mode d'emploi : elle reste basse. */
.portal-activities-page__bulk-bar:has(#portal-bulk-submit:enabled) .portal-activities-page__bulk-help,
.portal-attr-grid__bulk-bar:has(#portal-bulk-submit:enabled) .portal-attr-grid__bulk-help {
  display: none;
}

/* « Transmettre » flotte au même endroit (`.portal-submit-sticky`) : la barre lui
   laisse sa hauteur en dessous au lieu de passer sous lui. */
body:has(.portal-submit-sticky:not([hidden])) {
  --portal-submit-room: calc(var(--h-btn) + var(--space-5));
}

/* La barre collée recouvre le bas de l'écran : un contrôle du tableau atteint au
   clavier s'arrête au-dessus d'elle au lieu de passer dessous. */
.portal-activities-results:has(#portal-bulk-submit:enabled) .portal-activities-page__table-scroll,
.portal-attributes-results__grid:has(#portal-bulk-submit:enabled) .portal-attributes-page__table-scroll {
  scroll-padding-bottom: 8rem;
}

.portal-activities-page__bulk-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
}

.portal-activities-page__bulk-form {
  display: flex;
  flex-wrap: nowrap;
  align-items: center;
  gap: var(--space-2);
  margin: 0;
}

.portal-activities-page__bulk-help {
  margin: 0;
}

.portal-activities-page__columns-menu .ui-action-menu__panel,
.ui-action-menu__panel.portal-activities-page__columns-panel {
  min-width: 18rem;
  max-width: min(24rem, 90vw);
  padding: var(--space-4);
}

.portal-activities-page__columns-panel form {
  padding: 0;
}

.portal-activities-page__columns-list {
  margin: 0;
  padding: 0;
  list-style: none;
  max-height: min(18rem, 45vh);
  overflow-y: auto;
}

.portal-activities-page__columns-option {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
  padding: var(--space-2) 0;
  font-size: 0.875rem;
  cursor: pointer;
  line-height: 1.35;
}

.portal-activities-page__columns-option input {
  margin-top: 0.15rem;
  flex-shrink: 0;
}

.portal-activities-page__columns-option span {
  min-width: 0;
  word-break: break-word;
}

.portal-activities-page__columns-option--disabled {
  opacity: 0.65;
  cursor: default;
}

.portal-activities-page__columns-actions {
  display: flex;
  gap: var(--space-2);
  margin-top: var(--space-3);
  padding-top: var(--space-2);
  border-top: 1px solid var(--color-border);
}

.portal-activities-page__table-body {
  display: flex;
  flex-direction: column;
}

.portal-activities-page__table-scroll {
  width: 100%;
  overflow: auto;
  scrollbar-gutter: stable;
  -webkit-overflow-scrolling: touch;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface);
}

/* Tableaux Activités et Détails du produit : au plus un écran sous la barre du
   haut collée (52 px, 67 px sur téléphone), jamais moins de 16rem, même au zoom
   400 %. Le tableau défile dans ce cadre, la page autour de lui.
   `position: relative` : les étiquettes `.sr-only` des cellules (positionnées en
   absolu) se rapportaient à la carte et sortaient du cadre ; au-delà du bord
   droit, elles élargissaient la page de 6 px sur Android. */
.portal-activities-page__table-scroll,
.portal-attributes-page__table-scroll {
  position: relative;
  max-height: max(16rem, calc(100vh - 5rem));
  max-height: max(16rem, calc(100dvh - 5rem));
}

.portal-activities-page__table {
  width: 100%;
  min-width: 48rem;
  font-size: 0.875rem;
}

/* Ombres de défilement (technique background-attachment: local) : sur mobile
   la grille dépasse largement le conteneur sans aucun indice visuel (audit
   portail 18/09, ACT-08 / ATTR-01). L'ombre droite disparaît en fin de course. */
@media (max-width: 48em) {
  .portal-activities-page__table-scroll,
  .portal-attributes-page__table-scroll {
    background:
      linear-gradient(to right, var(--color-surface) 30%, rgba(255, 255, 255, 0)) left / 40px 100%
        no-repeat local,
      linear-gradient(to left, var(--color-surface) 30%, rgba(255, 255, 255, 0)) right / 40px 100%
        no-repeat local,
      linear-gradient(to right, rgba(31, 41, 55, 0.18), rgba(31, 41, 55, 0)) left / 14px 100% no-repeat scroll,
      linear-gradient(to left, rgba(31, 41, 55, 0.18), rgba(31, 41, 55, 0)) right / 14px 100% no-repeat scroll;
    background-color: var(--color-surface);
  }
}

.portal-activities-page__table thead tr {
  background: var(--color-primary-soft);
}

.portal-activities-page__table tbody tr {
  background: var(--color-surface);
}

/* La colonne Site prenait toute la largeur libre (`width: 100%`) : le nom du
   produit se repliait sur quatre lignes, une ligne d'activité faisait 115 px et
   deux seulement tenaient à l'écran (audit zoom du 25/09/2026). */
.portal-activities-page__th-site,
.portal-activities-page__td-site {
  min-width: 11rem;
}

.portal-activities-page__th-product,
.portal-activities-page__td-product {
  min-width: 12rem;
}

.portal-activities-page__td-site .portal-activities-row-site {
  width: max-content;
  max-width: 100%;
}

.portal-activities-page__table th,
.portal-activities-page__table td {
  padding: var(--space-2) var(--space-3);
  vertical-align: middle;
}

.portal-activities-page__th-check,
.portal-activities-page__td-check {
  width: 2.5rem;
  text-align: center;
}

.portal-activities-page__empty-cell {
  text-align: center;
  padding: var(--space-6) var(--space-3);
}

.catalog-product-list-page__toolbar-controls {
  flex: 1 1 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  min-width: 0;
}

.catalog-product-list-page__toolbar-actions {
  flex: 0 0 auto;
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
  margin-left: auto;
}

.ui-action-menu__panel.catalog-product-list-page__columns-panel {
  min-width: 14rem;
  max-width: 18rem;
  max-height: min(24rem, 70vh);
  overflow: auto;
  padding: var(--space-4);
}

.catalog-product-list-page__columns-panel .ui-action-menu__heading {
  padding-left: 0;
  padding-right: 0;
}

.catalog-product-list-page__columns-panel form {
  padding: 0;
}

.catalog-product-list-page__columns-list {
  list-style: none;
  margin: 0 0 var(--space-3);
  padding: 0;
}

.catalog-product-list-page__columns-option {
  display: flex;
  align-items: flex-start;
  gap: var(--space-2);
  padding: 0.35rem 0;
  font-size: 0.875rem;
  line-height: 1.35;
  cursor: pointer;
}

.catalog-product-list-page__columns-option--disabled {
  opacity: 0.65;
  cursor: default;
}

.catalog-product-list-page__columns-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-top: var(--space-1);
  padding-top: var(--space-3);
  border-top: 1px solid var(--border-color);
}

.ui-action-menu {
  position: relative;
}

.ui-action-menu > summary {
  list-style: none;
  cursor: pointer;
}

.ui-action-menu > summary::-webkit-details-marker,
.ui-action-menu > summary::marker {
  display: none;
}

.ui-action-menu__panel {
  position: absolute;
  top: calc(100% + 4px);
  right: 0;
  z-index: var(--z-dropdown);
  min-width: 14rem;
  padding: var(--space-2) 0;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-sm);
}

.ui-action-menu__heading {
  margin: 0;
  padding: var(--space-1) var(--space-3);
  font-size: var(--text-xs, 0.75rem);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--color-text-muted);
}

.ui-action-menu__list {
  margin: 0;
  padding: 0;
  list-style: none;
}

.ui-action-menu__item {
  display: block;
  padding: var(--space-2) var(--space-3);
  color: inherit;
  text-decoration: none;
  font-size: var(--text-sm, 0.875rem);
  transition: background-color var(--duration-fast) var(--ease-out);
}

.ui-action-menu__item:hover:not(:disabled):not([aria-disabled="true"]),
.ui-action-menu__item:focus-visible:not(:disabled):not([aria-disabled="true"]) {
  background: var(--color-surface-hover);
}

.ui-action-menu__panel--above {
  top: auto;
  bottom: calc(100% + 4px);
}

.ui-action-menu__separator {
  margin: var(--space-1) 0;
  border: 0;
  border-top: 1px solid var(--color-border);
}

.ui-action-menu button.ui-action-menu__item {
  width: 100%;
  background: transparent;
  border: 0;
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.ui-action-menu button.ui-action-menu__item:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

.ui-action-menu a.ui-action-menu__item[aria-disabled="true"] {
  opacity: 0.45;
  cursor: not-allowed;
  pointer-events: none;
}

.catalog-product-list-page__th-check,
.catalog-product-list-page__td-check {
  width: 2.75rem;
  text-align: center;
}

.catalog-product-list-page__table th.catalog-product-list-page__th-check,
.catalog-product-list-page__table td.catalog-product-list-page__td-check {
  vertical-align: middle;
}

.catalog-product-list-page__table-card {
  display: flex;
  flex: 1 1 0;
  flex-direction: column;
  min-height: 0;
  overflow: hidden;
}

.catalog-product-list-htmx-shell {
  position: relative;
}

.catalog-product-list-htmx-shell #product-list-loading.htmx-indicator.htmx-request {
  display: flex;
}

.catalog-product-list-htmx-shell #product-list-loading.htmx-request ~ #product-list-results {
  opacity: 0.55;
  pointer-events: none;
  transition: opacity var(--duration-fast, 0.15s) var(--ease-out, ease-out);
}

.catalog-product-list-htmx-shell > #product-list-results {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;
  overflow: hidden;
}

.catalog-product-list-results {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;
  min-width: 0;
  height: 100%;
}

.catalog-product-list-page__table-body {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;
  overflow: hidden;
  margin-top: var(--space-3);
}

/* Une seule zone de défilement : hauteur = contenu (peu de lignes) ou espace restant (liste longue). */
.catalog-product-list-page__table-scroll {
  flex: 0 1 auto;
  min-height: 0;
  max-height: 100%;
  width: 100%;
  box-sizing: border-box;
  overflow: auto;
  -webkit-overflow-scrolling: touch;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface);
}

.ui-card {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-sm);
  padding: var(--space-6);
}

.ui-card--accent {
  border-color: var(--color-accent-amber);
  background: linear-gradient(135deg, var(--color-surface-alt) 0%, var(--color-surface) 100%);
}

.ui-table-wrap {
  overflow-x: auto;
  border-radius: var(--radius-lg);
  border: 1px solid var(--color-border);
}

/* Scroll vertical avec hauteur limitée : utile quand la liste peut exploser
   (ex. catalogue produits). Combiner avec .ui-table--sticky-head pour garder
   le header visible pendant le scroll. */
.ui-table-wrap--scroll {
  max-height: 560px;
  overflow-y: auto;
}

/* Table large : force une largeur minimale et déclenche le scroll
   horizontal du .ui-table-wrap parent plutôt que de comprimer les colonnes.
   Utile pour les tableaux de prévisualisation d'import CSV. */
.ui-table--wide {
  min-width: 36rem;
}

.ui-table--sticky-head thead th {
  position: sticky;
  top: 0;
  z-index: 1;
}

.ui-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.9375rem;
}

/* Les champs héritent du 0.9375rem de la table (reset « font: inherit ») :
   sous 16px, Safari iOS zoome automatiquement à la mise au point — audit
   UI 18/09 (S-02). On les maintient à 1rem. */
.ui-table .ui-input,
.ui-table .ui-select,
.ui-table .ui-textarea {
  font-size: 1rem;
}

.ui-table th,
.ui-table td {
  padding: var(--space-3) var(--space-4);
  text-align: left;
  border-bottom: 1px solid var(--color-border);
}

.ui-table th {
  font-weight: 600;
  background: var(--color-primary-soft);
  color: var(--color-text);
}

/* Tri colonnes via lien (tri SQL sur tout le filtre / pagination). */
.portal-th-sort,
.ui-th-sort {
  color: inherit;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: 0.2rem;
  font-weight: inherit;
}
.portal-th-sort:hover,
.ui-th-sort:hover {
  text-decoration: underline;
}
.portal-th-sort--active,
.ui-th-sort--active {
  font-weight: 600;
}

.ui-table th.ui-sortable-header {
  cursor: pointer;
  user-select: none;
  white-space: nowrap;
}

.ui-table th .ui-sort-indicator {
  display: inline-block;
  margin-left: var(--space-2);
  min-width: 1.2em;
  color: var(--color-text-muted);
}

.ui-th-sort--active .ui-sort-indicator {
  color: var(--color-text);
  font-weight: 600;
}

.ui-table tr:last-child td {
  border-bottom: none;
}

.ui-table tr:hover td {
  background: rgba(232, 243, 236, 0.35);
}

/* Liste produits (catalogue) : table remplit le scroll, colonnes serrées + sauts de ligne. */
.catalog-product-list-page__table {
  width: 100%;
  min-width: 36rem;
  table-layout: auto;
}

/* En-têtes : pas de césure discrétionnaire type « charac-teristics ». */
.catalog-product-list-page__table th {
  hyphens: none;
  -webkit-hyphens: none;
  word-break: normal;
  overflow-wrap: normal;
}

/* Contenu : peut couper de très longs tokens sans césure automatique. */
.catalog-product-list-page__table td {
  word-break: normal;
  hyphens: none;
  -webkit-hyphens: none;
  overflow-wrap: break-word;
  vertical-align: top;
}

/* Colonne produit enrichie (Phase 5). */
.catalog-product-list-page__table th.catalog-product-list-page__th-product,
.catalog-product-list-page__table td.catalog-product-list-page__td-product {
  min-width: 14rem;
  max-width: 22rem;
  white-space: normal;
  vertical-align: top;
}

.catalog-product-list-page__th-product-inner {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 0.125rem;
}

.catalog-product-list-page__th-subsort {
  font-size: 0.75rem;
  font-weight: 500;
  opacity: 0.85;
}

.catalog-product-list-product-cell {
  display: flex;
  gap: var(--space-3);
  align-items: flex-start;
}

.catalog-product-list-product-cell__thumb {
  flex-shrink: 0;
}

.catalog-product-list-product-cell__img {
  width: 56px;
  height: 56px;
}

.catalog-product-list-product-cell__thumb-placeholder {
  display: block;
  width: 56px;
  height: 56px;
  border-radius: var(--radius-xs);
  border: 1px dashed var(--border-color);
  background: var(--surface-muted, var(--bg-muted));
}

.catalog-product-list-product-cell__body {
  min-width: 0;
  flex: 1;
}

.catalog-product-list-product-cell__primary {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.25rem 0.5rem;
  line-height: 1.3;
}

.catalog-product-list-product-cell__name {
  font-weight: 600;
}

.catalog-product-list-product-cell__ref {
  font-size: 0.8125rem;
  color: var(--text-muted);
}

.catalog-product-list-product-cell__meta {
  margin-top: 0.125rem;
  font-size: 0.8125rem;
  color: var(--text-muted);
  line-height: 1.35;
}

.catalog-product-list-product-cell__meta-sep {
  margin: 0 0.25rem;
}

.catalog-product-list-product-cell__supplier {
  color: inherit;
}

.catalog-product-list-product-cell__footer {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.5rem 0.75rem;
  margin-top: var(--space-2);
}

.catalog-product-list-product-cell__status {
  display: inline-flex;
  align-items: center;
  padding: 2px 8px;
  border-radius: 999px;
  font-size: 0.6875rem;
  font-weight: 600;
  line-height: 1.4;
  text-transform: uppercase;
  letter-spacing: 0.02em;
}

.catalog-product-list-product-cell__status--active {
  background: color-mix(in srgb, var(--color-success) 18%, transparent);
  color: var(--color-success);
}

.catalog-product-list-product-cell__status--draft {
  background: var(--surface-muted, var(--bg-muted));
  color: var(--text-muted);
}

.catalog-product-list-product-cell__status--archived {
  background: color-mix(in srgb, var(--color-danger) 15%, transparent);
  color: var(--color-danger);
}

.catalog-product-list-product-cell__status--dpp-published {
  background: color-mix(in srgb, var(--color-primary) 16%, transparent);
  color: var(--color-primary);
}

.catalog-product-list-product-cell__status--dpp-unpublished {
  background: var(--surface-muted, var(--bg-muted));
  color: var(--text-muted);
  border: 1px dashed color-mix(in srgb, var(--color-border) 70%, transparent);
}

/* Colonnes nom, collection, fournisseur (legacy / autres vues). */
.catalog-product-list-page__table th.catalog-product-list-page__th-name,
.catalog-product-list-page__table td.catalog-product-list-page__td-name {
  min-width: 6rem;
  max-width: 10rem;
  white-space: normal;
  vertical-align: top;
}

.catalog-product-list-page__table th.catalog-product-list-page__th-tight,
.catalog-product-list-page__table td.catalog-product-list-page__td-tight {
  min-width: 5.5rem;
  max-width: 8.5rem;
  white-space: normal;
  line-height: 1.3;
  font-size: 0.875rem;
  vertical-align: top;
}

/* Intitulés d’attributs : retrait à la ligne sur espaces, colonnes resserrées. */
.catalog-product-list-page__table th.catalog-product-list-page__th-attr,
.catalog-product-list-page__table td.catalog-product-list-page__td-attr {
  max-width: 11rem;
  min-width: 7rem;
  width: 8rem;
  box-sizing: border-box;
  white-space: normal;
  line-height: 1.25;
  font-size: 0.8rem;
  font-weight: 500;
  vertical-align: top;
  padding: var(--space-2) var(--space-3);
  text-align: left;
}

.catalog-product-list-page__table th.catalog-product-list-page__th-attr {
  font-weight: 600;
}

/* Pagination riche partagée (listes produits, portail, ventes, …). */
.ui-list-pagination,
.catalog-product-list-pagination {
  flex: 0 0 auto;
  margin-top: auto;
  justify-content: space-between;
  row-gap: var(--space-3);
  padding-top: var(--space-3);
  border-top: none;
}

.ui-list-pagination__range,
.catalog-product-list-pagination__range {
  flex: 1 1 auto;
  min-width: 10rem;
  margin: 0;
}

.ui-list-pagination__pages,
.catalog-product-list-pagination__pages {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 0.25rem;
}

.ui-list-pagination__ellipsis,
.catalog-product-list-pagination__ellipsis {
  padding: 0 0.35rem;
  color: var(--color-text-muted);
  user-select: none;
}

.ui-list-pagination__page--current,
.catalog-product-list-pagination__page--current {
  pointer-events: none;
}

.ui-list-pagination__jump,
.catalog-product-list-pagination__jump {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
}

.ui-list-pagination__jump-label,
.catalog-product-list-pagination__jump-label {
  margin: 0;
  white-space: nowrap;
}

.ui-list-pagination__jump-input,
.catalog-product-list-pagination__jump-input {
  width: 4.5rem;
}

/* Densité lignes : confortable (défaut) vs compact. */
.catalog-product-list-page__density-menu {
  position: relative;
}

.catalog-product-list-page__density-menu .ui-action-menu__panel {
  left: 0;
  right: auto;
}

.catalog-product-list-page__density-panel {
  min-width: 11rem;
  padding: var(--space-3);
}

.catalog-product-list-page__density-panel .ui-action-menu__heading {
  padding-left: 0;
  padding-right: 0;
}

.catalog-product-list-page__density-panel .ui-action-menu__item {
  padding-left: 0;
  padding-right: 0;
}

.catalog-product-list-page__density-list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.catalog-product-list-page--density-compact .catalog-product-list-page__table td,
.catalog-product-list-page--density-compact .catalog-product-list-page__table th {
  padding-top: var(--space-1);
  padding-bottom: var(--space-1);
}

.catalog-product-list-page--density-compact .catalog-product-list-product-cell__img,
.catalog-product-list-page--density-compact .catalog-product-list-product-cell__thumb-placeholder {
  width: 40px;
  height: 40px;
}

.catalog-product-list-page--density-compact .catalog-product-list-product-cell {
  gap: var(--space-2);
}

.catalog-product-list-page--density-compact .catalog-product-list-product-cell__meta,
.catalog-product-list-page--density-compact .catalog-product-list-product-cell__ref {
  font-size: 0.75rem;
}

.catalog-product-list-page--density-compact .catalog-product-list-product-cell__footer {
  margin-top: var(--space-1);
  gap: 0.35rem 0.5rem;
}

.catalog-product-list-page--density-compact .catalog-product-list-product-cell__status {
  font-size: 0.625rem;
  padding: 1px 6px;
}

/* Lignes : hover et focus clavier. */
.catalog-product-list-page__table tbody tr.catalog-product-list-page__row:hover td {
  background: rgba(232, 243, 236, 0.45);
}

.catalog-product-list-page__table tbody tr.catalog-product-list-page__row:focus-within td {
  background: color-mix(in srgb, var(--color-primary) 10%, var(--color-surface));
}

@media (max-width: 48em) {
  .ui-list-pagination,
  .catalog-product-list-pagination {
    flex-direction: column;
    align-items: stretch;
  }

  .ui-list-pagination__pages,
  .ui-list-pagination__jump,
  .catalog-product-list-pagination__pages,
  .catalog-product-list-pagination__jump {
    justify-content: center;
  }

  .catalog-product-list-page__toolbar-controls {
    flex-wrap: wrap;
  }

  .catalog-product-list-page__toolbar-actions {
    width: 100%;
    justify-content: flex-end;
  }
}

/* Tri client : on autorise le retour à la ligne (sauf photo ci-dessous). */
.catalog-product-list-page__table th.ui-sortable-header {
  white-space: normal;
}

/* Colonne visuelle (photo) : en-tête et cellule sur une ligne (gagne sur .ui-sortable-header). */
.catalog-product-list-page__table th.ui-table-col--narrow,
.catalog-product-list-page__table th.ui-table-col--narrow.ui-sortable-header,
.catalog-product-list-page__table tbody tr > td:first-child {
  white-space: nowrap;
  overflow: visible;
}

/* Classement ventes : réutilise la grille catalogue (toolbar, pagination, colonnes).
   La page empile KPI + carte + tableau ⇒ flux normal scrollable, sans hauteur
   verrouillée au viewport : le tableau prend sa hauteur naturelle (sinon écrasé). */
.sales-leaderboard-page.catalog-product-list-page {
  gap: var(--space-4);
}

.sales-leaderboard-page .catalog-product-list-page__table-card,
.sales-leaderboard-page .catalog-product-list-page__table-body {
  flex: 0 0 auto;
  overflow: visible;
}

.sales-leaderboard-page .catalog-product-list-page__table-scroll {
  max-height: 60vh;
}

/* -------------------------------------------------------------------------- */
/* Page ventes — Carte choroplèthe volume de ventes par pays fournisseur      */
/* -------------------------------------------------------------------------- */

.sales-overview-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.sales-country-map-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.sales-country-map-card__head {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.sales-country-map-card__subtitle {
  font-size: var(--fs-sm);
}

.sales-country-map-wrap {
  position: relative;
  min-height: 360px;
}

.sales-country-map {
  width: 100%;
  height: 360px;
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border-subtle);
  overflow: hidden;
  z-index: 0;
}

.sales-country-map.leaflet-container {
  background: color-mix(in srgb, var(--color-primary-soft) 55%, var(--color-bg));
}

/* Fond de carte volontairement désaturé/éclairci : transforme les tuiles OSM
   colorées et chargées en un canevas gris clair, pour que la donnée (vert) ressorte. */
.sales-country-map .leaflet-tile-pane {
  filter: grayscale(1) brightness(1.12) contrast(0.9);
}

.sales-country-map .leaflet-tile-pane::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: var(--color-primary-soft);
  opacity: 0.1;
  mix-blend-mode: soft-light;
}

.sales-country-map-empty {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: var(--space-4);
  margin: 0;
  border-radius: var(--radius-md);
  background: var(--color-surface);
  border: 1px dashed var(--color-border-subtle);
}

/* L'attribut [hidden] (basculé par le JS quand des ventes existent) doit gagner
   sur `display: flex` ci-dessus, sinon l'overlay opaque masque la carte en permanence. */
.sales-country-map-empty[hidden] {
  display: none;
}

.sales-country-map-legend {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--fs-sm);
  color: var(--color-text-muted);
}

.sales-country-map-legend__bar {
  flex: 1 1 auto;
  height: 0.5rem;
  max-width: 16rem;
  border-radius: var(--radius-pill, 999px);
  background: linear-gradient(
    to right,
    rgb(186, 224, 200),
    rgb(27, 84, 56)
  );
}

.sales-leaderboard-toolbar.catalog-product-list-page__toolbar {
  flex-wrap: nowrap;
  align-items: center;
  gap: var(--space-2) var(--space-3);
}

.sales-leaderboard-toolbar .catalog-product-list-page__filters {
  flex: 1 1 auto;
  min-width: 0;
}

.sales-leaderboard-filter-zone.catalog-product-list-page__filter-zone {
  margin-top: 0;
}

.sales-leaderboard-toolbar__actions {
  flex: 0 0 auto;
  margin-left: auto;
  display: flex;
  align-items: center;
  align-self: center;
}

@media (max-width: 48em) {
  .sales-leaderboard-toolbar.catalog-product-list-page__toolbar {
    flex-wrap: wrap;
  }
}

.catalog-product-list-htmx-shell #sales-leaderboard-loading.htmx-indicator.htmx-request {
  display: flex;
}

.catalog-product-list-htmx-shell #sales-leaderboard-loading.htmx-request ~ #sales-leaderboard-results {
  opacity: 0.55;
  pointer-events: none;
  transition: opacity var(--duration-fast, 0.15s) var(--ease-out, ease-out);
}

.catalog-product-list-htmx-shell > #sales-leaderboard-results {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;
  overflow: hidden;
}

.sales-leaderboard-results__top {
  margin-bottom: var(--space-2);
}

.sales-leaderboard-results__heading-row {
  width: 100%;
  align-items: center;
  gap: var(--space-3);
}

.sales-leaderboard-results__title-group {
  align-items: center;
  gap: var(--space-2);
}

.sales-leaderboard-group-switch {
  flex-shrink: 0;
}

.sales-leaderboard-group-switch__track-link {
  display: inline-flex;
  margin: 0;
  cursor: pointer;
  text-decoration: none;
}

.sales-leaderboard-group-switch .trace-view-switch__label {
  text-decoration: none;
  color: var(--color-text-muted);
}

.sales-leaderboard-group-switch:not(.sales-leaderboard-group-switch--supplier) .trace-view-switch__label--tree,
.sales-leaderboard-group-switch--supplier .trace-view-switch__label--map {
  color: var(--color-text);
  font-weight: 600;
}

.sales-leaderboard-group-switch--supplier .trace-view-switch__track {
  background: var(--color-primary);
}

.sales-leaderboard-group-switch--supplier .trace-view-switch__thumb {
  transform: translateX(calc(3.2rem - 1.95rem));
}

.ui-table__col-narrow {
  width: 1%;
  white-space: nowrap;
  vertical-align: middle;
}

.ui-badge {
  display: inline-flex;
  align-items: center;
  padding: 4px 10px;
  border-radius: 999px;
  font-size: 0.75rem;
  font-weight: 600;
}

.ui-badge--neutral {
  background: var(--color-bg);
  color: var(--color-text-muted);
}

.ui-badge--warning {
  background: rgba(183, 121, 43, 0.15);
  color: var(--color-accent-amber-deep);
}

.ui-badge--success {
  background: rgba(21, 128, 61, 0.12);
  color: var(--color-success);
}

.ui-badge--danger {
  background: rgba(180, 35, 24, 0.1);
  color: var(--color-danger);
}

/* Espacements utilitaires pour des badges empilés en flux (cellules de table). */
.ui-badge--inline-stack {
  margin-right: var(--space-2);
  margin-bottom: var(--space-1);
}

.ui-modal-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(31, 41, 55, 0.35);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-6);
  z-index: 40;
}

.ui-modal {
  background: var(--color-surface);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-md);
  max-width: 480px;
  width: 100%;
  padding: var(--space-6);
}

.ui-loader {
  width: 2rem;
  height: 2rem;
  border: 3px solid var(--color-primary-soft);
  border-top-color: var(--color-primary);
  border-radius: 50%;
  animation: ui-spin 0.7s linear infinite;
}

.ui-link-tabs {
  margin-bottom: var(--space-5);
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  align-items: center;
}

.ui-link-tab {
  display: inline-flex;
  align-items: center;
  padding: 6px 12px;
  border: 1px solid var(--color-border);
  border-radius: 999px;
  text-decoration: none;
  font-size: 0.875rem;
  color: var(--color-text-muted);
  background: var(--color-surface);
  transition: background 0.15s, border-color 0.15s, color 0.15s;
}

.ui-link-tab:hover {
  border-color: var(--color-primary);
  color: var(--color-text);
  background: var(--color-primary-soft);
}

.ui-link-tab.is-active,
.ui-link-tab[aria-current="page"] {
  border-color: var(--color-primary);
  color: var(--color-text);
  background: var(--color-primary-soft);
  font-weight: 600;
}

.ui-link-tab__count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.5rem;
  margin-left: var(--space-2);
  padding: 0 6px;
  border-radius: 999px;
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  color: var(--color-text-muted);
  font-size: 0.75rem;
  font-weight: 500;
  line-height: 1.4;
}

.ui-link-tab.is-active .ui-link-tab__count,
.ui-link-tab[aria-current="page"] .ui-link-tab__count {
  background: var(--color-surface);
  border-color: var(--color-primary);
  color: var(--color-primary);
}

/* HTMX : l’élément .htmx-indicator est masqué par défaut. HTMX pose la
   classe .htmx-request sur la cible pendant la requête (ou sur l'indicator
   lui-même), ce qui révèle le placeholder. */
.htmx-indicator {
  display: none;
}

.htmx-request .htmx-indicator,
.htmx-request.htmx-indicator {
  display: block;
}

/* Supplier certificates tab: serialize HTMX actions + loading overlay (hx-indicator target). */
.supplier-certificates-htmx-shell {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
}

/* Onglet certificats fournisseur / site : formulaire + tableau dans la même carte blanche. */
.supplier-certificates-card__body {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

#supplier-certificates-tab.supplier-certificates-tab-stack {
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
}

/* Certificats fournisseur / site : ligne d’ajout (champs + bouton), même grille que Sites. */
.supplier-certificates-add-form {
  display: grid;
  align-items: end;
  column-gap: var(--space-3);
  row-gap: var(--space-3);
  width: 100%;
  margin-bottom: var(--space-4);
}

.supplier-certificates-add-form > .ui-field {
  margin-bottom: 0;
  min-width: 0;
}

.supplier-certificates-add-form > input[type="hidden"] {
  display: none;
}

.supplier-certificates-add-form > .ui-field .ui-select,
.supplier-certificates-add-form > .ui-field .ui-input {
  max-width: none;
}

.supplier-certificates-add-form > .ui-btn {
  justify-self: end;
  white-space: nowrap;
  align-self: end;
  min-height: 2.5rem;
}

.supplier-certificates-add-form--supplier,
.supplier-certificates-add-form--site {
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) auto;
}

@media (max-width: 48em) {
  .supplier-certificates-add-form--supplier,
  .supplier-certificates-add-form--site {
    grid-template-columns: 1fr;
  }

  .supplier-certificates-add-form > .ui-btn {
    justify-self: stretch;
  }
}

/* Fournisseur — onglet Sites de production : formulaire d’ajout sur une ligne. */
.supplier-sites-create-form {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1.25fr) minmax(5.5rem, auto) auto;
  align-items: end;
  column-gap: var(--space-3);
  row-gap: var(--space-3);
  margin-bottom: var(--space-5);
}

.supplier-sites-create-form > .ui-field {
  margin-bottom: 0;
  min-width: 0;
}

.supplier-sites-create-form__country .ui-input {
  max-width: 6rem;
}

.supplier-sites-create-form > .ui-btn {
  justify-self: end;
}

.supplier-sites-table .supplier-sites-col--name {
  min-width: 9rem;
}

.supplier-sites-table .supplier-sites-col--country {
  width: 6rem;
}

.supplier-sites-country {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  white-space: nowrap;
}


.supplier-sites-table .supplier-sites-col--country .ui-input {
  width: 2.75rem;
  min-width: 0;
  padding-left: var(--space-2);
  padding-right: var(--space-2);
}

.supplier-sites-table .supplier-sites-col--address {
  width: 14%;
  max-width: 10rem;
}

.supplier-sites-table .supplier-sites-col--email {
  width: 20%;
  min-width: 11rem;
}

.supplier-sites-table .supplier-sites-col--draft,
.supplier-sites-table .supplier-sites-col--count {
  width: 5.5rem;
  white-space: nowrap;
}

.supplier-sites-table .supplier-sites-col--address .ui-input,
.supplier-sites-table .supplier-sites-col--email .ui-input {
  width: 100%;
  max-width: none;
}

.supplier-certificates-card__table {
  margin-top: 0;
}

.supplier-certificates-unified {
  width: 100%;
}

.supplier-certificate-add-section {
  margin-top: 0;
}

.supplier-certificates-htmx-loading {
  position: absolute;
  inset: 0;
  z-index: 3;
  align-items: center;
  justify-content: center;
  gap: var(--space-3);
  background: color-mix(in srgb, var(--color-surface) 78%, transparent);
  border-radius: var(--radius-lg, 10px);
  pointer-events: none;
}

.supplier-certificates-htmx-shell #supplier-certificates-tab-loading.htmx-indicator.htmx-request {
  display: flex;
}

#supplier-certificates-tab-loading.htmx-request + #supplier-certificates-tab {
  opacity: 0.62;
  pointer-events: none;
}

/* Liste dashboard certificats PENDING : validation inline HTMX + overlay. */
.pending-certificates-htmx-shell {
  position: relative;
}

.pending-certificates-htmx-loading {
  position: absolute;
  inset: 0;
  z-index: 3;
  display: none;
  align-items: center;
  justify-content: center;
  gap: var(--space-3);
  background: color-mix(in srgb, var(--color-surface) 78%, transparent);
  border-radius: var(--radius-lg, 10px);
  pointer-events: none;
}

.pending-certificates-htmx-shell #pending-certificates-htmx-loading.htmx-indicator.htmx-request {
  display: flex;
}

#pending-certificates-htmx-loading.htmx-request + #pending-certificates-panel {
  opacity: 0.62;
  pointer-events: none;
}

.ui-loader--inline {
  width: 1.1rem;
  height: 1.1rem;
  border-width: 2px;
  flex-shrink: 0;
}

@keyframes ui-spin {
  to {
    transform: rotate(360deg);
  }
}

.ui-toast-area {
  position: fixed;
  /* topbar desktop = padding (--space-4 × 2) + h-btn + 1px border + air ;
     ~88px → on cale les toasts juste sous le header pour ne pas masquer
     le bouton de déconnexion. */
  top: calc(var(--space-4) * 2 + var(--h-btn) + var(--space-3));
  right: var(--space-5);
  z-index: var(--z-toast);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  max-width: 28rem;
  width: calc(100vw - var(--space-8));
}

.ui-toast {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-4) var(--space-4) var(--space-4) var(--space-5);
  border-radius: var(--radius-md);
  font-size: var(--fs-base);
  line-height: var(--lh-base);
  box-shadow: var(--shadow-lg);
  border: 1px solid var(--color-border);
  border-left-width: 4px;
  background: var(--color-surface);
  color: var(--color-text);
}

.ui-toast__body {
  flex: 1;
  min-width: 0;
  padding-top: 2px;
  font-weight: var(--fw-medium);
}

.ui-toast__close {
  flex-shrink: 0;
  margin: -4px -4px -4px 0;
  width: 2.25rem;
  height: 2.25rem;
  border: none;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--color-text-muted);
  font-size: 1.5rem;
  line-height: 1;
  cursor: pointer;
}

.ui-toast__close:hover {
  background: rgba(0, 0, 0, 0.06);
  color: var(--color-text);
}

.ui-toast--success {
  border-color: var(--color-success);
  background: var(--color-success-bg);
}

.ui-toast--error {
  border-color: var(--color-danger);
  background: var(--color-danger-bg);
}

.ui-toast--info {
  border-color: var(--color-accent-amber);
  background: var(--color-warning-bg);
}

.ui-messages {
  list-style: none;
  margin: 0 0 var(--space-4);
  padding: 0;
}

.ui-progress {
  height: 8px;
  border-radius: 999px;
  background: var(--color-border);
  overflow: hidden;
}

.ui-progress__bar {
  height: 100%;
  width: var(--fill-pct, 0%);
  border-radius: 999px;
  background: linear-gradient(90deg, var(--color-primary), var(--color-accent-amber));
  transition: width 0.25s ease;
}

/* Supplier portal — submission recap + async indeterminate progress */
.portal-submit-poll__indeterminate {
  height: 10px;
  border-radius: 999px;
  background: var(--color-border);
  overflow: hidden;
  position: relative;
}

.portal-submit-poll__indeterminate::after {
  content: "";
  position: absolute;
  inset: 0;
  width: 42%;
  border-radius: 999px;
  background: linear-gradient(90deg, var(--color-primary), var(--color-accent-amber));
  animation: portal-submit-indeterminate-slide 1.35s ease-in-out infinite;
}

@keyframes portal-submit-indeterminate-slide {
  0% {
    transform: translateX(-30%);
    opacity: 0.85;
  }
  50% {
    transform: translateX(120%);
    opacity: 1;
  }
  100% {
    transform: translateX(280%);
    opacity: 0.85;
  }
}

@media (prefers-reduced-motion: reduce) {
  .portal-submit-poll__indeterminate::after {
    animation: none;
    left: 0;
    right: 0;
    width: auto;
    transform: none;
    opacity: 0.4;
  }
}

/* After clicking « Validate and submit » (sync wait) or async processing banner */
.portal-submit-progress--post-submit {
  max-width: 100%;
}

.portal-submit-progress__bar--emphasized {
  height: 14px;
  border-radius: 999px;
}

/* Indicateur "soumission en cours" : spinner + barre indeterminee animee. */
.portal-submit-poll__active {
  display: flex;
  align-items: center;
  gap: var(--space-3);
}

.portal-submit-poll__active .portal-submit-poll__indeterminate {
  flex: 1 1 auto;
}

.portal-submit-poll__active .portal-submit-poll__determinate {
  flex: 1 1 auto;
  height: 14px;
}

.portal-submit-poll__spinner {
  flex: 0 0 auto;
  width: 1.5rem;
  height: 1.5rem;
}

.portal-submit-inflight {
  padding: var(--space-3);
  border-radius: var(--radius-md, 12px);
  border: 1px solid var(--color-border);
  background: var(--color-surface);
}

.portal-submit-busy-overlay {
  position: fixed;
  inset: 0;
  z-index: calc(var(--z-modal) + 2);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-4);
  background: rgba(15, 18, 22, 0.42);
  backdrop-filter: blur(2px);
}

/* `hidden` + author `display:flex` : sans ceci l’overlay reste visible au chargement */
.portal-submit-busy-overlay[hidden] {
  display: none !important;
}

.portal-submit-busy-overlay__panel {
  max-width: 28rem;
  width: 100%;
  padding: var(--space-4);
  border-radius: var(--radius-md, 12px);
  border: 1px solid var(--color-border);
  background: var(--color-surface);
  box-shadow: var(--shadow-lg);
}

/* Bouton rouge sticky : CTA de soumission, centre en bas, sur toutes les pages. */
.portal-submit-sticky {
  position: fixed;
  left: 50%;
  bottom: var(--space-5, 20px);
  transform: translateX(-50%);
  z-index: calc(var(--z-modal) - 1);
  display: flex;
  justify-content: center;
  pointer-events: none;
  padding: 0 var(--space-4);
  max-width: 100%;
}

/* Le bouton est toujours dans le document et basculé par la saisie : [hidden]
   doit gagner sur le `display: flex` ci-dessus. */
.portal-submit-sticky[hidden] {
  display: none;
}

.portal-submit-sticky__cta {
  pointer-events: auto;
  box-shadow: var(--shadow-lg);
  border-radius: 999px;
  padding-inline: var(--space-5);
  font-weight: 600;
}

/* Modale de soumission : plus large que la modale par defaut, scrollable. */
.portal-submit-modal {
  position: relative;
  max-width: 960px;
  width: min(960px, 94vw);
  max-height: min(90vh, 1000px);
  overflow-y: auto;
  overscroll-behavior: contain;
}

/* Spinner de chargement (indicateur HTMX) pendant le fetch du corps de modale.
   Affichage pilote par la classe `htmx-request` (et non l'opacite par defaut)
   pour ne pas reserver d'espace quand le contenu est charge. */
.portal-submit-modal__loading {
  display: none;
}

.portal-submit-modal__loading.htmx-request {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 220px;
  opacity: 1;
}

.portal-submit-modal__close {
  position: absolute;
  top: var(--space-3);
  right: var(--space-3);
}

.portal-submit-modal[data-submitting="true"] .portal-submit-modal__close {
  display: none;
}

.portal-submit-modal__header {
  margin-bottom: var(--space-4);
  padding-right: var(--space-6);
}

.portal-submit-modal__alert-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-3);
  margin-bottom: var(--space-2);
}

.portal-submit-modal__alert-header .ui-heading-2 {
  margin: 0;
}

.portal-submission-cert-excluded-notice {
  margin-bottom: var(--space-3);
}

.portal-certificate-no-standard-notice {
  margin-bottom: var(--space-3);
  color: var(--color-warning);
}

.portal-cert-row--excluded {
  opacity: 0.92;
}

.portal-cert-row--excluded td {
  background: color-mix(in srgb, var(--color-warning-bg) 35%, transparent);
}

.portal-submit-modal__body > .portal-section + .portal-section,
.portal-submit-modal__body > .ui-card + .ui-card {
  margin-top: var(--space-4);
}

.portal-submit-modal::backdrop {
  background: rgba(31, 41, 55, 0.45);
}

/* Attestation + « Valider et soumettre » restent visibles sans faire défiler
   la modale (audit portail 18/09, SUB-01) : la carte qui les porte est la
   dernière du corps, le formulaire colle donc au bord bas du conteneur. */
.portal-declaration-form {
  position: sticky;
  bottom: 0;
  z-index: 1;
  margin-top: var(--space-3);
  padding-top: var(--space-3);
  border-top: 1px solid var(--color-border);
  background: var(--color-surface);
}

.portal-declaration-blocked {
  margin: var(--space-3) 0 0;
  color: var(--color-warning);
  font-weight: 600;
}

/* Le texte d'attente doit se lire d'un coup d'œil pendant l'envoi (SUB-07). */
.portal-submit-busy-overlay__panel .portal-submit-progress__label,
.portal-submit-inflight .portal-submit-progress__label {
  font-size: 1rem;
  font-weight: 600;
  color: var(--color-text);
}

@media (max-width: 640px) {
  .portal-submit-modal {
    max-width: 100%;
    max-height: 100vh;
    border-radius: 0;
  }
  .portal-submit-sticky {
    left: var(--space-3);
    right: var(--space-3);
    transform: none;
    padding: 0;
  }
  .portal-submit-sticky__cta {
    width: 100%;
  }
}

.portal-submission-stackbar {
  display: flex;
  width: 100%;
  min-height: 10px;
  border-radius: 999px;
  overflow: hidden;
  background: var(--color-border);
  gap: 2px;
}

.portal-submission-stackbar__seg {
  min-width: 4px;
  min-height: 10px;
  border-radius: var(--radius-xs);
}

.portal-submission-stackbar__seg--products {
  background: var(--color-primary);
}

.portal-submission-stackbar__seg--production_sites {
  background: var(--color-primary);
}

.portal-submission-stackbar__seg--certs {
  background: var(--color-accent-amber);
}

.portal-submission-breakdown__legend {
  list-style: none;
  margin: var(--space-3) 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3) var(--space-5);
  font-size: 0.875rem;
}

.portal-submission-breakdown__legend li {
  display: flex;
  align-items: center;
  gap: 0.4rem;
}

.portal-submission-breakdown__swatch {
  width: 0.65rem;
  height: 0.65rem;
  border-radius: var(--radius-xs);
  flex-shrink: 0;
}

.portal-submission-breakdown__swatch--products {
  background: var(--color-primary);
}

.portal-submission-breakdown__swatch--production_sites {
  background: var(--color-primary);
}

.portal-submission-breakdown__swatch--certs {
  background: var(--color-accent-amber);
}

.ui-mono {
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
  font-size: 0.875rem;
}

.ui-key-reveal {
  padding: var(--space-4);
  border-radius: var(--radius-md);
  background: var(--color-primary-soft);
  border: 1px dashed var(--color-primary);
  word-break: break-all;
}

.p-main--narrow {
  max-width: 28rem;
  margin: 0 auto;
  padding: var(--space-8) var(--space-4);
}

.p-topbar--simple {
  justify-content: flex-end;
}

.app-topbar {
  justify-content: space-between;
  gap: var(--space-4);
}

.portal-topbar__identity {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  min-width: 0;
}

.portal-topbar__portal-label {
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--color-text);
  white-space: nowrap;
}

.portal-topbar__separator {
  color: var(--color-text-muted);
  font-weight: 600;
  line-height: 1;
}

.portal-topbar__supplier-name {
  font-size: 0.9375rem;
  font-weight: 500;
  color: var(--color-text-muted);
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.portal-topbar__supplier-block {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  min-width: 0;
}

.portal-topbar__brand {
  display: block;
  margin-top: 0.125rem;
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--color-text-muted);
}

.p-topbar__start {
  display: flex;
  align-items: center;
  min-width: 0;
}

.p-topbar__end {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-shrink: 0;
}

/* Barre haute de l'app — la seule barre, à toutes les largeurs : bouton du
   tiroir (sous 48 em), fil d'Ariane, langue. Collée en haut. */
.app-topbar {
  position: sticky;
  top: 0;
  z-index: var(--z-sticky);
  min-height: 3.25rem;
  gap: var(--space-2);
  padding-block: var(--space-2);
}

.app-topbar .ui-breadcrumb ol {
  margin: 0;
}

.app-topbar .p-topbar__start {
  flex: 1 1 auto;
}

/* Le bouton du tiroir n'existe que sous le point de rupture : au-dessus, la
   barre latérale est une navigation permanente. */
.p-topbar__burger {
  display: none;
  flex: none;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  margin-left: calc(var(--space-2) * -1);
  padding: 0;
  border: 0;
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--color-text);
  cursor: pointer;
}

.p-topbar__burger:hover {
  background: var(--color-primary-soft);
}

.p-topbar__burger:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
}

.p-topbar__burger svg {
  display: block;
}

@media (max-width: 48em) {
  .p-topbar__burger {
    display: inline-flex;
  }

  .app-topbar {
    padding-inline: var(--space-4);
  }
}

/* --- Marque -------------------------------------------------------------
   Le nom en sérif, en capitales espacées, sans pavé de couleur : la tenue
   vient de la lettre (chantier UI 20/09/2026, lot 2 a). */
.p-sidebar__head {
  margin-bottom: var(--space-4);
  padding: var(--space-2) var(--space-4) var(--space-5);
  border-bottom: 1px solid var(--color-border-subtle);
}

.p-sidebar__brand {
  display: block;
  font-family: var(--font-serif);
  font-size: 1.25rem;
  font-weight: var(--fw-regular);
  letter-spacing: 0.28em;
  text-transform: uppercase;
  line-height: 1.2;
  color: var(--color-text);
  text-decoration: none;
}

.p-sidebar__brand:hover {
  color: var(--color-text);
  font-weight: var(--fw-semibold);
  text-decoration: none;
}

.p-sidebar__brand:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 3px;
}

.p-sidebar__org {
  display: block;
  margin-top: var(--space-1);
  font-size: var(--fs-sm);
  color: var(--color-text-muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* --- Compte en pied de barre latérale --------------------------------------
   Remplace le bouton « Déconnexion » de la barre haute, qui occupait sur
   toutes les pages la place de l'action principale. */
.p-sidebar__foot {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  margin-top: auto;
  padding-top: var(--space-3);
  border-top: 1px solid var(--color-border-subtle);
}

.p-me {
  display: flex;
  flex: 1;
  align-items: center;
  gap: var(--space-3);
  min-width: 0;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-md);
  color: var(--color-text);
  text-decoration: none;
}

.p-me:hover {
  background: var(--color-primary-soft);
  text-decoration: none;
}

.p-me:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
}

.p-me__avatar {
  display: grid;
  flex-shrink: 0;
  place-items: center;
  width: 2rem;
  height: 2rem;
  border-radius: var(--radius-sm);
  background: var(--color-primary);
  color: var(--color-on-primary);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
}

.p-me__id {
  min-width: 0;
  line-height: 1.3;
}

.p-me__name,
.p-me__sub {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.p-me__name {
  font-size: var(--fs-sm);
  font-weight: var(--fw-medium);
}

.p-me__sub {
  font-size: var(--fs-xs);
  color: var(--color-text-muted);
}

/* --- Portail fournisseur : densité guidée ---------------------------------
   Le fournisseur saisit peu, rarement, souvent sur téléphone. Corps à 15 px
   (contre 14) et cibles tactiles partout, pas seulement sous le point de
   rupture (audit UI 20/09, lot 3). */
.portal-body {
  font-size: 0.9375rem;
}

.portal-body .ui-btn,
.portal-body .ui-input,
.portal-body .ui-select,
.portal-body .p-sidebar__nav a {
  min-height: 44px;
}

.portal-body .ui-btn--compact {
  min-height: 40px;
}

.portal-body .ui-dropzone__label {
  min-height: 44px;
}

/* Ligne de progression sous le titre, sur chaque page du portail. */
.portal-progress-line {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2) var(--space-3);
}

.portal-progress-line .ui-meter {
  width: 8rem;
}

.portal-progress-line__pct {
  font-weight: var(--fw-semibold);
  font-variant-numeric: tabular-nums;
  color: var(--color-text);
}

.p-me--static {
  cursor: default;
}

.p-me--static:hover {
  background: transparent;
}

.p-me__logout-form {
  flex-shrink: 0;
  margin: 0;
}

.p-me__logout {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.25rem;
  height: 2.25rem;
  padding: 0;
  border: 1px solid transparent;
  border-radius: var(--radius-md);
  background: transparent;
  color: var(--color-text-muted);
  cursor: pointer;
}

.p-me__logout:hover {
  color: var(--color-danger);
  background: var(--color-danger-bg);
}

.p-me__logout:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
}

.p-me__logout svg {
  display: block;
}

@media (max-width: 48em) {
  .p-me {
    min-height: 44px;
  }

  .p-me__logout {
    width: 44px;
    height: 44px;
  }
}

/* --- En-tête de page (layouts/app.html) --------------------------------------
   Sur-titre, <h1> en sérif, ligne de contexte ; actions à droite. */
.p-page-header {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--space-4) var(--space-5);
  margin-bottom: var(--space-6);
  padding-bottom: var(--space-5);
  border-bottom: 1px solid var(--color-border);
}

.p-page-header__lead {
  flex: 1 1 20rem;
  min-width: 0;
}

.p-page-header__eyebrow {
  margin: 0 0 var(--space-2);
  font-size: var(--fs-xs);
  font-weight: var(--fw-semibold);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--color-text-faint);
}

.p-page-header__title {
  margin: 0;
  font-family: var(--font-serif);
  font-size: clamp(1.75rem, 1.2rem + 1.4vw, 2.25rem);
  font-weight: var(--fw-regular);
  letter-spacing: -0.015em;
  line-height: 1.1;
  color: var(--color-text);
  overflow-wrap: anywhere;
}

.p-page-header__meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-3);
  margin: var(--space-2) 0 0;
  font-size: var(--fs-sm);
  color: var(--color-text-muted);
}

.p-page-header__actions {
  display: flex;
  flex: none;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
}

/* Téléphone : l'en-tête se déplie, les actions occupent la largeur et
   atteignent la cible tactile de 44 px. */
@media (max-width: 48em) {
  .p-main {
    padding: var(--space-6) var(--space-4) var(--space-10);
  }

  .p-page-header {
    margin-bottom: var(--space-5);
    padding-bottom: var(--space-4);
  }

  .p-page-header__actions {
    flex: 1 1 100%;
  }

  .p-page-header__actions > .ui-btn,
  .p-page-header__actions form > .ui-btn {
    flex: 1 1 auto;
    min-height: 44px;
  }
}

/* Portail sur écran bas (PC Windows à 150 % : 580 px, ou zoom) : l'en-tête se
   resserre. Titre de 36 à 24 px et marges réduites ; le contenu commençait sous le
   tiers de l'écran (audit zoom du 25/09/2026). */
@media (max-height: 43.75em) {
  .portal-body .p-main {
    padding-top: var(--space-5);
  }

  .portal-body .p-page-header {
    gap: var(--space-2) var(--space-4);
    margin-bottom: var(--space-4);
    padding-bottom: var(--space-3);
  }

  .portal-body .p-page-header__title {
    font-size: var(--fs-xl);
  }

  .portal-body .p-page-header__meta {
    margin-top: var(--space-1);
  }
}

.p-sidebar__nav {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin-top: 0;
}

/* Colonne de menu de 320 px, seulement tant que le menu est dans la grille : à
   partir de 64 em. En dessous, il passe en tiroir (section « Mobile drawer »).
   Hors média, cette règle l'emportait sur celle du tiroir (deux classes contre
   une) et le contenu restait coincé dans 320 px, le reste de l'écran vide
   (téléphone, zoom 200 % ; audit zoom du 25/09/2026). */
@media (min-width: 64.0625em) {
  .portal-body .p-shell {
    grid-template-columns: 320px 1fr;
  }
}

.p-sidebar__nav a {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-1);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  color: var(--color-text);
  text-decoration: none;
}

.portal-body .p-sidebar__nav--app .p-sidebar__nav-label {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.portal-nav-progress {
  justify-self: end;
  line-height: 1.2;
  font-size: 0.8125rem;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  color: var(--color-text-muted);
}

.portal-nav__badge-slot {
  display: contents;
}

.portal-nav__badge {
  flex-shrink: 0;
  margin-left: auto;
  min-width: 1.25rem;
  padding: 0.125rem 0.375rem;
  border-radius: 999px;
  font-size: 0.75rem;
  font-weight: 600;
  line-height: 1.2;
  font-variant-numeric: tabular-nums;
  text-align: center;
}

.portal-nav__badge--done {
  padding-inline: 0.25rem;
  /* Vert plus sombre que --color-success : 4,5:1 sur le fond teinté. */
  color: var(--color-success-fg);
  background: color-mix(in srgb, var(--color-success) 12%, transparent);
}

.portal-nav__badge--pending {
  color: var(--color-surface);
  background: var(--color-accent-amber-deep);
}

/* Portail : alerte soumission en attente sous le libellé */
.p-sidebar__nav--app a.portal-nav-submission {
  flex-wrap: wrap;
  align-items: flex-start;
}

.p-sidebar__nav a:hover {
  background: var(--color-primary-soft);
  text-decoration: none;
}

.p-sidebar__nav a[aria-current="page"] {
  background: var(--color-primary-soft);
  font-weight: 600;
  color: var(--color-primary);
}

.p-sidebar__nav--app a {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-width: 0;
}

.p-sidebar__nav-icon {
  display: inline-flex;
  flex-shrink: 0;
  align-items: center;
  justify-content: center;
  width: 1.75rem;
  height: 1.75rem;
  border-radius: var(--radius-sm);
  background: var(--color-bg);
  color: var(--color-text-muted);
  transition: background 0.15s ease, color 0.15s ease;
}

.p-sidebar__nav-label {
  min-width: 0;
}

.p-sidebar__nav--app a:hover .p-sidebar__nav-icon,
.p-sidebar__nav--app a[aria-current="page"] .p-sidebar__nav-icon {
  background: var(--color-surface);
  color: var(--color-primary);
}

.p-sidebar__nav--app a[aria-current="page"] .p-sidebar__nav-icon {
  background: rgba(255, 255, 255, 0.72);
}

.settings-account__subsection {
  padding-top: var(--space-4);
  margin-top: var(--space-4);
  border-top: 1px solid var(--color-border);
}

.settings-account__subsection:first-child,
.settings-account__subsection--flush {
  padding-top: var(--space-3);
  margin-top: var(--space-3);
  border-top: 0;
}

.settings-team-add-form {
  display: grid;
  grid-template-columns: minmax(12rem, 2fr) minmax(8rem, 1fr) auto;
  gap: var(--space-2);
  align-items: end;
}

.settings-team-add-form .ui-field {
  margin: 0;
  min-width: 0;
}

.settings-team-add-form__actions {
  display: flex;
  align-items: flex-end;
  padding-bottom: 1px;
}

.settings-team-add-form__actions .ui-btn {
  white-space: nowrap;
}

@media (max-width: 40em) {
  .settings-team-add-form {
    grid-template-columns: 1fr;
  }

  .settings-team-add-form__actions .ui-btn {
    width: 100%;
  }
}

.portal-certificate-row-actions__inline-form {
  display: inline-flex;
  margin: 0;
}

.settings-team-card__table .portal-certificate-table__field {
  min-width: 8rem;
  max-width: 100%;
}

.settings-team-role-form__select {
  min-width: 10rem;
}

@media (max-width: 40em) {
  .settings-team-card__table .portal-certificate-table__field {
    width: 100%;
  }
}

/* Fiche fournisseur — méta pleine largeur (pas de visuel hero) */
.supplier-detail__hero {
  display: block;
  margin-bottom: 0;
}

.supplier-detail__hero-body {
  flex: none;
  width: 100%;
  max-width: none;
}

@media (min-width: 40em) {
  .supplier-detail__hero .product-detail__meta--compact {
    grid-template-columns: repeat(4, minmax(9.5rem, 1fr));
  }
}

.supplier-detail-status-actions {
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding-top: var(--space-4);
  border-top: 1px solid var(--color-border);
}

.supplier-detail-status-actions__primary {
  flex-wrap: wrap;
  gap: var(--space-2);
}

.supplier-portal-link-action {
  margin-left: auto;
  max-width: 100%;
}

.supplier-portal-link-action__text {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-1);
  margin: 0;
  font-size: var(--text-sm, 0.875rem);
  color: var(--color-text-muted);
}

.supplier-portal-link-action__status {
  font-weight: 500;
  color: var(--color-text, inherit);
}

.supplier-portal-link-action__state {
  margin: 0 var(--space-1);
  font-size: 0.8125rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  vertical-align: baseline;
}

.supplier-portal-link-action__form {
  display: inline;
  margin: 0;
}

.supplier-portal-link-action__btn {
  display: inline;
  padding: 0;
  border: 0;
  background: none;
  min-height: 0;
  font: inherit;
  font-weight: 600;
  color: var(--color-primary);
  text-decoration: underline;
  cursor: pointer;
}

.supplier-portal-link-action__btn:hover {
  color: var(--color-primary-hover);
}

.supplier-portal-actions {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  margin-top: var(--space-5);
  padding-top: var(--space-5);
  border-top: 1px solid var(--color-border);
}

.supplier-portal-actions__open .ui-btn {
  display: inline-flex;
}

.supplier-portal-actions__row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  align-items: stretch;
}

.supplier-portal-actions__form {
  margin: 0;
  display: flex;
}

.supplier-portal-actions__form .ui-btn {
  width: 100%;
}

@media (min-width: 40em) {
  /* --bp-sm */
  .supplier-portal-actions__form .ui-btn {
    width: auto;
    min-width: 10rem;
  }
}

.supplier-portal-actions__btn--danger {
  border-color: var(--color-danger);
  color: var(--color-danger);
  background: transparent;
}

.supplier-portal-actions__btn--danger:hover {
  background: rgba(180, 35, 24, 0.08);
  color: var(--color-danger);
}

.supplier-portal-actions__danger {
  padding-top: var(--space-2);
  border-top: 1px dashed var(--color-border);
}

/* Arbre de traçabilité — chaîne horizontale (produit → composants) */
.ui-card:has(.trace-tree) {
  min-width: 0;
}

.trace-tree {
  --trace-line: var(--color-border-strong);
  --trace-line-width: 2px;
  --trace-border: var(--color-border);
  --trace-node-bg: var(--color-surface);
  --trace-pill: var(--color-text-muted);
  /* Zone de scroll interne (grille) : hauteur plafond pour ne pas étirer la page */
  --trace-tree-scroll-max-h: min(70vh, 800px);
  margin-top: var(--space-4);
  padding: var(--space-4);
  background: var(--color-surface-alt);
  border-radius: var(--radius-lg);
  border: 1px solid var(--trace-border);
  box-sizing: border-box;
  width: 100%;
  max-width: 100%;
  min-width: 0;
}

.trace-tree__heading {
  margin: 0 0 var(--space-3);
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-text-muted);
}

.trace-tree__scroller {
  max-width: 100%;
  min-width: 0;
  max-height: var(--trace-tree-scroll-max-h, min(70vh, 800px));
  overflow: auto;
  padding: var(--space-2) var(--space-1) var(--space-4);
  margin: 0 calc(-1 * var(--space-1));
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
}

.trace-tree__chain {
  display: flex;
  flex-direction: row;
  flex-wrap: nowrap;
  align-items: center;
  gap: 0;
  width: max-content;
  min-width: 100%;
}

.trace-tree__lane {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  min-width: min-content;
  max-width: none;
}

.trace-tree__lane--center {
  justify-content: center;
}

.trace-tree__lane--root .trace-tree__root {
  width: auto;
  min-width: min-content;
}

/* Produit + (activités produit alignées au centre du bloc composants) */
.trace-tree__root-mega {
  display: flex;
  flex-direction: row;
  flex-wrap: nowrap;
  align-items: center;
  gap: 0;
  min-width: min-content;
}

.trace-tree__root-rest--vcenter {
  display: flex;
  flex-direction: row;
  flex-wrap: nowrap;
  align-items: center;
  gap: 0;
  min-width: min-content;
}

.trace-tree__root-mega > .trace-node--product {
  flex: 0 0 auto;
  width: min(17rem, 88vw);
  max-width: 17rem;
}

.trace-tree__join {
  flex: 0 0 2.5rem;
  align-self: center;
  height: var(--trace-line-width);
  margin: 0 0.125rem;
  background: var(--trace-line);
  flex-shrink: 0;
}

.trace-tree__join--inline {
  flex: 0 0 1.75rem;
  width: 1.75rem;
  align-self: center;
  height: var(--trace-line-width);
  background: var(--trace-line);
  flex-shrink: 0;
}

.trace-tree__root {
  max-width: none;
}

.trace-tree__root-inner,
.trace-tree__segment-inline,
.trace-tree__material-flow {
  display: flex;
  flex-direction: row;
  flex-wrap: nowrap;
  align-items: center;
  gap: 0;
  min-width: min-content;
}

.trace-tree__root-inner > .trace-node--product,
.trace-tree__root-mega > .trace-node--product,
.trace-tree__root-inner > .trace-node--component,
.trace-tree__root-inner > .trace-node--activity,
.trace-tree__segment-inline > .trace-node--component,
.trace-tree__segment-inline > .trace-node--activity,
.trace-tree__material-flow > .trace-node--material,
.trace-tree__material-flow > .trace-node--activity {
  flex: 0 0 auto;
  width: min(17rem, 88vw);
  max-width: 17rem;
}

.trace-tree__root-inner > .trace-tree__fork,
.trace-tree__segment-inline > .trace-tree__fork,
.trace-tree__material-flow > .trace-tree__fork {
  flex: 0 1 auto;
  align-self: center;
  min-width: min-content;
}

/* Plusieurs activités au même rang (même ActivityType.order) : embranchement */
.trace-tree__fork {
  display: flex;
  flex-direction: row;
  flex-wrap: nowrap;
  align-items: flex-start;
  gap: var(--space-5);
  position: relative;
  padding-top: 0.875rem;
  margin-top: 0.125rem;
}

.trace-tree__fork::before {
  content: "";
  position: absolute;
  top: 0;
  left: 6px;
  right: 6px;
  height: var(--trace-line-width);
  background: var(--trace-line);
}

.trace-tree__fork-branch {
  flex: 1 1 0;
  min-width: min(11rem, 40vw);
  max-width: 17rem;
}

.trace-tree__fork-branch .trace-node--activity {
  width: 100%;
  max-width: none;
}

/* Composants du produit : pile verticale (Tige au-dessus, Semelle en dessous, etc.) */
.trace-tree__fork--components {
  --trace-vfork-gap: var(--space-8);
  flex-direction: column;
  align-items: stretch;
  gap: var(--trace-vfork-gap);
  padding-top: 0;
  margin-top: 0;
  padding-left: var(--space-4);
  margin-left: var(--space-2);
  min-width: min(18rem, 92vw);
  max-width: 28rem;
}

.trace-tree__fork--components::before {
  content: "";
  position: absolute;
  left: calc(-1 * var(--space-4));
  top: calc(50% - (var(--trace-line-width) / 2));
  width: var(--space-4);
  height: var(--trace-line-width);
  background: var(--trace-line);
  z-index: 0;
}

.trace-tree__fork--components::after {
  content: "";
  position: absolute;
  left: calc(-1 * var(--space-4));
  top: 0;
  bottom: 0;
  width: var(--trace-line-width);
  background: var(--trace-line);
  z-index: 0;
}

.trace-tree__fork-branch--component {
  flex: 0 0 auto;
  min-width: 0;
  max-width: none;
  width: 100%;
}

.trace-tree__fork-branch--component > .trace-tree__column {
  position: relative;
  z-index: 1;
  width: 100%;
  min-width: 0;
}

/*
 * Piles verticales (plusieurs composants ou plusieurs matières) :
 * tronc vertical (border-left du fork) + embranchement horizontal vers chaque carte (::before sur la branche).
 */
.trace-tree__fork--components .trace-tree__fork-branch--component,
.trace-tree__fork--materials .trace-tree__fork-branch--material {
  position: relative;
}

.trace-tree__fork--components .trace-tree__fork-branch--component::before,
.trace-tree__fork--materials .trace-tree__fork-branch--material::before {
  content: "";
  position: absolute;
  top: calc(50% - (var(--trace-line-width) / 2));
  height: var(--trace-line-width);
  background: var(--trace-line);
  z-index: 0;
}

.trace-tree__fork--components .trace-tree__fork-branch--component::after,
.trace-tree__fork--materials .trace-tree__fork-branch--material::after {
  display: none;
}

.trace-tree__fork--components .trace-tree__fork-branch--component::before {
  left: calc(-1 * var(--space-4));
  width: var(--space-4);
}

.trace-tree__fork--components .trace-tree__fork-branch--component::after {
  left: calc(-1 * var(--space-4));
}

.trace-tree__fork--materials .trace-tree__fork-branch--material::before {
  left: calc(-1 * var(--space-3));
  width: var(--space-3);
}

.trace-tree__fork--materials .trace-tree__fork-branch--material::after {
  left: calc(-1 * var(--space-3));
}

/* Matières d’un composant : pile verticale (comme les composants) */
.trace-tree__fork--materials {
  --trace-vfork-gap: var(--space-6);
  margin-top: 0;
  width: 100%;
  flex-direction: column;
  align-items: stretch;
  gap: var(--trace-vfork-gap);
  padding-top: 0;
  padding-left: var(--space-3);
}

.trace-tree__fork--materials::before {
  content: "";
  position: absolute;
  left: calc(-1 * var(--space-3));
  top: 0;
  bottom: 0;
  width: var(--trace-line-width);
  background: var(--trace-line);
  z-index: 0;
}

.trace-tree__fork-branch--material {
  flex: 0 0 auto;
  min-width: 0;
  max-width: none;
  width: 100%;
}

.trace-tree__fork-branch--material .trace-tree__material-group {
  position: relative;
  z-index: 1;
  width: 100%;
}

.trace-tree__column {
  min-width: min-content;
  display: flex;
  flex-direction: column;
  gap: 0;
}

.trace-tree__column-body {
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
  min-width: min-content;
}

.trace-tree__material-group {
  min-width: min-content;
}

.trace-tree__empty {
  margin: var(--space-3) 0 0;
  text-align: center;
}

.trace-grid__scroll {
  box-sizing: border-box;
  width: 100%;
  max-width: 100%;
  min-width: 0;
  max-height: var(--trace-tree-scroll-max-h, min(70vh, 800px));
  overflow-x: auto;
  overflow-y: auto;
  padding-bottom: var(--space-3);
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
}

.trace-view-toolbar {
  align-items: center;
  gap: var(--space-3);
}

.trace-view-switch {
  display: inline-flex;
  align-items: center;
  gap: 0.625rem;
  flex-shrink: 0;
}

.trace-view-switch__label {
  font-size: 0.8125rem;
  font-weight: 500;
  color: var(--color-text-muted);
  line-height: 1.2;
  user-select: none;
  transition: color 0.2s ease, font-weight 0.2s ease;
}

.trace-view-switch:has(.trace-view-switch__input:not(:checked)) .trace-view-switch__label--tree,
.trace-view-switch:has(.trace-view-switch__input:checked) .trace-view-switch__label--map {
  color: var(--color-text);
  font-weight: 600;
}

.trace-view-switch__control {
  display: inline-flex;
  margin: 0;
  cursor: pointer;
}

.trace-view-switch__track {
  position: relative;
  display: block;
  width: 3.2rem;
  height: 1.95rem;
  border-radius: 999px;
  background: var(--color-border-strong);
  transition: background-color 0.25s cubic-bezier(0.4, 0, 0.2, 1);
}

.trace-view-switch__thumb {
  position: absolute;
  top: 2px;
  left: 2px;
  width: calc(1.95rem - 4px);
  height: calc(1.95rem - 4px);
  border-radius: 50%;
  background: var(--color-surface);
  transition: transform 0.25s cubic-bezier(0.4, 0, 0.2, 1);
}

.trace-view-switch__input:checked + .trace-view-switch__track {
  background: var(--color-primary);
}

.trace-view-switch__input:checked + .trace-view-switch__track .trace-view-switch__thumb {
  transform: translateX(calc(3.2rem - 1.95rem));
}

.trace-view-switch__input:focus-visible + .trace-view-switch__track {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
}

.trace-map__wrap {
  margin-top: var(--space-2);
}

.trace-map__canvas {
  width: 100%;
  height: 420px;
  border-radius: var(--radius-md);
  border: 1px solid var(--trace-border);
  background: var(--color-surface-alt);
  z-index: 0;
}

.trace-map__empty {
  margin-top: var(--space-3);
  padding: var(--space-4);
  text-align: center;
  background: var(--color-surface-alt);
  border-radius: var(--radius-md);
  border: 1px dashed var(--trace-border);
}

.trace-map__legend {
  margin-top: var(--space-3);
}

.trace-map__legend-title {
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-text-muted);
  margin-bottom: var(--space-2) !important;
}

.trace-map__legend-list {
  list-style: none;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-4);
}

.trace-map__legend-item {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-size: 0.875rem;
}

.trace-map__legend-swatch {
  width: 0.75rem;
  height: 0.75rem;
  border-radius: 999px;
  flex-shrink: 0;
}

.trace-map-step-marker-wrap,
.trace-map-arrow-wrap {
  background: transparent !important;
  border: none !important;
}

.trace-map-step-marker {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  border-radius: 999px;
  color: var(--color-on-primary);
  font-size: 0.6875rem;
  font-weight: 700;
  line-height: 1;
  box-shadow: none;
  border: 2px solid var(--color-surface);
}

.trace-map-arrow {
  display: block;
  overflow: visible;
  filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.28));
}

.trace-grid {
  --trace-grid-bg: var(--color-bg);
  --trace-grid-card-bg: var(--color-surface-alt);
  --trace-grid-border: var(--color-border);
  --trace-grid-text: var(--color-text);
  --trace-grid-muted: var(--color-text-muted);
  --trace-grid-line: var(--color-border-strong);
  --trace-row-h: 220px;
  display: grid;
  width: max-content;
}

.trace-grid-card {
  background: var(--trace-grid-card-bg);
  border: 1px solid var(--trace-grid-border);
  border-radius: var(--radius-lg);
  padding: 14px 16px;
  width: 232px;
  min-height: calc(var(--trace-row-h) - 8px);
  display: flex;
  flex-direction: column;
  box-shadow: none;
  opacity: 0;
  animation: trace-grid-card-enter 0.28s cubic-bezier(0.22, 1, 0.36, 1) forwards;
}

.trace-grid-card.trace-grid-card--required {
  border-color: var(--color-border-strong);
  border-width: 2px;
}

.trace-grid-card-wrap {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  width: 232px;
}

.trace-grid-card-wrap--required {
  align-self: center;
}

.trace-grid-card__required-label {
  font-size: 0.6875rem;
  font-weight: 600;
  color: var(--color-text-muted);
  line-height: 1.2;
  margin: 0 0 4px;
}

.trace-grid-card p {
  margin: 0;
}

.trace-grid-card__head {
  display: flex;
  align-items: flex-start;
  gap: 9px;
  padding-bottom: 11px;
  margin-bottom: 11px;
  border-bottom: 1px solid var(--trace-grid-border);
}

.trace-grid-card__icon {
  width: 22px;
  height: 22px;
  border-radius: var(--radius-sm);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  font-size: 9px;
  font-weight: 700;
}

.trace-grid-card__activity {
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--trace-grid-text);
  line-height: 1.4;
  padding-top: 2px;
  overflow-wrap: anywhere;
  word-break: break-word;
  min-width: 0;
  flex: 1 1 auto;
}

.trace-grid-card__tag {
  display: inline-block;
  font-size: 10px;
  font-weight: 500;
  padding: 3px 8px;
  border-radius: var(--radius-sm);
  margin-bottom: 6px;
}

.trace-grid-card__meta {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.trace-grid-card__mat {
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
  font-size: 10px;
  color: var(--trace-grid-muted);
  margin: 0;
}

.trace-grid-card__site {
  margin-top: 10px;
  padding: 7px 9px;
  background: var(--trace-grid-bg);
  border-radius: var(--radius-sm);
  border: 1px solid var(--trace-grid-border);
}

.trace-grid-card__site-row {
  display: flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
}

.trace-grid-card__site-country {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  gap: 2px;
  font-size: 9px;
  font-weight: 600;
  color: var(--trace-grid-muted);
  letter-spacing: 0.03em;
}


.trace-grid-card__site-name {
  font-size: 10px;
  font-weight: 500;
  color: var(--trace-grid-text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  flex: 1;
  min-width: 0;
}

a.trace-grid-card__site-name {
  display: block;
  margin: 0;
  text-decoration: none;
  color: inherit;
}

a.trace-grid-card__site-name:hover {
  text-decoration: underline;
  color: var(--color-primary);
}

.trace-grid-card__site-supplier {
  font-size: 9px;
  color: var(--trace-grid-muted);
  margin-top: 2px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.trace-grid-card__site-empty {
  font-size: 9px;
  color: var(--trace-grid-muted);
  font-style: italic;
  margin: 0;
}

.trace-grid-card__assign {
  margin-top: 8px;
}

/* L'affectation part sans rechargement : si elle échoue, la carte doit le dire
   elle-même — il n'y a plus de bandeau de page pour le faire. */
.trace-grid-card__assign-error {
  margin: 6px 0 0;
  font-size: 0.75rem;
  color: var(--color-danger);
}

.trace-grid-card__assign .portal-inline-form {
  display: flex;
  flex-direction: column;
  gap: 6px;
  align-items: stretch;
}

.trace-grid-card__assign .ui-select {
  max-width: 100%;
  min-width: 0;
  font-size: 11px;
}

.trace-grid-card__foot {
  display: flex;
  align-items: center;
  gap: 5px;
  margin-top: auto;
  padding-top: 12px;
  border-top: 1px solid var(--trace-grid-border);
  font-size: 9px;
  letter-spacing: 0.04em;
  color: var(--trace-grid-muted);
  flex-wrap: wrap;
}

/* Pastille d'état. Le libellé qu'elle précède (« Non démarré », « Terminé »)
   porte l'information : elle la redouble, elle ne la remplace pas — c'est ce
   qui autorise un gris discret sur l'attente (WCAG 1.4.11). */
.trace-grid-card__foot::before {
  content: "";
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--color-border-strong);
  flex-shrink: 0;
}

.trace-grid-card[data-status="in_progress"] .trace-grid-card__foot::before {
  background: var(--color-accent-amber);
}

.trace-grid-card[data-status="completed"] .trace-grid-card__foot::before {
  background: var(--color-success);
}

.trace-grid-tag--product {
  background: var(--tint-product-bg);
  color: var(--tint-product-fg);
}

.trace-grid-tag--doublure {
  background: var(--tint-doublure-bg);
  color: var(--tint-doublure-fg);
}

.trace-grid-tag--semelle {
  background: var(--tint-semelle-bg);
  color: var(--tint-semelle-fg);
}

.trace-grid-tag--tige {
  background: var(--tint-tige-bg);
  color: var(--tint-tige-fg);
}

/* Plusieurs activités produit-global (même type) dans une colonne : pile
   verticale au lieu d’une expansion JSON qui masquait les cartes suivantes. */
.trace-grid-card-stack {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  align-self: center;
  justify-content: center;
}

.trace-grid-card-stack .trace-grid-card {
  min-height: auto;
}

.trace-grid-conn--simple {
  width: 60px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.trace-grid-conn__line {
  width: 100%;
  height: 1px;
  background: var(--trace-grid-line);
}

.trace-grid-conn__line--half {
  width: 50%;
  margin-right: auto;
}

.trace-grid-conn--fork {
  width: 60px;
}

.trace-grid-conn--trunk {
  width: 60px;
}

/* Carte visée par le bouton « Continuer » du tableau de bord fournisseur. */
.trace-grid-card--target {
  outline: 3px solid var(--color-primary);
  outline-offset: 3px;
  animation:
    trace-grid-card-enter 0.28s cubic-bezier(0.22, 1, 0.36, 1) forwards,
    trace-grid-card-target 2.4s ease-out 0.3s forwards;
}

@keyframes trace-grid-card-target {
  from {
    box-shadow: 0 0 0 8px var(--color-primary-soft);
  }
  to {
    box-shadow: 0 0 0 0 transparent;
  }
}

@keyframes trace-grid-card-enter {
  from {
    opacity: 0;
    transform: translateX(-8px);
  }
  to {
    opacity: 1;
    transform: translateX(0);
  }
}

.trace-node {
  position: relative;
  background: var(--trace-node-bg);
  border: 1px solid var(--trace-border);
  border-radius: var(--radius-lg);
  padding: 10px 12px;
  font-size: 0.8125rem;
  line-height: 1.35;
  box-shadow: none;
}

.trace-node--product {
  border-color: var(--color-border);
}

.trace-node--component {
  border-color: var(--color-border);
}

.trace-node--material {
  border-style: dashed;
  border-color: var(--color-border-strong);
  box-shadow: none;
}

.trace-node--activity {
  border-color: var(--color-border);
  padding-top: 11px;
}

.trace-node--activity .trace-node__name {
  text-transform: none;
  letter-spacing: 0;
  font-size: 0.9375rem;
  font-weight: 700;
}

.trace-node--merged-mat .trace-node__header--merged-mat {
  margin-bottom: 6px;
  padding-bottom: 6px;
}

.trace-node--merged-mat .trace-node__header--merged-mat .trace-node__header-main {
  min-width: 0;
}

.trace-node--merged-mat.trace-node--activity .trace-node__name--merged-chain {
  font-size: 0.8125rem;
  font-weight: 600;
  line-height: 1.45;
  margin: 0 0 6px;
  text-transform: none;
  letter-spacing: 0;
}

.trace-node__merged-sep {
  font-weight: 500;
  color: var(--color-text-muted);
}

.trace-node__pill {
  position: absolute;
  right: 10px;
  bottom: 9px;
  max-width: 42%;
  font-size: 0.625rem;
  font-weight: 500;
  letter-spacing: 0.02em;
  text-transform: lowercase;
  color: var(--trace-pill);
  line-height: 1.2;
  text-align: right;
  pointer-events: none;
}

.trace-node__header {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  margin-bottom: 8px;
  padding-bottom: 8px;
  border-bottom: 1px solid var(--color-border-subtle);
}

.trace-node__header--split {
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-3);
}

.trace-node__header-main {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  min-width: 0;
}

.trace-node__locale {
  margin: 0;
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  font-size: 0.6875rem;
  font-weight: 600;
  color: var(--color-text-muted);
  letter-spacing: 0.02em;
}


.trace-node__country {
  text-transform: none;
}

.trace-node__icon {
  flex-shrink: 0;
  color: var(--color-text-muted);
  line-height: 0;
}

.trace-node__icon svg {
  display: block;
  width: 18px;
  height: 18px;
}

.trace-node__titles {
  min-width: 0;
}

.trace-node__kind {
  margin: 0;
  font-size: 0.5625rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-text-muted);
}

.trace-node__name {
  margin: 2px 0 0;
  font-size: 0.875rem;
  font-weight: 600;
  color: var(--color-text);
  word-break: break-word;
}

.trace-node__attrs {
  margin: 0;
}

.trace-node__attr {
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  align-items: flex-start;
  gap: var(--space-3);
  padding: 5px 0;
  font-size: 0.6875rem;
  border-top: 1px solid var(--color-border-subtle);
}

.trace-node__attr:first-child {
  border-top: none;
  padding-top: 0;
}

.trace-node__attr dt {
  flex-shrink: 0;
  margin: 0;
  padding-top: 0.1em;
  color: var(--color-text-muted);
  font-weight: 500;
}

.trace-node__attr dd {
  margin: 0;
  text-align: right;
  color: var(--color-text);
  font-weight: 500;
  word-break: break-word;
}

.trace-node__value {
  font-size: 0.65rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-text);
}

.trace-node--activity .trace-node__attrs {
  padding-right: 0;
  padding-bottom: 1.1rem;
}

.trace-node--activity.trace-node--tagged .trace-node__attrs {
  padding-bottom: 1.35rem;
}

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* Supplier portal polish */
.portal-page-title {
  margin: 0 0 var(--space-4);
}

/* Écran d'accès refusé du portail : seul écran sans session, donc le sélecteur
   de langue y est indispensable (audit portail 18/09, ERR-01). */
.portal-error-page {
  max-width: 760px;
  margin: 0 auto;
  padding-top: var(--space-8);
}

.portal-error-card__lang {
  display: flex;
  justify-content: flex-end;
  margin-bottom: var(--space-3);
}

.portal-error-card__message {
  font-weight: 600;
}

.portal-shell {
  max-width: 1600px;
  margin: 0 auto;
  /* Match .portal-stack gap so the first card sits at the same distance
     from the topbar as the cards are from each other. */
  padding-top: var(--space-5);
}

.portal-sidebar__required-attrs {
  border-top: 1px solid rgba(0, 0, 0, 0.08);
  padding-top: var(--space-3);
}

.portal-sidebar__required-attrs-list {
  list-style: disc;
  padding-left: 1.125rem;
  margin-top: var(--space-2);
}

.portal-attribute-required-badge {
  margin-inline-start: 0.35rem;
  vertical-align: middle;
  font-size: 0.75rem;
}

.portal-attr-row--brand-readonly td,
td.portal-attr-row--brand-readonly {
  background: rgba(249, 250, 251, 0.92);
}

.portal-attr-grid__th-brand {
  background: rgba(249, 250, 251, 0.92);
}

.portal-stack {
  gap: var(--space-5);
}

.portal-product-trace-layout {
  display: grid;
  gap: var(--space-5);
  grid-template-columns: 1fr;
  align-items: stretch;
}

/* Deux colonnes à partir de 64 em, et non 48 em : le menu du portail prend 320 px,
   et entre 48 et 64 em la seconde colonne débordait du bord droit (106 px à
   853 px de large, audit zoom du 25/09/2026). */
@media (min-width: 64em) {
  .portal-product-trace-layout:has(.portal-product-trace-attributes) {
    grid-template-columns: 2fr 3fr;
  }
}

.portal-product-trace-layout > .portal-section {
  margin-bottom: 0;
}

.portal-product-trace-summary {
  display: flex;
  flex-direction: column;
  height: 100%;
}

.portal-product-trace-summary__media {
  display: flex;
  flex: 1 1 auto;
  align-items: flex-start;
  gap: var(--space-4);
  margin-top: var(--space-3);
  min-height: 0;
}

.portal-product-trace-summary__attrs {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  flex: 1 1 auto;
  min-width: 0;
  margin: 0;
}

.portal-product-trace-summary__attr {
  display: grid;
  gap: var(--space-1);
}

.portal-product-trace-summary__attr-label {
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--color-text-muted);
  margin: 0;
}

.portal-product-trace-summary__attr-value {
  margin: 0;
  font-size: 0.9375rem;
  overflow-wrap: anywhere;
}

/* Attributs obligatoires manquants sur la fiche produit : même rouge que les
   activités obligatoires de la grille (.trace-grid-card--required). */
.portal-attr-missing-summary {
  margin: 0 0 var(--space-3);
  font-weight: 600;
  color: var(--color-warning);
}

.portal-attr-row--missing .ui-input,
.portal-attr-row--missing .ui-select {
  border-color: var(--color-warning-graph);
  box-shadow: inset 0 0 0 1px var(--color-warning-graph);
}

.portal-attr-row--missing td:first-child {
  box-shadow: inset 3px 0 0 0 var(--color-warning-graph);
}

.portal-product-trace-attributes__lead {
  font-weight: 600;
  margin-top: var(--space-2);
}

.portal-product-trace-summary__img {
  width: 100%;
  max-width: 12.5rem;
  aspect-ratio: 1;
  object-fit: cover;
}

.portal-section {
  margin-bottom: var(--space-4);
}

.portal-section-detail-title {
  margin-top: var(--space-5);
  margin-bottom: var(--space-2);
}

.portal-hero-score {
  margin-top: var(--space-4);
  margin-bottom: var(--space-4);
  padding: var(--space-4);
  border-radius: var(--radius-md, 8px);
  background: var(--color-surface-muted);
  border: 1px solid rgba(0, 0, 0, 0.08);
}

.portal-hero-score__label {
  margin: 0 0 var(--space-2);
  font-size: 1.125rem;
  font-weight: 600;
}

.portal-hero-score__top {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  margin-bottom: var(--space-3);
}

.portal-hero-score__pct {
  flex-shrink: 0;
  /* Hauteur ≈ 2 lignes de métriques (1.125rem × 1.4) + l'interligne */
  font-size: calc(2 * 1.125rem * 1.4 + var(--space-1));
  line-height: 1;
  font-weight: 700;
}

.portal-hero-score__metrics {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  justify-content: center;
  gap: var(--space-1);
  margin: 0;
  text-align: right;
}

.portal-hero-score__metric {
  margin: 0;
  font-size: 1.125rem;
  line-height: 1.4;
}

.portal-hero-score__bar {
  height: 0.75rem;
  border-radius: 999px;
  background: rgba(0, 0, 0, 0.08);
  overflow: hidden;
}

.portal-hero-score__bar-fill {
  display: block;
  height: 100%;
  border-radius: inherit;
  background: var(--color-primary);
  transition: width 0.2s ease;
}

.portal-hero-score--start .portal-hero-score__bar-fill {
  background: var(--color-text-muted);
}

.portal-hero-score--progress .portal-hero-score__bar-fill {
  background: var(--color-info-fg);
}

.portal-hero-score--almost .portal-hero-score__bar-fill {
  background: var(--color-primary);
}

.portal-hero-score--done .portal-hero-score__bar-fill {
  background: var(--color-success-fg);
}

/* Suppliers list — global % + detail rows */
.supplier-progress-summary {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-width: 7rem;
}

.supplier-progress-summary__pct {
  flex-shrink: 0;
  min-width: 2.75rem;
  font-size: var(--fs-md);
  line-height: 1.2;
  font-weight: var(--fw-semibold);
  font-variant-numeric: tabular-nums;
}

.supplier-progress-summary .ui-meter {
  flex: 1 1 3.5rem;
}

.portal-next-action {
  margin-bottom: var(--space-4);
  padding: var(--space-4);
}

.portal-next-action__title {
  margin-top: 0;
  margin-bottom: var(--space-2);
  font-size: 1.25rem;
}

.portal-next-action__body {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
}

.portal-next-action__text {
  margin: 0;
  flex: 1 1 12rem;
  min-width: 0;
  font-size: 1.125rem;
  line-height: 1.5;
}

.portal-next-action__cta {
  flex: 0 0 auto;
  font-size: 1.0625rem;
}

/* Filet de reprise : révélé quand l'envoi ou le suivi de soumission décroche.
   Le fournisseur doit le voir dans une modale déjà occupée par un sablier. */
.portal-submit-stall {
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md, 8px);
  background: var(--color-warning-bg);
  border: 1px solid var(--color-warning);
  color: var(--color-warning);
}

.portal-almost-banner {
  margin: 0 0 var(--space-4);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md, 8px);
  background: var(--color-success-bg);
  border: 1px solid var(--color-success-border);
  color: var(--color-success-fg);
  font-size: 1.125rem;
  font-weight: 600;
}

.portal-kpi-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(11rem, 100%), 1fr));
  gap: var(--space-3);
}

.portal-kpi-sep {
  opacity: 0.55;
  font-weight: 500;
  margin: 0 0.1em;
}

.portal-dashboard-progress-scroll {
  max-height: min(44rem, 75vh);
  overflow-y: auto;
  border: 1px solid rgba(0, 0, 0, 0.08);
  border-radius: var(--radius-md, 8px);
}

/* Lignes produit : tout complété (activités + détails fournisseur) */
.portal-dashboard-progress-scroll .ui-table tr.portal-dashboard-row--complete td {
  background: rgba(187, 247, 208, 0.55);
}
.portal-dashboard-progress-scroll .ui-table tr.portal-dashboard-row--complete:hover td {
  background: rgba(167, 240, 191, 0.75);
}

/* Activités à 100 % mais attributs fournisseur encore incomplets */
.portal-dashboard-progress-scroll .ui-table tr.portal-dashboard-row--activities-complete td {
  background: rgba(230, 247, 237, 0.45);
}
.portal-dashboard-progress-scroll .ui-table tr.portal-dashboard-row--activities-complete:hover td {
  background: rgba(220, 242, 230, 0.65);
}

/* Compteurs x/y : couleur selon l’état (lisible même sans fond de ligne) */
.portal-dashboard-meter {
  font-variant-numeric: tabular-nums;
  font-weight: 600;
}
.portal-dashboard-meter--complete {
  color: var(--color-success);
}
.portal-dashboard-meter--partial {
  color: var(--color-warning);
}
.portal-dashboard-meter--behind {
  color: var(--color-warning);
}
.portal-dashboard-meter--na {
  font-weight: 500;
  color: var(--color-text-muted);
}

.portal-dashboard-product-hint {
  max-width: 28rem;
  word-break: break-word;
}

/* Portail attributs : carte produit lorsque chaque attribut fournisseur a une valeur */
section.ui-card.portal-attributes-product--complete {
  background: rgba(230, 247, 237, 0.7);
  border-color: rgba(200, 228, 215, 0.65);
}

.portal-attributes-product-head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-3);
  flex-wrap: wrap;
  margin-bottom: var(--space-3);
}

.portal-attributes-required-meter-block {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 2px;
  min-width: 6.5rem;
}

.portal-attributes-required-meter-block .portal-dashboard-meter {
  font-size: 1.15rem;
  line-height: 1.2;
}

.portal-table--sticky .ui-table tbody tr.portal-attributes-row--required > td:first-child {
  box-shadow: inset 3px 0 0 0 var(--color-warning);
}

.portal-table--sticky .ui-table tbody tr.portal-attributes-row--required-missing > td {
  background: rgba(254, 243, 199, 0.42);
}

.portal-bulk-form .ui-table tbody tr.portal-attributes-row--required > td:first-child {
  box-shadow: inset 3px 0 0 0 var(--color-warning);
}

/* Portail certificats : ligne en statut traité (PROCESSED) */
.ui-table tr.portal-certificate-row--complete td {
  background: rgba(230, 247, 237, 0.7);
}
.ui-table tr.portal-certificate-row--complete:hover td {
  background: rgba(210, 238, 222, 0.85);
}

.portal-kpi-card {
  padding: var(--space-4);
}

a.portal-kpi-card--interactive {
  display: block;
  text-decoration: none;
  color: inherit;
  transition: box-shadow 0.15s ease;
}

a.portal-kpi-card--interactive:hover {
  box-shadow: var(--shadow-md);
}

a.portal-kpi-card--interactive:focus-visible {
  outline: 2px solid currentColor;
  outline-offset: 2px;
}

.portal-kpi-card--active {
  box-shadow: inset 0 0 0 2px color-mix(in srgb, currentColor 35%, transparent);
}

.portal-kpi-card--complete {
  background: rgba(230, 247, 237, 0.85);
  border-color: rgba(21, 128, 61, 0.35);
}

.portal-kpi-card--complete .portal-kpi-value {
  color: var(--color-success);
}

a.portal-kpi-card--interactive.portal-kpi-card--complete:hover {
  background: rgba(210, 238, 222, 0.95);
  box-shadow: var(--shadow-md);
}

.portal-dashboard-product-filter__chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  align-items: center;
}

.portal-kpi-value {
  font-size: 1.3rem;
}

.portal-actions-row {
  margin-top: var(--space-3);
  display: flex;
  gap: var(--space-2);
  flex-wrap: wrap;
}

.portal-sites-list__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  margin-bottom: var(--space-3);
}

.portal-sites-list__head .ui-heading-2 {
  margin-bottom: 0;
}

.portal-merge-selection-summary {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin-bottom: var(--space-3);
  border-left: 3px solid var(--color-border);
  padding-left: var(--space-3);
}

.portal-merge-selection-summary__body {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2) var(--space-3);
}

.portal-merge-selection-summary__lines {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-1) var(--space-3);
  flex: 1 1 auto;
  min-width: 0;
  font-size: 0.9375rem;
  line-height: 1.4;
}

.portal-merge-selection-summary__lines > span:not([hidden]) + span:not([hidden])::before {
  content: "·";
  margin-right: var(--space-3);
  color: var(--color-text-muted);
}

.portal-merge-selection-summary__actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: var(--space-2);
  flex: 0 0 auto;
}

.portal-dedupe-suggestions__head {
  margin-bottom: var(--space-3);
}

.portal-dedupe-suggestions__count {
  font-size: 0.9375rem;
  font-weight: 600;
}

.portal-dedupe-suggestions__picker {
  margin-bottom: var(--space-3);
}

.portal-dedupe-suggestions__select {
  max-width: 28rem;
}

.portal-dedupe-suggestions__panels {
  min-width: 0;
}

.portal-dedupe-group {
  min-width: 0;
}

.portal-dedupe-group__title {
  font-size: 1rem;
  font-weight: 600;
  line-height: 1.35;
}

.portal-dedupe-group__members {
  margin: 0;
  padding: 0;
  border-left: 3px solid color-mix(in srgb, var(--color-warning) 45%, transparent);
  padding-left: var(--space-3);
}

.portal-dedupe-group__member {
  min-width: 0;
  padding-bottom: var(--space-3);
}

.portal-dedupe-group__member:last-child {
  padding-bottom: 0;
}

.portal-dedupe-group__member-name {
  word-break: break-word;
}

.portal-dedupe-group__member-meta {
  font-size: 0.8125rem;
  line-height: 1.35;
}

.portal-merge-certs-pair-table__group-row th {
  font-size: 0.8125rem;
  font-weight: 600;
  text-align: left;
  background: var(--color-surface-muted);
  border-bottom: 1px solid var(--color-border);
}

.portal-filters {
  display: grid;
  grid-template-columns: 1fr 220px auto;
  gap: var(--space-2);
}

/* Portal certificates — toolbar + add grid + row edit details */
.portal-certificates-toolbar {
  display: grid;
  grid-template-columns: minmax(12rem, 1fr);
  gap: var(--space-3);
  align-items: start;
}

.portal-certificates-toolbar__statuses {
  margin: 0;
  padding: 0;
  border: 0;
  min-width: 0;
}

.portal-certificates-toolbar__statuses-legend {
  padding: 0;
  margin: 0 0 var(--space-2);
}

.portal-certificates-toolbar__statuses-inner {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-4);
  align-items: center;
}

.portal-certificates-toolbar__status-item {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  margin: 0;
  font-size: 0.9375rem;
  white-space: nowrap;
  cursor: pointer;
}

.portal-certificates-toolbar__status-item input {
  margin: 0;
}

.portal-certificates-toolbar__status-item .ui-badge {
  flex-shrink: 0;
}

.portal-certificates-toolbar__hint {
  grid-column: 1 / -1;
  margin-top: 0;
  max-width: 52rem;
}

.portal-certificates-section__head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  margin-bottom: var(--space-3);
}

.portal-certificates-section__head--actions-only {
  justify-content: flex-end;
  margin-top: calc(-1 * var(--space-2));
}

.portal-certificates-section__title {
  margin: 0;
}

.portal-certificates-section__action-filter-label {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  margin: 0;
  font-size: 0.9375rem;
  white-space: nowrap;
  cursor: pointer;
}

.portal-certificates-section__action-filter-label input {
  margin: 0;
}

.portal-certificates-section__add-title {
  margin: 0;
}

.portal-certificate-add-foot {
  border-top: 1px solid var(--color-border);
}

/* Grille fluide : les colonnes se replient au lieu de pousser la page.
   Avant (audit UI 20/09/2026) : cinq colonnes fixes dont les minima cumulés,
   ajoutés au min-width des champs date, portaient la page à 1 640 px pour un
   écran de 1 440 — soit 9 contrôles sur 18 hors de l'écran, inatteignables
   puisque `base.css` impose `body { overflow-x: hidden }`.
   `min()` évite le débordement sous 210 px de large. */
.portal-certificate-add-form {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(13rem, 100%), 1fr));
  gap: var(--space-4) var(--space-2);
  align-items: end;
}

/* Champ « Fichier PDF » de la création : pleine largeur sous les champs,
   pour que le sélecteur natif et le retour de sélection restent lisibles. */
.portal-certificate-add-form__field--file {
  grid-column: 1 / -1;
}

.portal-certificate-add-form .ui-field {
  margin: 0;
  min-width: 0;
}

.portal-certificate-add-form .portal-certificate-table__field {
  box-sizing: border-box;
  width: 100%;
  max-width: none;
  min-height: 2rem;
}

.portal-certificate-add-form .portal-certificate-table__field--date {
  /* Plancher retiré : il dépassait la colonne et élargissait la grille. */
  min-width: 0;
}

.portal-certificate-add-form__actions {
  display: flex;
  align-items: flex-end;
  padding-bottom: 1px;
  grid-column: 1 / -1;
  justify-content: flex-end;
}

.portal-certificate-add-form__actions .ui-btn {
  white-space: nowrap;
}

.portal-certificate-add-foot__title-row td {
  padding-top: var(--space-4);
  padding-bottom: var(--space-2);
  background: var(--color-surface-muted);
}

.portal-certificate-add-row td {
  vertical-align: middle;
  background: var(--color-surface-muted);
}

.portal-certificate-add-row__empty {
  display: block;
  text-align: center;
}

.portal-certificate-star {
  flex-shrink: 0;
  color: var(--color-accent);
}

.portal-certificate-site-cell {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  min-width: 0;
}

.portal-certificate-site-cell--supplier {
  font-weight: 600;
}

/* Motif du dernier refus sous une demande rouverte (portail, bloc « À déposer »). */
.portal-certificate-request-hint--rejected {
  color: var(--color-danger);
  font-size: 0.875rem;
}

.portal-certificate-row-details {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  background: var(--color-surface-muted);
  text-align: left;
  box-shadow: none;
}

.portal-certificate-row-actions {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: var(--space-2);
  width: 100%;
}

.portal-certificate-row-actions--locked {
  align-items: stretch;
}

.portal-certificate-row-readonly {
  font-size: 0.8125rem;
  line-height: 1.35;
  max-width: 20rem;
}

.portal-certificate-row-actions__delete-form {
  display: inline-flex;
  margin: 0;
}

.portal-certificate-row-actions__preview-slot {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  flex-wrap: wrap;
  gap: var(--space-1);
}

.portal-certificate-row-actions__save-btn {
  white-space: nowrap;
}

/* Retour immédiat sous la référence : fichier sélectionné (ok) ou refusé (error).
   Posé par portal_certificates_add.js ; masqué tant qu'aucun fichier n'est choisi. */
.portal-cert-file-feedback {
  margin: var(--space-1) 0 0;
  font-size: 0.8125rem;
  line-height: 1.3;
}

.portal-cert-file-feedback[data-state="ok"] {
  color: var(--color-primary);
}

.portal-cert-file-feedback[data-state="error"] {
  color: var(--color-danger);
}

/* Progressive enhancement : bouton « Enregistrer » grisé tant que la ligne n'a
   pas réellement changé (classe posée par le JS après comparaison à l'état
   initial). Sans JS, aucune classe → bouton actif. Grisage marqué : le public
   du portail doit voir sans ambiguïté que le bouton est inactif. */
tr.portal-certificate-row--clean .portal-certificate-row-actions__save-btn {
  opacity: 0.35;
  filter: grayscale(1);
  pointer-events: none;
}

/* Mention statique « un fichier est déjà déposé » (fichier committé, aucun
   staged) ; le JS la masque dès qu'un nouveau fichier valide est choisi. */
.portal-cert-file-present-hint {
  margin: var(--space-1) 0 0;
  font-size: 0.8125rem;
  line-height: 1.3;
  color: var(--color-text-muted);
}

/* Bouton « Joindre le PDF » : icône + libellé visible (public peu à l'aise
   avec l'informatique — une icône seule ne suffit pas). */
.portal-certificate-row-actions__upload-btn {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  white-space: nowrap;
  flex-shrink: 0;
  padding: 6px 8px;
}

.portal-certificate-row-actions__icon-btn {
  flex-shrink: 0;
  padding: 6px;
}

.portal-certificate-row-actions__icon-btn svg {
  display: block;
  width: 1.125rem;
  height: 1.125rem;
}

.portal-certificate-row-actions__icon-btn--disabled {
  opacity: 0.45;
  pointer-events: none;
  cursor: not-allowed;
}

.portal-certificate-row-actions__icon-btn--danger {
  color: var(--color-danger);
}

.portal-certificate-row-actions__icon-btn--danger:hover:not(:disabled),
.portal-certificate-row-actions__icon-btn--danger:focus-visible {
  color: var(--color-danger);
  background: color-mix(in srgb, var(--color-danger) 12%, transparent);
}

.portal-certificate-row-actions__icon-btn--success {
  color: var(--color-success);
}

.portal-certificate-row-actions__icon-btn--success:hover:not(:disabled),
.portal-certificate-row-actions__icon-btn--success:focus-visible {
  color: var(--color-success);
  background: color-mix(in srgb, var(--color-success) 12%, transparent);
}

.ui-table-wrap.portal-certificates-table-wrap td:has(.portal-certificate-row-actions) {
  overflow: visible;
  vertical-align: middle;
}

.portal-certificates-table-wrap {
  overflow-x: auto;
}

.portal-certificates-table-wrap td .ui-badge {
  white-space: nowrap;
}

.portal-certificates-table-wrap .portal-certificate-table__field {
  box-sizing: border-box;
  width: 100%;
  max-width: none;
  min-height: 2rem;
}

.portal-certificates-table-wrap .portal-certificate-table__field--date {
  min-width: 9.5rem;
}

.portal-certificate-col--reference {
  min-width: 9rem;
}

.portal-certificate-col--standard {
  min-width: 12rem;
}

.portal-certificate-col--site {
  min-width: 9rem;
}

.portal-certificate-col--grade {
  min-width: 8rem;
}

.portal-certificate-col--valid {
  min-width: 10rem;
}

.portal-certificate-col--status {
  min-width: 8rem;
}

.portal-certificate-col--actions {
  min-width: 14rem;
}

.portal-certificate-status-cell {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-1);
}

.portal-certificate-row-form {
  display: none;
}

.portal-certificate-row-details__summary {
  cursor: pointer;
  list-style: none;
  display: flex;
  flex-wrap: nowrap;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  font-weight: 600;
  font-size: 0.875rem;
  min-height: 2.625rem;
  box-sizing: border-box;
}

.portal-certificate-row-details__summary::-webkit-details-marker {
  display: none;
}

.portal-certificate-row-details__summary::marker {
  content: "";
}

.portal-certificate-row-details__summary-label {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  flex: 1 1 auto;
  min-width: 0;
}

.portal-certificate-row-details__summary-inner {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  min-width: 0;
  flex: 1 1 auto;
}

.portal-certificate-row-details__summary-badge {
  flex-shrink: 0;
  white-space: nowrap;
  font-size: 0.75rem;
  font-weight: 600;
}

.portal-certificate-row-details__summary-meta {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
}

.portal-certificate-row-details__panel {
  padding: var(--space-3);
  border-top: 1px solid var(--color-border);
  background: var(--color-surface);
  border-radius: 0 0 var(--radius-sm) var(--radius-sm);
}

.portal-certificate-row-details__form {
  align-items: flex-start;
}

.portal-certificate-identity-hint {
  flex-basis: 100%;
  max-width: 42rem;
}

.portal-certificate-identity-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
  gap: var(--space-2);
  width: 100%;
  flex-basis: 100%;
  align-items: flex-end;
}

.portal-certificate-identity-grid .portal-field {
  min-width: 0;
}

.portal-certificate-row--complete .portal-certificate-row-details__summary {
  opacity: 0.92;
  font-weight: 500;
}

.portal-bulk-form,
.portal-inline-form,
.portal-submit-form {
  display: flex;
  gap: var(--space-2);
  flex-wrap: wrap;
  align-items: flex-end;
}

.portal-field {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 160px;
}

.portal-field > span {
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--color-text-muted);
  text-transform: uppercase;
  letter-spacing: 0.02em;
}

/* Autant de colonnes que la place en permet : quatre colonnes fixes d'au moins
   160 px débordaient du bord droit dès le zoom 150 % (champs Pays et E-mail hors
   d'atteinte, audit zoom du 25/09/2026). */
.portal-site-form {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 12rem), 1fr));
  gap: var(--space-2);
}

/* Le bouton reste seul sous les champs : sur grand écran, une cinquième colonne
   l'aurait aligné sur eux, étiré à leur hauteur. */
.portal-site-form > .ui-btn {
  grid-column: 1;
}

/* Liste / fusion « Sites existants » : nom + adresse lisibles (retours à la ligne, scroll horizontal si besoin). */
.portal-sites-merge-table {
  min-width: min(100%, 72rem);
  table-layout: auto;
}

.portal-sites-merge-table td {
  padding: var(--space-1) var(--space-2);
  vertical-align: middle;
}

.portal-sites-merge-table .portal-site-col--name {
  min-width: 12rem;
  max-width: 18rem;
}

.portal-sites-merge-table .portal-site-col--address {
  min-width: 14rem;
  max-width: 22rem;
}

.portal-sites-merge-table .portal-site-table__field {
  box-sizing: border-box;
  width: 100%;
  max-width: none;
  min-height: 2rem;
}

.portal-site-row__name-line {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-2);
  min-width: 0;
}

.portal-site-row__name-input,
.portal-site-row__address-input {
  width: 100%;
  max-width: 100%;
}

.portal-site-row__activities {
  flex: 0 0 auto;
  font-size: 0.8125rem;
  line-height: 1.35;
  color: var(--color-text-muted);
  white-space: nowrap;
}

.portal-site-row__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-1);
}

.portal-site-col--actions {
  min-width: 13rem;
}

/* Tableau des sites du portail — proportions des colonnes.
   Sans plancher sur l'adresse et le pays, la mise en page automatique donnait
   la largeur au texte le plus long : 439 px à la phrase « Consultation seule… »
   de la colonne Actions, 111 px au champ adresse et 41 px au champ pays — une
   seule lettre visible sur les deux. Constaté en production le 22/09/2026.
   Réservé aux écrans larges : en dessous de 48em le tableau s'empile
   (`ui-table--stackable`) et ces largeurs n'ont plus de sens. */
@media (min-width: 48.0625em) {
  .portal-sites-table {
    width: 100%;
  }
  .portal-sites-table .portal-site-col--name {
    width: 26%;
    min-width: 13rem;
  }
  .portal-sites-table .portal-site-col--address {
    width: 30%;
    /* 17rem de colonne : le champ (mesuré par le test a11y) reste ≥ 220 px
       après le padding horizontal des cellules (2 × --space-4 = 32 px).
       15rem laissait l'input à ~210 px. */
    min-width: 17rem;
  }
  .portal-sites-table .portal-site-col--country {
    width: 6rem;
    min-width: 6rem;
  }
  .portal-sites-table .portal-site-col--country .ui-input--cc {
    width: 4.25rem;
    min-width: 4.25rem;
    text-align: center;
    text-transform: uppercase;
  }
  .portal-sites-table .portal-site-col--email {
    min-width: 10rem;
  }
  .portal-sites-table .portal-site-col--actions {
    width: 24%;
  }
  .portal-sites-table .portal-site-table__field {
    width: 100%;
    max-width: none;
  }
  .portal-sites-table .portal-site-row__readonly-hint {
    display: block;
    font-size: 0.8125rem;
    line-height: 1.35;
  }
}

.portal-site-row__delete-btn {
  min-width: 5.5rem;
}

/* Barre de recherche des sites (portail) : même gabarit que la recherche des
   certificats, largeur bornée pour ne pas s'étaler sur toute la page. */
.portal-sites-search {
  margin-bottom: var(--space-3);
  max-width: 28rem;
}

.portal-sites-search__empty {
  margin: var(--space-3) 0;
}

/* Édition inline : chaque champ s'enregistre seul quand on le quitte
   (apps/portal/site_field.py). Le retour « Enregistré » ou l'erreur se place
   sous le champ, comme dans le tableau des informations produit. */
.portal-site-field {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  min-width: 0;
}

/* Le badge est toujours rendu (remplacé en place par la réponse) : `.ui-badge`
   impose un affichage qui l'emporterait sur l'attribut `hidden`. */
.portal-site-row__pending[hidden] {
  display: none;
}

@media (max-width: 40em) {
  .portal-sites-merge-table.ui-table--stackable td.portal-site-col--name,
  .portal-sites-merge-table.ui-table--stackable td.portal-site-col--address {
    flex-direction: column;
    align-items: stretch;
    gap: var(--space-2);
  }

  .portal-sites-merge-table.ui-table--stackable td.portal-site-col--name::before,
  .portal-sites-merge-table.ui-table--stackable td.portal-site-col--address::before {
    width: 100%;
  }

  .portal-sites-merge-table.ui-table--stackable td.portal-site-col--name .portal-site-table__field,
  .portal-sites-merge-table.ui-table--stackable td.portal-site-col--address .portal-site-table__field {
    width: 100%;
    max-width: none;
  }
}

.portal-suggestion {
  margin-top: var(--space-3);
}

.portal-submit-panel {
  margin-top: var(--space-2);
}

.portal-submit-card {
  margin-top: var(--space-2);
  padding: var(--space-3);
}

.portal-checkbox-label {
  display: flex;
  align-items: center;
  gap: var(--space-1);
}

.portal-pagination {
  margin-top: var(--space-3);
  margin-bottom: var(--space-3);
  display: flex;
  gap: var(--space-2);
  align-items: center;
}

.portal-table--sticky thead th {
  position: sticky;
  top: 0;
  z-index: 2;
}

.portal-body .ui-toast-area {
  position: fixed;
  top: calc(var(--space-4) * 2 + var(--h-btn) + var(--space-3));
  right: var(--space-5);
  z-index: var(--z-toast);
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  max-width: min(90vw, 28rem);
  width: calc(100vw - var(--space-8));
}

.portal-body .ui-toast {
  border-left: 4px solid var(--color-primary);
  box-shadow: var(--shadow-lg);
}

.portal-body .ui-toast--success {
  border-left-color: var(--color-success);
}

.portal-body .ui-toast--error,
.portal-body .ui-toast--danger {
  border-left-color: var(--color-danger);
}

.portal-body .ui-toast--warning {
  border-left-color: var(--color-accent-amber);
}

/* legacy max-width: 48em — desktop-first base layout (.portal-filters,
   .portal-kpi-grid, .portal-site-form sont déjà multi-colonnes par défaut)
   + tap-targets 44px sur écrans tactiles. Conversion mobile-first reportée
   à un lot dédié. */
@media (max-width: 48em) {
  /* --bp-md */
  .portal-filters {
    grid-template-columns: 1fr;
  }

  .portal-certificates-toolbar {
    grid-template-columns: 1fr;
  }

  .portal-certificate-add-form {
    grid-template-columns: 1fr;
  }

  .portal-certificate-add-form__actions {
    justify-content: stretch;
  }

  .portal-certificate-add-form__actions .ui-btn {
    width: 100%;
  }

  .portal-kpi-grid {
    grid-template-columns: 1fr;
  }

  .portal-site-form {
    grid-template-columns: 1fr;
  }

  .portal-inline-form .ui-select,
  .portal-inline-form .ui-input,
  .portal-inline-form .ui-btn {
    width: 100%;
    max-width: none;
  }

  .portal-pagination {
    flex-wrap: wrap;
  }

  .ui-toast__close,
  .ui-btn--icon,
  .ui-tab {
    min-height: 44px;
    min-width: 44px;
  }
}

/* Page 404 globale (thème Vialid, typo Inter / tokens) */
.p-body-404 {
  display: flex;
  flex-direction: column;
}

.p-404 {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-8) var(--space-4);
}

.p-404__inner {
  width: 100%;
  max-width: 26rem;
  text-align: center;
}

.p-404__brand {
  margin-bottom: var(--space-6);
}

.p-404__code {
  margin: 0 0 var(--space-3);
  font-size: clamp(3rem, 14vw, 4.75rem);
  font-weight: 800;
  line-height: 1;
  letter-spacing: -0.04em;
  color: var(--color-primary);
  opacity: 0.92;
}

.p-404__heading {
  margin: 0 0 var(--space-3);
  font-size: 1.25rem;
  font-weight: 700;
  color: var(--color-text);
}

.p-404__lead {
  margin: 0 0 var(--space-4);
  font-size: 0.95rem;
  color: var(--color-text-muted);
}

.p-404__path {
  margin: 0 0 var(--space-5);
  font-size: 0.8125rem;
  color: var(--color-text-muted);
}

.p-404__path-label {
  display: block;
  margin-bottom: var(--space-1);
  font-weight: 600;
}

.p-404__path-value {
  display: inline-block;
  max-width: 100%;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-md);
  background: var(--color-primary-soft);
  border: 1px solid var(--color-border);
  color: var(--color-text);
  font-size: 0.8125rem;
  word-break: break-all;
}

.p-404__actions {
  margin: 0;
}

/* ── Supplier portal: Submission tab ─────────────────────────────── */
.portal-nav-submission {
  position: relative;
}
.portal-banner {
  display: block;
}
.portal-banner--info {
  background: var(--color-primary-soft);
  border-color: var(--color-primary);
}

/* Product detail — sections are separate .ui-card blocks (see product_detail.html).
   Trace grid heading + subtitle stay grouped in one card. */
.product-detail-section-heading {
  margin-bottom: var(--space-2);
}

.product-detail__hero {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: var(--space-4);
}

.product-detail__hero-media {
  flex: 0 0 auto;
  display: flex;
  align-items: flex-start;
  gap: var(--space-4);
}

.product-detail__hero-body {
  flex: 1 1 16rem;
  min-width: 0;
}

.product-detail__meta--compact,
.product-detail__attrs {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(9.5rem, 1fr));
  gap: var(--space-2) var(--space-4);
  margin: 0;
}

.product-detail__attrs {
  margin-top: var(--space-3);
  padding-top: var(--space-3);
  border-top: 1px solid var(--color-border);
}

.product-detail__meta-item {
  min-width: 0;
}

.product-detail__meta-label {
  margin: 0 0 var(--space-1);
  font-size: var(--text-xs, 0.75rem);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.02em;
  color: var(--color-text-muted);
}

.product-detail__meta-value {
  margin: 0;
  font-size: var(--text-sm, 0.875rem);
  word-break: break-word;
}

.product-detail__qr-link {
  display: block;
  flex: 0 0 auto;
  border-radius: var(--radius-sm);
  line-height: 0;
  transition: box-shadow var(--duration-fast, 0.15s) var(--ease-out, ease-out);
}

.product-detail__qr-link:hover,
.product-detail__qr-link:focus-visible {
  box-shadow: var(--shadow-focus, 0 0 0 3px color-mix(in srgb, var(--color-primary) 35%, transparent));
}

/* Image "hero" du produit : max 200x200, couverture + bordure subtile. */
.product-detail__hero-img,
.product-detail__hero-placeholder {
  display: block;
  width: 200px;
  height: 200px;
  max-width: 100%;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border-color);
}

.product-detail__hero-img {
  object-fit: cover;
}

.product-detail__hero-placeholder {
  background: var(--surface-muted, var(--bg-muted));
}

/* QR code page publique — même gabarit 200×200 que la photo produit. */
.product-detail__qr {
  display: block;
  width: 200px;
  height: 200px;
  max-width: 100%;
  border: 1px solid var(--border-color);
  border-radius: var(--radius-sm);
  background: var(--color-surface);
}

/* QR d'un produit non actif : visible mais clairement inerte (audit UI 18/09, V-01). */
.product-detail__qr-inactive {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
  max-width: 200px;
}

.product-detail__qr--inactive {
  opacity: 0.35;
  filter: grayscale(1);
}

/* Conteneur SVG des charts "score history" et "scan trend". */
.product-detail__chart {
  height: 130px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  margin-bottom: var(--space-3);
}

/* Carte imbriquée d'un composant produit : padding un cran plus large
   que .ui-card--nested pour respirer avec les sous-formulaires internes. */
.product-detail__component-card {
  padding: var(--space-5);
}

/* Select "nom de matière" dans le formulaire d'ajout inline : pousse
   le bouton submit contre le bord droit en gardant une largeur minimale. */
.product-detail__material-select {
  flex: 1;
  min-width: 10rem;
}

/* Public DPP theme editor ---------------------------------------------- */
/* Ligne d'édition d'une couleur : input texte + input color picker. */
.theme-color-row {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  max-width: 16rem;
}

/* Input[type="color"] carré rendu discret (sans bordure ni fond).
   Conserve le cursor pointer pour l'affordance. */
.theme-color-picker {
  width: 2.5rem;
  height: 2.5rem;
  border: 0;
  background: transparent;
  padding: 0;
  cursor: pointer;
}

.theme-contrast-badges {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1);
  margin-top: var(--space-1);
}

.theme-contrast-badge {
  display: inline-flex;
  align-items: center;
  padding: 0.125rem 0.5rem;
  border-radius: var(--radius-sm);
  font-size: var(--text-xs);
  line-height: 1.35;
  border: 1px solid transparent;
}

.theme-contrast-badge--aa {
  color: var(--color-success-fg);
  background: var(--color-success-bg);
  border-color: var(--color-success-border);
}

.theme-contrast-badge--aaa {
  color: var(--color-info-fg);
  background: var(--color-info-bg);
  border-color: var(--color-info-border);
}

.theme-contrast-badge--fail {
  color: var(--color-danger-fg);
  background: var(--color-danger-bg);
  border-color: var(--color-danger-border);
  font-weight: 600;
}

.theme-contrast-badge--unknown {
  color: var(--color-muted-fg);
  background: var(--color-muted-bg);
  border-color: var(--color-muted-border);
}

.public-dpp-font-select {
  max-width: 28rem;
}

.ui-actions--cluster {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
}

/* Compliance dashboard -------------------------------------------------- */
.ui-grid {
  display: grid;
  gap: var(--space-4);
}
.ui-grid--auto-fit {
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
}
.ui-card--compact {
  padding: var(--space-4);
}
.compliance-card {
  color: inherit;
  transition: border-color 0.15s ease, transform 0.15s ease;
}
.compliance-card:hover {
  border-color: var(--color-primary);
}
.compliance-card.is-selected {
  border-color: var(--color-primary);
  box-shadow: 0 0 0 2px var(--color-primary-soft);
}
.compliance-card__head {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  margin-bottom: var(--space-3);
}
.compliance-card__title {
  margin: 0 0 var(--space-1) 0;
  font-size: 1rem;
  font-weight: 600;
}
.compliance-card__title-link {
  color: inherit;
  text-decoration: none;
}
.compliance-card__title-link:hover {
  text-decoration: underline;
}
/* Part de conformes d'une norme : le chiffre qu'on cherchait en divisant de
   tête quatre compteurs bruts (lot 4 c). */
.compliance-card__share {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2) var(--space-3);
  margin-top: var(--space-3);
}

.compliance-card__share .ui-meter {
  flex: 1 1 5rem;
  min-width: 4rem;
}

.compliance-card__pct {
  font-size: var(--fs-xl);
  font-weight: var(--fw-semibold);
  font-variant-numeric: tabular-nums;
  line-height: 1;
}

.compliance-card__pct--success {
  color: var(--color-success);
}

.compliance-card__pct--warning {
  color: var(--color-warning);
}

.compliance-card__pct--danger {
  color: var(--color-danger);
}

.compliance-card__pct--muted {
  color: var(--color-text-muted);
}

.compliance-card__share-detail {
  flex: 1 1 100%;
  font-size: var(--fs-sm);
  color: var(--color-text-muted);
}

.compliance-lead {
  max-width: 60ch;
}

.compliance-select-hint {
  margin: 0;
}

.compliance-card__stats {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--space-2);
  margin-top: var(--space-3);
}
a.compliance-stat {
  display: block;
  padding: var(--space-2);
  border-radius: var(--radius-md);
  text-align: center;
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  text-decoration: none;
  color: inherit;
  transition:
    border-color 0.12s ease,
    box-shadow 0.12s ease,
    transform 0.12s ease;
}
a.compliance-stat:hover {
  border-color: var(--color-primary);
}
a.compliance-stat:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
}
a.compliance-stat.is-active {
  box-shadow: 0 0 0 2px var(--color-primary-soft);
  border-color: var(--color-primary);
}
.compliance-stat__value {
  display: block;
  font-size: 1.25rem;
  font-weight: 600;
  line-height: 1.2;
}
.compliance-stat__label {
  display: block;
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--color-text-muted);
}
.compliance-stat--ok {
  background: rgba(16, 185, 129, 0.08);
  border-color: rgba(16, 185, 129, 0.35);
  color: var(--color-success-fg);
}
.compliance-stat--ok .compliance-stat__label {
  color: var(--color-success-fg);
}
.compliance-stat--ko {
  background: rgba(220, 38, 38, 0.08);
  border-color: rgba(220, 38, 38, 0.35);
  color: var(--color-danger-fg);
}
.compliance-stat--ko .compliance-stat__label {
  color: var(--color-danger-fg);
}
.compliance-card__rules {
  list-style: none;
  padding: 0;
  margin: var(--space-3) 0 0 0;
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  font-size: 0.8rem;
}
.compliance-card__rules code {
  font-size: 0.72rem;
}

/* ---------------------------------------------------------------------- */
/* Home retailer V1 — filtres, hero, QR, HTMX, vue d’ensemble, leaderboard */
/* ---------------------------------------------------------------------- */
.dash-v1 {
  /* Jetons propres à l'accueil : coins arrondis, marges et écarts plus
     généreux que le reste de l'application (passe UI du 12/10). */
  --dash-radius: 12px;
  --dash-pad: var(--space-8);
  --dash-gap: var(--space-6);
  display: flex;
  flex-direction: column;
  gap: var(--space-8);
  min-width: 0;
}

/* Rythme vertical homogène entre les blocs du corps (hors filtres HTMX du shell). */
#home-dashboard-body {
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
  min-width: 0;
}

@media (min-width: 48em) {
  #home-dashboard-body {
    gap: var(--space-8);
  }
}

.dash-v1__greeting,
.dash-v1__macro,
.dash-v1__network-map-supplier {
  display: flex;
  flex-direction: column;
  gap: var(--space-6);
  min-width: 0;
}

@media (min-width: 48em) {
  .dash-v1__greeting,
  .dash-v1__macro,
  .dash-v1__network-map-supplier {
    gap: var(--space-8);
  }
}

.dash-empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: var(--space-2);
  padding: var(--space-6) var(--space-4);
  border: 1px dashed var(--color-border-subtle);
  border-radius: var(--radius-md);
  color: var(--color-text-muted);
}
.dash-empty-state--compact {
  padding: var(--space-4);
}
.dash-empty-state__illu {
  color: var(--color-text-muted);
}
.dash-empty-state__title {
  margin: 0;
  font-size: 1rem;
  font-weight: 600;
  color: var(--color-text);
}
.dash-empty-state__body {
  max-width: 32rem;
}

@media (max-width: 47.99em) {
  .dash-sticky-col--lb-0 {
    position: sticky;
    left: 0;
    z-index: 2;
    background: var(--color-surface);
    box-shadow: none;
  }
}

.dash-v1 .ui-badge--warning {
  color: var(--color-text);
  background: color-mix(in srgb, var(--color-warning) 35%, var(--color-surface));
  border: 1px solid color-mix(in srgb, var(--color-warning) 55%, var(--color-border-subtle));
}
.dash-section-title {
  margin: 0 0 var(--space-4);
  font-size: 1.25rem;
  font-weight: var(--fw-semibold);
  letter-spacing: -0.01em;
  text-transform: none;
  color: var(--color-text);
  line-height: var(--lh-tight);
}

/* ---- Deux colonnes : le travail (à faire, fournisseurs) à gauche, le contexte
   (lecture des passeports, qualité, flux) à droite ; empilées sur téléphone, le
   travail d'abord. */
.dash-v1__layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--dash-gap);
  min-width: 0;
}
.dash-v1__work,
.dash-v1__context {
  display: flex;
  flex-direction: column;
  gap: var(--dash-gap);
  min-width: 0;
}
@media (min-width: 64em) {
  .dash-v1__layout {
    grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
    gap: var(--dash-gap);
    align-items: start;
  }
}

.dash-hero {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--dash-gap);
}

@media (min-width: 48em) {
  .dash-hero {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (min-width: 64em) {
  .dash-hero {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}

.dash-hero .dash-tile {
  min-width: 0;
}

.dash-tile {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--dash-pad);
  border: 1px solid var(--color-border-subtle);
  border-radius: var(--dash-radius);
  background: var(--color-surface);
  text-decoration: none;
  color: var(--color-text);
  transition: border-color var(--duration-fast) var(--ease-out),
              box-shadow var(--duration-fast) var(--ease-out);
}
.dash-tile:hover {
  border-color: var(--color-border);
  box-shadow: var(--shadow-sm);
}
.dash-tile__open {
  margin-top: auto;
  padding-top: var(--space-2);
}
.dash-tile__label {
  font-size: 1.0625rem;
  font-weight: var(--fw-semibold);
  letter-spacing: 0;
  text-transform: none;
  color: var(--color-text);
}
.dash-tile__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: var(--color-bg);
  color: var(--color-text-muted);
}
.dash-tile__value {
  font-size: 2.75rem;
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.05;
  font-variant-numeric: tabular-nums;
  overflow-wrap: break-word;
}
.dash-tile__value--dpp {
  color: var(--color-primary);
}
.dash-tile__value--certs-pending {
  color: var(--color-text);
}
/* En attente de TA revue : une file à traiter, pas un manquement. L'échéance
   dépassée juste en dessous, elle, reste en rouge — c'est un vrai défaut. */
.dash-tile__value--certs-pending.dash-tile__value--alert {
  color: var(--color-warning);
}
.dash-tile__value--certs-expired {
  color: var(--color-text);
}
.dash-tile__value--certs-expired.dash-tile__value--alert {
  color: var(--color-danger);
}
.dash-tile__value--certs-expiring {
  color: var(--color-text);
}
.dash-tile__value--certs-expiring.dash-tile__value--warn {
  color: var(--color-accent-amber);
}
.dash-tile .dash-card__link {
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--color-primary);
  text-decoration: none;
}
.dash-tile:hover .dash-card__link {
  text-decoration: underline;
}
.dash-tile__hint {
  font-size: 0.9375rem;
  color: var(--color-text-muted);
}
.dash-tile__detail {
  font-size: 0.9375rem;
  color: var(--color-text-muted);
}

/* ---- Bloc plein « fournisseurs à relancer » : la seule action de masse qui
   part de l'accueil, posée à côté des certificats. ----------------------- */
.dash-cta {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--dash-pad);
  border-radius: var(--dash-radius);
  background: var(--color-primary);
  color: var(--color-on-primary);
}
.dash-cta__title {
  margin: 0;
  font-size: 1.25rem;
  font-weight: var(--fw-semibold);
  line-height: var(--lh-tight);
  color: inherit;
}
.dash-cta__text {
  margin: 0;
  font-size: 1rem;
  line-height: var(--lh-base);
  color: inherit;
}
.dash-cta__btn {
  align-self: flex-start;
  margin-top: auto;
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 10px 20px;
  border-radius: var(--radius-pill);
  background: var(--color-surface);
  color: var(--color-primary);
  font-weight: var(--fw-semibold);
  text-decoration: none;
  transition: background var(--duration-fast) var(--ease-out);
}
.dash-cta__btn:hover {
  background: var(--color-primary-soft);
}
.dash-cta__btn:focus-visible {
  outline: 2px solid var(--color-on-primary);
  outline-offset: 2px;
}

/* ---- Entonnoir du catalogue (brouillons → publiés → conformes) --------- */
.dash-funnel {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
  min-width: 0;
}
.dash-funnel__bar {
  display: flex;
  height: 12px;
  border-radius: 999px;
  overflow: hidden;
  background: var(--color-bg);
}
.dash-funnel__segment {
  flex: 0 0 var(--part, 0%);
  min-width: 0;
}
.dash-funnel__segment--draft,
.dash-funnel__swatch--draft {
  background: var(--color-border);
}
.dash-funnel__segment--active,
.dash-funnel__swatch--active {
  background: var(--color-primary);
}
.dash-funnel__segment--compliant,
.dash-funnel__swatch--compliant {
  background: var(--color-success);
}
.dash-funnel__legend {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-4) var(--space-8);
  margin: 0;
  padding: 0;
  list-style: none;
}
@media (min-width: 48em) {
  .dash-funnel__legend {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}
.dash-funnel__link {
  display: grid;
  grid-template-columns: auto auto 1fr;
  grid-template-rows: auto auto;
  column-gap: var(--space-3);
  align-items: baseline;
  min-height: 44px;
  text-decoration: none;
  color: var(--color-text);
}
.dash-funnel__link:hover .dash-funnel__label {
  text-decoration: underline;
}
.dash-funnel__swatch {
  width: 12px;
  height: 12px;
  border-radius: 3px;
  align-self: center;
}
.dash-funnel__value {
  font-size: 2.25rem;
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.05;
  font-variant-numeric: tabular-nums;
}
.dash-funnel__value--ok {
  color: var(--color-success);
}
.dash-funnel__label {
  font-size: 1.0625rem;
  font-weight: var(--fw-semibold);
  color: var(--color-text);
}
.dash-funnel__detail {
  grid-column: 2 / -1;
  font-size: 0.9375rem;
  color: var(--color-text-muted);
}
.dash-funnel__note {
  margin: 0;
  font-size: 0.9375rem;
}

/* Barre de proportion — la part atteinte d'un tout (complétude d'un
   fournisseur, conformité d'une norme, avancement d'un portail).
   À ne pas confondre avec `.ui-progress`, plus épaisse et animée, qui dit
   qu'un travail est EN COURS (un import, une soumission). Deux sens
   distincts, deux composants — un seul de chaque (lot 4 a). */
.ui-meter {
  height: 4px;
  width: 100%;
  background: var(--color-bg);
  border-radius: 999px;
  overflow: hidden;
}
.ui-meter__fill {
  display: block;
  height: 100%;
  width: var(--pct, 0%);
  background: var(--color-accent-amber);
  border-radius: 999px;
}
.ui-meter__fill--dpp {
  background: var(--color-primary);
}
.ui-meter__fill--compliance-danger {
  background: var(--color-danger);
}
.ui-meter__fill--compliance-warning {
  background: var(--color-accent-amber);
}
.ui-meter__fill--compliance-success {
  background: var(--color-primary);
}
.ui-meter__fill--compliance-muted {
  background: var(--color-border-subtle);
}

/* ---- Cartes centrales -------------------------------------------------- */
.dash-center {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--dash-gap);
  min-width: 0;
}
.dash-center .dash-card {
  min-width: 0;
}

@media (max-width: 47.99em) {
  .dash-v1 {
    --dash-pad: var(--space-5);
    --dash-gap: var(--space-4);
  }
}

.dash-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
  padding: var(--dash-pad);
  border: 1px solid var(--color-border-subtle);
  border-radius: var(--dash-radius);
  background: var(--color-surface);
}
.dash-card__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  flex-wrap: wrap;
}
.dash-card__title {
  margin: 0;
  font-size: 1.25rem;
  font-weight: var(--fw-semibold);
  letter-spacing: -0.01em;
  color: var(--color-text);
  line-height: var(--lh-tight);
}
.dash-card__link {
  font-size: 0.9375rem;
  color: var(--color-primary);
  text-decoration: none;
  font-weight: var(--fw-semibold);
}
.dash-card__link:hover {
  text-decoration: underline;
}

/* Cible tactile : ≥ 44px de haut sur mobile (audit UI 18/09, D-08). */
@media (max-width: 48em) {
  .dash-card__link {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }
}

/* Carte « Qualité » : retours défectueux sur 12 mois --------------------- */
.dash-quality__subtitle {
  margin: 0;
  font-size: 1rem;
  font-weight: var(--fw-semibold);
  color: var(--color-text);
}
.dash-quality-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
}
.dash-quality-row {
  display: flex;
  justify-content: space-between;
  gap: var(--space-4);
  min-height: 48px;
  padding: var(--space-2) 0;
  border-bottom: 1px solid var(--color-border-subtle);
  font-size: 1rem;
}
.dash-quality-row:last-child {
  border-bottom: 0;
}
.dash-quality-row__rate {
  color: var(--color-danger);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* Santé des flux, en pied de l'accueil ---------------------------------- */
.dash-flows__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  font-size: 0.9375rem;
}
.dash-flows__item {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-1) var(--space-3);
}
.dash-flows__label {
  font-weight: 600;
}
.dash-flows__detail {
  color: var(--color-text-muted);
}
.dash-flows__detail--failed {
  color: var(--color-danger);
}

/* Salutation et fraîcheur des chiffres, sous le titre de l'accueil ------- */
.dash-greeting {
  margin: var(--space-1) 0 0;
  font-size: 1rem;
  color: var(--color-text-muted);
}

/* File d'actions « à faire cette semaine » ------------------------------ */
.dash-action-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
}
.dash-action-row {
  border-bottom: 1px solid var(--color-border-subtle);
}
.dash-action-row:last-child {
  border-bottom: 0;
}
.dash-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--color-text-muted);
  flex-shrink: 0;
}
.dash-dot--critical {
  background: var(--color-danger);
}
.dash-dot--moderate {
  background: var(--color-accent-amber);
}
.dash-action-row__link {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: var(--space-4);
  min-width: 0;
  min-height: 56px;
  padding: var(--space-4) 0;
  text-decoration: none;
  color: var(--color-text);
}
.dash-action-row__main {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
.dash-action-row__link:hover .dash-action-row__name {
  color: var(--color-primary);
  text-decoration: underline;
}
.dash-action-row__name {
  font-size: 1rem;
  font-weight: var(--fw-medium);
  line-height: var(--lh-base);
}
.dash-action-row__cta {
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--color-primary);
  white-space: nowrap;
}
.dash-action-row__reason {
  font-size: 0.9375rem;
  color: var(--color-text-muted);
}

/* Carte « Activité QR code » -------------------------------------------- */
.dash-qr-summary {
  display: flex;
  align-items: baseline;
  gap: var(--space-2);
  flex-wrap: wrap;
}
.dash-qr-summary__value {
  font-size: 2.75rem;
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.05;
  font-variant-numeric: tabular-nums;
  overflow-wrap: break-word;
}
.dash-qr-summary__window {
  font-size: 0.9375rem;
  color: var(--color-text-muted);
}
.dash-qr-summary__hint {
  font-size: 0.78rem;
  color: var(--color-text-muted);
}
.dash-qr-summary__delta {
  font-size: 0.9375rem;
  color: var(--color-text-muted);
}
.dash-qr-summary__delta--up {
  color: var(--color-success);
}
.dash-qr-summary__delta--down {
  color: var(--color-danger);
}
.dash-badge {
  display: inline-flex;
  align-items: center;
  padding: 2px var(--space-2);
  border-radius: 999px;
  font-size: 0.75rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.dash-badge--up {
  background: rgba(21, 128, 61, 0.12);
  color: var(--color-success);
}
.dash-badge--down {
  background: rgba(180, 35, 24, 0.12);
  color: var(--color-danger);
}
.dash-sparkline {
  display: block;
  width: 100%;
  height: 48px;
  color: var(--color-primary);
}
.dash-qr-countries {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}
.dash-qr-country {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: 0.85rem;
}
.dash-qr-country__code {
  font-weight: 500;
  flex: 1;
}
.dash-qr-country__pct {
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--color-text-muted);
}

/* État vide --------------------------------------------------------------- */
.dash-empty {
  margin: 0;
  padding: var(--space-4);
  border: 1px dashed var(--color-border-subtle);
  border-radius: var(--radius-sm);
  color: var(--color-text-muted);
  text-align: center;
}
.dash-empty strong {
  display: block;
  margin-bottom: 4px;
  color: var(--color-text);
}
.dash-empty p {
  margin: 0;
  font-size: 1rem;
}
.dash-empty--inline {
  border: 0;
  padding: var(--space-2) 0;
  text-align: left;
}

/* Éditeur thème page publique DPP : onglets (gauche) + aperçu (droite) */
/* Mobile-first : layout vertical empilé (onglets au-dessus, preview en dessous). */
.public-dpp-theme-editor {
  margin-top: var(--space-5);
}

.public-dpp-theme-editor-inner {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-4);
  align-items: start;
}
.public-dpp-theme-editor-fields {
  min-width: 0;
}
.public-dpp-theme-preview-column {
  position: static;
  align-self: start;
  min-width: 0;
}
.public-dpp-theme-preview-heading {
  margin: 0 0 var(--space-3);
  font-size: 1.05rem;
}
.public-dpp-theme-preview-iframe {
  display: block;
  width: 100%;
  min-height: 560px;
  border: 1px solid var(--border-color);
  border-radius: var(--radius-md);
  background: var(--color-surface);
}
@media (min-width: 64em) {
  /* --bp-lg : desktop → 2 colonnes 50/50 côte à côte, aperçu sticky à droite. */
  .public-dpp-theme-editor-inner {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: var(--space-6);
  }
  .public-dpp-theme-preview-column {
    position: sticky;
    top: var(--space-4);
  }
  .public-dpp-theme-preview-iframe {
    min-height: clamp(680px, 72vh, 920px);
  }
}

/* ======================================================================== */
/* Accessibility & UX (batch 2)                                             */
/* ======================================================================== */

/* --- Focus-visible universel -------------------------------------------- */
/* Éléments UI déjà arrondis : on préserve leur border-radius natif pour
   éviter l'aplatissement des coins au focus clavier. */
.ui-btn:focus-visible,
.ui-link-tab:focus-visible,
.ui-input:focus-visible,
.ui-select:focus-visible,
.ui-textarea:focus-visible,
.p-sidebar__nav a:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
}

/* Éléments génériques sans radius UI : on pose un radius-xs pour le ring. */
a:focus-visible,
button:focus-visible,
[tabindex="0"]:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
  border-radius: var(--radius-xs);
}

/* --- Boutons : min-height, :active, aria-busy --------------------------- */
.ui-btn {
  min-height: var(--h-btn);
}

.ui-btn--compact {
  min-height: var(--h-btn-sm);
}

.ui-btn--lg {
  min-height: var(--h-btn-lg);
}

.ui-btn:active:not(:disabled) {
  transform: translateY(1px);
}

.ui-btn[aria-busy="true"] {
  position: relative;
  color: transparent;
  pointer-events: none;
}

.ui-btn[aria-busy="true"]::after {
  content: "";
  position: absolute;
  inset: 0;
  margin: auto;
  width: 16px;
  height: 16px;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: 50%;
  animation: ui-spin 0.7s linear infinite;
  color: var(--color-surface);
}

/* --- prefers-reduced-motion global -------------------------------------- */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* --- Skip link ---------------------------------------------------------- */
.skip-link {
  position: absolute;
  top: -40px;
  left: var(--space-2);
  background: var(--color-primary);
  color: var(--color-surface);
  padding: var(--space-2) var(--space-4);
  border-radius: var(--radius-sm);
  z-index: var(--z-modal);
  text-decoration: none;
  font-weight: var(--fw-semibold);
}

.skip-link:focus {
  top: var(--space-2);
}

/* --- Astérisque required -------------------------------------------------
   Un champ obligatoire vide n'est pas une erreur : c'est ce qui reste à faire.
   Le portail marquait déjà le sien en terracotta
   (`.portal-attr-grid__required-mark`) ; les deux surfaces s'accordent. */
.ui-label:has(+ .ui-input[required])::after,
.ui-label:has(+ .ui-select[required])::after,
.ui-label:has(+ .ui-textarea[required])::after,
.ui-label[data-required]::after {
  content: " *";
  color: var(--color-warning);
  font-weight: var(--fw-bold);
}

/* --- Utilitaires typographiques ----------------------------------------- */
.ui-heading-1 {
  font-size: var(--fs-2xl);
  font-weight: var(--fw-semibold);
  line-height: var(--lh-tight);
  margin: 0 0 var(--space-4);
}

.ui-heading-2 {
  font-size: var(--fs-xl);
  font-weight: var(--fw-semibold);
  line-height: var(--lh-tight);
  margin: 0 0 var(--space-3);
}

.ui-heading-3 {
  font-size: var(--fs-lg);
  font-weight: var(--fw-semibold);
  line-height: var(--lh-tight);
  margin: 0 0 var(--space-2);
}

.ui-body {
  font-size: var(--fs-sm);
  line-height: var(--lh-base);
}

.ui-caption {
  font-size: var(--fs-xs);
  line-height: var(--lh-base);
  color: var(--color-text-muted);
}

.ui-text-mono {
  font-family: var(--font-mono, ui-monospace, SFMono-Regular, monospace);
  font-size: var(--fs-xs);
}

/* --- Utilitaires layout ------------------------------------------------- */
/* .ui-stack et .ui-stack--sm : valeurs existantes préservées (top du fichier).
   Seul le variant --lg est ajouté ici. */
.ui-stack--lg {
  gap: var(--space-6);
}

.ui-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
}

.ui-row--between {
  justify-content: space-between;
}

.ui-row--end {
  justify-content: flex-end;
}

.ui-spacer {
  flex: 1;
}

/* --- Utilitaires espacement (migration des marges inline) ---------------- */
/* Utilisation : reset de marge sur un <p>/<h*>/<div> enfant d'une .ui-card
   qui n'utilise pas .ui-stack, OU ajustement ponctuel. Toujours préférer
   .ui-stack + gap quand possible. */
.ui-m-0 {
  margin: 0;
}
.ui-mt-0 {
  margin-top: 0;
}
.ui-mb-0 {
  margin-bottom: 0;
}
.ui-mt-2 {
  margin-top: var(--space-2);
}
.ui-mt-3 {
  margin-top: var(--space-3);
}
.ui-mt-4 {
  margin-top: var(--space-4);
}
.ui-mt-5 {
  margin-top: var(--space-5);
}
.ui-mt-6 {
  margin-top: var(--space-6);
}
.ui-mt-8 {
  margin-top: var(--space-8);
}
.ui-mb-1 {
  margin-bottom: var(--space-1);
}
.ui-mb-2 {
  margin-bottom: var(--space-2);
}
.ui-mb-3 {
  margin-bottom: var(--space-3);
}
.ui-mb-4 {
  margin-bottom: var(--space-4);
}
.ui-mb-5 {
  margin-bottom: var(--space-5);
}
.ui-mb-6 {
  margin-bottom: var(--space-6);
}

/* Champs .ui-field dans un .ui-stack : le gap du stack remplace la
   margin-bottom intrinsèque de .ui-field. Évite ~10 style="margin:0" dans
   les formulaires empilés (product_detail, suppliers/detail, settings/app…). */
.ui-stack > .ui-field {
  margin-bottom: 0;
}

/* --- Variantes .ui-row -------------------------------------------------- */
.ui-row--tight {
  gap: var(--space-2);
}
.ui-row--wide {
  gap: var(--space-4);
}
.ui-row--bottom {
  align-items: flex-end;
}

/* --- Cartes imbriquées / variantes -------------------------------------- */
/* Carte nichée dans une autre .ui-card : padding réduit + pas d'ombre pour
   éviter l'effet "carte-dans-carte-dans-carte". */
.ui-card--nested {
  padding: var(--space-4);
  box-shadow: none;
}

/* Bordure pointillée (ex. blocs "composant en cours d'édition"). */
.ui-card--dashed {
  border-style: dashed;
}

/* Carte neutre/indicative : surface atténuée + bordure plus légère
   (ex. hints contextuels, panneaux d'info secondaire). */
.ui-card--hint {
  background: var(--surface-muted);
  border-color: var(--border-color);
}

/* --- Variantes .ui-input ------------------------------------------------ */
/* .ui-input max-width par défaut = 32rem. Variantes pour champs plus étroits
   ou plus larges selon le contexte (adresses, codes couleur, URLs…). */
.ui-input--wide {
  max-width: 36rem;
}
.ui-input--narrow {
  max-width: 24rem;
}
.ui-input--xxs {
  max-width: 12rem;
}
.ui-input--xs {
  max-width: 8rem;
}
/* Code pays ISO 2 lettres (ex. FR, IT) — champ très étroit. */
.ui-input--cc {
  max-width: 4rem;
}

/* --- Séparateur horizontal interne -------------------------------------- */
/* Délimite une zone secondaire (révélée dynamiquement, ex. clé API) d'une
   zone principale au sein d'une même carte : marge + padding + filet.
   Utilise l'alias --border-color (cf. tokens.css) pour hériter du thème. */
.ui-divider-top {
  margin-top: var(--space-4);
  padding-top: var(--space-4);
  border-top: 1px solid var(--border-color);
}

/* --- Fieldset reset ----------------------------------------------------- */
/* Annule l'habillage par défaut du navigateur pour un <fieldset> utilisé
   comme simple regroupement logique (pas de bordure/marge intrinsèque). */
.ui-fieldset--reset {
  border: 0;
  margin: 0;
  padding: 0;
}

/* --- Label pour couple checkbox + texte --------------------------------- */
/* Annule le font-weight 600 de .ui-label (inapproprié pour un choix optionnel)
   et aligne checkbox + texte sur une même ligne. */
.ui-label--checkbox {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-weight: normal;
  cursor: pointer;
  margin: 0;
}

/* Variante : texte multi-ligne — checkbox en haut plutôt que centré. */
.ui-label--checkbox--top {
  align-items: flex-start;
}

/* Ajustement visuel d'une checkbox alignée avec la première ligne d'un texte. */
.ui-checkbox-nudge {
  margin-top: 0.2rem;
}

/* --- Thumbnail image (règle de migration) ------------------------------- */
/* Coins arrondis + bordure subtile. Pour tailles/positionnement,
   combiner avec une classe spécifique (ex. .product-detail__hero-img). */
.ui-thumb {
  display: block;
  object-fit: cover;
  border-radius: var(--radius-xs);
  border: 1px solid var(--border-color);
  flex-shrink: 0;
}

.ui-thumb--sm {
  width: 40px;
  height: 40px;
}

.portal-product-thumb {
  cursor: zoom-in;
}

.portal-product-thumb-preview {
  position: fixed;
  z-index: 1200;
  width: 200px;
  height: 200px;
  padding: 4px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border-color);
  background: var(--surface-elevated);
  box-shadow: var(--shadow-lg);
  pointer-events: none;
}

.portal-product-thumb-preview__img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: var(--radius-xs);
}

/* --- Texte / table ------------------------------------------------------ */
.ui-text-break {
  word-break: break-all;
}

.ui-nowrap {
  white-space: nowrap;
}

.ui-va-top {
  vertical-align: top;
}

/* Colonne numérique : alignée à droite + chiffres tabulaires (glyphes de
   même largeur → les colonnes s'alignent verticalement dans un tableau). */
.ui-num {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

/* Ligne de métadonnée compacte : marge neutralisée + taille réduite.
   Utilisée pour empiler plusieurs infos techniques (IDs, hashes,
   timestamps) dans un panneau de détails (audit, logs). Se combine
   avec .p-muted pour la couleur. */
.ui-meta-line {
  margin: 0;
  font-size: var(--fs-sm);
}

/* Pre soft-wrap : le contenu retourne à la ligne au lieu de déborder
   horizontalement. À combiner avec .ui-mono pour un bloc de code/texte. */
.ui-pre-wrap {
  white-space: pre-wrap;
}

/* Retours à la ligne du texte (ex. chaînes i18n multi-paragraphes). */
.ui-pre-line {
  white-space: pre-line;
}

/* Variante scroll : + hauteur max + scroll vertical pour des contenus
   potentiellement très longs (snapshots JSON, logs étendus). */
.ui-pre-wrap--scroll {
  white-space: pre-wrap;
  max-height: 28rem;
  overflow: auto;
}

/* Font-family monospace sans imposer de font-size (contrairement à
   .ui-mono / .ui-text-mono qui fixent la taille). Utile quand on veut
   juste rendre un identifiant en monospace dans un contexte body. */
.ui-font-mono {
  font-family: var(--font-mono);
}

/* Grille <dl> en deux colonnes (clé/valeur) : métadonnées compactes dans
   une carte. Équivalent de <dl class="ui-stack ui-stack--sm"> avec layout
   tabulaire. Réutilisé dans supplier detail, product detail, etc. */
.ui-dl-grid {
  margin: 0;
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: var(--space-2) var(--space-4);
}

/* Liste sans marge externe, avec indentation standard pour les puces. */
.ui-ul-flush {
  margin: 0;
  padding-left: var(--space-5);
}

/* Formulaire inline juxtaposé à un bouton (cellule d'actions de tableau). */
.ui-form-inline-gap {
  display: inline-block;
  margin-left: var(--space-2);
}

/* Formulaire inline sans marge additionnelle. À utiliser quand l'espacement
   vient d'ailleurs (frère avec margin-right, parent flex, etc.). */
.ui-form-inline {
  display: inline-block;
}

.ui-danger-zone {
  border: 1px solid var(--color-danger);
  background: rgba(180, 35, 24, 0.04);
  border-radius: var(--radius-md);
  padding: var(--space-4);
  margin-top: var(--space-6);
}

/* ConfirmDialog — unified destructive/confirmation modal.
   Used via data-confirm attributes on forms. See static/js/confirm_dialog.js. */
.ui-confirm-dialog {
  max-width: 480px;
  width: 90vw;
  border: none;
  border-radius: var(--radius-md);
  padding: var(--space-6);
  box-shadow: var(--shadow-xl);
  background: var(--color-surface);
  color: var(--color-text);
}

.ui-confirm-dialog::backdrop {
  background: rgba(0, 0, 0, 0.5);
}

.ui-confirm-dialog__title {
  font-size: var(--fs-lg);
  font-weight: var(--fw-semibold);
  margin: 0 0 var(--space-3);
}

.ui-confirm-dialog__message {
  color: var(--color-text-muted);
  margin: 0 0 var(--space-5);
  line-height: var(--lh-base);
  white-space: pre-line;
}

.ui-confirm-dialog__type-to-confirm {
  margin-bottom: var(--space-5);
}

.ui-confirm-dialog__expected {
  background: var(--color-bg);
  padding: 2px 6px;
  border-radius: var(--radius-xs);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.9em;
}

.ui-confirm-dialog__actions {
  margin-top: var(--space-5);
}

/* Fenêtre « nouvelle clé API » : la clé et le bouton copier côte à côte. */
.ui-api-key-dialog__row {
  display: flex;
  gap: var(--space-2);
  align-items: center;
}

.ui-api-key-dialog__row .ui-input {
  flex: 1;
  min-width: 0;
}

.ui-api-key-dialog__row .ui-btn {
  white-space: nowrap;
  flex-shrink: 0;
}

.ui-confirm-dialog--destructive [data-confirm-ok] {
  background: var(--color-danger);
  color: var(--color-on-primary);
  border-color: transparent;
}

.ui-confirm-dialog--destructive [data-confirm-ok]:hover:not(:disabled) {
  filter: brightness(0.95);
}

/* CSV catalog import preview: recap before confirm (soft warnings). */
.ui-csv-import-soft-warn-notice {
  padding: var(--space-4);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border);
  background: var(--color-bg);
}

@keyframes ui-confirm-dialog-enter {
  from {
    opacity: 0;
    transform: scale(0.96);
  }
  to {
    opacity: 1;
    transform: scale(1);
  }
}

@keyframes ui-confirm-dialog-backdrop {
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
}

.ui-confirm-dialog[open] {
  animation: ui-confirm-dialog-enter var(--duration-fast) var(--ease-out);
}

.ui-confirm-dialog[open]::backdrop {
  animation: ui-confirm-dialog-backdrop var(--duration-fast) var(--ease-out);
}

@media (prefers-reduced-motion: reduce) {
  .ui-confirm-dialog[open],
  .ui-confirm-dialog[open]::backdrop {
    animation: none;
  }
}

/* --- Catalog: inline-edit popover (category list row actions) ---------- */
/* Voir templates/catalog/category_list.html. */
.catalog-category-edit {
  position: relative;
  display: inline-block;
  margin-right: var(--space-2);
}

.catalog-category-edit__toggle {
  list-style: none;
}

.catalog-category-edit__toggle::-webkit-details-marker {
  display: none;
}

.catalog-category-edit__popover {
  position: absolute;
  z-index: 2;
  margin-top: var(--space-2);
  padding: var(--space-4);
  min-width: 16rem;
  max-width: min(22rem, 92vw);
}

.catalog-category-edit__popover--wide {
  min-width: 18rem;
  max-width: min(28rem, 94vw);
}

/* --- Empty state ------------------------------------------------------- */
/* Placeholder rendu dans une carte ou un tableau quand la collection est vide.
   Sert aussi de point d'ancrage pour la première action (CTA) afin que les
   nouveaux utilisateurs ne se retrouvent pas devant un écran muet.
   Voir templates/components/empty_state.html pour la signature. */
.ui-empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: var(--space-12) var(--space-6);
  gap: var(--space-3);
  border: 1px dashed var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface);
}

.ui-empty-state__icon {
  width: 64px;
  height: 64px;
  color: var(--color-text-muted);
  opacity: 0.5;
  margin-bottom: var(--space-2);
}

.ui-empty-state__icon svg {
  width: 100%;
  height: 100%;
  display: block;
}

.ui-empty-state__title {
  font-size: var(--fs-lg);
  font-weight: var(--fw-semibold);
  margin: 0;
}

.ui-empty-state__description {
  color: var(--color-text-muted);
  margin: 0;
  max-width: 40ch;
}

/* Variante compacte pour cartes imbriquées (.ui-card--nested) ou pour
   les sections internes où le padding pleine taille respire trop. */
.ui-empty-state--compact {
  padding: var(--space-6) var(--space-4);
  gap: var(--space-2);
}

.ui-empty-state--compact .ui-empty-state__icon {
  width: 40px;
  height: 40px;
  margin-bottom: var(--space-1);
}

.ui-empty-state--compact .ui-empty-state__title {
  font-size: var(--fs-base);
}

/* --- Skeleton ---------------------------------------------------------- */
/* Placeholder animé pour les zones en chargement (HTMX, lazy KPI, etc.).
   Toujours rendu avec aria-hidden="true" ; le parent doit porter aria-busy="true"
   pour annoncer l'état au lecteur d'écran. Voir templates/components/skeleton.html. */
.ui-skeleton {
  display: block;
  width: var(--skeleton-width, 100%);
  height: var(--skeleton-height, 1em);
  border-radius: var(--radius-xs);
  background: linear-gradient(
    90deg,
    var(--color-border-subtle) 0%,
    rgba(255, 255, 255, 0.5) 50%,
    var(--color-border-subtle) 100%
  );
  background-size: 200% 100%;
  animation: ui-skeleton-shimmer 1.5s infinite ease-in-out;
}

.ui-skeleton--text {
  height: var(--fs-base);
}

.ui-skeleton--title {
  height: var(--fs-xl);
}

.ui-skeleton--avatar {
  width: 40px;
  height: 40px;
  border-radius: 50%;
}

.ui-skeleton--card {
  height: 120px;
  border-radius: var(--radius-md);
}

.ui-skeleton-row {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

/* Marqueur "vide" injecté en JS dans les charts (cf. product_detail.html,
   product_compliance.html). Évite les inline styles dans innerHTML. */
.p-empty-mark {
  margin: var(--space-3);
  color: var(--color-text-muted);
}

/* SVG de chart injecté en JS — équivalent inline `style="display:block"`. */
.trace-svg {
  display: block;
}

@keyframes ui-skeleton-shimmer {
  from {
    background-position: 200% 0;
  }
  to {
    background-position: -200% 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  .ui-skeleton {
    animation: none;
    background: var(--color-border-subtle);
  }
}

/* ======================================================================== */
/* Tabs (underline) — intra-page section navigation                         */
/* ======================================================================== */

.ui-tabs {
  display: flex;
  gap: var(--space-1);
  border-bottom: 1px solid var(--color-border);
  margin-bottom: var(--space-6);
  overflow-x: auto;
  scrollbar-width: thin;
}

.ui-tab {
  padding: var(--space-3) var(--space-4);
  border-bottom: 2px solid transparent;
  color: var(--color-text-muted);
  text-decoration: none;
  font-weight: var(--fw-medium);
  white-space: nowrap;
  /* Sur téléphone, le min-width tactile (44 px) laissait les onglets rétrécir
     sous leur texte et se chevaucher : ils défilent, ils ne rétrécissent pas. */
  flex-shrink: 0;
  transition:
    color var(--duration-fast),
    border-color var(--duration-fast);
}

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

.ui-tab:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
  border-radius: var(--radius-xs);
}

.ui-tab--active {
  color: var(--color-primary);
  border-bottom-color: var(--color-primary);
}

.ui-tab__count {
  display: inline-block;
  margin-left: var(--space-2);
  padding: 2px 6px;
  background: var(--color-primary-soft);
  color: var(--color-primary);
  border-radius: var(--radius-pill);
  font-size: var(--fs-xs);
}

/* ======================================================================== */
/* Breadcrumb                                                               */
/* ======================================================================== */

.ui-breadcrumb ol {
  list-style: none;
  padding: 0;
  margin: 0 0 var(--space-4);
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  font-size: var(--fs-sm);
  color: var(--color-text-muted);
}

.ui-breadcrumb li {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
}

.ui-breadcrumb a {
  color: var(--color-text-muted);
  text-decoration: none;
}

.ui-breadcrumb a:hover {
  color: var(--color-primary);
}

.ui-breadcrumb [aria-current="page"] {
  color: var(--color-text);
  font-weight: var(--fw-medium);
}

.ui-breadcrumb__separator {
  color: var(--color-text-muted);
}

/* Fournisseur — fil d’Ariane + statut sur une ligne (sans titre h1 dupliqué). */
.supplier-detail-header {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-3);
}

.supplier-detail-header .ui-breadcrumb ol {
  margin-bottom: 0;
  font-size: var(--fs-base);
}

.supplier-detail-header__status {
  font-size: var(--fs-base);
  flex-shrink: 0;
}

/* ======================================================================== */
/* Pagination                                                               */
/* ======================================================================== */

.ui-pagination {
  /* Same vertical breathing room above and below so the controls don't
     stick to the table whether they are rendered above or below it. */
  margin-top: var(--space-4);
  margin-bottom: var(--space-4);
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  align-items: center;
  justify-content: center;
}

.ui-pagination__info {
  color: var(--color-text-muted);
  font-size: var(--fs-sm);
  padding: 0 var(--space-2);
}

.ui-pagination__btn--disabled {
  opacity: 0.5;
  pointer-events: none;
}

.ui-pagination__total {
  font-weight: 500;
}

/* --- Classement ventes (leaderboard) : tableau dense, scroll, colonnes lisibles */
.sales-leaderboard-table {
  min-width: 64rem;
}

.sales-leaderboard-table th:first-child,
.sales-leaderboard-table td:first-child {
  width: 4.25rem;
  max-width: 5rem;
  white-space: nowrap;
}

.sales-leaderboard-table tbody tr:nth-child(even) td {
  background: color-mix(in srgb, var(--color-primary-soft) 45%, transparent);
}

.sales-leaderboard-table tbody tr:hover td {
  background: rgba(232, 243, 236, 0.55);
}

.sales-leaderboard-table tfoot .sales-leaderboard-table__total-row th,
.sales-leaderboard-table tfoot .sales-leaderboard-table__total-row td {
  position: sticky;
  bottom: 0;
  z-index: 1;
  background: var(--color-primary-soft);
  border-top: 2px solid var(--color-border);
  font-weight: 600;
}

.sales-leaderboard-table__total-label {
  text-align: left;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  font-size: 0.8125rem;
}

.sales-leaderboard-product-cell {
  display: flex;
  gap: var(--space-2);
  align-items: center;
  min-width: 0;
}

.sales-leaderboard-product-cell__thumb {
  flex-shrink: 0;
}

.sales-leaderboard-product-cell__body {
  min-width: 0;
}

a.ui-link.ui-link--underlined {
  text-decoration: underline;
}

a.ui-link.ui-link--underlined:hover {
  text-decoration: underline;
}

/* ======================================================================== */
/* Mobile drawer & responsive shell                                         */
/* ======================================================================== */

/* Bouton de fermeture du tiroir et voile : masqués par défaut (desktop). */
.p-sidebar__close {
  display: none;
}

.p-nav-backdrop {
  display: none;
}

/* legacy max-width: 48em — sidebar drawer override of desktop p-shell layout
   (voir base.css pour le shell desktop). Conversion mobile-first du drawer
   nécessite un refactor coordonné base.css + components.css, reporté. */
@media (max-width: 48em) {
  /* --bp-md : sidebar bascule en drawer hors-flux. */

  /* La barre haute est collée : les messages se calent juste dessous. */
  .ui-toast-area,
  .portal-body .ui-toast-area {
    top: calc(3.25rem + var(--space-2));
    right: var(--space-3);
    width: calc(100vw - var(--space-6));
  }

  .p-shell {
    grid-template-columns: 1fr;
  }

  .p-sidebar {
    position: fixed;
    top: 0;
    left: 0;
    bottom: 0;
    width: 80vw;
    max-width: 420px;
    z-index: var(--z-modal);
    transform: translateX(-100%);
    transition: transform var(--duration-base) var(--ease-out);
    border-right: 1px solid var(--color-border);
    overflow-y: auto;
  }

  .p-sidebar[data-open="true"] {
    transform: translateX(0);
  }

  .p-sidebar__close {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    position: absolute;
    top: var(--space-2);
    right: var(--space-2);
    padding: var(--space-2);
    min-height: 44px;
    min-width: 44px;
  }

  .p-sidebar__close svg {
    display: block;
  }

  .p-nav-backdrop {
    display: block;
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.4);
    z-index: calc(var(--z-modal) - 1);
    opacity: 0;
    pointer-events: none;
    transition: opacity var(--duration-base);
  }

  .p-nav-backdrop[data-open="true"] {
    opacity: 1;
    pointer-events: auto;
  }
}

/* Verrouille le scroll du body quand le drawer est ouvert. */
body.is-drawer-open {
  overflow: hidden;
}

@media (prefers-reduced-motion: reduce) {
  .p-sidebar,
  .p-nav-backdrop {
    transition: none;
  }
}

/* Portail : tiroir jusqu'à 64 em (1 024 px), et non 48 em comme l'application. Sa
   colonne de 320 px prenait jusqu'à 38 % de l'écran entre les deux (Mac zoomé à
   150 %, PC à 150 % zoomé ; audit zoom du 25/09/2026). Mêmes règles que le bloc
   ci-dessus, pour la seule plage 48–64 em ; le script suit le même seuil
   (`data-nav-drawer-desktop`, layouts/portal.html). */
@media (min-width: 48.0625em) and (max-width: 64em) {
  .portal-body .p-shell {
    grid-template-columns: 1fr;
  }

  .portal-body .p-topbar__burger {
    display: inline-flex;
  }

  .portal-body .p-sidebar {
    position: fixed;
    top: 0;
    left: 0;
    bottom: 0;
    width: 80vw;
    max-width: 420px;
    z-index: var(--z-modal);
    transform: translateX(-100%);
    transition: transform var(--duration-base) var(--ease-out);
    border-right: 1px solid var(--color-border);
    overflow-y: auto;
  }

  .portal-body .p-sidebar[data-open="true"] {
    transform: translateX(0);
  }

  .portal-body .p-sidebar__close {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    position: absolute;
    top: var(--space-2);
    right: var(--space-2);
    padding: var(--space-2);
    min-height: 44px;
    min-width: 44px;
  }

  .portal-body .p-nav-backdrop {
    display: block;
    position: fixed;
    inset: 0;
    background: color-mix(in srgb, var(--color-text) 40%, transparent);
    z-index: calc(var(--z-modal) - 1);
    opacity: 0;
    pointer-events: none;
    transition: opacity var(--duration-base);
  }

  .portal-body .p-nav-backdrop[data-open="true"] {
    opacity: 1;
    pointer-events: auto;
  }
}

@media (min-width: 48.0625em) and (max-width: 64em) and (prefers-reduced-motion: reduce) {
  .portal-body .p-sidebar,
  .portal-body .p-nav-backdrop {
    transition: none;
  }
}

/* ======================================================================== */
/* Tables card-stack mobile (.ui-table--stackable)                          */
/* ======================================================================== */

/* legacy max-width: 40em — card-stack overrides display: table par défaut.
   Inverser obligerait à dupliquer toute la logique table en min-width. */
@media (max-width: 40em) {
  /* --bp-sm : chaque ligne devient une carte verticale, le thead est masqué
     visuellement et chaque cellule expose son intitulé via data-label. */
  .ui-table--stackable {
    border: none;
  }

  /* display:none et non un déport hors écran : les liens de tri du thead
     restaient focusables à -9999px (audit portail 18/09, NAV-02). Chaque
     cellule porte son intitulé via data-label, rien n'est perdu. */
  .ui-table--stackable thead {
    display: none;
  }

  .ui-table--stackable tbody,
  .ui-table--stackable tr,
  .ui-table--stackable td {
    display: block;
    width: 100%;
  }

  .ui-table--stackable tr {
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius-sm);
    padding: var(--space-3);
    margin-bottom: var(--space-3);
  }

  .ui-table--stackable tr:last-child {
    margin-bottom: 0;
  }

  /* Intitulé et valeur côte à côte quand ils tiennent, l'un sous l'autre sinon :
     un intitulé long (« Atributos do fornecedor preenchidos ») poussait la valeur
     hors de l'écran à 320 px (audit zoom du 25/09/2026). */
  .ui-table--stackable td {
    padding: var(--space-1) 0;
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    align-items: flex-start;
    gap: var(--space-3);
    border-bottom: none;
  }

  .ui-table--stackable td:has(.portal-certificate-row-actions) {
    align-items: center;
    flex-wrap: nowrap;
  }

  .ui-table--stackable td:has(.portal-certificate-row-actions) .portal-certificate-row-actions {
    flex: 1 1 auto;
    min-width: 0;
    max-width: 100%;
  }

  .ui-table--stackable td::before {
    content: attr(data-label);
    font-weight: var(--fw-semibold);
    color: var(--color-text-muted);
  }

  /* Pas de cadre/scroll horizontal autour d'une table déjà devenue cards. */
  .ui-table-wrap:has(.ui-table--stackable) {
    border: none;
    overflow: visible;
  }

  /* Colonne figée du tableau de bord : en carte, il n'y a plus de colonnes à
     figer, et `position: sticky` ferait flotter le nom du fournisseur. */
  .ui-table--stackable .dash-sticky-col {
    position: static;
  }

  /* Le tiroir de conformité et l'avancement fournisseurs défilaient
     horizontalement dans leur propre cadre : en carte, ils n'en ont plus besoin. */
  .compliance-drawer__table-scroll,

  .compliance-drawer__table.ui-table--stackable th,
  .compliance-drawer__table.ui-table--stackable td {
    border-bottom: none;
  }

  .compliance-drawer__missing {
    max-width: none;
  }

  /* Liste produits : le wrapper de scroll custom doit aussi laisser les cartes
     respirer (pas de min-width table ni d'overflow horizontal). */
  .catalog-product-list-page__table-scroll:has(.ui-table--stackable) {
    border: none;
    overflow: visible;
  }

  /* Audit UI 18/09 (P-01) : en rendu « cartes », la page liste produits doit
     redevenir un flux normal scrollable. Sans ces règles, --fill verrouille la
     page à 100dvh et __table-body (overflow:hidden) rogne 24 lignes sur 25 —
     même logique que .sales-leaderboard-page, plus haut. */
  .catalog-product-list-body .p-main {
    display: block;
  }

  .catalog-product-list-page--fill {
    flex: 0 0 auto;
    min-height: 0;
    max-height: none;
    overflow: visible;
  }

  .catalog-product-list-page__table-card,
  .catalog-product-list-page__table-body,
  .catalog-product-list-htmx-shell > #product-list-results {
    flex: 0 0 auto;
    overflow: visible;
  }

  .catalog-product-list-results {
    height: auto;
  }

  .catalog-product-list-page__table.ui-table--stackable {
    min-width: 0;
  }

  .catalog-product-list-page__table.ui-table--stackable td.catalog-product-list-page__td-product,
  .catalog-product-list-page__table.ui-table--stackable td.catalog-product-list-page__td-attr {
    min-width: 0;
    max-width: none;
    white-space: normal;
  }
}

/* --- File dropzone --------------------------------------------------------
   Drag & drop wrapper around an <input type="file" hidden>. The component is
   activated by static/js/file_dropzone.js on [data-dropzone].
*/
.ui-dropzone {
  position: relative;
  width: 100%;
  max-width: 32rem;
  border: 2px dashed var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  transition: border-color var(--duration-fast) var(--ease-out),
    background-color var(--duration-fast) var(--ease-out);
}

/* Pas d'attribut [hidden] : WebKit ignore le clic <label for> → input file masqué. */
.ui-dropzone__input {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
  opacity: 0;
  pointer-events: none;
}

.ui-dropzone__label {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  padding: var(--space-6) var(--space-4);
  text-align: center;
  cursor: pointer;
  color: var(--color-text);
}

.ui-dropzone__icon {
  width: var(--icon-lg);
  height: var(--icon-lg);
  color: var(--color-text-muted);
  flex-shrink: 0;
}

.ui-dropzone__primary {
  font-size: var(--fs-sm);
  color: var(--color-text);
}

.ui-dropzone__primary strong {
  color: var(--color-primary);
}

.ui-dropzone__hint {
  font-size: var(--fs-xs);
  color: var(--color-text-muted);
}

.ui-dropzone:hover {
  border-color: var(--color-accent-brown);
}

.ui-dropzone:focus-within {
  border-color: var(--color-primary);
  box-shadow: var(--shadow-focus);
  outline: none;
}

.ui-dropzone--dragover {
  border-color: var(--color-primary);
  background: var(--color-primary-soft);
}

.ui-dropzone--has-file {
  border-style: solid;
  border-color: var(--color-primary);
  background: var(--color-primary-soft);
}

.ui-dropzone--invalid {
  border-color: var(--color-danger);
  background: rgba(180, 35, 24, 0.06);
}

.ui-dropzone__preview {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border-top: 1px solid var(--color-border-subtle);
  background: var(--color-surface);
  border-bottom-left-radius: var(--radius-md);
  border-bottom-right-radius: var(--radius-md);
}

.ui-dropzone__preview[hidden] {
  display: none;
}

.ui-dropzone__thumb {
  width: 48px;
  height: 48px;
  border-radius: var(--radius-sm);
  background: var(--color-bg);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  overflow: hidden;
  color: var(--color-text-muted);
}

.ui-dropzone__thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.ui-dropzone__file {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-width: 0;
}

.ui-dropzone__file-name {
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  color: var(--color-text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.ui-dropzone__file-meta {
  font-size: var(--fs-xs);
  color: var(--color-text-muted);
}

.ui-dropzone__file-meta--error {
  color: var(--color-danger);
}

.ui-dropzone__remove {
  appearance: none;
  background: transparent;
  border: none;
  border-radius: var(--radius-pill);
  width: 28px;
  height: 28px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--color-text-muted);
  cursor: pointer;
  flex-shrink: 0;
}

.ui-dropzone__remove:hover {
  background: var(--color-bg);
  color: var(--color-danger);
}

.ui-dropzone__remove:focus-visible {
  outline: 2px solid var(--color-primary);
  outline-offset: 2px;
}

/* --- Error summary --------------------------------------------------------
   Block placed at the top of long forms, focused on render via
   form_blur_validate.js. Surfaced when the view exposes `create_error` or
   `error` (no Django Form needed).
*/
.ui-error-summary {
  border: 1px solid var(--color-danger);
  border-left-width: 4px;
  background: rgba(180, 35, 24, 0.06);
  border-radius: var(--radius-md);
  padding: var(--space-4) var(--space-5);
  margin-bottom: var(--space-4);
  color: var(--color-text);
  box-shadow: var(--shadow-xs);
}

.ui-error-summary:focus {
  outline: none;
  box-shadow: var(--shadow-focus);
}

.ui-error-summary__title {
  margin: 0 0 var(--space-2);
  color: var(--color-danger);
}

.ui-error-summary p {
  margin: 0;
}

.ui-error-summary ul {
  margin: var(--space-2) 0 0;
  padding-left: var(--space-5);
}

/* --- Spinner --------------------------------------------------------------
   Reusable inline spinner (cf. templates/components/spinner.html).
*/
.ui-spinner {
  display: inline-block;
  width: 1em;
  height: 1em;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: 50%;
  animation: ui-spinner-rotate 0.8s linear infinite;
  vertical-align: -0.125em;
}

.ui-spinner--sm { font-size: 0.875rem; }
.ui-spinner--md { font-size: 1.25rem; }
.ui-spinner--lg { font-size: 2rem; }

@keyframes ui-spinner-rotate {
  to { transform: rotate(360deg); }
}

@media (prefers-reduced-motion: reduce) {
  .ui-spinner { animation-duration: 1.6s; }
}

/* ======================================================================== */
/* Mobile inputs : empêche l'auto-zoom Safari iOS (zoom déclenché si        */
/* font-size < 16px sur le focus d'un champ).                                */
/* ======================================================================== */
/* legacy max-width: 48em — règle mobile-only ciblant uniquement iOS Safari. */
@media (max-width: 48em) {
  .ui-input,
  .ui-select,
  .ui-textarea,
  input[type="text"],
  input[type="email"],
  input[type="number"],
  input[type="tel"],
  input[type="url"],
  input[type="password"],
  input[type="search"],
  input[type="date"],
  select,
  textarea {
    font-size: 16px;
  }
}

/* --- CSV import preview (catalog product create) ------------------------ */
.catalog-csv-preview-stats {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-4);
  align-items: flex-start;
}

.catalog-csv-preview-stats__item {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  min-width: 7rem;
}

.catalog-csv-preview-stats__value {
  font-size: 1.35rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  line-height: 1.2;
  color: var(--color-text);
}

.catalog-csv-preview-entities {
  padding: var(--space-4);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border);
  background: var(--color-bg-subtle);
}

.catalog-csv-preview-entity-grid {
  display: grid;
  /* Min ~17rem so FR badges + 4-digit counts stay inside the card; auto-fill wraps rows. */
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 17.5rem), 1fr));
  gap: var(--space-3);
}

.catalog-csv-preview-entity-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  min-width: 0;
  padding: var(--space-3);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border);
  background: var(--color-surface);
  box-shadow: none;
}

.catalog-csv-preview-entity-card--errors {
  border-color: rgba(180, 35, 24, 0.35);
  background: rgba(180, 35, 24, 0.04);
}

.catalog-csv-preview-entity-card__title {
  font-size: 0.8125rem;
  font-weight: 600;
  line-height: 1.3;
  color: var(--color-text);
  overflow-wrap: anywhere;
}

.catalog-csv-preview-entity-card__nums {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.catalog-csv-preview-entity-card__nums--triple {
  flex-direction: row;
  flex-wrap: wrap;
  gap: var(--space-2);
  align-items: flex-end;
  justify-content: space-between;
}

.catalog-csv-preview-entity-card__nums--triple .catalog-csv-preview-entity-card__stat {
  flex: 1 1 4.25rem;
  min-width: 0;
}

.catalog-csv-preview-entity-card__hint {
  font-size: 0.75rem;
  line-height: 1.35;
}

.catalog-csv-preview-entity-card__badge--same {
  color: rgb(75, 85, 99);
  background: rgba(107, 114, 128, 0.1);
  border: 1px solid rgba(107, 114, 128, 0.25);
}

.catalog-csv-preview-entity-card__stat {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: var(--space-1);
  min-width: 0;
}

.catalog-csv-preview-entity-card__stat--solo {
  flex-direction: row;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
}

.catalog-csv-preview-entity-card__badge {
  display: inline-flex;
  align-self: flex-start;
  align-items: center;
  padding: 0.125rem 0.5rem;
  border-radius: 999px;
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  white-space: normal;
  line-height: 1.25;
  max-width: 100%;
}

.catalog-csv-preview-entity-card__badge--new {
  color: rgb(21, 128, 61);
  background: rgba(21, 128, 61, 0.12);
  border: 1px solid rgba(21, 128, 61, 0.25);
}

.catalog-csv-preview-entity-card__badge--mut {
  color: rgb(30, 64, 175);
  background: rgba(37, 99, 235, 0.1);
  border: 1px solid rgba(37, 99, 235, 0.22);
}

.catalog-csv-preview-entity-card__badge--err {
  color: rgb(153, 27, 27);
  background: rgba(180, 35, 24, 0.1);
  border: 1px solid rgba(180, 35, 24, 0.28);
}

.catalog-csv-preview-entity-card__value {
  font-size: 1.25rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  line-height: 1.2;
  color: var(--color-text);
  text-align: end;
  flex-shrink: 0;
  min-width: 0;
}

.catalog-csv-preview-entity-card__stat--solo .catalog-csv-preview-entity-card__value {
  text-align: start;
}

.catalog-csv-import-preview--has-errors {
  box-shadow: inset 4px 0 0 0 var(--color-danger);
}

.catalog-csv-preview-legend-details__summary {
  cursor: pointer;
  user-select: none;
}

.catalog-csv-preview-stepper {
  margin-bottom: var(--space-4);
}

.catalog-csv-preview-stepper__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  align-items: stretch;
}

.catalog-csv-preview-stepper__step {
  flex: 1 1 8rem;
  display: flex;
  gap: var(--space-2);
  align-items: center;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border);
  background: var(--color-bg);
}

.catalog-csv-preview-stepper__step--complete {
  border-color: rgba(21, 128, 61, 0.35);
  background: rgba(21, 128, 61, 0.06);
}

.catalog-csv-preview-stepper__step--attention {
  border-color: rgba(180, 35, 24, 0.45);
  background: rgba(180, 35, 24, 0.06);
}

.catalog-csv-preview-stepper__step--upcoming {
  opacity: 0.85;
}

.catalog-csv-preview-stepper__num {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.5rem;
  height: 1.5rem;
  border-radius: 999px;
  font-size: 0.75rem;
  font-weight: 700;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
}

.catalog-csv-preview-stepper__label {
  font-size: 0.8125rem;
  font-weight: 600;
  line-height: 1.25;
}

.catalog-csv-preview-entity-bullets {
  list-style: disc;
  padding-left: 1.25rem;
}

.catalog-csv-preview-error-excerpt {
  word-break: break-word;
  max-width: 100%;
}

/* Sales CSV import — business key + merge modes (preview step) */
.sales-import-merge-policy__card {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  padding: var(--space-4, 1rem);
  background: var(--color-surface-subtle);
}

.sales-import-merge-policy__key-list {
  margin: 0;
  padding-left: 1.25rem;
  list-style: disc;
}

.sales-import-merge-policy__key-list li {
  margin-bottom: 0.25rem;
  line-height: 1.45;
}

.sales-import-merge-policy__modes {
  padding-top: 0.25rem;
}

.sales-import-merge-policy__replace {
  padding-top: var(--space-3, 0.75rem);
  margin-top: 0.25rem;
  border-top: 1px solid var(--color-border);
}

@media (min-width: 48rem) {
  .catalog-csv-preview-actions-sticky {
    position: sticky;
    bottom: 0;
    z-index: 15;
    margin-top: var(--space-4);
    margin-left: calc(-1 * var(--space-4, 1rem));
    margin-right: calc(-1 * var(--space-4, 1rem));
    padding-left: var(--space-4, 1rem);
    padding-right: var(--space-4, 1rem);
  }

  .catalog-csv-preview-actions-sticky__inner {
    background: var(--color-surface);
    border-top: 1px solid var(--color-border);
    padding-top: var(--space-3);
    padding-bottom: var(--space-2);
    box-shadow: none;
  }
}

/* Sales list — matching overview bar */
.sales-match-stats__bar {
  display: flex;
  height: 10px;
  border-radius: 999px;
  overflow: hidden;
  background: var(--color-border);
}

.sales-match-stats__segment {
  display: block;
  height: 100%;
  min-width: 0;
}

.sales-match-stats__segment--matched {
  background: var(--color-success);
}

.sales-match-stats__segment--pending {
  background: var(--color-warning-graph);
}

.sales-match-stats__segment--ambiguous {
  background: var(--color-danger);
}

.sales-match-stats__segment--manual {
  background: var(--color-info-fg);
}

.sales-match-stats__legend {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem 1.25rem;
  list-style: none;
  padding: 0;
}

.sales-match-stats__dot {
  display: inline-block;
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 999px;
  margin-right: 0.35rem;
  vertical-align: middle;
}

.sales-match-stats__dot--matched {
  background: var(--color-success);
}

.sales-match-stats__dot--pending {
  background: var(--color-warning-graph);
}

.sales-match-stats__dot--ambiguous {
  background: var(--color-danger);
}

.sales-match-stats__dot--manual {
  background: var(--color-info-fg);
}

.sales-preview-match-rollup {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3, 0.75rem);
}

.sales-preview-match-rollup__stat {
  flex: 1 1 140px;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md, 8px);
  padding: var(--space-3, 0.75rem);
}

.sales-preview-match-rollup__label {
  display: block;
  font-size: 0.8125rem;
  font-weight: 600;
  margin-bottom: 0.35rem;
}

.sales-preview-match-rollup__value {
  font-size: 1.5rem;
  font-weight: 700;
  line-height: 1.2;
}

.sales-preview-match-rollup__stat--matched {
  border-left: 4px solid var(--color-success);
}

.sales-preview-match-rollup__stat--pending {
  border-left: 4px solid var(--color-warning-graph);
}

.sales-preview-match-rollup__stat--ambiguous {
  border-left: 4px solid var(--color-danger);
}

.ui-badge--sale {
  background: rgba(37, 99, 235, 0.12);
  color: var(--color-info-fg);
}

.ui-badge--return {
  background: rgba(234, 88, 12, 0.12);
  color: var(--color-warning);
}

.ui-badge--return_non_defective {
  background: rgba(245, 158, 11, 0.14);
  color: var(--color-warning);
}

.ui-badge--return_defective {
  background: rgba(220, 38, 38, 0.12);
  color: var(--color-danger-fg);
}

.ui-badge--match-matched {
  background: rgba(22, 163, 74, 0.12);
  color: var(--color-success);
}

.ui-badge--match-pending {
  background: rgba(234, 88, 12, 0.12);
  color: var(--color-warning);
}

.ui-badge--match-ambiguous {
  background: rgba(220, 38, 38, 0.12);
  color: var(--color-danger-fg);
}

.ui-badge--match-manual {
  background: rgba(37, 99, 235, 0.12);
  color: var(--color-info-fg);
}

/* Sales list — source column (import filename may be long) */
.sales-list__source-cell {
  max-width: 14rem;
}

.sales-list__source-filename {
  display: inline-block;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  vertical-align: bottom;
}

/* -------------------------------------------------------------------------- */
/* Dashboard home — Vue d'ensemble (KPI cards)                                 */
/* -------------------------------------------------------------------------- */

.dash-overview {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  margin-bottom: 0;
}

.dash-overview__head {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--space-4);
}

.dash-overview__title {
  margin: 0;
}

.dash-overview__year {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: var(--space-1);
}

.ui-select--inline {
  width: auto;
  min-width: 6rem;
  max-width: 10rem;
}

.dash-overview__section-label {
  margin: 0;
  font-weight: var(--fw-semibold);
}

.dash-overview__grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-3);
}

.dash-overview__grid > .dashboard-kpi-card {
  min-width: 0;
}

@media (min-width: 48em) {
  .dash-overview__grid {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}

/* Commerce : 5 indicateurs sur une seule ligne (priorité sur la grille 2/4 cols) */
.dash-overview__grid.dash-overview__grid--commerce {
  grid-template-columns: repeat(5, minmax(0, 1fr));
}

.dash-overview__commerce {
  min-height: 4rem;
  max-width: 100%;
  /* Si les 5 colonnes dépassent la largeur (mobile), défilement local — pas de scroll de page. */
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior-x: contain;
}

@media (max-width: 47.99em) {
  .dash-overview__grid.dash-overview__grid--commerce {
    grid-template-columns: repeat(5, minmax(5.25rem, 1fr));
    gap: var(--space-2);
  }

  .dash-overview__grid.dash-overview__grid--commerce > .dashboard-kpi-card {
    padding: var(--space-2) var(--space-3);
  }

  .dash-overview__grid.dash-overview__grid--commerce .dashboard-kpi-card__label {
    font-size: 0.68rem;
    line-height: 1.25;
  }

  .dash-overview__grid.dash-overview__grid--commerce .dashboard-kpi-card__value {
    font-size: 1rem;
    font-variant-numeric: tabular-nums;
  }
}

.dashboard-kpi-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: var(--space-4);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border-subtle);
  background: var(--color-surface);
  box-shadow: var(--shadow-xs);
  color: var(--color-text);
  text-decoration: none;
  transition: border-color 0.15s, box-shadow 0.15s;
}

.dashboard-kpi-card:hover {
  border-color: var(--color-primary);
  box-shadow: var(--shadow-sm);
}

.dashboard-kpi-card--static {
  cursor: default;
}

.dashboard-kpi-card--static:hover {
  border-color: var(--color-border-subtle);
  box-shadow: var(--shadow-xs);
}

.dashboard-kpi-card__label {
  font-size: var(--fs-sm);
  color: var(--color-text-muted);
  font-weight: var(--fw-medium);
  line-height: var(--lh-tight);
}

.dashboard-kpi-card__value {
  font-size: var(--fs-xl);
  font-weight: var(--fw-bold);
  line-height: var(--lh-tight);
  letter-spacing: -0.02em;
  overflow-wrap: break-word;
}

/* Dashboard — graphique historique ventes / retours */
.dash-sales-chart-panel {
  margin-bottom: var(--space-8);
}

.dash-sales-chart {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  padding: var(--space-5);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border-subtle);
  background: var(--color-surface);
  box-shadow: var(--shadow-xs);
}

.dash-sales-chart__title {
  margin: 0;
  font-size: var(--fs-md);
  font-weight: var(--fw-semibold);
}

.dash-sales-chart__toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--space-4);
}

.dash-sales-chart__fieldset {
  margin: 0;
  padding: 0;
  border: none;
  min-width: 0;
}

.dash-sales-chart__legend {
  padding: 0;
  margin-bottom: var(--space-2);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  color: var(--color-text-muted);
}

.dash-sales-chart__radios {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.dash-sales-chart__radio {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-pill);
  border: 1px solid var(--color-border-subtle);
  background: var(--color-bg);
  cursor: pointer;
  font-size: var(--fs-sm);
}

.dash-sales-chart__radio:has(input:checked) {
  border-color: var(--color-primary);
  background: var(--color-primary-soft);
}

.dash-sales-chart__radio--active {
  border-color: var(--color-primary);
  background: var(--color-primary-soft);
}

.dash-sales-chart__radio input {
  margin: 0;
}

.dash-sales-chart__period {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: var(--space-1);
}

.dash-sales-chart__canvas-wrap {
  position: relative;
  width: 100%;
  height: min(22rem, 50vh);
}

.dash-sales-chart__canvas {
  display: block;
  width: 100% !important;
  height: 100% !important;
}

.dash-sales-chart__details {
  font-size: var(--fs-sm);
}

.dash-sales-chart__details summary {
  cursor: pointer;
  color: var(--color-primary);
  font-weight: var(--fw-medium);
}

.dash-sales-chart__table-scroll {
  overflow-x: auto;
  margin-top: var(--space-3);
}

.dash-sales-chart__table {
  min-width: 36rem;
}

/* ---- Dashboard conformité multi-standards ------------------------------ */
.dash-compliance {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}
.dash-compliance__title {
  margin-bottom: 0;
}
.dash-compliance__global {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-3);
  padding: var(--space-4);
  border-radius: var(--radius-md);
  border: 1px solid var(--color-border-subtle);
  background: var(--color-surface);
}
@media (min-width: 40em) {
  .dash-compliance__global {
    grid-template-columns: repeat(3, 1fr);
  }
}
.dash-compliance__global-metric {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}
.dash-compliance__global-metric--fine .dash-compliance__global-value {
  font-size: var(--fs-xl, 1.5rem);
  color: var(--color-danger);
}
.dash-compliance__global-label {
  font-size: var(--fs-sm);
  color: var(--color-text-muted);
}
.dash-compliance__global-value {
  font-size: var(--fs-lg);
  font-weight: 700;
}
.dash-compliance__grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: var(--dash-gap);
}
.dash-compliance-card {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: var(--dash-pad);
  border-radius: var(--dash-radius);
  border: 1px solid var(--color-border-subtle);
  background: var(--color-surface);
}
.dash-compliance-card__name {
  margin: 0;
  font-size: 1.0625rem;
  font-weight: var(--fw-semibold);
  color: var(--color-text);
}
.dash-compliance-card__pct {
  font-size: 2.75rem;
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.05;
  font-variant-numeric: tabular-nums;
}
.dash-compliance-card__pct--danger {
  color: var(--color-danger);
}
.dash-compliance-card__pct--warning {
  color: var(--color-warning);
}
.dash-compliance-card__pct--success {
  color: var(--color-success);
}
.dash-compliance-card__pct--muted,
.dash-compliance-card__pct--neutral {
  color: var(--color-text-muted);
}
.dash-compliance-card__progress {
  margin-top: 0;
}
.dash-compliance-card__counts {
  font-size: 0.9375rem;
  color: var(--color-text-muted);
}
/* Détail replié : le gros pourcentage suffit à la lecture, l'explication
   (chaîne tracée / fiche produit) s'ouvre d'un clic. */
.dash-compliance-card__more {
  font-size: 0.9375rem;
}
.dash-compliance-card__why {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: 44px;
  cursor: pointer;
  list-style: none;
  color: var(--color-primary);
  font-weight: var(--fw-semibold);
  border-radius: var(--radius-sm);
}
.dash-compliance-card__why::-webkit-details-marker {
  display: none;
}
.dash-compliance-card__why::before {
  content: "+";
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: var(--color-primary-soft);
  font-weight: 700;
  line-height: 1;
}
.dash-compliance-card__more[open] .dash-compliance-card__why::before {
  content: "−";
}
.dash-compliance-card__why:hover {
  text-decoration: underline;
}
.dash-compliance-card__why:focus-visible {
  outline: none;
  box-shadow: var(--shadow-focus);
}
/* Découpage chaîne tracée / fiche produit (normes à règle d'étapes) */
.dash-compliance-card__split {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  margin: 0;
  padding-top: var(--space-2);
  font-size: 0.9375rem;
}
.dash-compliance-card__split-row dt {
  color: var(--color-text-muted);
}
.dash-compliance-card__split-row dd {
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.dash-compliance-card__cta {
  align-self: flex-start;
}

/* Panneau latéral conformité (HTMX) */
.compliance-drawer {
  position: fixed;
  inset: 0;
  z-index: 1200;
  display: flex;
  justify-content: flex-end;
  pointer-events: none;
}
.compliance-drawer__backdrop {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.35);
  pointer-events: auto;
}
.compliance-drawer__panel {
  position: relative;
  width: 480px;
  max-width: 100%;
  height: 100%;
  background: var(--color-surface);
  box-shadow: none;
  display: flex;
  flex-direction: column;
  pointer-events: auto;
  transform: translateX(100%);
  animation: compliance-drawer-slide-in 0.22s ease-out forwards;
  border-left: 1px solid var(--color-border-subtle);
}
@media (max-width: 47.99em) {
  .compliance-drawer {
    align-items: flex-end;
  }
  .compliance-drawer__panel {
    width: 100%;
    max-height: 92vh;
    height: auto;
    min-height: 50vh;
    border-left: none;
    border-radius: var(--radius-md) var(--radius-md) 0 0;
    animation: compliance-drawer-slide-up 0.22s ease-out forwards;
  }
  @keyframes compliance-drawer-slide-up {
    from {
      transform: translateY(100%);
    }
    to {
      transform: translateY(0);
    }
  }
}
@keyframes compliance-drawer-slide-in {
  from {
    transform: translateX(100%);
  }
  to {
    transform: translateX(0);
  }
}
.compliance-drawer__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--color-border-subtle);
  flex-shrink: 0;
}
.compliance-drawer__title {
  margin: 0;
  font-size: var(--fs-md);
}
.compliance-drawer__close {
  font-size: 1.5rem;
  line-height: 1;
  min-width: 2.5rem;
}
.compliance-drawer #compliance-drawer-inner {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.compliance-drawer__tabs {
  display: flex;
  gap: 0;
  padding: 0 var(--space-4);
  border-bottom: 1px solid var(--color-border-subtle);
  flex-shrink: 0;
}
.compliance-drawer__tab {
  flex: 1;
  padding: var(--space-2) var(--space-3);
  border: none;
  border-bottom: 2px solid transparent;
  background: transparent;
  font: inherit;
  cursor: pointer;
  color: var(--color-text-muted);
}
.compliance-drawer__tab.is-active {
  color: var(--color-text);
  border-bottom-color: var(--color-primary);
  font-weight: 600;
}
.compliance-drawer__tabpanel {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  padding: var(--space-3) var(--space-4) var(--space-4);
  overflow: hidden;
}
.compliance-drawer__table-scroll {
  flex: 1;
  min-height: 0;
  overflow: auto;
}
.compliance-drawer__table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--fs-sm);
}
.compliance-drawer__table th,
.compliance-drawer__table td {
  padding: var(--space-2) var(--space-2) var(--space-2) 0;
  text-align: left;
  vertical-align: top;
  border-bottom: 1px solid var(--color-border-subtle);
}
.compliance-drawer__table th {
  font-weight: 600;
  color: var(--color-text-muted);
}
.compliance-drawer__missing {
  max-width: 12rem;
}
.compliance-drawer__more {
  flex-shrink: 0;
  padding-top: var(--space-3);
}
.compliance-drawer__load-more {
  width: 100%;
}

/* ---- Avancement fournisseurs (dashboard, lazy HTMX) ------------------- */
.dash-supplier-progress-shell {
  margin-top: 0;
}
.dash-supplier-progress-skel__card {
  min-height: 8rem;
}
.dash-supplier-progress-skel__line {
  height: 0.75rem;
  border-radius: var(--radius-sm);
  background: var(--color-bg);
  margin-bottom: var(--space-2);
  max-width: 100%;
}
.dash-supplier-progress-skel__line--title {
  max-width: 14rem;
  height: 1rem;
}
.dash-supplier-progress {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}
.dash-supplier-progress__title {
  margin: 0;
}
.dash-supplier-progress__columns {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-5);
}
@media (min-width: 64em) {
  .dash-supplier-progress__columns {
    grid-template-columns: 3fr 2fr;
    gap: var(--space-8);
  }
}
.dash-supplier-progress__subtitle {
  margin: 0 0 var(--space-2);
  font-size: 1rem;
  font-weight: var(--fw-semibold);
  color: var(--color-text);
}
.dash-supplier-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
}
.dash-supplier-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  min-height: 56px;
  padding: var(--space-3) 0;
  border-bottom: 1px solid var(--color-border-subtle);
}
.dash-supplier-row:last-child {
  border-bottom: 0;
}
.dash-supplier-row__main {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}
.dash-supplier-row__name {
  font-size: 1rem;
  font-weight: var(--fw-semibold);
  color: var(--color-text);
  text-decoration: none;
}
.dash-supplier-row__name:hover {
  color: var(--color-primary);
  text-decoration: underline;
}
.dash-supplier-row__meta {
  font-size: 0.9375rem;
  color: var(--color-text-muted);
  display: flex;
  flex-wrap: wrap;
  gap: 0 var(--space-2);
}
.dash-supplier-row__part + .dash-supplier-row__part::before {
  content: "·";
  margin-right: var(--space-2);
}
.dash-supplier-progress__silent-badge {
  margin-left: var(--space-2);
}

/* Modale relance fournisseur (focus trap : static/js/supplier_relance_modal.js) */
.supplier-relance {
  position: fixed;
  inset: 0;
  z-index: 1200;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-4);
  box-sizing: border-box;
}
.supplier-relance__backdrop {
  position: absolute;
  inset: 0;
  background: rgba(15, 18, 28, 0.45);
  cursor: pointer;
}
.supplier-relance__panel {
  position: relative;
  z-index: 1;
  width: min(36rem, 100%);
  max-height: min(90vh, 40rem);
  overflow: auto;
  background: var(--color-surface);
  border-radius: var(--radius-lg, 12px);
  box-shadow: var(--shadow-lg);
  padding: var(--space-5);
  outline: none;
}
.supplier-relance__head {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-3);
  margin-bottom: var(--space-3);
}
.supplier-relance__title {
  margin: 0;
  font-size: var(--fs-lg);
  line-height: 1.25;
  flex: 1;
}
.supplier-relance__close {
  flex-shrink: 0;
}
.supplier-relance__list {
  margin: 0 0 var(--space-4);
  padding-left: 1.25rem;
}
.supplier-relance__textarea {
  width: 100%;
  min-height: 10rem;
  resize: vertical;
  font-family: inherit;
}
.supplier-relance__actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
  margin-top: var(--space-3);
}
.supplier-relance--sent .supplier-relance__panel--sent,
.supplier-relance--error .supplier-relance__panel--sent {
  text-align: center;
  padding: var(--space-6);
}
.supplier-relance--sent .supplier-relance__backdrop--sent {
  cursor: default;
}

/* === Page Composition produit ============================================
   Refonte UX : header de synthèse, cartes composant claires (statut couleur,
   actions discrètes), tableau matières avec total live. */

.composition-summary__header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: var(--space-4);
  margin-bottom: var(--space-4);
}
.composition-summary__stats {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: var(--space-3);
}
.composition-summary__stat {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface);
}
.composition-summary__stat-value {
  font-size: 1.5rem;
  font-weight: 700;
  color: var(--color-text);
  line-height: 1.1;
}
.composition-summary__stat-label {
  font-size: 0.8125rem;
  color: var(--color-text-muted);
  text-transform: uppercase;
  letter-spacing: 0.03em;
}

.composition-card {
  border-left: 4px solid var(--color-border);
  position: relative;
}
.composition-card--status-complete {
  border-left-color: var(--color-success);
}
.composition-card--status-partial {
  border-left-color: var(--color-warning);
}
.composition-card--status-empty {
  border-left-color: var(--color-border);
}
.composition-card--whole {
  background: color-mix(in srgb, var(--color-surface) 92%, var(--color-border) 8%);
  border-left-color: color-mix(in srgb, var(--color-text) 35%, transparent);
}

.composition-card__header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: var(--space-3);
  margin-bottom: var(--space-3);
}
.composition-card__title-block {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  min-width: 0;
}
.composition-card__badges {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
}
.composition-card__count {
  font-size: 0.8125rem;
}
.composition-card__delete {
  margin: 0;
  flex: 0 0 auto;
}
.composition-card__delete-btn {
  font-size: 1.25rem;
  line-height: 1;
  padding: 0 0.5rem;
  min-width: 2rem;
  height: 2rem;
}
.composition-card__hint {
  font-size: 0.875rem;
}
.composition-card__edit {
  margin-bottom: var(--space-4);
  padding: var(--space-3);
  background: color-mix(in srgb, var(--color-surface) 80%, var(--color-border) 20%);
  border-radius: var(--radius-md);
}
.composition-card__materials {
  margin-top: var(--space-3);
}
.composition-card__readonly-list {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}
.composition-card__add-material {
  padding-top: var(--space-3);
  border-top: 1px dashed var(--color-border);
}

.composition-field--grow {
  flex: 1 1 12rem;
  min-width: 0;
  margin-bottom: 0;
}
.composition-field--inline {
  flex: 0 0 auto;
  margin-bottom: 0;
}

.composition-table {
  width: 100%;
}
.composition-table__pct {
  text-align: right;
  white-space: nowrap;
  width: 8rem;
}
.composition-table__actions {
  width: 1%;
  text-align: right;
}
.composition-table__actions .ui-form-inline-gap {
  display: inline-block;
  margin-left: var(--space-2);
}
.composition-table__delete {
  font-size: 1.1rem;
  line-height: 1;
  padding: 0 0.5rem;
}
.composition-table__total-label {
  text-align: right;
  font-weight: 600;
}

.composition-add {
  border: 1px dashed var(--color-border);
  background: transparent;
  box-shadow: none;
}

.composition-badge--main {
  /* badge "principal" : on s'appuie sur ui-badge--success mais en variante
     plus discrète */
  background: color-mix(in srgb, var(--color-success) 12%, transparent);
  color: var(--color-success);
}

@media (max-width: 640px) {
  .composition-card__header {
    flex-direction: column;
  }
  .composition-card__edit,
  .composition-card__add-material {
    flex-direction: column;
    align-items: stretch;
  }
  .composition-table__pct {
    width: auto;
  }
}

/* Supplier attestations: automatic follow-up submission tokens (auto-v1) */
.ui-table tbody tr.attestations-token-row--auto > td {
  background: var(--surface-muted);
}

/* PR-7 : confettis portail (décoratif, ≤ 2s) */
.portal-confetti {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 9999;
  overflow: hidden;
}

.portal-confetti__piece {
  position: absolute;
  top: -12px;
  width: 10px;
  height: 14px;
  opacity: 0.9;
  animation: portal-confetti-fall 1.8s ease-in forwards;
}

.portal-confetti__piece:nth-child(1) { left: 5%; background: var(--color-accent-amber); animation-delay: 0s; transform: rotate(15deg); }
.portal-confetti__piece:nth-child(2) { left: 12%; background: var(--color-primary); animation-delay: 0.05s; transform: rotate(-20deg); }
.portal-confetti__piece:nth-child(3) { left: 20%; background: var(--color-success); animation-delay: 0.1s; transform: rotate(35deg); }
.portal-confetti__piece:nth-child(4) { left: 28%; background: var(--color-accent-terracotta); animation-delay: 0.02s; transform: rotate(-10deg); }
.portal-confetti__piece:nth-child(5) { left: 36%; background: var(--color-accent-brown); animation-delay: 0.08s; transform: rotate(25deg); }
.portal-confetti__piece:nth-child(6) { left: 44%; background: var(--color-danger); animation-delay: 0.12s; transform: rotate(-30deg); }
.portal-confetti__piece:nth-child(7) { left: 52%; background: var(--color-primary-hover); animation-delay: 0.04s; transform: rotate(10deg); }
.portal-confetti__piece:nth-child(8) { left: 60%; background: var(--color-warning-graph); animation-delay: 0.15s; transform: rotate(-15deg); }
.portal-confetti__piece:nth-child(9) { left: 68%; background: var(--color-text); animation-delay: 0.06s; transform: rotate(40deg); }
.portal-confetti__piece:nth-child(10) { left: 76%; background: var(--color-success); animation-delay: 0.1s; transform: rotate(-25deg); }
.portal-confetti__piece:nth-child(11) { left: 84%; background: var(--color-danger); animation-delay: 0.03s; transform: rotate(20deg); }
.portal-confetti__piece:nth-child(12) { left: 92%; background: var(--color-accent-amber-deep); animation-delay: 0.14s; transform: rotate(-35deg); }
.portal-confetti__piece:nth-child(13) { left: 8%; background: var(--color-accent-brown); animation-delay: 0.18s; transform: rotate(5deg); }
.portal-confetti__piece:nth-child(14) { left: 48%; background: var(--color-accent-amber); animation-delay: 0.16s; transform: rotate(-5deg); }
.portal-confetti__piece:nth-child(15) { left: 72%; background: var(--color-primary); animation-delay: 0.2s; transform: rotate(30deg); }
.portal-confetti__piece:nth-child(16) { left: 96%; background: var(--color-success); animation-delay: 0.09s; transform: rotate(-40deg); }

@keyframes portal-confetti-fall {
  0% {
    transform: translateY(0) rotate(0deg);
    opacity: 1;
  }
  100% {
    transform: translateY(110vh) rotate(720deg);
    opacity: 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  .portal-confetti {
    display: none;
  }
}

/* Portail attributs : grille editable produits x attributs */
.portal-attr-grid__table {
  width: 100%;
  min-width: 48rem;
  margin: 0;
  font-size: 0.875rem;
}

.portal-attr-grid__table th,
.portal-attr-grid__table td {
  white-space: nowrap;
  vertical-align: top;
}

.portal-attr-grid__th-product,
.portal-attr-grid__td-product {
  width: 11rem;
  min-width: 9rem;
  max-width: 11rem;
  white-space: normal;
  overflow-wrap: anywhere;
  word-break: break-word;
  hyphens: auto;
}

.portal-attr-grid__td-product a {
  overflow-wrap: anywhere;
  word-break: break-word;
  white-space: normal;
}

.portal-attr-grid__table td.portal-attributes-row--required-missing {
  background: rgba(254, 243, 199, 0.42);
}

.portal-attr-grid__th-attr {
  min-width: 11rem;
}

.portal-attr-grid__required-mark {
  color: var(--color-warning);
  font-weight: 700;
  text-decoration: none;
  margin-left: 0.15rem;
}

.portal-attr-grid__collection {
  display: block;
  font-size: 0.75rem;
  overflow-wrap: anywhere;
  word-break: break-word;
}

.portal-attr-grid__field {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.portal-attr-grid__pending {
  align-self: flex-start;
}

/* État d'une cellule qui s'enregistre seule : le retour remplace le bouton
   « Enregistrer » retiré, donc il doit rester lisible sans être criard.
   ``.portal-field > span`` met les libellés en capitales grises : on annule. */
.portal-attr-grid__cell-error,
.portal-attr-grid__cell-saved {
  align-self: flex-start;
  font-size: 0.75rem;
  font-weight: 500;
  text-transform: none;
  letter-spacing: normal;
}

.portal-attr-grid__cell-error {
  color: var(--color-danger);
}

.portal-attr-grid__cell-saved {
  color: var(--color-text-muted);
}

.portal-attr-grid .ui-input--compact,
.portal-attr-grid .ui-select--compact,
.portal-attr-grid__bulk-value .ui-input--compact,
.portal-attr-grid__bulk-value .ui-select--compact {
  min-width: 9rem;
  max-width: 14rem;
}

.portal-attr-grid__bulk-bar {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin-top: var(--space-3);
}

.portal-attr-grid__bulk-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: var(--space-2);
}

.portal-attr-grid__bulk-form {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  margin: 0;
}

/* Harmonise la hauteur de tous les contrôles de la barre d'attribution
   (toggle, select, champ valeur, bouton appliquer) pour un alignement net. */
.portal-attr-grid__bulk-bar .ui-btn--compact,
.portal-attr-grid__bulk-value .ui-input--compact,
.portal-attr-grid__bulk-form .ui-select--compact {
  min-height: var(--h-btn-sm);
  height: var(--h-btn-sm);
}

.portal-attr-grid__bulk-value .ui-input--compact,
.portal-attr-grid__bulk-form .ui-select--compact {
  padding-top: 0;
  padding-bottom: 0;
}

.portal-attr-grid__bulk-value {
  display: inline-flex;
  align-items: center;
}

.portal-attr-grid__bulk-help {
  font-size: 0.875rem;
}

/* ── Page « Certificats » — liste unifiée : raffinements UI/UX ───────── */

.certificate-level-cell {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-1);
}

.certificate-draft-badge {
  background: color-mix(in srgb, var(--color-primary) 12%, transparent);
  color: var(--color-primary);
}

/* Champs « discrets » : la ligne se lit comme de la donnée ; l'affordance
   d'édition (bordure + fond) n'apparaît qu'au survol de la ligne ou au
   focus du champ. On garde la largeur de bordure (1px transparent) pour
   éviter tout saut de mise en page. */
.certificate-list-table .ui-input,
.certificate-list-table .ui-select,
.supplier-certificates-card__table .ui-input,
.supplier-certificates-card__table .ui-select {
  padding: 6px 8px;
  background-color: transparent;
  border-color: transparent;
}

.certificate-list-table tbody tr:hover .ui-input:not(:disabled),
.certificate-list-table tbody tr:hover .ui-select:not(:disabled),
.certificate-list-table .ui-input:focus,
.certificate-list-table .ui-select:focus,
.supplier-certificates-card__table tbody tr:hover .ui-input:not(:disabled),
.supplier-certificates-card__table tbody tr:hover .ui-select:not(:disabled),
.supplier-certificates-card__table .ui-input:focus,
.supplier-certificates-card__table .ui-select:focus {
  background-color: var(--color-surface);
  border-color: var(--color-border);
}

.certificate-list-table .ui-select,
.supplier-certificates-card__table .ui-select {
  min-width: 8.5rem;
}

.certificate-list-table .portal-certificate-table__field--date,
.supplier-certificates-card__table .portal-certificate-table__field--date {
  min-width: 8.5rem;
}

.certificate-list-table th,
.certificate-list-table td,
.supplier-certificates-card__table td {
  vertical-align: middle;
}

.certificate-list-table__actions {
  white-space: nowrap;
  text-align: right;
}

/* Barre d'actions : icônes sur une seule ligne, alignées à droite. */
.certificate-list-table .portal-certificate-row-actions {
  flex-direction: row;
  align-items: center;
  justify-content: flex-end;
  gap: var(--space-1);
}

.certificate-list-table .portal-certificate-row-actions__preview-slot {
  flex-wrap: nowrap;
}

/* « Enregistrer » masqué tant que la ligne est intacte. Visible par défaut
   (sans JS) → dégradation gracieuse, aucune régression d'accessibilité.
   Classes posées par JS (liste certificats + onglet fournisseur). */
tr.certificate-row--clean .portal-certificate-row-actions__save-btn {
  display: none;
}

/* Ligne modifiée non enregistrée : fond léger + repère latéral. */
tr.certificate-row--dirty > td {
  background: color-mix(in srgb, var(--color-primary) 6%, transparent);
}

tr.certificate-row--dirty > td:first-child {
  box-shadow: inset 3px 0 0 0 var(--color-primary);
}

/* Bascule « Fournisseurs | Sites de production » (référentiel org-level).
   Calqué sur .sales-leaderboard-group-switch : mêmes primitives .trace-view-switch__*,
   préfixe propre car ce switch navigue entre deux pages et non entre deux groupements. */
.suppliers-view-switch {
  flex-shrink: 0;
}

.suppliers-view-switch__track-link {
  display: inline-flex;
  margin: 0;
  cursor: pointer;
  text-decoration: none;
}

.suppliers-view-switch .trace-view-switch__label {
  text-decoration: none;
  color: var(--color-text-muted);
}

.suppliers-view-switch:not(.suppliers-view-switch--sites) .trace-view-switch__label--tree,
.suppliers-view-switch--sites .trace-view-switch__label--map {
  color: var(--color-text);
  font-weight: 600;
}

.suppliers-view-switch--sites .trace-view-switch__track {
  background: var(--color-primary);
}

.suppliers-view-switch--sites .trace-view-switch__thumb {
  transform: translateX(calc(3.2rem - 1.95rem));
}

/* ── Page « Sites de production » (/sites/) ────────────────────────────────
   Le tableau mêle du texte multi-ligne (nom + adresse, plusieurs fournisseurs
   par usine) et des colonnes de comptage. Sans alignement explicite, les
   nombres flottent au milieu de colonnes larges et le rythme vertical part.
   Classes locales : ``ui-table`` est partagé par toutes les listes du produit
   et ne doit pas bouger pour une seule page. */
.sites-list-table th,
.sites-list-table td {
  vertical-align: top;
  padding-top: var(--space-4);
  padding-bottom: var(--space-4);
}

.sites-list-table thead th {
  vertical-align: bottom;
  white-space: nowrap;
}

/* Comptages : alignés à droite et en chiffres de largeur fixe, pour que les
   unités se superposent d'une ligne à l'autre. ``width: 1%`` + ``nowrap`` est
   l'idiome qui réduit une colonne de tableau à la largeur de son contenu : sans
   lui, trois colonnes d'un seul chiffre mangeaient 365 px et le nom de l'usine
   était comprimé à 200 px, ce qui cassait les adresses sur trois lignes. */
.sites-list-table .sites-list-col--num {
  width: 1%;
  text-align: right;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

.sites-list-table .sites-list-col--country {
  width: 1%;
  white-space: nowrap;
}

/* Colonnes étroites : le padding par défaut (16 px de chaque côté) coûtait plus
   large que leur contenu. Resserré, il rend ~70 px au nom de l'usine. */
.sites-list-table .sites-list-col--num,
.sites-list-table .sites-list-col--country {
  padding-left: var(--space-2);
  padding-right: var(--space-2);
}

.sites-list-table thead .sites-list-col--num .ui-sort-indicator {
  margin-left: var(--space-1);
  min-width: 0.9em;
}

/* L'espace récupéré va au nom et à l'adresse, la colonne qui porte le plus de
   texte : c'est ce qui régularise la hauteur des lignes. */
.sites-list-table .sites-list-col--name {
  width: 32%;
  min-width: 15rem;
}

.sites-list-table .sites-list-col--supplier {
  min-width: 14rem;
}

.sites-list-table .sites-list-col--action {
  width: 17rem;
}

/* Le sélecteur et son bouton sur une seule ligne : empilés, ils doublaient la
   hauteur de chaque ligne du tableau. */
.sites-list-reassign {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.sites-list-reassign .ui-input {
  flex: 1 1 auto;
  min-width: 0;
}

.sites-list-reassign .ui-btn {
  flex: 0 0 auto;
  white-space: nowrap;
}

/* Nom de l'usine : le badge de statut reste solidaire du nom et ne se coupe
   jamais en deux. */
.sites-list-name {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-2);
}

.sites-list-name .ui-badge {
  white-space: nowrap;
}

.sites-list-address {
  display: block;
  margin-top: var(--space-1);
}

/* Un fournisseur par ligne, espacement porté par le CSS plutôt que par des
   <br /> successifs. */
.sites-list-suppliers {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

/* Compteur « Utilisé par » dépliable : panneau flottant du composant menu (hors flux,
   la colonne ne bouge pas), items = liens vers les fiches fournisseurs. Seuls les
   textes hors menu (placeholder de chargement, cas vide) ont besoin du padding
   horizontal que les items portent déjà eux-mêmes. */
.sites-users-menu .ui-action-menu__panel {
  text-align: left;
}

.sites-users-empty {
  margin: 0;
  padding: 0 var(--space-3);
}

/* ── Page « Doublons de sites » (/sites/duplicates/) ───────────────────────
   Le résumé était une liste à puces : quatre nombres noyés dans du texte. En
   tuiles alignées, ils se lisent d'un coup d'œil. */
.sites-dup-stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));
  gap: var(--space-4) var(--space-5);
  margin: var(--space-4) 0;
  padding: 0;
  list-style: none;
}

.sites-dup-stats li {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
}

.sites-dup-stats__value {
  font-size: 1.375rem;
  font-weight: 600;
  line-height: 1.1;
  font-variant-numeric: tabular-nums;
}

.sites-dup-stats__label {
  font-size: 0.8125rem;
  color: var(--color-text-muted);
}

.sites-dup-table th,
.sites-dup-table td {
  vertical-align: top;
  padding-top: var(--space-3);
  padding-bottom: var(--space-3);
}

.sites-dup-table .sites-dup-col--country {
  width: 5rem;
  white-space: nowrap;
}

.sites-dup-table .sites-dup-col--num {
  width: 6rem;
  text-align: right;
  white-space: nowrap;
}

/* Choix du gardien : des étiquettes empilées avec un interligne régulier. */
.sites-dup-keepers {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  margin-top: var(--space-2);
}

/* Liste marque « Certificats » (certificats v2, phase 5) */
.certificate-tabs__count {
  display: inline-block;
  min-width: 1.5em;
  margin-left: 0.35em;
  padding: 0 0.4em;
  border-radius: 999px;
  background: rgba(0, 0, 0, 0.08);
  font-size: 0.8em;
  line-height: 1.5em;
  text-align: center;
}

.ui-btn--primary .certificate-tabs__count {
  background: rgba(255, 255, 255, 0.25);
}

.certificate-status-cell {
  display: flex;
  flex-direction: column;
  gap: 0.15rem;
}

.certificate-status-cell__detail {
  font-size: 0.85em;
}

.certificate-reject,
.certificate-revoke {
  position: relative;
  display: inline-block;
}

.certificate-reject__summary,
.certificate-revoke__summary {
  list-style: none;
  cursor: pointer;
}

.certificate-reject__summary::-webkit-details-marker,
.certificate-revoke__summary::-webkit-details-marker {
  display: none;
}

.certificate-reject__form,
.certificate-revoke__form {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  min-width: 18rem;
  margin-top: 0.5rem;
  padding: 0.75rem;
  border: 1px solid var(--ui-border);
  border-radius: var(--radius-sm);
  background: var(--ui-surface);
  text-align: left;
}

.certificate-reject__reason,
.certificate-revoke__reason {
  width: 100%;
  resize: vertical;
}

.certificate-revoke__warning {
  margin: 0;
  font-size: 0.85em;
}

/* Portail fournisseur, mobile (≤ 48em) — audit portail 18/09.
   ACT-04 : tout contrôle sous 16 px déclenche le zoom automatique de Safari iOS.
   ACT-09 / ATTR-03 / SUB-05 : cases à cocher de 13 px et boutons sous 44 px. */
@media (max-width: 48em) {
  .portal-body .ui-input,
  .portal-body .ui-select,
  .portal-body select,
  .portal-body input:not([type="checkbox"]):not([type="radio"]) {
    font-size: 1rem;
  }

  .portal-body input[type="checkbox"] {
    width: 20px;
    height: 20px;
    margin: 0;
  }

  .portal-body .portal-checkbox-label {
    min-height: 44px;
    gap: var(--space-3);
  }

  .portal-body .portal-activities-page__th-check,
  .portal-body .portal-activities-page__td-check,
  .portal-body .portal-attr-grid__th-check,
  .portal-body .portal-attr-grid__td-check {
    padding: 12px;
  }

  .portal-body .ui-btn,
  .portal-body .ui-select,
  .portal-body select {
    min-height: 44px;
  }

  .portal-body .p-sidebar__nav-label {
    white-space: normal;
  }
}

/* Code pays ou langue — remplace les drapeaux emoji, absents sous Windows
   (chantier UI/UX 2026-09-20, § 7.4). Décoratif : toujours aria-hidden, le
   nom lisible est porté par l'élément voisin. */
.ui-cc {
  display: inline-flex;
  align-items: center;
  padding: 2px 4px;
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-xs);
  color: var(--color-text-muted);
  font-size: 0.625rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  line-height: 1;
  text-transform: uppercase;
  vertical-align: middle;
}

/* Écran d'accueil du portail fournisseur (templates/portal/_welcome_modal.html). */
.portal-welcome-modal {
  max-width: 560px;
  width: 90vw;
  border: none;
  border-radius: var(--radius-md);
  padding: var(--space-6);
  box-shadow: var(--shadow-xl);
  background: var(--color-surface);
  color: var(--color-text);
}

.portal-welcome-modal::backdrop {
  background: rgba(0, 0, 0, 0.5);
}

.portal-welcome-modal__intro,
.portal-welcome-modal__saved {
  margin: var(--space-3) 0;
  line-height: var(--lh-base);
}

.portal-welcome-modal__saved {
  color: var(--color-text-muted);
}

.portal-welcome-modal__steps {
  margin: var(--space-3) 0 var(--space-5);
  padding-left: var(--space-5);
  line-height: var(--lh-base);
}

/* Portal help — sommaire en tuiles, questions dépliables, tutoriel page par page */
.portal-help__lead {
  margin: 0;
  font-size: var(--fs-md);
  line-height: var(--lh-relaxed);
  max-width: 68ch;
}

.portal-help__toc {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: var(--space-3);
}

.portal-help__tile {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  min-height: 44px;
  padding: var(--space-3);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  color: var(--color-text);
  text-decoration: none;
  font-weight: var(--fw-medium);
  line-height: var(--lh-tight);
  transition: border-color var(--duration-fast) var(--ease-out),
    background-color var(--duration-fast) var(--ease-out);
}

.portal-help__tile:hover {
  border-color: var(--color-primary);
  background: var(--color-primary-soft);
}

.portal-help__tile:focus-visible {
  outline: none;
  box-shadow: var(--shadow-focus);
}

.portal-help__tile-icon,
.portal-help__section-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  border-radius: var(--radius-md);
  background: var(--color-primary-soft);
  color: var(--color-primary);
}

.portal-help__tile-icon {
  width: 2rem;
  height: 2rem;
}

.portal-help__section-icon {
  width: 2.75rem;
  height: 2.75rem;
}

.portal-help__section-icon svg {
  width: 24px;
  height: 24px;
}

.portal-help__section-head {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-bottom: var(--space-3);
}

.portal-help__section-head .ui-heading-2,
.portal-help__page-titles .ui-heading-3 {
  margin: 0;
}

.portal-help__faq {
  display: flex;
  flex-direction: column;
  border-top: 1px solid var(--color-border);
}

.portal-help__item {
  border-bottom: 1px solid var(--color-border);
}

.portal-help__question {
  cursor: pointer;
  list-style: none;
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-height: 44px;
  padding: var(--space-3) var(--space-2);
  font-weight: var(--fw-semibold);
  line-height: var(--lh-base);
}

.portal-help__question::-webkit-details-marker {
  display: none;
}

.portal-help__question::before {
  content: "+";
  flex: 0 0 auto;
  width: 1.5rem;
  height: 1.5rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-pill);
  background: var(--color-primary-soft);
  color: var(--color-primary);
  font-weight: var(--fw-bold);
}

.portal-help__item[open] > .portal-help__question::before {
  content: "−";
  background: var(--color-primary);
  color: var(--color-on-primary);
}

.portal-help__question:hover {
  background: var(--color-surface-hover);
}

.portal-help__question:focus-visible {
  outline: none;
  box-shadow: var(--shadow-focus);
  border-radius: var(--radius-sm);
}

.portal-help__answer {
  margin: 0;
  padding: 0 var(--space-2) var(--space-4) calc(1.5rem + var(--space-3) + var(--space-2));
  line-height: var(--lh-relaxed);
  max-width: 72ch;
}

.portal-help__tuto {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
}

.portal-help__tuto > .ui-heading-2 {
  margin: var(--space-2) 0 0;
}

.portal-help__hint,
.portal-help__page-intro {
  margin: 0;
  color: var(--color-text-muted);
  line-height: var(--lh-base);
  max-width: 72ch;
}

/* Ancre du sommaire : la barre haute est fixe, sans cette marge elle masque le titre visé. */
.portal-help__page,
.portal-help > .ui-card {
  scroll-margin-top: 5rem;
}

.portal-help__page-head {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding-bottom: var(--space-4);
  margin-bottom: var(--space-4);
  border-bottom: 1px solid var(--color-border);
}

.portal-help__page-titles {
  flex: 1 1 auto;
  min-width: 0;
}

.portal-help__page-titles .ui-heading-3 {
  margin-bottom: var(--space-1);
}

.portal-help__open {
  flex: 0 0 auto;
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.portal-help__steps {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
}

.portal-help__step {
  display: flex;
  align-items: flex-start;
  gap: var(--space-3);
  padding: var(--space-3);
  border-radius: var(--radius-md);
  background: var(--color-surface-alt);
  line-height: var(--lh-relaxed);
}

.portal-help__step-num {
  flex: 0 0 auto;
  width: 2rem;
  height: 2rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-pill);
  background: var(--color-primary);
  color: var(--color-on-primary);
  font-weight: var(--fw-bold);
  font-size: var(--fs-sm);
}

.portal-help__step-text {
  flex: 1 1 auto;
  min-width: 0;
  padding-top: 0.3rem;
  max-width: 72ch;
}

@media (max-width: 47.9375em) {
  .portal-help__page-head {
    flex-wrap: wrap;
  }

  .portal-help__open {
    flex-basis: 100%;
  }
}

/* Portal tour — bouton « Visite guidée » et bulle driver.js habillée aux jetons */
.portal-tour-btn {
  position: fixed;
  right: var(--space-4);
  bottom: var(--space-5, 20px);
  z-index: calc(var(--z-modal) - 1);
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: 44px;
  padding: 0 var(--space-4) 0 var(--space-3);
  border: 1px solid var(--color-primary);
  border-radius: 999px;
  background: var(--color-surface);
  color: var(--color-primary);
  font: inherit;
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  box-shadow: var(--shadow-lg);
  cursor: pointer;
}

/* Le script pose [hidden] sur les pages sans visite : l'attribut doit gagner sur display. */
.portal-tour-btn[hidden] {
  display: none;
}

.portal-tour-btn:hover {
  background: var(--color-primary-soft);
}

.portal-tour-btn:focus-visible {
  outline: none;
  box-shadow: var(--shadow-focus), var(--shadow-lg);
}

.portal-tour-btn__icon {
  display: inline-flex;
  width: 1.5rem;
  height: 1.5rem;
  align-items: center;
  justify-content: center;
  border-radius: 999px;
  background: var(--color-primary);
  color: var(--color-on-primary);
}

.portal-tour-btn__icon svg {
  width: 16px;
  height: 16px;
}

@media (max-width: 47.9375em) {
  .portal-tour-btn {
    right: var(--space-3);
    padding: 0;
    width: 48px;
    height: 48px;
    justify-content: center;
  }

  .portal-tour-btn__label {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
  }

  /* Le bouton rouge d'envoi prend toute la largeur en bas : la visite monte au-dessus. */
  body:has(.portal-submit-sticky:not([hidden])) .portal-tour-btn {
    bottom: calc(var(--space-5, 20px) + 56px + var(--space-3));
  }
}

.driver-active .portal-tour-btn {
  visibility: hidden;
}

.driver-popover.portal-tour-popover {
  font-family: var(--font-sans);
  color: var(--color-text);
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-xl);
  padding: var(--space-4);
  min-width: 260px;
  max-width: min(360px, calc(100vw - 2 * var(--space-4)));
}

.portal-tour-popover .driver-popover-arrow {
  border-color: var(--color-surface);
}

.portal-tour-popover .driver-popover-arrow-side-left {
  border-top-color: transparent;
  border-bottom-color: transparent;
  border-right-color: transparent;
}

.portal-tour-popover .driver-popover-arrow-side-right {
  border-top-color: transparent;
  border-bottom-color: transparent;
  border-left-color: transparent;
}

.portal-tour-popover .driver-popover-arrow-side-top {
  border-bottom-color: transparent;
  border-left-color: transparent;
  border-right-color: transparent;
}

.portal-tour-popover .driver-popover-arrow-side-bottom {
  border-top-color: transparent;
  border-left-color: transparent;
  border-right-color: transparent;
}

.portal-tour-popover .driver-popover-title {
  font-family: var(--font-sans);
  font-size: var(--fs-lg);
  font-weight: var(--fw-semibold);
  line-height: var(--lh-tight);
  padding-right: var(--space-6);
}

.portal-tour-popover .driver-popover-description {
  margin-top: var(--space-2);
  font-size: var(--fs-md);
  line-height: var(--lh-relaxed);
  color: var(--color-text);
}

.portal-tour-popover .driver-popover-close-btn {
  color: var(--color-text-muted);
  width: 36px;
  height: 36px;
  font-size: 22px;
}

.portal-tour-popover .driver-popover-close-btn:hover,
.portal-tour-popover .driver-popover-close-btn:focus {
  color: var(--color-text);
}

.portal-tour-popover .driver-popover-footer {
  margin-top: var(--space-4);
  gap: var(--space-2);
}

.portal-tour-popover .driver-popover-progress-text {
  color: var(--color-text-muted);
  font-size: var(--fs-sm);
}

.portal-tour-popover .driver-popover-footer-btn {
  min-height: 44px;
  padding: 0 var(--space-4);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  color: var(--color-text);
  font-size: var(--fs-sm);
  font-weight: var(--fw-semibold);
  line-height: 1;
}

.portal-tour-popover .driver-popover-next-btn {
  border-color: var(--color-primary);
  background: var(--color-primary);
  color: var(--color-on-primary);
}

.portal-tour-popover .driver-popover-footer-btn:hover,
.portal-tour-popover .driver-popover-footer-btn:focus {
  background: var(--color-surface-hover);
}

.portal-tour-popover .driver-popover-next-btn:hover,
.portal-tour-popover .driver-popover-next-btn:focus {
  background: var(--color-primary-hover);
}

.portal-tour-popover .driver-popover-footer-btn:focus-visible {
  box-shadow: var(--shadow-focus);
}

.portal-tour-popover .driver-popover-navigation-btns button + button {
  margin-left: var(--space-2);
}

/* Fenêtre d'envoi : case et bouton sur une ligne, « Tout annuler » en lien discret dessous */
.portal-declaration-form__row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
}

.portal-declaration-form__row .portal-checkbox-label {
  flex: 1 1 18rem;
  gap: var(--space-2);
  min-height: 44px;
}

.portal-declaration-form__row .portal-checkbox-label input {
  width: 1.25rem;
  height: 1.25rem;
  flex: 0 0 auto;
}

.portal-submission-discard {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  margin: var(--space-4) 0 0;
  font-size: var(--fs-sm);
}

.portal-submission-discard__form {
  display: inline;
}

.portal-submission-discard__btn {
  border-color: transparent;
  background: transparent;
  color: var(--color-danger-fg);
  text-decoration: underline;
}

/* Demande transférée (apps/portal/transfer.py) : carte d'étape, fenêtre, page de réponse */
.trace-grid-card__transfer {
  display: grid;
  gap: var(--space-1);
  margin: var(--space-2) 0 0;
  font-size: var(--fs-sm);
}

.trace-grid-card__transfer .ui-badge {
  justify-self: start;
}

.trace-grid-card__transfer-line,
.trace-grid-card__transfer-msg {
  margin: 0;
  color: var(--color-text-muted);
  line-height: var(--lh-base);
}

.trace-grid-card__transfer-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-1);
  margin-top: var(--space-2);
}

.portal-transfer-modal {
  max-width: 620px;
}

.portal-transfer-modal__facts,
.portal-transfer-card__facts {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: var(--space-1) var(--space-3);
  margin: 0 0 var(--space-3);
}

.portal-transfer-modal__facts dt,
.portal-transfer-card__facts dt {
  color: var(--color-text-muted);
}

.portal-transfer-modal__facts dd,
.portal-transfer-card__facts dd {
  margin: 0;
  font-weight: 600;
}

.portal-transfer-modal__actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: var(--space-2);
}

.portal-transfer-modal__error {
  margin: 0;
  color: var(--color-danger-fg);
}

/* Fenêtre « Chercher une usine » des menus d'affectation (portal_site_search.js). */
.portal-site-search-modal {
  max-width: 520px;
}

.portal-site-search-modal__results {
  list-style: none;
  margin: 0;
  padding: 0;
}

.portal-site-search-modal__result {
  width: 100%;
  justify-content: flex-start;
  text-align: left;
}

.portal-site-search-modal .ui-row .ui-input {
  flex: 1 1 auto;
  min-width: 0;
}

.portal-transfer-page {
  max-width: 640px;
  margin: 0 auto;
  padding-top: var(--space-8);
  padding-bottom: var(--space-12);
}

.portal-transfer-card__intro,
.portal-transfer-card__message,
.portal-transfer-card__privacy {
  line-height: var(--lh-base);
}

.portal-transfer-form__choice {
  display: grid;
  gap: var(--space-1);
  margin: 0;
  padding: 0;
  border: 0;
}

.portal-transfer-form__option {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.portal-transfer-form__site {
  display: grid;
  gap: var(--space-2);
}
