/*
  AigleSpear, feuille de style du site.

  Applique la direction artistique : clair dominant, une seule couleur
  d'action, gris tièdes accordés à sa teinte, aucun dégradé, aucun halo,
  aucune ombre portée décorative. La hiérarchie tient sur des traits d'un
  pixel et sur du vide.

  Deux familles, deux fonctions strictes : Instrument Sans pour ce qui se
  lit, JetBrains Mono pour ce qui se mesure, empreintes, hachages, durées,
  libellés. Les deux sont servies par ce site, jamais par un tiers : une
  requête vers un hébergeur de polices divulguerait l'adresse du visiteur,
  ce qui serait difficile à défendre sur un produit qui parle de vie privée.

  Le mouvement sert la lecture : il ne décore pas.
*/

/* ── Polices ─────────────────────────────────────────────────────────── */

@font-face {
  font-family: 'Instrument Sans';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/vendor/fonts/instrument-sans-latin-400.woff2') format('woff2');
}
@font-face {
  font-family: 'Instrument Sans';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('/vendor/fonts/instrument-sans-latin-500.woff2') format('woff2');
}
@font-face {
  font-family: 'Instrument Sans';
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url('/vendor/fonts/instrument-sans-latin-600.woff2') format('woff2');
}
@font-face {
  font-family: 'Instrument Sans';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('/vendor/fonts/instrument-sans-latin-700.woff2') format('woff2');
}
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('/vendor/fonts/jetbrains-mono-latin-400.woff2') format('woff2');
}
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url('/vendor/fonts/jetbrains-mono-latin-500.woff2') format('woff2');
}
@font-face {
  font-family: 'JetBrains Mono';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('/vendor/fonts/jetbrains-mono-latin-700.woff2') format('woff2');
}

/* ── Jetons ──────────────────────────────────────────────────────────── */

:root {
  --papier: #ffffff;
  --papier-2: #faf8f6;
  --trait: #e7e2dd;
  --trait-fort: #d3ccc4;

  --encre: #1b1614;
  --encre-2: #57534e;
  --encre-3: #78716c;

  --braise: #c2410c;
  --braise-fonce: #7c2d12;
  --braise-voile: #fdf1e7;
  --braise-bord: #f3c9ac;

  --olive: #3f6212;
  --olive-voile: #f6f9ef;
  --olive-bord: #dce7c4;

  --r-xs: 4px;
  --r-sm: 6px;
  --r-md: 8px;

  --ease: cubic-bezier(0.22, 1, 0.36, 1);
  --fast: 180ms;
  --mid: 320ms;

  --mono: 'JetBrains Mono', ui-monospace, 'SF Mono', 'Cascadia Mono', Menlo, Consolas, monospace;
  --sans: 'Instrument Sans', system-ui, -apple-system, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
}

* {
  box-sizing: border-box;
}

/*
  Les lignes masquées le sont par l'attribut `hidden`, que le JS bascule.
  Sans cette règle, un `display` posé par ailleurs (grid, flex) l'emporterait
  sur la valeur `none` du navigateur et la ligne resterait visible.
*/
[hidden] {
  display: none !important;
}

html {
  scroll-behavior: smooth;
}

body {
  margin: 0;
  background: var(--papier);
  color: var(--encre);
  font-family: var(--sans);
  font-size: 15px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

a {
  color: var(--braise);
  text-decoration: none;
  position: relative;
}

/* Soulignement qui se déploie plutôt qu'un simple changement de couleur. */
a::after {
  content: '';
  position: absolute;
  left: 0;
  bottom: -2px;
  width: 100%;
  height: 1px;
  background: currentColor;
  transform: scaleX(0);
  transform-origin: right;
  transition: transform var(--fast) var(--ease);
}

a:hover::after {
  transform: scaleX(1);
  transform-origin: left;
}

/* Le focus reprend la couleur de la marque : un anneau bleu par défaut
   jurerait avec une identité chaude. */
:focus-visible {
  outline: 2px solid var(--braise);
  outline-offset: 2px;
  border-radius: 2px;
}

.wrap {
  max-width: 1080px;
  margin: 0 auto;
  padding: 0 24px;
}

.mono {
  font-family: var(--mono);
}

/* ── En-tête ─────────────────────────────────────────────────────────── */

header {
  border-bottom: 1px solid var(--trait);
  position: sticky;
  top: 0;
  /* Fond plein, pas de surface translucide floutée : la DA proscrit le
     verre dépoli, et un fond opaque reste lisible sur n'importe quel
     contenu qui défile dessous. */
  background: var(--papier);
  z-index: 20;
}

.head-in {
  display: flex;
  align-items: center;
  gap: 12px;
  height: 62px;
}

.mark {
  width: 22px;
  height: 22px;
  color: var(--braise);
  flex: none;
}

.brand {
  font-weight: 600;
  letter-spacing: 0.01em;
  font-size: 15px;
  text-transform: uppercase;
}

.head-spacer {
  flex: 1;
}

.head-meta {
  font-family: var(--mono);
  font-size: 12px;
  color: var(--encre-3);
}

.head-link {
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--encre-2);
}

.head-link:hover {
  color: var(--braise);
}

/* ── Hero ────────────────────────────────────────────────────────────── */

.hero {
  padding: 72px 0 48px;
  border-bottom: 1px solid var(--trait);
}

h1 {
  font-size: clamp(30px, 5vw, 44px);
  line-height: 1.08;
  letter-spacing: -0.03em;
  margin: 0 0 16px;
  font-weight: 600;
  max-width: 20ch;
}

.lede {
  color: var(--encre-2);
  max-width: 62ch;
  margin: 0;
  font-size: 16px;
}

/* Chaque mot du titre entre séparément, avec un léger décalage. */
.word {
  display: inline-block;
  will-change: transform, opacity;
}

.eyebrow {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--encre-3);
  margin: 0 0 14px;
}

/* ── Verdict ─────────────────────────────────────────────────────────── */

.verdict {
  margin: 36px 0 0;
  border: 1px solid var(--trait);
  border-radius: var(--r-md);
  background: var(--papier-2);
  padding: 22px 24px;
  display: flex;
  align-items: center;
  gap: 18px;
  flex-wrap: wrap;
  transition:
    border-color var(--mid) var(--ease),
    background var(--mid) var(--ease);
}

.verdict-icon {
  width: 30px;
  height: 30px;
  flex: none;
  color: var(--encre-3);
}

.verdict-text strong {
  display: block;
  font-size: 17px;
  letter-spacing: -0.015em;
  font-weight: 600;
}

.verdict-text span {
  color: var(--encre-2);
  font-size: 14px;
}

/*
  Progression monochrome plutôt que feu tricolore : laissé passer est
  l'état ordinaire et ne mérite aucune couleur criarde, signalé porte la
  braise, refusé la braise sombre. Un rouge distinct entrerait en collision
  avec la couleur de marque, qui est déjà celle du signal.
*/
.verdict[data-state='allow'] {
  border-color: var(--olive-bord);
  background: var(--olive-voile);
}
.verdict[data-state='allow'] .verdict-icon {
  color: var(--olive);
}
.verdict[data-state='challenge'] {
  border-color: var(--braise-bord);
  background: var(--braise-voile);
}
.verdict[data-state='challenge'] .verdict-icon {
  color: var(--braise);
}
.verdict[data-state='deny'] {
  border-color: var(--braise-fonce);
  background: var(--braise-voile);
}
.verdict[data-state='deny'] .verdict-icon {
  color: var(--braise-fonce);
}

/* ── Grille d'indicateurs ────────────────────────────────────────────── */

.stats {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
  gap: 14px;
  margin-top: 14px;
}

.stat {
  border: 1px solid var(--trait);
  border-radius: var(--r-md);
  background: var(--papier);
  padding: 16px 18px;
  transition:
    transform var(--fast) var(--ease),
    border-color var(--fast) var(--ease);
}

.stat:hover {
  transform: translateY(-2px);
  border-color: var(--trait-fort);
}

.stat-k {
  font-family: var(--mono);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.09em;
  color: var(--encre-3);
}

.stat-v {
  font-family: var(--mono);
  font-size: 19px;
  margin-top: 6px;
  word-break: break-all;
  line-height: 1.35;
  font-weight: 500;
}

.stat-v.small {
  font-size: 13px;
}

/* Jauge horizontale, sans dégradé : une barre pleine sur un rail. */
.gauge {
  height: 4px;
  background: var(--trait);
  border-radius: 2px;
  margin-top: 10px;
  overflow: hidden;
}

.gauge i {
  display: block;
  height: 100%;
  width: 0;
  background: var(--encre-3);
  transition: width 900ms var(--ease);
}

.gauge i[data-tone='ok'] {
  background: var(--olive);
}
.gauge i[data-tone='warn'] {
  background: var(--braise);
}
.gauge i[data-tone='danger'] {
  background: var(--braise-fonce);
}

/* ── Sections ────────────────────────────────────────────────────────── */

section {
  padding: 56px 0;
  border-bottom: 1px solid var(--trait);
}

h2 {
  font-size: 21px;
  letter-spacing: -0.02em;
  margin: 0 0 6px;
  font-weight: 600;
}

h3 {
  font-size: 15px;
  margin: 0 0 6px;
  font-weight: 600;
}

.sub {
  color: var(--encre-2);
  margin: 0 0 24px;
  max-width: 68ch;
  font-size: 14px;
}

.reveal {
  opacity: 0;
  transform: translateY(14px);
}

/* ── Tableaux ────────────────────────────────────────────────────────── */

.tablewrap {
  border: 1px solid var(--trait);
  border-radius: var(--r-md);
  overflow-x: auto;
  background: var(--papier);
}

table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
}

th {
  text-align: left;
  font-family: var(--mono);
  font-weight: 400;
  font-size: 10px;
  text-transform: uppercase;
  letter-spacing: 0.09em;
  color: var(--encre-3);
  padding: 11px 14px;
  border-bottom: 1px solid var(--trait);
  white-space: nowrap;
  position: sticky;
  top: 0;
  background: var(--papier-2);
}

td {
  padding: 10px 14px;
  border-bottom: 1px solid var(--trait);
  vertical-align: top;
}

tr:last-child td {
  border-bottom: 0;
}

tbody tr {
  transition: background var(--fast) var(--ease);
}

tbody tr:hover {
  background: var(--papier-2);
}

/* Une ligne signalée se marque par un fond teinté, jamais par une barre
   latérale : un bord accentué se cogne au rayon des angles. */
tbody tr.flagged {
  background: var(--braise-voile);
}

tbody tr.flagged:hover {
  background: #fbe6d6;
}

td.id {
  font-family: var(--mono);
  color: var(--encre);
  white-space: nowrap;
}

td.val {
  font-family: var(--mono);
  color: var(--encre-2);
  max-width: 420px;
  word-break: break-all;
}

td.num {
  font-family: var(--mono);
  text-align: right;
  color: var(--encre-2);
  white-space: nowrap;
}

.layer {
  display: inline-block;
  width: 18px;
  height: 18px;
  line-height: 17px;
  text-align: center;
  border-radius: var(--r-xs);
  font-family: var(--mono);
  font-size: 10px;
  border: 1px solid var(--trait-fort);
  color: var(--encre-3);
}

.layer[data-l='A'] {
  color: var(--braise-fonce);
  border-color: var(--braise-bord);
  background: var(--braise-voile);
}

.missing td {
  color: var(--encre-3);
}

/* ── Statuts ─────────────────────────────────────────────────────────── */

/*
  Carré, jamais rond ni pilule : le rayon circulaire adoucit, et ce produit
  ne doit pas paraître doux. Deux formes, encadrée pour une vue de détail,
  nue pour les vues denses, où deux cents pastilles encadrées feraient deux
  cents bruits.
*/
.statut {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  border: 1px solid var(--trait);
  background: var(--papier-2);
  border-radius: var(--r-xs);
  padding: 5px 10px;
  color: var(--encre-3);
  white-space: nowrap;
}

.statut i,
.st i {
  width: 6px;
  height: 6px;
  display: block;
  flex: none;
  background: currentColor;
}

.statut.ok {
  color: var(--olive);
  border-color: var(--olive-bord);
  background: var(--olive-voile);
}

.statut.warn {
  color: var(--braise-fonce);
  border-color: var(--braise-bord);
  background: var(--braise-voile);
}

.statut.warn i {
  background: var(--braise);
}

.statut.deny {
  color: var(--papier);
  background: var(--braise-fonce);
  border-color: var(--braise-fonce);
}

.st {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--mono);
  font-size: 12px;
  color: var(--encre-3);
  white-space: nowrap;
}

.st.ok {
  color: var(--olive);
}
.st.warn,
.st.deny {
  color: var(--braise-fonce);
}
.st.warn i {
  background: var(--braise);
}

/* ── Étiquettes de drapeaux ──────────────────────────────────────────── */

.flags {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.flag {
  border: 1px solid var(--trait);
  border-radius: var(--r-xs);
  padding: 6px 10px;
  font-family: var(--mono);
  font-size: 12px;
  color: var(--encre-2);
  background: var(--papier-2);
  display: flex;
  align-items: center;
  gap: 7px;
  transition:
    transform var(--fast) var(--ease),
    border-color var(--fast) var(--ease);
}

.flag:hover {
  transform: translateY(-1px);
  border-color: var(--trait-fort);
}

.flag svg {
  width: 13px;
  height: 13px;
  flex: none;
}

/* Une protection n'est pas une faute : elle reste neutre. Seules les
   manipulations portent la couleur du signal. */
.flag[data-tone='defense'] {
  color: var(--encre-2);
}
.flag[data-tone='warn'] {
  color: var(--braise-fonce);
  border-color: var(--braise-bord);
  background: var(--braise-voile);
}
.flag[data-tone='danger'] {
  color: var(--papier);
  border-color: var(--braise-fonce);
  background: var(--braise-fonce);
}

.empty {
  color: var(--encre-3);
  font-size: 14px;
}

/* ── Cartes ──────────────────────────────────────────────────────────── */

.cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
  gap: 14px;
}

.card {
  border: 1px solid var(--trait);
  border-radius: var(--r-md);
  background: var(--papier);
  padding: 20px;
  transition:
    transform var(--mid) var(--ease),
    border-color var(--mid) var(--ease);
}

.card:hover {
  transform: translateY(-3px);
  border-color: var(--trait-fort);
}

.card svg {
  width: 20px;
  height: 20px;
  color: var(--braise);
  margin-bottom: 12px;
}

.card p {
  margin: 0;
  color: var(--encre-2);
  font-size: 13.5px;
}

.card .expect {
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid var(--trait);
  font-size: 12.5px;
  color: var(--encre-3);
}

/* ── Boutons ─────────────────────────────────────────────────────────── */

button {
  font: inherit;
  font-size: 14px;
  font-weight: 600;
  background: var(--papier);
  color: var(--encre);
  border: 1px solid var(--trait);
  border-radius: var(--r-sm);
  padding: 9px 16px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  transition:
    transform var(--fast) var(--ease),
    border-color var(--fast) var(--ease),
    background var(--fast) var(--ease),
    color var(--fast) var(--ease);
}

button:hover {
  border-color: var(--encre);
}

button:active {
  transform: scale(0.97);
}

button svg {
  width: 15px;
  height: 15px;
}

/* Une seule action principale par écran, et elle seule porte la braise. */
button.primary {
  background: var(--braise);
  border-color: var(--braise);
  color: var(--papier);
}

button.primary:hover {
  background: var(--braise-fonce);
  border-color: var(--braise-fonce);
}

button.ghost {
  background: transparent;
  border-color: transparent;
  color: var(--encre-2);
  padding-left: 8px;
  padding-right: 8px;
}

button.ghost:hover {
  color: var(--braise);
  border-color: transparent;
}

button[disabled] {
  opacity: 0.5;
  cursor: not-allowed;
}

button[disabled]:hover {
  border-color: var(--trait);
}

.actions {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  margin-top: 20px;
}

/* ── Champs ──────────────────────────────────────────────────────────── */

input,
select {
  font: inherit;
  font-size: 14px;
  font-family: var(--mono);
  padding: 9px 12px;
  border: 1px solid var(--trait);
  border-radius: var(--r-sm);
  background: var(--papier);
  color: var(--encre);
  transition:
    border-color var(--fast) var(--ease),
    box-shadow var(--fast) var(--ease);
}

input::placeholder {
  color: var(--encre-3);
}

input:focus,
select:focus {
  outline: none;
  border-color: var(--braise);
  box-shadow: 0 0 0 3px var(--braise-voile);
}

.field {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.field > label {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--encre-3);
}

.form-row {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  align-items: flex-end;
}

.form-row .grow {
  flex: 1 1 220px;
}

/* ── Bandeaux ────────────────────────────────────────────────────────── */

.notice {
  border: 1px solid var(--braise-bord);
  border-radius: var(--r-sm);
  background: var(--braise-voile);
  padding: 16px 18px;
  display: flex;
  gap: 13px;
  align-items: flex-start;
  font-size: 13.5px;
  color: var(--encre-2);
  margin-bottom: 24px;
}

.notice svg {
  width: 17px;
  height: 17px;
  color: var(--braise);
  flex: none;
  margin-top: 2px;
}

.notice strong {
  color: var(--encre);
  font-weight: 600;
}

.notice.neutre {
  border-color: var(--trait);
  background: var(--papier-2);
}

.notice.neutre svg {
  color: var(--encre-3);
}

/* Message court sous une action : succès, erreur, attente. */
.statusline {
  font-family: var(--mono);
  font-size: 12px;
  color: var(--encre-3);
  min-height: 18px;
  margin: 12px 0 0;
}

.statusline.ok {
  color: var(--olive);
}
.statusline.ko {
  color: var(--braise-fonce);
}

/* ── Progression de l'analyse ────────────────────────────────────────── */

.scan {
  max-width: 520px;
}

/*
  L'élément natif est conservé, le script pilote sa propriété `value`, mais
  entièrement redessiné : une barre pleine sur un rail, sans dégradé ni relief.
*/
progress {
  appearance: none;
  -webkit-appearance: none;
  display: block;
  width: 100%;
  height: 3px;
  margin-top: 16px;
  border: 0;
  border-radius: 2px;
  background: var(--trait);
  overflow: hidden;
}

progress::-webkit-progress-bar {
  background: var(--trait);
}

progress::-webkit-progress-value {
  background: var(--braise);
  transition: width var(--mid) var(--ease);
}

progress::-moz-progress-bar {
  background: var(--braise);
}

.scan-step {
  font-family: var(--mono);
  font-size: 13px;
  color: var(--encre-2);
  margin: 0;
}

/* ── Liste descriptive du rapport ────────────────────────────────────── */

.dl {
  border: 1px solid var(--trait);
  border-radius: var(--r-md);
  overflow: hidden;
}

.dl-row {
  display: grid;
  grid-template-columns: 220px 1fr;
  gap: 20px;
  padding: 11px 16px;
  border-top: 1px solid var(--trait);
  align-items: baseline;
}

.dl-row:first-child {
  border-top: 0;
}

.dl-row:nth-child(even) {
  background: var(--papier-2);
}

.dl-row dt {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--encre-3);
}

.dl-row dd {
  margin: 0;
  font-family: var(--mono);
  font-size: 13px;
  word-break: break-word;
}

pre {
  font-family: var(--mono);
  font-size: 12px;
  line-height: 1.6;
  background: var(--papier-2);
  border: 1px solid var(--trait);
  border-radius: var(--r-sm);
  padding: 16px;
  overflow: auto;
  margin: 16px 0 0;
}

code {
  font-family: var(--mono);
}

/* ── Loader plein écran ──────────────────────────────────────────────── */

/*
  Écran de chargement épuré : le fond de la page, la marque au centre qui
  respire doucement, rien d'autre. Aucun texte, aucune étape, aucune barre.
  Present des le HTML, il couvre tout jusqu'a ce que la decision soit rendue,
  puis disparait et laisse le site apparaitre d'un coup.
*/
.loader {
  position: fixed;
  inset: 0;
  z-index: 50;
  background: var(--papier);
  display: flex;
  align-items: center;
  justify-content: center;
}

.loader-mark {
  width: 40px;
  height: 40px;
  color: var(--braise);
  display: block;
  animation: pulse-mark 1.15s var(--ease) infinite;
}

.loader-mark svg {
  width: 100%;
  height: 100%;
  display: block;
}

@keyframes pulse-mark {
  0%,
  100% {
    opacity: 0.35;
    transform: scale(0.9);
  }
  50% {
    opacity: 1;
    transform: scale(1);
  }
}

@media (prefers-reduced-motion: reduce) {
  .loader-mark {
    animation: none;
    opacity: 0.8;
  }
}

/* ── Page d'accueil ──────────────────────────────────────────────────── */

/*
  Une seule chose à lire, donc une seule colonne, centrée verticalement.
  Le reste du parcours, mesures, scores, signaux, vit dans la vue
  détaillée : cette page n'est pas un tableau de bord.
*/
.landing {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}

.landing main {
  flex: 1;
  display: flex;
  align-items: center;
  padding: 64px 24px;
}

.landing .bloc {
  width: 100%;
  max-width: 680px;
}

.landing section {
  padding: 0;
  border-bottom: 0;
  margin-top: 40px;
}

.landing h1 {
  margin-bottom: 18px;
}

.id-label {
  font-family: var(--mono);
  font-size: 11px;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--encre-3);
  margin: 0 0 10px;
}

/*
  L'identifiant est le seul contenu de la page : il en occupe donc la place.
  La taille est calée pour qu'un UUID de 36 caractères tienne sur une seule
  ligne à toutes les largeurs utiles, le laisser passer à la ligne isolait un
  caractère orphelin, ce qui se voit d'autant plus qu'il n'y a rien d'autre à
  regarder. La coupure reste autorisée à l'intérieur du mot en dernier
  recours : un identifiant n'a pas de césure naturelle.
*/
.id-valeur {
  font-family: var(--mono);
  font-weight: 500;
  font-size: clamp(13px, 3.3vw, 23px);
  line-height: 1.4;
  letter-spacing: -0.01em;
  margin: 0;
  padding: 20px 22px;
  border: 1px solid var(--trait);
  border-radius: var(--r-md);
  background: var(--papier-2);
  word-break: break-all;
}

/* ── Console d'administration ────────────────────────────────────────── */

/* Les identifiants et les nombres se comparent à l'œil : ils passent en
   monospace, le reste des colonnes garde la police de lecture. */
#visiteurs td,
#blocklist td {
  font-family: var(--mono);
  font-size: 12.5px;
}

#visiteurs td:first-child,
#blocklist td:nth-child(2) {
  color: var(--encre);
  word-break: break-all;
}

/* Une action de tableau reste discrète : elle ne concurrence pas l'action
   principale de la page. */
#visiteurs button,
#blocklist button {
  font-size: 12px;
  padding: 4px 10px;
  font-weight: 500;
}

#stats ul {
  margin: 0;
  padding: 0;
  list-style: none;
  border: 1px solid var(--trait);
  border-radius: var(--r-md);
  overflow: hidden;
}

#stats li {
  padding: 10px 16px;
  border-top: 1px solid var(--trait);
  font-size: 13.5px;
}

#stats > ul > li:first-child {
  border-top: 0;
}

#stats li ul {
  border: 0;
  border-radius: 0;
  margin-top: 8px;
}

#stats li li {
  font-family: var(--mono);
  font-size: 12px;
  color: var(--encre-2);
  padding: 5px 0 5px 14px;
  border-top: 0;
}

footer {
  padding: 40px 0 64px;
  color: var(--encre-3);
  font-size: 13px;
  border-top: 1px solid var(--trait);
}

/* ── Apparition ──────────────────────────────────────────────────────── */

.rise {
  animation: rise 480ms var(--ease) both;
}

@keyframes rise {
  from {
    opacity: 0;
    transform: translateY(12px);
  }
}

@media (max-width: 720px) {
  .dl-row {
    grid-template-columns: 1fr;
    gap: 4px;
  }
  .hero {
    padding: 48px 0 36px;
  }
}

/* Le mouvement est un confort, jamais une condition de lecture. */
@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    animation-duration: 0.001ms !important;
    transition-duration: 0.001ms !important;
  }

  .reveal,
  .word {
    opacity: 1 !important;
    transform: none !important;
  }
}
