/* Duva : compléments d'application (chargé après duva-tokens.css et duva.css).
   Ne définit que ce que les maquettes faisaient en attribut style ou en JavaScript, et l'état des composants
   ajoutés par le noyau d'interface. Aucune valeur en dur : les tokens de duva-tokens.css (jamais édité ici).
   CSP stricte : ce fichier remplace tous les `style="…"` des maquettes. */

/* ------------------------------------------------------------------ base -- */

[hidden] { display: none !important; }
.sprite { position: absolute; width: 0; height: 0; overflow: hidden; }

/* ---------------------------------------------------------- largeurs (%) -- */
/* Remplissage de jauge, squelettes : une classe par pourcentage entier. */
.u-w-0 { width: 0%; }
.u-w-1 { width: 1%; }
.u-w-2 { width: 2%; }
.u-w-3 { width: 3%; }
.u-w-4 { width: 4%; }
.u-w-5 { width: 5%; }
.u-w-6 { width: 6%; }
.u-w-7 { width: 7%; }
.u-w-8 { width: 8%; }
.u-w-9 { width: 9%; }
.u-w-10 { width: 10%; }
.u-w-11 { width: 11%; }
.u-w-12 { width: 12%; }
.u-w-13 { width: 13%; }
.u-w-14 { width: 14%; }
.u-w-15 { width: 15%; }
.u-w-16 { width: 16%; }
.u-w-17 { width: 17%; }
.u-w-18 { width: 18%; }
.u-w-19 { width: 19%; }
.u-w-20 { width: 20%; }
.u-w-21 { width: 21%; }
.u-w-22 { width: 22%; }
.u-w-23 { width: 23%; }
.u-w-24 { width: 24%; }
.u-w-25 { width: 25%; }
.u-w-26 { width: 26%; }
.u-w-27 { width: 27%; }
.u-w-28 { width: 28%; }
.u-w-29 { width: 29%; }
.u-w-30 { width: 30%; }
.u-w-31 { width: 31%; }
.u-w-32 { width: 32%; }
.u-w-33 { width: 33%; }
.u-w-34 { width: 34%; }
.u-w-35 { width: 35%; }
.u-w-36 { width: 36%; }
.u-w-37 { width: 37%; }
.u-w-38 { width: 38%; }
.u-w-39 { width: 39%; }
.u-w-40 { width: 40%; }
.u-w-41 { width: 41%; }
.u-w-42 { width: 42%; }
.u-w-43 { width: 43%; }
.u-w-44 { width: 44%; }
.u-w-45 { width: 45%; }
.u-w-46 { width: 46%; }
.u-w-47 { width: 47%; }
.u-w-48 { width: 48%; }
.u-w-49 { width: 49%; }
.u-w-50 { width: 50%; }
.u-w-51 { width: 51%; }
.u-w-52 { width: 52%; }
.u-w-53 { width: 53%; }
.u-w-54 { width: 54%; }
.u-w-55 { width: 55%; }
.u-w-56 { width: 56%; }
.u-w-57 { width: 57%; }
.u-w-58 { width: 58%; }
.u-w-59 { width: 59%; }
.u-w-60 { width: 60%; }
.u-w-61 { width: 61%; }
.u-w-62 { width: 62%; }
.u-w-63 { width: 63%; }
.u-w-64 { width: 64%; }
.u-w-65 { width: 65%; }
.u-w-66 { width: 66%; }
.u-w-67 { width: 67%; }
.u-w-68 { width: 68%; }
.u-w-69 { width: 69%; }
.u-w-70 { width: 70%; }
.u-w-71 { width: 71%; }
.u-w-72 { width: 72%; }
.u-w-73 { width: 73%; }
.u-w-74 { width: 74%; }
.u-w-75 { width: 75%; }
.u-w-76 { width: 76%; }
.u-w-77 { width: 77%; }
.u-w-78 { width: 78%; }
.u-w-79 { width: 79%; }
.u-w-80 { width: 80%; }
.u-w-81 { width: 81%; }
.u-w-82 { width: 82%; }
.u-w-83 { width: 83%; }
.u-w-84 { width: 84%; }
.u-w-85 { width: 85%; }
.u-w-86 { width: 86%; }
.u-w-87 { width: 87%; }
.u-w-88 { width: 88%; }
.u-w-89 { width: 89%; }
.u-w-90 { width: 90%; }
.u-w-91 { width: 91%; }
.u-w-92 { width: 92%; }
.u-w-93 { width: 93%; }
.u-w-94 { width: 94%; }
.u-w-95 { width: 95%; }
.u-w-96 { width: 96%; }
.u-w-97 { width: 97%; }
.u-w-98 { width: 98%; }
.u-w-99 { width: 99%; }
.u-w-100 { width: 100%; }
.skeleton { display: block; }
.skeleton--72 { width: 72px; }

/* ----------------------------------------------------- tiroir, console ---- */

.app-scrim { position: fixed; inset: 0; background: var(--overlay); z-index: calc(var(--z-header) + 1); }
@media (max-width: 1080px) {
  /* Le tiroir passe au-dessus de l'en-tête collant (même plan que lui dans les maquettes). */
  .app-sidebar { z-index: calc(var(--z-header) + 2); }
  /* Fermé, le tiroir est hors écran mais son ombre (duva.css) déborde sur le bord gauche de la
     page : elle n'existe que tiroir ouvert. */
  .app-sidebar:not([data-open="true"]) { box-shadow: none; }
}
@media (min-width: 1081px) { .app-scrim { display: none; } }
.app--console .app-header { border-bottom: 2px solid var(--warning-solid); }
.app-header__account { display: inline-flex; align-items: center; }

/* ----------------------------------------------------------------- pages -- */

.breadcrumb { margin-bottom: var(--space-2); }
.breadcrumb__list { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-1); }
.breadcrumb__item { display: inline-flex; align-items: center; gap: var(--space-1); }

.statusbar--info { color: var(--info); background: var(--info-surface); border-color: var(--info-border); }

.table--flush { min-width: 0; }
/* Tableau dans une carte étroite (détail d'un message, colonne de gauche) : les cellules se replient
   au lieu de déborder de la carte, donc rien n'est coupé ni caché derrière un défilement. `is-tight`
   perd son `nowrap` : la date passe à la ligne dans une carte étroite. */
.table--fit td, .table--fit th { overflow-wrap: anywhere; }
.table--fit td.is-tight { white-space: normal; width: auto; }
.table--fit thead th { white-space: normal; overflow-wrap: normal; }  /* les titres se replient entre mots */
/* La date se replie entre ses mots (« 20 sept. » « 2026, » « 6 h 52 »), jamais au milieu d'un mot. */
.table--fit td.is-date { overflow-wrap: normal; }

@media print {
  .app-sidebar, .app-header, .app-scrim, .toasts, .statusbar { display: none; }
  .app { display: block; }
}

/* --------------------------------------------------------- authentification */

.auth {
  min-height: 100vh; display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: var(--space-5); padding: var(--space-6) var(--space-4);
}
.auth__card { width: min(420px, 100%); padding: var(--space-6); }
.auth__head { display: flex; flex-direction: column; gap: var(--space-2); margin-bottom: var(--space-5); }
.auth__icon { color: var(--accent); }
.auth__card form { display: flex; flex-direction: column; gap: var(--space-4); }
.input--lg { min-height: var(--control-lg); padding: var(--space-3) var(--space-3); font-size: 15px; }
.input--code {
  font-family: var(--font-mono); font-size: 24px; letter-spacing: 0.4em; text-align: center;
  font-variant-numeric: tabular-nums;
}

.qr { display: flex; flex-direction: column; align-items: center; gap: var(--space-4); }
/* Noir sur blanc dans les deux thèmes : le SVG porte son propre fond blanc et sa marge blanche. */
.qr__code svg { display: block; width: min(100%, 200px); height: auto; border-radius: var(--radius-sm); }
.qr__manual { width: 100%; }
.qr__manual summary { cursor: pointer; min-height: var(--control-md); display: flex; align-items: center; }
.qr__manual > * + * { margin-top: var(--space-2); }

.recovery { display: flex; flex-direction: column; gap: var(--space-3); align-items: flex-start; }
.recovery__list {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(12ch, 1fr)); gap: var(--space-2); width: 100%;
  padding: var(--space-3); border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--surface-sunken);
}
.recovery__list code { font-size: 14px; letter-spacing: 0.04em; }

/* ------------------------------------------------------------ composants -- */

.btn[data-state="copied"] { color: var(--success); border-color: var(--success-border); }
.btn[data-state="error"] { color: var(--danger); border-color: var(--danger-border); }
.btn--ghost[data-state="copied"] { border-color: transparent; }

.chip__x { width: 24px; height: 24px; text-decoration: none; }

.stat__delta--good { color: var(--success); }
.stat__delta--bad { color: var(--danger); }

.dot--sandbox { background: var(--sandbox); }
.dns__row--bad td { background: var(--danger-surface); }
.kv__plain { font-family: var(--font-sans); font-size: 14px; }

.gauge__state { display: inline-flex; align-items: center; gap: var(--space-1); font-family: var(--font-sans); font-weight: 600; margin-right: var(--space-2); }

.tab { display: inline-flex; align-items: center; text-decoration: none; }
.tab:hover { color: var(--ink); }
.tab[aria-current="page"] { color: var(--accent); border-bottom-color: var(--accent); font-weight: 600; }

.code__tablist { display: flex; align-items: center; gap: var(--space-1); min-width: 0; overflow-x: auto; }
.code__tab--static { color: var(--ink); font-weight: 600; cursor: default; display: inline-flex; align-items: center; }

/* Graphiques : les classes de série portent fill et stroke ; les repères n'ont pas de contour. */
.chart__bar, .chart__dot { stroke: none; }
.spark__area { stroke: none; opacity: 0.12; }
.chart-legend__swatch--1 { background: var(--chart-1); }
.chart-legend__swatch--2 { background: var(--chart-2); }
.chart-legend__swatch--3 { background: var(--chart-3); }
.chart-legend__swatch--4 { background: var(--chart-4); }
.chart-legend__swatch--5 { background: var(--chart-5); }

.menu__form { margin: 0; }
.menu__item { font-size: 14px; }

/* Aperçu de message : le contenu d'un client est rendu sur fond blanc, comme dans un client de courriel. */
.preview-frame__iframe { display: block; width: 100%; height: 420px; border: 0; background: #fff; }
.preview-frame__text { white-space: pre-wrap; word-break: break-word; font-family: var(--font-mono); }

/* --------------------------------------------------------------- modales -- */

dialog.modal { padding: 0; margin: auto; color: var(--ink); }
dialog.modal::backdrop { background: var(--overlay); }
.modal__close { margin-left: auto; }
.modal__icon { color: var(--warning); }

.toasts:empty { display: none; }

/* ------------------------------------------------------------------ HTMX -- */
/* `includeIndicatorStyles` est désactivé (CSP) : ces règles remplacent la feuille injectée par htmx. */

.htmx-indicator { opacity: 0; transition: opacity 0.15s ease; }
.htmx-request .htmx-indicator, .htmx-request.htmx-indicator { opacity: 1; }
.htmx-request { cursor: progress; }

/* Zone échangée par HTMX (lot 1 : messages, vue d'ensemble) : pendant la requête, le squelette
   remplace le contenu. L'élément `.htmx-request` est la zone (`hx-indicator` pointe sur elle). */
.swap-zone__loading { display: none; }
.swap-zone.htmx-request > .swap-zone__loading { display: block; }
.swap-zone.htmx-request > .swap-zone__content { display: none; }
/* Sélecteur de période : liens du groupe de boutons, période courante = aria-current. */
.btn-group .btn[aria-current="true"] { background: var(--accent-surface); color: var(--accent); border-color: var(--accent-border); z-index: 1; }
/* Un identifiant de message (36 caractères en mono) ne doit pas déborder d'un écran étroit. */
.page-head__text .t-h1 { overflow-wrap: anywhere; }

.auth__brand { display: flex; justify-content: center; }

/* ------------------------------------------ écrans du compte (équipe, paramètres, production) -- */

.bullets { list-style: disc; padding-left: var(--space-5); margin: var(--space-2) 0; display: flex; flex-direction: column; gap: var(--space-1); }
.conditions { display: flex; flex-direction: column; gap: var(--space-3); }
.conditions__item { display: flex; align-items: flex-start; gap: var(--space-2); }
.conditions__item .icon { flex: none; margin-top: 2px; color: var(--warning); }
.conditions__item--ok .icon { color: var(--success); }
.table td form { margin: 0; }

/* ------------------------------------- lot 2a : domaines, clés, webhooks, suppressions, stats -- */

/* Texte de client ou de DNS long (URL, adresse) : il se replie, il n'élargit pas la page. */
.cell-wrap { font-family: var(--font-mono); font-size: 13px; word-break: break-all; max-width: 420px; }

.fieldset { border: 0; padding: 0; margin: 0; min-inline-size: 0; display: flex; flex-direction: column; gap: var(--space-2); }
.fieldset legend { padding: 0; margin-bottom: var(--space-1); }
.checkbox-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: var(--space-2) var(--space-4); }

/* Ligne d'en-tête d'un tableau (première colonne) : même mesure que les cellules. */
.table tbody th {
  padding: var(--space-2) var(--space-3); border-bottom: 1px solid var(--border); vertical-align: middle;
  height: var(--row-dense); text-align: left; font-weight: 500; background: transparent;
}
.table tbody th.is-mono { font-family: var(--font-mono); font-size: 13px; }
.table tbody th.is-tight { width: 1%; white-space: nowrap; }
.table tbody tr:hover th { background: var(--surface-hover); }

/* Graphiques plus larges que la page : ils défilent dans leur cadre, au clavier aussi (le tracé garde
   sa taille 1 pour 1, les valeurs restent lisibles). Une classe par largeur de dessin utilisée. */
.chart-scroll { overflow-x: auto; }
.chart-scroll[tabindex] { border-radius: var(--radius-sm); }
.chart-scroll--w1100 .chart { min-width: 1100px; }
.chart-scroll--w1400 .chart { min-width: 1400px; }
.chart-scroll--w2400 .chart { min-width: 2400px; }
.chart-scroll--w3240 .chart { min-width: 3240px; }

/* --------------------------------------------------- console interne (6c) -- */

/* Tuile d'indicateur qui mène à l'écran concerné. */
a.stat--link { color: inherit; text-decoration: none; }
a.stat--link:hover { border-color: var(--accent); }
.stat--warning { border-left: 3px solid var(--warning-solid); }
.stat--danger { border-left: 3px solid var(--danger-solid); }

/* Détails d'audit ou d'événement repliés : le texte est celui d'un client, borné, jamais interprété. */
.audit-details summary { cursor: pointer; color: var(--accent); font-size: 12px; min-height: var(--control-sm); display: flex; align-items: center; }
.audit-details__body {
  margin-top: var(--space-1); padding: var(--space-2); max-width: 60ch; max-height: 240px; overflow: auto;
  white-space: pre-wrap; word-break: break-word; font-family: var(--font-mono); font-size: 12px; line-height: 16px;
  background: var(--surface-sunken); border: 1px solid var(--border); border-radius: var(--radius-sm);
}

/* Formulaire de suspension déployé dans une ligne de tableau. */
.inline-action summary { cursor: pointer; color: var(--danger); font-weight: 600; min-height: var(--control-sm); display: flex; align-items: center; }
.inline-action[open] { min-width: 260px; padding: var(--space-2) 0; }

/* Tableau DNS : la valeur d'un enregistrement (une clé DKIM fait ~400 caractères) garde une largeur
   lisible, et le détail du dernier contrôle (texte externe, souvent long) passe à la ligne au lieu
   d'élargir la colonne de statut et de pousser le tableau hors de sa carte. */
.dns .dns__value { min-width: 16rem; }
.dns .dns__status { min-width: 8rem; max-width: 16rem; overflow-wrap: anywhere; }
.dns td:nth-child(2) { overflow-wrap: anywhere; }  /* le nom : ~40 caractères en mono */

/* Espacement vertical utilitaire (légende sous un bloc de paires clé/valeur). */
.u-mt-3 { margin-top: var(--space-3); }
