/* ==========================================================================
   dnstools.oxmo.org — feuille de style unique
   ==========================================================================

   AUCUNE RESSOURCE EXTERNE. Pas de CDN, pas de police distante, pas d'image
   hebergee ailleurs. C'est ce qui permet la CSP stricte du vhost
   (default-src 'self') : la moindre @import vers un tiers la ferait echouer,
   et le symptome serait une page nue sans erreur visible cote serveur.

   LES DEUX THEMES SONT COMPLETS. Le theme clair est defini sur :root nu, le
   sombre est redefini a DEUX endroits :
     - @media (prefers-color-scheme: dark) garde par :not([data-theme="light"])
     - :root[data-theme="dark"]
   Les deux sont necessaires. Sans le premier, un visiteur qui n'a jamais
   touche a la bascule reste en clair alors que son systeme est en sombre.
   Sans le second, la bascule ne peut pas forcer le sombre chez quelqu'un dont
   le systeme est en clair. La garde :not([data-theme="light"]) est ce qui
   permet a la bascule de forcer le CLAIR chez quelqu'un dont le systeme est en
   sombre -- sans elle, le media query l'emporterait.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. Jetons — theme clair
   -------------------------------------------------------------------------- */
:root {
	color-scheme: light;

	/* Fonds, du plus profond au plus proche */
	--bg:            #f6f7fb;
	--bg-tint:       #eef1f8;
	--surface:       #ffffff;
	--surface-2:     #f9fafc;
	--surface-hover: #f1f4fa;

	/* Texte */
	--text:      #16181d;
	--text-soft: #4a5160;
	--text-dim:  #767e8f;

	/* Traits */
	--line:        #e2e6ef;
	--line-strong: #cdd4e2;

	/* Accent — un cyan profond, choisi pour tenir le contraste AA sur fond
	   blanc ET sur fond sombre sans changer de teinte, ce qui evite d'avoir
	   deux identites de marque selon le theme. */
	--accent:      #0a7ea4;
	--accent-soft: #e3f2f8;
	--accent-text: #075f7c;
	--accent-on:   #ffffff;

	/* Severites — les quatre seules couleurs qui portent du sens.
	   Chaque niveau a un fond, un trait et un texte, tous verifies AA. */
	--ok:         #0f7b46;
	--ok-bg:      #e6f5ed;
	--ok-line:    #a8dcc1;
	--info:       #1c62c4;
	--info-bg:    #e8f0fd;
	--info-line:  #b3cdf4;
	--warn:       #9a6100;
	--warn-bg:    #fdf2dd;
	--warn-line:  #ecd08a;
	--problem:    #bb2033;
	--problem-bg: #fdeaec;
	--problem-line:#f3bcc3;

	/* Elevation — tres discrete en clair, remplacee par la lumiere en sombre */
	--shadow-sm: 0 1px 2px rgba(16, 24, 40, .05);
	--shadow:    0 4px 16px -4px rgba(16, 24, 40, .1), 0 2px 6px -2px rgba(16, 24, 40, .06);
	--shadow-lg: 0 20px 48px -12px rgba(16, 24, 40, .18);

	/* Halo decoratif de l'en-tete de page */
	--glow-1: rgba(10, 126, 164, .12);
	--glow-2: rgba(99, 91, 255, .10);

	/* Geometrie */
	--r-sm: 8px;
	--r:    12px;
	--r-lg: 18px;
	--r-xl: 26px;

	--fs-mono: ui-monospace, "SF Mono", "SFMono-Regular", "Cascadia Mono",
	           "JetBrains Mono", "Fira Mono", Menlo, Consolas, monospace;
	--fs-ui:   system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue",
	           "Noto Sans", sans-serif;

	--wrap: 1140px;
}

/* --------------------------------------------------------------------------
   2. Jetons — theme sombre
   -------------------------------------------------------------------------- */
@media (prefers-color-scheme: dark) {
	:root:not([data-theme="light"]) {
		color-scheme: dark;

		--bg:            #0a0e17;
		--bg-tint:       #0d1220;
		--surface:       #121826;
		--surface-2:     #161d2e;
		--surface-hover: #1b2437;

		--text:      #e8ecf4;
		--text-soft: #a6b0c4;
		--text-dim:  #7b8699;

		--line:        #232c40;
		--line-strong: #33405c;

		--accent:      #38bdf8;
		--accent-soft: #0d2c3c;
		--accent-text: #7dd3fc;
		--accent-on:   #04141d;

		--ok:         #3ddc97;
		--ok-bg:      #0d2a1e;
		--ok-line:    #1e5a3f;
		--info:       #7dabff;
		--info-bg:    #131f38;
		--info-line:  #2b4573;
		--warn:       #f5c451;
		--warn-bg:    #2c2312;
		--warn-line:  #614c1c;
		--problem:    #ff7183;
		--problem-bg: #331520;
		--problem-line:#6d2536;

		--shadow-sm: 0 1px 2px rgba(0, 0, 0, .4);
		--shadow:    0 4px 20px -4px rgba(0, 0, 0, .55);
		--shadow-lg: 0 24px 56px -12px rgba(0, 0, 0, .7);

		--glow-1: rgba(56, 189, 248, .16);
		--glow-2: rgba(129, 106, 255, .14);
	}
}

:root[data-theme="dark"] {
	color-scheme: dark;

	--bg:            #0a0e17;
	--bg-tint:       #0d1220;
	--surface:       #121826;
	--surface-2:     #161d2e;
	--surface-hover: #1b2437;

	--text:      #e8ecf4;
	--text-soft: #a6b0c4;
	--text-dim:  #7b8699;

	--line:        #232c40;
	--line-strong: #33405c;

	--accent:      #38bdf8;
	--accent-soft: #0d2c3c;
	--accent-text: #7dd3fc;
	--accent-on:   #04141d;

	--ok:         #3ddc97;
	--ok-bg:      #0d2a1e;
	--ok-line:    #1e5a3f;
	--info:       #7dabff;
	--info-bg:    #131f38;
	--info-line:  #2b4573;
	--warn:       #f5c451;
	--warn-bg:    #2c2312;
	--warn-line:  #614c1c;
	--problem:    #ff7183;
	--problem-bg: #331520;
	--problem-line:#6d2536;

	--shadow-sm: 0 1px 2px rgba(0, 0, 0, .4);
	--shadow:    0 4px 20px -4px rgba(0, 0, 0, .55);
	--shadow-lg: 0 24px 56px -12px rgba(0, 0, 0, .7);

	--glow-1: rgba(56, 189, 248, .16);
	--glow-2: rgba(129, 106, 255, .14);
}

/* --------------------------------------------------------------------------
   3. Base
   -------------------------------------------------------------------------- */
*, *::before, *::after { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

@media (prefers-reduced-motion: reduce) {
	html { scroll-behavior: auto; }
	*, *::before, *::after {
		animation-duration: .01ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: .01ms !important;
	}
}

body {
	margin: 0;

	/* --------------------------------------------------------------------
	   PIED DE PAGE COLLE EN BAS
	   --------------------------------------------------------------------
	   Sur une page courte -- un outil avant qu'on lui soumette un domaine --
	   le contenu ne remplit pas l'ecran. Sans ce dispositif, le pied de page
	   se pose au milieu du vide avec une grande bande de fond en dessous : on
	   croit la page tronquee.

	   Trois morceaux INDISSOCIABLES : le corps en colonne flexible, sa hauteur
	   minimale a un ecran, et <main> qui absorbe la place restante (regle
	   "main { flex: 1 0 auto }" plus bas). Retirer l'un des trois suffit a
	   faire remonter le pied.

	   100dvh APRES 100vh, et non a la place : sur mobile, 100vh compte la
	   barre d'adresse comme si elle n'existait pas et fait depasser la page
	   d'une centaine de pixels. 100dvh suit la hauteur reellement visible. La
	   ligne 100vh reste comme repli -- un navigateur qui ignore dvh lit la
	   premiere et saute la seconde.
	   -------------------------------------------------------------------- */
	display: flex;
	flex-direction: column;
	min-height: 100vh;
	min-height: 100dvh;

	font-family: var(--fs-ui);
	font-size: 16px;
	line-height: 1.6;
	/* Fond explicite : la page est parfois rendue dans un cadre qui peint son
	   propre fond, un body transparent emprunterait alors celui de l'hote. */
	background: var(--bg);
	color: var(--text);
	-webkit-font-smoothing: antialiased;
	font-feature-settings: "kern" 1, "liga" 1;
	/* Le corps ne defile jamais horizontalement : les tableaux larges ont
	   leur propre conteneur (.scroll-x). */
	overflow-x: hidden;
}

/* Absorbe toute la hauteur libre, ce qui pousse le pied de page en bas.
   "1 0 auto" et non "1" : la base auto laisse le contenu dicter sa hauteur
   naturelle sur les pages longues, la croissance ne joue que sur les courtes.
   Avec la base 0 de "flex: 1", le contenu d'une page longue serait comprime. */
main { flex: 1 0 auto; }

h1, h2, h3, h4 {
	margin: 0 0 .5em;
	line-height: 1.22;
	letter-spacing: -.018em;
	font-weight: 650;
	text-wrap: balance;
}
h1 { font-size: clamp(1.9rem, 1.3rem + 2.4vw, 2.9rem); }
h2 { font-size: clamp(1.35rem, 1.1rem + 1vw, 1.75rem); }
h3 { font-size: 1.12rem; }

p { margin: 0 0 1em; text-wrap: pretty; }
p:last-child { margin-bottom: 0; }

a { color: var(--accent-text); text-decoration-thickness: 1px; text-underline-offset: 2px; }
a:hover { color: var(--accent); }

code, kbd, samp, pre { font-family: var(--fs-mono); font-size: .875em; }

:focus-visible {
	outline: 2px solid var(--accent);
	outline-offset: 2px;
	border-radius: 4px;
}

hr { border: 0; border-top: 1px solid var(--line); margin: 2rem 0; }

.wrap { width: 100%; max-width: var(--wrap); margin-inline: auto; padding-inline: clamp(1rem, 4vw, 2rem); }
.narrow { max-width: 780px; }

.visually-hidden {
	position: absolute; width: 1px; height: 1px;
	padding: 0; margin: -1px; overflow: hidden;
	clip-path: inset(50%); white-space: nowrap; border: 0;
}

.skip-link {
	position: absolute; left: 1rem; top: -4rem; z-index: 100;
	background: var(--accent); color: var(--accent-on);
	padding: .6rem 1rem; border-radius: var(--r-sm); font-weight: 600;
	transition: top .15s;
}
.skip-link:focus { top: 1rem; }

/* --------------------------------------------------------------------------
   4. En-tete
   -------------------------------------------------------------------------- */
.site-header {
	position: sticky; top: 0; z-index: 40;
	background: color-mix(in srgb, var(--bg) 82%, transparent);
	backdrop-filter: saturate(1.6) blur(14px);
	-webkit-backdrop-filter: saturate(1.6) blur(14px);
	border-bottom: 1px solid var(--line);
}
.site-header .wrap {
	display: flex; align-items: center; gap: 1rem;
	min-height: 62px;
}

.brand {
	display: inline-flex; align-items: center; gap: .58rem;
	font-weight: 680; font-size: 1.06rem; letter-spacing: -.02em;
	color: var(--text); text-decoration: none; flex: 0 0 auto;
}
.brand:hover { color: var(--text); }
.brand svg { width: 26px; height: 26px; flex: 0 0 auto; }
.brand .tld { color: var(--text-dim); font-weight: 500; }

.site-nav { margin-left: auto; display: flex; align-items: center; gap: .3rem; }

.nav-link {
	color: var(--text-soft); text-decoration: none;
	padding: .42rem .7rem; border-radius: var(--r-sm);
	font-size: .92rem; font-weight: 520;
	transition: background .14s, color .14s;
}
.nav-link:hover { background: var(--surface-hover); color: var(--text); }
.nav-link[aria-current="page"] { color: var(--accent-text); background: var(--accent-soft); }

.header-tools { display: flex; align-items: center; gap: .35rem; margin-left: .35rem; }

.icon-btn {
	display: inline-grid; place-items: center;
	width: 36px; height: 36px; padding: 0;
	border: 1px solid var(--line); border-radius: var(--r-sm);
	background: var(--surface); color: var(--text-soft);
	cursor: pointer; transition: background .14s, color .14s, border-color .14s;
}
.icon-btn:hover { background: var(--surface-hover); color: var(--text); border-color: var(--line-strong); }
.icon-btn svg { width: 17px; height: 17px; }

/* La bascule montre l'icone de la cible, pas de l'etat courant : en clair on
   propose la lune, en sombre le soleil. Les deux sont dans le DOM, une seule
   est visible — sans quoi il faudrait du JS pour permuter le balisage, et
   l'icone serait fausse pendant le premier rendu. */
.theme-toggle .i-sun  { display: none; }
.theme-toggle .i-moon { display: block; }
@media (prefers-color-scheme: dark) {
	:root:not([data-theme="light"]) .theme-toggle .i-sun  { display: block; }
	:root:not([data-theme="light"]) .theme-toggle .i-moon { display: none; }
}
:root[data-theme="dark"] .theme-toggle .i-sun  { display: block; }
:root[data-theme="dark"] .theme-toggle .i-moon { display: none; }

.lang-switch {
	display: inline-flex; align-items: center;
	border: 1px solid var(--line); border-radius: var(--r-sm);
	overflow: hidden; background: var(--surface); height: 36px;
}
.lang-switch a {
	padding: 0 .58rem; height: 100%; display: inline-grid; place-items: center;
	font-size: .78rem; font-weight: 650; letter-spacing: .04em;
	text-transform: uppercase; text-decoration: none; color: var(--text-dim);
	transition: background .14s, color .14s;
}
.lang-switch a:hover { background: var(--surface-hover); color: var(--text); }
.lang-switch a[aria-current="true"] { background: var(--accent); color: var(--accent-on); }

/* Navigation repliee sur petit ecran : le detail des 14 outils vit dans le
   menu deroulant, l'en-tete ne garde que la marque et les commandes. */
.nav-toggle { display: none; }
@media (max-width: 860px) {
	.site-nav .nav-link { display: none; }
	.nav-toggle { display: inline-grid; }
}

/* --------------------------------------------------------------------------
   5. Menu des outils (deroulant)
   -------------------------------------------------------------------------- */
.tool-menu { position: relative; }
.tool-menu-panel {
	position: absolute; right: 0; top: calc(100% + .5rem);
	width: min(92vw, 620px);
	background: var(--surface); border: 1px solid var(--line);
	border-radius: var(--r-lg); box-shadow: var(--shadow-lg);
	padding: .6rem; display: none; z-index: 50;
}
.tool-menu-panel[data-open="true"] { display: grid; }
@media (min-width: 620px) { .tool-menu-panel[data-open="true"] { grid-template-columns: 1fr 1fr; gap: .15rem; } }

.tool-menu-panel a {
	display: block; padding: .5rem .65rem; border-radius: var(--r-sm);
	text-decoration: none; color: var(--text);
}
.tool-menu-panel a:hover { background: var(--surface-hover); }
.tool-menu-panel .tm-name { font-weight: 580; font-size: .93rem; display: block; }
.tool-menu-panel .tm-desc { color: var(--text-dim); font-size: .8rem; display: block; line-height: 1.4; }

/* --------------------------------------------------------------------------
   6. Zone d'en-tete de page (hero)
   -------------------------------------------------------------------------- */
.hero {
	position: relative;
	padding: clamp(2.6rem, 7vw, 5rem) 0 clamp(2rem, 4vw, 3rem);
	overflow: hidden;
}
/* Deux halos de couleur tres diffus. En clair ils se voient a peine, en
   sombre ils remplacent l'ombre portee pour donner de la profondeur. */
.hero::before {
	content: ""; position: absolute; inset: -40% -10% auto -10%; height: 130%;
	background:
		radial-gradient(52% 60% at 22% 12%, var(--glow-1), transparent 68%),
		radial-gradient(46% 56% at 82% 4%,  var(--glow-2), transparent 66%);
	pointer-events: none; z-index: 0;
}
.hero > * { position: relative; z-index: 1; }

.hero h1 { margin-bottom: .45rem; }
.hero .lede {
	font-size: clamp(1rem, .95rem + .35vw, 1.16rem);
	color: var(--text-soft); max-width: 62ch; margin-bottom: 1.8rem;
}

.eyebrow {
	display: inline-flex; align-items: center; gap: .45rem;
	font-size: .78rem; font-weight: 620; letter-spacing: .06em;
	text-transform: uppercase; color: var(--accent-text);
	background: var(--accent-soft); border: 1px solid color-mix(in srgb, var(--accent) 22%, transparent);
	padding: .3rem .7rem; border-radius: 999px; margin-bottom: 1rem;
}
.eyebrow .dot {
	width: 6px; height: 6px; border-radius: 50%; background: var(--accent);
	box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 20%, transparent);
}

/* --------------------------------------------------------------------------
   7. Formulaires
   -------------------------------------------------------------------------- */
.field-row {
	display: flex; gap: .5rem; flex-wrap: wrap;
	max-width: 660px;
}
.field-row .grow { flex: 1 1 240px; min-width: 0; }

label { display: block; font-size: .84rem; font-weight: 580; color: var(--text-soft); margin-bottom: .3rem; }
.hint { font-size: .82rem; color: var(--text-dim); margin-top: .35rem; }

input[type="text"], input[type="url"], input[type="email"], input[type="number"],
select, textarea {
	width: 100%;
	font: inherit; font-size: .97rem;
	padding: .68rem .85rem;
	color: var(--text); background: var(--surface);
	border: 1px solid var(--line-strong); border-radius: var(--r);
	transition: border-color .14s, box-shadow .14s, background .14s;
}
input::placeholder, textarea::placeholder { color: var(--text-dim); }
input:focus, select:focus, textarea:focus {
	outline: none;
	border-color: var(--accent);
	box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 20%, transparent);
}
textarea { min-height: 190px; resize: vertical; font-family: var(--fs-mono); font-size: .84rem; line-height: 1.55; }

select {
	appearance: none;
	background-image: linear-gradient(45deg, transparent 50%, currentColor 50%),
	                  linear-gradient(135deg, currentColor 50%, transparent 50%);
	background-position: calc(100% - 17px) calc(50% + 1px), calc(100% - 12px) calc(50% + 1px);
	background-size: 5px 5px, 5px 5px;
	background-repeat: no-repeat;
	padding-right: 2.2rem;
}

.check {
	display: flex; align-items: flex-start; gap: .55rem;
	margin-bottom: .55rem; font-size: .92rem; color: var(--text);
}
.check input { width: auto; margin-top: .28rem; accent-color: var(--accent); flex: 0 0 auto; }
.check label { margin: 0; font-weight: 500; color: var(--text); font-size: .92rem; }

fieldset { border: 1px solid var(--line); border-radius: var(--r); padding: 1rem 1.1rem; margin: 0 0 1.1rem; }
legend { font-size: .84rem; font-weight: 640; color: var(--text-soft); padding-inline: .4rem; }

/* Boutons */
.btn {
	display: inline-flex; align-items: center; justify-content: center; gap: .45rem;
	font: inherit; font-size: .95rem; font-weight: 600;
	padding: .68rem 1.25rem; border-radius: var(--r);
	border: 1px solid transparent; cursor: pointer;
	background: var(--accent); color: var(--accent-on);
	text-decoration: none; white-space: nowrap;
	transition: filter .14s, transform .08s, box-shadow .14s;
}
.btn:hover { filter: brightness(1.08); color: var(--accent-on); }
.btn:active { transform: translateY(1px); }
.btn svg { width: 16px; height: 16px; }

.btn-ghost {
	background: var(--surface); color: var(--text); border-color: var(--line-strong);
}
.btn-ghost:hover { background: var(--surface-hover); color: var(--text); filter: none; }

.btn-sm { padding: .4rem .75rem; font-size: .85rem; border-radius: var(--r-sm); }

/* --------------------------------------------------------------------------
   8. Cartes et grilles
   -------------------------------------------------------------------------- */
.card {
	background: var(--surface);
	border: 1px solid var(--line);
	border-radius: var(--r-lg);
	padding: 1.35rem 1.45rem;
	box-shadow: var(--shadow-sm);
}
.card + .card { margin-top: 1rem; }
.card h2, .card h3 { margin-top: 0; }

.card-head {
	display: flex; align-items: center; justify-content: space-between;
	gap: 1rem; flex-wrap: wrap; margin-bottom: 1rem;
}
.card-head h2, .card-head h3 { margin-bottom: 0; }

.grid { display: grid; gap: 1rem; }
.grid-2 { grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); }
.grid-3 { grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); }

/* Carte d'outil de la page d'accueil */
.tool-card {
	display: flex; flex-direction: column; gap: .4rem;
	padding: 1.15rem 1.25rem;
	background: var(--surface); border: 1px solid var(--line);
	border-radius: var(--r-lg); text-decoration: none; color: var(--text);
	position: relative; overflow: hidden;
	transition: border-color .16s, transform .16s, box-shadow .16s, background .16s;
}
.tool-card:hover {
	border-color: color-mix(in srgb, var(--accent) 45%, var(--line));
	transform: translateY(-2px);
	box-shadow: var(--shadow);
	color: var(--text);
}
.tool-card .tc-icon {
	width: 34px; height: 34px; border-radius: 10px;
	display: grid; place-items: center; margin-bottom: .3rem;
	background: var(--accent-soft); color: var(--accent-text);
	border: 1px solid color-mix(in srgb, var(--accent) 18%, transparent);
}
.tool-card .tc-icon svg { width: 17px; height: 17px; }
.tool-card .tc-name { font-weight: 620; font-size: 1rem; letter-spacing: -.01em; }
.tool-card .tc-desc { color: var(--text-dim); font-size: .875rem; line-height: 1.5; }
.tool-card .tc-arrow {
	margin-top: .35rem; color: var(--accent-text); font-size: .85rem; font-weight: 600;
	opacity: 0; transform: translateX(-4px); transition: opacity .16s, transform .16s;
}
.tool-card:hover .tc-arrow { opacity: 1; transform: translateX(0); }

.section-label {
	font-size: .78rem; font-weight: 660; letter-spacing: .08em;
	text-transform: uppercase; color: var(--text-dim);
	margin: 2.5rem 0 .9rem;
}

/* --------------------------------------------------------------------------
   9. Jauge de score
   -------------------------------------------------------------------------- */
.score-block {
	display: flex; align-items: center; gap: clamp(1rem, 3vw, 2.2rem);
	flex-wrap: wrap;
}
.gauge { position: relative; width: 148px; height: 148px; flex: 0 0 auto; }
.gauge svg { width: 100%; height: 100%; transform: rotate(-90deg); }
.gauge .track { fill: none; stroke: var(--line); stroke-width: 11; }
.gauge .value {
	fill: none; stroke-width: 11; stroke-linecap: round;
	stroke: var(--gauge-color, var(--accent));
	/* Anime par transition sur stroke-dashoffset : le JS pose la valeur
	   finale apres le premier rendu. Sans JS, la valeur est deja correcte
	   dans l'attribut, l'arc s'affiche simplement sans animation. */
	transition: stroke-dashoffset 1s cubic-bezier(.22, 1, .36, 1);
}
.gauge .readout {
	position: absolute; inset: 0;
	display: grid; place-content: center; text-align: center;
}
.gauge .readout .n {
	font-size: 2.5rem; font-weight: 700; line-height: 1;
	letter-spacing: -.03em; font-variant-numeric: tabular-nums;
	color: var(--gauge-color, var(--accent));
}
.gauge .readout .d { font-size: .74rem; color: var(--text-dim); letter-spacing: .06em; text-transform: uppercase; }

.score-summary { display: flex; gap: .55rem; flex-wrap: wrap; margin-top: .9rem; }
.tally {
	display: inline-flex; align-items: center; gap: .4rem;
	padding: .3rem .7rem; border-radius: 999px;
	font-size: .84rem; font-weight: 580;
	border: 1px solid var(--line); background: var(--surface-2); color: var(--text-soft);
}
.tally .n { font-variant-numeric: tabular-nums; font-weight: 700; }
.tally[data-sev="ok"]      { color: var(--ok);      background: var(--ok-bg);      border-color: var(--ok-line); }
.tally[data-sev="info"]    { color: var(--info);    background: var(--info-bg);    border-color: var(--info-line); }
.tally[data-sev="warn"]    { color: var(--warn);    background: var(--warn-bg);    border-color: var(--warn-line); }
.tally[data-sev="problem"] { color: var(--problem); background: var(--problem-bg); border-color: var(--problem-line); }

/* --------------------------------------------------------------------------
   10. Constats
   -------------------------------------------------------------------------- */
.finding {
	position: relative;
	background: var(--surface); border: 1px solid var(--line);
	border-radius: var(--r); padding: .95rem 1.1rem .95rem 1.35rem;
	margin-bottom: .6rem; overflow: hidden;
}
/* Rail colore a gauche : c'est le repere principal quand on parcourt une
   liste de vingt constats sans les lire. */
.finding::before {
	content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 4px;
	background: var(--sev, var(--line-strong));
}
.finding[data-sev="ok"]      { --sev: var(--ok); }
.finding[data-sev="info"]    { --sev: var(--info); }
.finding[data-sev="warn"]    { --sev: var(--warn); }
.finding[data-sev="problem"] { --sev: var(--problem); }

.finding-head { display: flex; align-items: flex-start; gap: .6rem; }
.finding-head .sev-icon { flex: 0 0 auto; width: 18px; height: 18px; margin-top: .16rem; color: var(--sev); }
.finding-title { font-weight: 600; font-size: .98rem; letter-spacing: -.005em; }
.finding-detail { color: var(--text-soft); font-size: .9rem; margin-top: .2rem; }

.finding-fix {
	margin-top: .7rem; padding-top: .7rem;
	border-top: 1px dashed var(--line);
	font-size: .88rem; color: var(--text-soft);
}
.finding-fix strong { color: var(--text); font-weight: 600; }

/* --------------------------------------------------------------------------
   11. Enregistrements et valeurs monospace
   -------------------------------------------------------------------------- */
.record {
	position: relative;
	display: flex; align-items: flex-start; gap: .6rem;
	background: var(--surface-2); border: 1px solid var(--line);
	border-radius: var(--r-sm); padding: .6rem .75rem;
	font-family: var(--fs-mono); font-size: .82rem; line-height: 1.55;
	word-break: break-all; margin-top: .55rem;
}
.record .rec-body { flex: 1 1 auto; min-width: 0; }
.record .rec-meta {
	display: block; font-family: var(--fs-ui); font-size: .74rem;
	color: var(--text-dim); margin-bottom: .18rem; letter-spacing: .03em;
	text-transform: uppercase; word-break: normal;
}

.copy-btn {
	flex: 0 0 auto; display: inline-grid; place-items: center;
	width: 28px; height: 28px; padding: 0;
	border: 1px solid var(--line); border-radius: 6px;
	background: var(--surface); color: var(--text-dim);
	cursor: pointer; transition: color .14s, border-color .14s, background .14s;
}
.copy-btn:hover { color: var(--accent-text); border-color: var(--accent); background: var(--accent-soft); }
.copy-btn svg { width: 14px; height: 14px; }
.copy-btn[data-copied="true"] { color: var(--ok); border-color: var(--ok-line); background: var(--ok-bg); }

/* --------------------------------------------------------------------------
   12. Tableaux
   -------------------------------------------------------------------------- */
/* Tout tableau large vit dans ce conteneur. C'est lui qui defile, jamais le
   corps de page — verifie a 360 px. */
.scroll-x {
	overflow-x: auto;
	-webkit-overflow-scrolling: touch;
	border: 1px solid var(--line); border-radius: var(--r);
	background: var(--surface);
}
.scroll-x > table { border: 0; margin: 0; }

table { width: 100%; border-collapse: collapse; font-size: .89rem; }
th, td {
	text-align: left; padding: .6rem .8rem;
	border-bottom: 1px solid var(--line); vertical-align: top;
}
thead th {
	font-size: .74rem; font-weight: 660; letter-spacing: .05em;
	text-transform: uppercase; color: var(--text-dim);
	background: var(--surface-2); white-space: nowrap;
	position: sticky; top: 0; z-index: 1;
}
tbody tr:last-child td { border-bottom: 0; }
tbody tr:hover { background: var(--surface-hover); }
td.mono, .mono { font-family: var(--fs-mono); font-size: .82rem; word-break: break-all; }
td.num, .num { font-variant-numeric: tabular-nums; text-align: right; white-space: nowrap; }
td.nowrap, .nowrap { white-space: nowrap; }

/* --------------------------------------------------------------------------
   13. Pastilles d'etat
   -------------------------------------------------------------------------- */
.pill {
	display: inline-flex; align-items: center; gap: .32rem;
	padding: .16rem .55rem; border-radius: 999px;
	font-size: .76rem; font-weight: 620; letter-spacing: .01em;
	border: 1px solid var(--line); background: var(--surface-2); color: var(--text-soft);
	white-space: nowrap;
}
.pill[data-sev="ok"]      { color: var(--ok);      background: var(--ok-bg);      border-color: var(--ok-line); }
.pill[data-sev="info"]    { color: var(--info);    background: var(--info-bg);    border-color: var(--info-line); }
.pill[data-sev="warn"]    { color: var(--warn);    background: var(--warn-bg);    border-color: var(--warn-line); }
.pill[data-sev="problem"] { color: var(--problem); background: var(--problem-bg); border-color: var(--problem-line); }
.pill .dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; flex: 0 0 auto; }

/* --------------------------------------------------------------------------
   14. Encarts
   -------------------------------------------------------------------------- */
.note {
	border: 1px solid var(--line); border-left: 3px solid var(--accent);
	background: var(--surface-2); border-radius: var(--r);
	padding: .85rem 1.05rem; font-size: .9rem; color: var(--text-soft);
	margin: 1rem 0;
}
.note strong { color: var(--text); }
.note[data-sev="warn"]    { border-left-color: var(--warn);    background: var(--warn-bg); }
.note[data-sev="problem"] { border-left-color: var(--problem); background: var(--problem-bg); }
.note[data-sev="ok"]      { border-left-color: var(--ok);      background: var(--ok-bg); }

.empty {
	text-align: center; padding: 2.5rem 1rem;
	color: var(--text-dim); font-size: .95rem;
}

/* --------------------------------------------------------------------------
   15. Onglets
   -------------------------------------------------------------------------- */
.tabs {
	display: flex; gap: .2rem; border-bottom: 1px solid var(--line);
	margin-bottom: 1.2rem; overflow-x: auto;
}
.tabs a, .tabs button {
	padding: .55rem .9rem; border: 0; background: none; cursor: pointer;
	font: inherit; font-size: .9rem; font-weight: 560; color: var(--text-dim);
	border-bottom: 2px solid transparent; margin-bottom: -1px;
	text-decoration: none; white-space: nowrap;
	transition: color .14s, border-color .14s;
}
.tabs a:hover, .tabs button:hover { color: var(--text); }
.tabs [aria-selected="true"], .tabs [aria-current="page"] {
	color: var(--accent-text); border-bottom-color: var(--accent);
}

/* --------------------------------------------------------------------------
   16. Indicateur de chargement
   -------------------------------------------------------------------------- */
.loading {
	display: inline-flex; align-items: center; gap: .5rem;
	color: var(--text-dim); font-size: .88rem;
}
.spinner {
	width: 15px; height: 15px; flex: 0 0 auto;
	border: 2px solid var(--line-strong); border-top-color: var(--accent);
	border-radius: 50%; animation: spin .7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

.skeleton {
	background: linear-gradient(90deg, var(--surface-2) 25%, var(--surface-hover) 50%, var(--surface-2) 75%);
	background-size: 200% 100%;
	animation: shimmer 1.4s ease-in-out infinite;
	border-radius: var(--r-sm); height: 1em;
}
@keyframes shimmer { to { background-position: -200% 0; } }

/* --------------------------------------------------------------------------
   17. Pied de page
   -------------------------------------------------------------------------- */
.site-footer {
	margin-top: 4rem; padding: 2.2rem 0 2.8rem;
	border-top: 1px solid var(--line);
	background: var(--bg-tint);
	font-size: .88rem; color: var(--text-dim);
}
.site-footer .wrap { display: flex; gap: 1rem; flex-wrap: wrap; align-items: center; justify-content: space-between; }
.site-footer a { color: var(--text-soft); text-decoration: none; }
.site-footer a:hover { color: var(--accent-text); text-decoration: underline; }
.footer-links { display: flex; gap: 1.1rem; flex-wrap: wrap; }

/* --------------------------------------------------------------------------
   18. Utilitaires
   -------------------------------------------------------------------------- */
.stack > * + * { margin-top: 1rem; }
.stack-sm > * + * { margin-top: .5rem; }
.row { display: flex; gap: .6rem; align-items: center; flex-wrap: wrap; }
.muted { color: var(--text-dim); }
.soft  { color: var(--text-soft); }
.small { font-size: .85rem; }
.tnum  { font-variant-numeric: tabular-nums; }
.mt-0 { margin-top: 0; } .mb-0 { margin-bottom: 0; }
.mt-2 { margin-top: 2rem; }

@media print {
	.site-header, .site-footer, .copy-btn, .btn { display: none !important; }
	body { background: #fff; color: #000; }
	.card, .finding { break-inside: avoid; border-color: #ccc; }
}

/* --------------------------------------------------------------------------
   19. Constats qui pesent sur la note
   --------------------------------------------------------------------------
   Ajoute le 2026-08-17. La severite seule ne disait pas ce qui coutait des
   points : "info" recouvre a la fois un defaut mineur qui fait baisser la note
   et une simple remarque qui n'y touche pas. Les deux etaient rendus a
   l'identique, si bien qu'un domaine sortait a 95 "avec que des ok et des
   info" sans qu'on puisse voir ou etaient passes les cinq points manquants.

   La regle de lecture est desormais celle de la couleur du rail :

     vert    conforme, rien a signaler
     gris    remarque sans effet sur la note
     orange  fait perdre des points
     rouge   probleme, fait perdre beaucoup de points

   L'attribut data-cost n'est present que si le cout est superieur a zero,
   c'est lui qui commande la bascule.
   -------------------------------------------------------------------------- */

/* Neutre : rail gris, teinte volontairement effacee. Le lecteur doit pouvoir
   sauter ces constats du regard. */
.finding[data-sev="info"]:not([data-cost]) { --sev: var(--line-strong); }
.finding[data-sev="info"]:not([data-cost]) .sev-icon { color: var(--text-dim); }

/* Coute des points : orange, quelle que soit la severite nominale. Un "info"
   qui fait perdre 4 points se lit alors comme ce qu'il est -- quelque chose a
   regarder -- et non comme une remarque anodine. */
.finding[data-sev="info"][data-cost] { --sev: var(--warn); }
.finding[data-sev="info"][data-cost] .sev-icon { color: var(--warn); }

/* Le rail des constats qui coutent est plus large : la difference se voit en
   parcourant la page sans lire, ce qui est precisement l'usage. */
.finding[data-cost]::before { width: 5px; }

/* Etiquette du cout, a droite du titre. */
.cost {
	display: inline-block;
	margin-left: .5rem;
	padding: .05rem .45rem;
	border-radius: 999px;
	font-size: .72rem;
	font-weight: 680;
	letter-spacing: .01em;
	white-space: nowrap;
	font-variant-numeric: tabular-nums;
	vertical-align: .08em;
	color: var(--warn);
	background: var(--warn-bg);
	border: 1px solid var(--warn-line);
}
.finding[data-sev="problem"] .cost {
	color: var(--problem);
	background: var(--problem-bg);
	border-color: var(--problem-line);
}


/* --------------------------------------------------------------------------
   20. Donnees observees dans un constat
   --------------------------------------------------------------------------
   Ajoute le 2026-08-17. Les constats enoncaient un verdict sans montrer sur
   quoi il reposait : "2 serveurs de noms actifs" ne disait pas lesquels, et le
   lecteur ne pouvait ni verifier ni agir. Ce bloc affiche les valeurs
   reellement lues.

   Grille a deux colonnes : le libelle a gauche, cale sur la largeur du plus
   long, la valeur a droite. Une entree sans libelle occupe toute la largeur --
   c'est le cas des listes (serveurs de noms, MX), ou un libelle repete a
   chaque ligne serait du bruit.
   -------------------------------------------------------------------------- */
.evidence {
	display: grid;
	grid-template-columns: auto 1fr;
	gap: .15rem .8rem;
	margin: .7rem 0 0;
	padding: .55rem .75rem;
	background: var(--surface-2);
	border: 1px solid var(--line);
	border-radius: var(--r-sm);
	font-size: .82rem;
}
.evidence dt {
	color: var(--text-dim);
	font-family: var(--fs-ui);
	white-space: nowrap;
}
.evidence dd {
	margin: 0;
	font-family: var(--fs-mono);
	color: var(--text);
	/* break-all et non break-word : les valeurs sont des noms de domaine, des
	   adresses IP et des enregistrements, qui n'ont pas d'espaces ou coupure. */
	word-break: break-all;
}
.evidence dd.full { grid-column: 1 / -1; }
