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

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

   ---------------------------------------------------------------------------
   LA CHARTE VIENT DE www.forum.oxmo.org/map.php, STYLE « 2010 - GRIS »
   ---------------------------------------------------------------------------
   Valeurs relevees le 2026-08-18 dans la table replacement du forum, jeu 7 :

     #cbcbcb  fond de page        #444444  bordures
     #efefef  bloc                #646464  bandeau de titre, texte #ffffff
     #d6d6d6  alternance, filets  #767676  texte attenue
     #000000  texte               #636363  survol
     #8e8e8e  jauges

   Le forum est PLAT ET CARRE : bandeau de titre plein en tete de chaque bloc,
   bordure franche de 1 px, tables a filets, aucune ombre portee, aucun
   degrade.

   dns.oxmo.org SUIT LA MEME CHARTE depuis le 2026-08-19. Elle etait douce et
   ombree la-bas -- coins a 18 px, ombres portees, halos en degrade, accent
   bleu -- et les deux sites, qui se citent l'un l'autre dans leur barre et
   leur pied de page, semblaient etre de deux auteurs differents.

   Consequence : LES VALEURS CI-DESSOUS SONT PARTAGEES. Le verificateur de
   dns.oxmo.org compare ses jetons a ceux de ce fichier, nom par nom (les siens
   sont en anglais : --fond y est --bg, --tete y est --accent). Changer une
   couleur ici sans la changer la-bas fait echouer verifier.sh du voisin, ce
   qui est exactement le but : c'est le seul lien entre les deux depots.

   ---------------------------------------------------------------------------
   LE THEME SOMBRE N'EXISTE PAS DANS LE FORUM — IL EST DERIVE ICI
   ---------------------------------------------------------------------------
   Donc fragile : chaque jeton defini en clair DOIT l'etre en sombre, et
   reciproquement. Le verificateur du site compare les deux listes et echoue si
   elles different. Ne pas ajouter un jeton d'un seul cote.

   Le sombre est redefini a DEUX endroits, et les deux sont necessaires :
     - @media (prefers-color-scheme: dark), garde par :not([data-theme="light"])
     - :root[data-theme="dark"]
   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. 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;

	--fond:        #cbcbcb;
	--bloc:        #efefef;
	--alt:         #d6d6d6;
	--bord:        #444444;
	--bord-fin:    #b4b4b4;
	--tete:        #646464;
	--tete-txt:    #ffffff;
	--texte:       #000000;
	--attenue:     #767676;
	--lien:        #000000;
	--survol:      #636363;
	--jauge:       #8e8e8e;
	--champ:       #ffffff;
	--actif:       #f0b9a8;

	/* Severites — les seules couleurs qui portent du sens. */
	--ok:          #116600;
	--ok-fond:     #e3ecdf;
	--alerte:      #8a5200;
	--alerte-fond: #f3ead9;
	--ko:          #a8121f;
	--ko-fond:     #f2e0e1;

	/* La carte. Les teintes de terre et d'eau sont de la DONNEE de rendu, pas
	   de la chrome : elles changent entre les deux themes, mais l'epingle non
	   -- voir plus bas. */
	--carte-eau:   #cfe0ea;
	--carte-terre: #e9e5dd;
	--carte-trait: #9a9a9a;
	--carte-moi:   #f5e6c8;

	/* Les deux courbes du test de debit. Elles doivent se distinguer d'un coup
	   d'oeil ET rester lisibles sur les deux themes, d'ou deux teintes
	   franchement opposees plutot que deux nuances d'une meme famille. */
	--courbe-dl:   #116600;
	--courbe-ul:   #cc4c02;

	--police: verdana, tahoma, arial, helvetica, sans-serif;
	--mono:   ui-monospace, "SF Mono", "Cascadia Mono", "DejaVu Sans Mono", menlo, consolas, monospace;
	--large:  1180px;
}

/* --------------------------------------------------------------------------
   2. Jetons — theme sombre
   -------------------------------------------------------------------------- */
@media (prefers-color-scheme: dark) {
	:root:not([data-theme="light"]) {
		color-scheme: dark;
		--fond:        #1c1c1c;
		--bloc:        #262626;
		--alt:         #333333;
		--bord:        #565656;
		--bord-fin:    #414141;
		--tete:        #3a3a3a;
		--tete-txt:    #eaeaea;
		--texte:       #e8e8e8;
		--attenue:     #9d9d9d;
		--lien:        #e8e8e8;
		--survol:      #b5b5b5;
		--jauge:       #6f6f6f;
		--champ:       #1a1a1a;
		--actif:       #7a4030;
		--ok:          #7fc16a;
		--ok-fond:     #22301e;
		--alerte:      #d8a441;
		--alerte-fond: #33291a;
		--ko:          #e8797f;
		--ko-fond:     #331e20;
		--carte-eau:   #24333d;
		--carte-terre: #2c2c2a;
		--carte-trait: #6a6a6a;
		--carte-moi:   #453a24;
		--courbe-dl:   #7fc16a;
		--courbe-ul:   #ec7014;
	}
}
:root[data-theme="dark"] {
	color-scheme: dark;
	--fond:        #1c1c1c;
	--bloc:        #262626;
	--alt:         #333333;
	--bord:        #565656;
	--bord-fin:    #414141;
	--tete:        #3a3a3a;
	--tete-txt:    #eaeaea;
	--texte:       #e8e8e8;
	--attenue:     #9d9d9d;
	--lien:        #e8e8e8;
	--survol:      #b5b5b5;
	--jauge:       #6f6f6f;
	--champ:       #1a1a1a;
	--actif:       #7a4030;
	--ok:          #7fc16a;
	--ok-fond:     #22301e;
	--alerte:      #d8a441;
	--alerte-fond: #33291a;
	--ko:          #e8797f;
	--ko-fond:     #331e20;
	--carte-eau:   #24333d;
	--carte-terre: #2c2c2a;
	--carte-trait: #6a6a6a;
	--carte-moi:   #453a24;
	--courbe-dl:   #7fc16a;
	--courbe-ul:   #ec7014;
}

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

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

body {
	margin: 0;
	padding: 10px;
	background: var(--fond);
	color: var(--texte);
	font-family: var(--police);
	/* 13 px et non les 12 du forum : la page porte des tableaux de donnees
	   qu'on lit longtemps, la ou le forum affiche surtout des titres. La
	   famille et l'interligne sont ceux du forum, l'echelle est d'un cran. */
	font-size: 13px;
	line-height: 1.45;
}

a { color: var(--lien); text-decoration: none; }
a:hover { color: var(--survol); text-decoration: underline; }

h1, h2, h3 { font-family: inherit; }

code, kbd, samp, .mono { font-family: var(--mono); }

/* --------------------------------------------------------------------------
   LE PIED EST COLLE EN BAS DE L'ECRAN
   --------------------------------------------------------------------------
   Trois reglages solidaires, repris de dns.oxmo.org : la page est une colonne
   flex d'au moins une hauteur d'ecran, et main pousse en occupant le reste.
   Retirer l'un des trois suffit a faire remonter le pied au milieu d'une page
   courte -- un outil sans resultat n'a que son formulaire a montrer.

   La hauteur retranche les 20 px de padding du body, sans quoi la page
   depasserait d'autant et l'ecran defilerait sur une page qui tient pourtant.

   100dvh APRES 100vh, et non a la place : sur mobile, 100vh compte la barre
   d'adresse comme si elle n'existait pas. Un navigateur qui ignore dvh lit la
   premiere ligne et saute la seconde. */
.page {
	max-width: var(--large); margin: 0 auto;
	display: flex; flex-direction: column;
	min-height: calc(100vh - 20px);
	min-height: calc(100dvh - 20px);
}
/* base 0 refusee : avec "flex: 1", le contenu d'une page longue serait comprime. */
main { flex: 1 0 auto; }

/* --------------------------------------------------------------------------
   4. En-tete — calque sur celui de dns.oxmo.org
   --------------------------------------------------------------------------
   Les deux sites sont voisins et se renvoient l'un a l'autre. Leur en-tete a
   desormais la MEME GEOMETRIE : marque a gauche, boutons d'outils, puis a
   droite le menu, la bascule de langue et celle de theme. Seuls les jetons de
   couleur different -- ce site porte la charte grise du forum.

   L'EN-TETE NE DOIT JAMAIS DEBORDER. C'est une rangee sans retour a la ligne :
   sans garde, la somme des largeurs sort a droite des que l'ecran retrecit, et
   la bascule de theme finit hors champ. min-width: 0 sur la marque est la
   piece essentielle -- sans elle, un element flex refuse de descendre sous la
   largeur de son contenu, et aucune troncature ne peut s'appliquer.
   -------------------------------------------------------------------------- */
.site-header .wrap {
	display: flex; align-items: center; gap: 4px;
	flex-wrap: nowrap;
	padding-bottom: 6px;
	margin-bottom: 8px;
	border-bottom: 1px solid var(--attenue);
}

.brand {
	display: inline-flex; align-items: center; gap: 6px;
	font-size: 13px; font-weight: bold;
	color: var(--texte); text-decoration: none;
	/* Le seul element de l'en-tete dont on accepte de perdre une partie. */
	flex: 0 1 auto; min-width: 0; overflow: hidden;
}
.brand > span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.brand:hover { color: var(--texte); text-decoration: none; }
.brand svg { width: 17px; height: 17px; flex: 0 0 auto; }
.brand .tld { color: var(--attenue); font-weight: normal; }

/* LES BOUTONS D'OUTILS SONT AU MILIEU DE LA BARRE.
   Deux marges automatiques, pas une : avec la seule marge de gauche, tout
   l'espace libre passait devant eux et les collait au groupe de droite, si
   bien qu'on cliquait « fr » en visant « JSON ». Une marge fixe de 100 px a
   corrige la collision sans corriger la disposition -- les dix boutons
   restaient massees a droite, la barre vide a gauche.

   Les deux marges partagent l'espace en parts egales, donc les outils se
   posent a mi-chemin entre la marque et le groupe de droite. Ces deux-la font
   des largeurs voisines (environ 130 et 110 px), le milieu de la barre et le
   milieu de l'espace libre tombent donc presque au meme endroit -- sans avoir
   a sortir la barre du flux, ce qu'un centrage absolu aurait exige au prix
   d'un recouvrement des que la place manque.

   L'ecart se resserre tout seul quand la fenetre retrecit, symetriquement,
   jusqu'a la bascule en deux lignes sous 700 px. */
.site-nav { margin: 0 auto; display: flex; align-items: center; gap: 4px; flex: 0 0 auto; }

.nav-link {
	display: inline-flex; align-items: center; gap: 5px;
	padding: 4px 9px;
	background: var(--bloc);
	border: 1px solid var(--bord);
	border-radius: 3px;
	color: var(--texte);
	font-size: 11px; letter-spacing: .04em; text-transform: uppercase;
	text-decoration: none; white-space: nowrap;
}
.nav-link:hover { background: var(--alt); color: var(--texte); text-decoration: none; }
.nav-link[aria-current="page"] { background: var(--actif); font-weight: bold; }

/* Le pictogramme est a la taille du texte qu'il precede et legerement efface :
   six glyphes a pleine encre dans une rangee tirent l'oeil plus que les mots,
   alors qu'ils ne servent qu'a les retrouver. Celui du bouton courant revient
   a pleine encre. */
.nav-link svg { width: 14px; height: 14px; flex: 0 0 auto; opacity: .75; }
.nav-link[aria-current="page"] svg { opacity: 1; }

.header-tools {
	display: flex; align-items: center; gap: 4px; margin-left: 4px;
	/* Jamais comprimees : ce sont des cibles tactiles, et une cible reduite a
	   douze pixels de large n'est plus cliquable au doigt. */
	flex: 0 0 auto;
}

.icon-btn {
	display: inline-grid; place-items: center;
	width: 26px; height: 26px; padding: 0;
	border: 1px solid var(--bord); border-radius: 3px;
	background: var(--bloc); color: var(--texte);
	font-family: inherit; cursor: pointer;
}
.icon-btn:hover { background: var(--alt); color: var(--texte); }
.icon-btn svg { width: 14px; height: 14px; opacity: .75; }
.icon-btn:hover svg { opacity: 1; }

/* 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 JavaScript 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(--bord); border-radius: 3px;
	overflow: hidden; background: var(--bloc); height: 26px;
}
.lang-switch a {
	padding: 0 6px; height: 100%; display: inline-grid; place-items: center;
	font-size: 11px; letter-spacing: .04em;
	text-transform: uppercase; text-decoration: none; color: var(--texte);
}
.lang-switch a:hover { background: var(--alt); color: var(--texte); text-decoration: none; }
.lang-switch a[aria-current="true"] { background: var(--actif); font-weight: bold; }

/* --------------------------------------------------------------------------
   Le menu de TOUS les outils
   -------------------------------------------------------------------------- */
.tool-menu { position: relative; }
.tool-menu-panel {
	position: absolute; right: 0; top: calc(100% + 4px);
	width: min(92vw, 620px);
	background: var(--bloc); border: 1px solid var(--bord);
	border-radius: 6px; padding: 4px;
	display: none; z-index: 50;
	box-shadow: 0 6px 18px rgba(0, 0, 0, .28);
}
.tool-menu-panel[data-open="true"] { display: grid; }
@media (min-width: 620px) { .tool-menu-panel[data-open="true"] { grid-template-columns: 1fr 1fr; gap: 2px; } }

/* Chaque entree porte le pictogramme de son outil, MEME DESSIN QUE LA TUILE DE
   L'ACCUEIL et que le bouton de la barre : c'est ce qui permet de retrouver un
   outil a la forme plutot qu'a la lecture, dans les trois endroits ou il
   apparait.

   Le pictogramme est pose sur DEUX RANGEES (grid-row 1 / span 2), comme dans
   la tuile : cale sur la seule premiere rangee, il se centrerait sur
   l'intitule et laisserait la description se glisser sous lui, decalee d'un
   cran par rapport a celle de l'entree voisine. */
.tool-menu-panel a {
	display: grid; grid-template-columns: auto 1fr; column-gap: 7px;
	align-items: start;
	padding: 4px 7px; border-radius: 3px;
	text-decoration: none; color: var(--texte);
}
.tool-menu-panel a svg {
	grid-row: 1 / span 2;
	width: 15px; height: 15px; flex: 0 0 auto;
	color: var(--attenue); margin-top: 2px;
}
.tool-menu-panel a:hover svg { color: var(--texte); }

/* Le pictogramme de l'entree. L'ancre devient une grille de deux colonnes et le
   dessin occupe LES DEUX RANGEES -- sinon il se poserait au-dessus de
   l'intitule, l'ancre etant en display:block. Sa colonne est de largeur fixe :
   c'est ce qui aligne verticalement tous les intitules du panneau, quelle que
   soit la largeur du dessin.

   Il est en couleur attenuee : c'est un reperage, pas une information. Au
   survol il reprend la couleur du texte, comme dans la barre. */
.tool-menu-panel a {
	display: grid; grid-template-columns: 16px 1fr;
	column-gap: 7px; align-items: start;
}
.tool-menu-panel a > svg {
	grid-row: 1 / 3; width: 15px; height: 15px;
	margin-top: 2px; color: var(--attenue);
}
.tool-menu-panel a:hover > svg { color: var(--texte); }
.tool-menu-panel a:hover { background: var(--alt); color: var(--texte); text-decoration: none; }
.tool-menu-panel .tm-name { font-weight: bold; font-size: 12px; display: block; }
.tool-menu-panel .tm-desc { color: var(--attenue); font-size: 11px; display: block; line-height: 1.4; }

/* Le filet entre les outils du site et les sites voisins. Tendu sur toute la
   grille -- en deux colonnes, un element ordinaire n'en occuperait qu'une. Les
   marges negatives le font toucher les bords du panneau malgre son padding. */
.tool-menu-panel .tm-sep {
	grid-column: 1 / -1;
	border: 0; border-top: 1px solid var(--bord);
	margin: 5px -4px; height: 0;
}

/* Les deux voisins, sous le filet : leur propre grille a deux colonnes, tendue
   sur toute la largeur du panneau. Elle ne suit PAS celle des outils -- un
   nombre impair d'outils y decalerait la paire d'une colonne. En dessous de
   620px le panneau passe a une colonne et eux aussi, faute de place pour deux
   intitules et leurs descriptions. */
.tool-menu-panel .tm-voisins {
	grid-column: 1 / -1;
	display: grid; gap: 2px;
}
@media (min-width: 620px) { .tool-menu-panel .tm-voisins { grid-template-columns: 1fr 1fr; } }

/* --------------------------------------------------------------------------
   SUR TELEPHONE, LE PANNEAU EST ANCRE A LA PAGE, PAS AU BOUTON
   --------------------------------------------------------------------------
   Lecon prise sur dns.oxmo.org, ou le panneau sortait par la GAUCHE de l'ecran.
   La cause est arithmetique : pose en absolute/right:0 dans .tool-menu, son
   bord droit se cale sur celui du BOUTON, qui n'est pas au bord de la page --
   la langue et la bascule de theme le suivent, une centaine de pixels. Sa
   largeur se deploie ensuite vers la gauche et deborde.

   Ancre sur .site-header .wrap, c'est-a-dire sur la page elle-meme, et tendu
   de bord a bord, il ne PEUT plus deborder : il n'y a plus de soustraction a
   faire juste.

   Sur un ecran court -- telephone couche -- ses onze entrees depassent la
   hauteur visible, et comme il est en position absolue il n'allonge pas le
   document : le bas serait inatteignable. D'ou la hauteur maximale et le
   defilement interne.
   -------------------------------------------------------------------------- */
@media (max-width: 760px) {
	.site-header .wrap { position: relative; }
	.tool-menu { position: static; }
	.tool-menu-panel {
		left: 0; right: 0; width: auto;
		max-height: calc(100vh - 90px); overflow-y: auto;
	}
}

/* Le fil : le nom du site est desormais dans la marque, il n'a plus a y etre
   repete. Le filet de fermeture est celui de l'en-tete. */
.fil {
	margin-bottom: 10px;
	font-weight: bold;
}

/* ---------------------------------------------------------------------------
   L'EN-TETE SUR TELEPHONE : DEUX LIGNES
   ---------------------------------------------------------------------------
   Ligne 1 : la marque a gauche, et a droite le groupe menu / langue / theme --
   la disposition de dns.oxmo.org, telle quelle.
   Ligne 2 : les boutons d'outils, en grille pleine largeur.

   dns.oxmo.org, lui, MASQUE ses boutons d'outils sous 960 px et ne laisse que le
   menu. Ici ils restent : ce site en a six dans la barre, pas quatorze, et
   deux rangees de trois suffisent a les porter.

   C'EST L'ORDRE D'AFFICHAGE QUI CHANGE, PAS CELUI DU DOCUMENT. Les boutons
   d'outils restent ecrits avant le groupe de droite, donc lus avant lui sans
   feuille de style et parcourus avant lui au clavier.

   TROIS COLONNES, et le calcul tient a 320 px : (306 - 8) / 3 = 99 px par
   bouton, quand « TRACEROUTE » avec son pictogramme en demande 89. Aucun
   libelle ne passe sous son icone, contrairement a quatre colonnes.
   --------------------------------------------------------------------------- */
@media (max-width: 700px) {
	.site-header .wrap { flex-wrap: wrap; }

	.brand        { order: 1; flex: 1 1 auto; }
	.header-tools { order: 2; margin-left: auto; }
	.site-nav {
		order: 3;
		flex: 1 0 100%;
		margin: 6px 0 0;
		display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
		gap: 4px;
	}
	.nav-link { justify-content: center; padding: 8px 4px; }

	/* Cibles tactiles : le groupe de droite ne compte que trois boutons, il
	   peut se payer de la hauteur sans couter une rangee. */
	.icon-btn, .lang-switch { height: 32px; }
	.icon-btn { width: 32px; }
	.lang-switch a { padding: 0 9px; }
}

/* Sous 460 px, le domaine s'efface de la marque : « ip » suffit a dire ou l'on
   est, et les trois boutons de droite ne doivent jamais etre comprimes. */
@media (max-width: 460px) {
	.brand .tld { display: none; }
}

/* --------------------------------------------------------------------------
   5. Blocs — la forme de base de toute la page
   -------------------------------------------------------------------------- */
.bloc {
	background: var(--bloc);
	border: 1px solid var(--bord);
	border-radius: 6px;
	overflow: hidden;
	margin-bottom: 10px;
}
.bloc > .titre {
	margin: 0;
	padding: 8px 12px;
	background: var(--tete);
	color: var(--tete-txt);
	font-size: 13px;
	font-weight: bold;
}
.bloc > .titre a { color: inherit; text-decoration: underline; }
.bloc > .int { padding: 9px 11px; }
.bloc > .note {
	margin: 0;
	padding: 7px 12px;
	background: var(--alt);
	border-top: 1px solid var(--bord);
	font-size: 11px;
	line-height: 1.5;
	color: var(--texte);
}

.colonnes { display: flex; gap: 10px; align-items: flex-start; flex-wrap: wrap; }
.colonnes > * { flex: 1 1 320px; min-width: 0; }

/* --------------------------------------------------------------------------
   6. Tables de donnees
   -------------------------------------------------------------------------- */
.tab { width: 100%; border-collapse: collapse; }
.tab th, .tab td {
	padding: 4px 6px;
	text-align: left;
	vertical-align: top;
	border-bottom: 1px solid var(--alt);
}
.tab tr:last-child > * { border-bottom: 0; }
.tab th {
	font-size: 11px;
	font-weight: normal;
	color: var(--attenue);
	white-space: nowrap;
	width: 1%;
}
.tab td.val { font-weight: bold; }
.tab td.num { text-align: right; white-space: nowrap; font-family: var(--mono); }
.tab .vide { color: var(--attenue); font-style: italic; font-weight: normal; }

/* Un tableau plus large que son bloc defile DANS son bloc, jamais la page. */
.defile { overflow-x: auto; -webkit-overflow-scrolling: touch; }

.jauge { height: 8px; background: var(--alt); border-radius: 4px; overflow: hidden; min-width: 40px; }
.jauge i { display: block; height: 100%; background: var(--jauge); }

/* --------------------------------------------------------------------------
   7. Le bloc d'adresse — la reponse a la question du site
   -------------------------------------------------------------------------- */
.adresse { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }
.adresse .valeurs { flex: 1 1 240px; min-width: 0; }
.adresse .etiquette {
	font-size: 11px; color: var(--attenue);
	text-transform: uppercase; letter-spacing: .06em;
	margin-bottom: 2px;
}
.adresse .v4 {
	font-family: var(--mono);
	font-size: clamp(20px, 4.5vw, 30px);
	line-height: 1.15;
	word-break: break-all;
}
.adresse .v6 {
	font-family: var(--mono);
	font-size: 12px;
	color: var(--attenue);
	word-break: break-all;
	margin-top: 3px;
}
.adresse .actions { display: flex; flex-direction: column; gap: 4px; }

.bouton {
	display: inline-flex; align-items: center; gap: 5px;
	padding: 5px 10px;
	background: var(--alt);
	border: 1px solid var(--bord);
	border-radius: 3px;
	color: var(--texte);
	font-family: inherit; font-size: 11px;
	cursor: pointer;
	text-decoration: none;
}
.bouton:hover { background: var(--bloc); color: var(--texte); text-decoration: none; }
.bouton svg { width: 13px; height: 13px; }

/* --------------------------------------------------------------------------
   8. Formulaires
   -------------------------------------------------------------------------- */
/* ---------------------------------------------------------------------------
   LES CHAMPS D'UN FORMULAIRE S'ALIGNENT PAR LE BAS
   ---------------------------------------------------------------------------
   Sans align-items, les colonnes s'etirent et leur contenu se cale en haut :
   le champ d'adresse, dont l'intitule passe au-dessus parce que sa boite prend
   toute la largeur, se retrouvait plus bas que le champ « Port », dont
   l'intitule restait EN LIGNE faute d'un display: block. Deux champs voisins,
   deux hauteurs, deux alignements.

   Alignes par le bas, tous les champs posent leur boite de saisie sur la meme
   ligne, quel que soit ce qu'il y a au-dessus -- et le bouton d'envoi s'y pose
   aussi.
   --------------------------------------------------------------------------- */
/* .saisie et NON form.saisie : la rangee de boutons des outils developpeur
   (part/texte.php) est un <div> portant la meme classe. Vise par « form. »,
   elle n'etait pas en flex du tout -- ses selecteurs et son bouton
   s'alignaient sur la ligne de base du texte, d'ou un pixel d'ecart entre eux
   selon leur corps de police. */
.saisie { display: flex; gap: 6px; flex-wrap: wrap; align-items: flex-end; }
.saisie > * { flex: 0 0 auto; }
.saisie .champ { flex: 1 1 240px; min-width: 0; }

/* .etiquette est aussi utilisee sur des <div> (le bloc d'adresse de
   l'accueil) ; posee sur un <label>, elle heritait de l'affichage EN LIGNE et
   le margin-bottom ne s'appliquait pas. */
label.etiquette { display: block; }

input[type="text"], input[type="url"], input[type="number"], select, textarea {
	width: 100%;
	padding: 5px 7px;
	background: var(--champ);
	color: var(--texte);
	border: 1px solid var(--bord);
	border-radius: 3px;
	font-family: inherit;
	font-size: 13px;
}
textarea { font-family: var(--mono); font-size: 12px; min-height: 150px; resize: vertical; }
input:focus, select:focus, textarea:focus { outline: 2px solid var(--survol); outline-offset: -1px; }

button.envoi {
	padding: 5px 14px;
	background: var(--tete); color: var(--tete-txt);
	border: 1px solid var(--bord); border-radius: 3px;
	font-family: inherit; font-size: 12px; font-weight: bold;
	cursor: pointer;
}
button.envoi:hover { background: var(--survol); }

/* --------------------------------------------------------------------------
   9. La grille des outils
   -------------------------------------------------------------------------- */
.groupe + .groupe { margin-top: 12px; }
.groupe > h3 {
	display: flex; align-items: center; gap: 8px;
	margin: 0 0 6px;
	font-size: 11px; font-weight: bold;
	text-transform: uppercase; letter-spacing: .07em;
	color: var(--attenue);
}
.groupe > h3::after { content: ""; flex: 1 1 auto; height: 1px; background: var(--bord-fin); }

/* Nombre de colonnes FIXE, jamais deduit du contenu : auto-fit supprime les
   pistes vides et donnerait des tuiles de largeurs differentes d'un groupe a
   l'autre selon le nombre d'outils qu'il contient. */
.tuiles {
	display: grid;
	grid-template-columns: repeat(3, minmax(0, 1fr));
	grid-auto-rows: 1fr;
	gap: 6px;
}
.tuile {
	display: grid;
	grid-template-columns: auto minmax(0, 1fr);
	column-gap: 8px; row-gap: 1px;
	align-content: start;
	padding: 7px 9px;
	background: var(--alt);
	border: 1px solid var(--bord-fin);
	border-radius: 4px;
	color: var(--texte);
	text-decoration: none;
}
.tuile:hover { border-color: var(--bord); background: var(--bloc); color: var(--texte); text-decoration: none; }
.tuile svg { grid-row: 1 / span 2; width: 20px; height: 20px; color: var(--attenue); margin-top: 2px; }
.tuile b { font-size: 12px; }
.tuile span { font-size: 11px; color: var(--attenue); line-height: 1.4; }

/* --------------------------------------------------------------------------
   10. La carte
   -------------------------------------------------------------------------- */
.carte { position: relative; background: var(--carte-eau); }
.carte svg { display: block; width: 100%; height: auto; }
/* vector-effect: non-scaling-stroke N'EST PAS UN DETAIL.
   L'epaisseur d'un trait SVG s'exprime en unites du viewBox, donc elle est
   divisee par le facteur de zoom. Le cadre des Etats-Unis fait 4 000 unites
   affichees sur 480 px : sans cette propriete, un trait de 0,25 unite mesure
   trois centiemes de pixel et AUCUNE frontiere ne se voit -- ce qui etait le
   cas au premier rendu. Avec elle, l'epaisseur est lue en pixels d'ecran et
   reste constante a tous les niveaux de zoom, ce qui est le comportement
   attendu d'une carte. */
.carte .terre,
.carte .region,
.carte .grille { vector-effect: non-scaling-stroke; }

.carte .terre  { fill: var(--carte-terre); stroke: var(--carte-trait); stroke-width: .7; stroke-linejoin: round; }
.carte .moi    { fill: var(--carte-moi); stroke-width: 1; }
.carte .region { fill: none; stroke: var(--carte-trait); stroke-width: .5; opacity: .65; }
.carte .grille { fill: none; stroke: var(--carte-trait); stroke-width: .5; opacity: .28; }

/* L'epingle et son disque de precision NE CHANGENT PAS entre les themes :
   c'est de la donnee, comme le degrade de la carte des membres du forum. */
.carte .halo    { fill: #ec7014; fill-opacity: .18; stroke: #cc4c02; stroke-opacity: .55; stroke-width: 1; vector-effect: non-scaling-stroke; }
.carte .epingle { fill: #cc4c02; stroke: #3a1a05; stroke-width: .5; }
.carte .epingle-oeil { fill: #ffffff; }

.carte .zoom { position: absolute; top: 6px; left: 6px; display: flex; flex-direction: column; }
.carte .zoom button {
	width: 22px; height: 22px; padding: 0;
	background: var(--bloc); color: var(--texte);
	border: 1px solid var(--bord);
	font-family: inherit; font-size: 14px; line-height: 1; cursor: pointer;
}
.carte .zoom button:first-child { border-radius: 3px 3px 0 0; border-bottom: 0; }
.carte .zoom button:last-child  { border-radius: 0 0 3px 3px; }
.carte .zoom button:hover { background: var(--alt); }

.carte .credit {
	position: absolute; right: 4px; bottom: 3px;
	padding: 1px 4px;
	background: color-mix(in srgb, var(--bloc) 85%, transparent);
	border: 1px solid var(--bord-fin);
	border-radius: 2px;
	font-size: 10px; color: var(--attenue);
}

/* --------------------------------------------------------------------------
   10 bis. La courbe du test de debit
   -------------------------------------------------------------------------- */
.courbe {
	position: relative;
	margin: 9px 0 0;
	border: 1px solid var(--bord-fin);
	border-radius: 4px;
	background: var(--alt);
	overflow: hidden;
}
/* La hauteur est posee ICI et non sur le canvas : le script la lit pour
   dimensionner le tampon en pixels reels (densite d'ecran comprise). Un canvas
   dimensionne par CSS seul rend une courbe floue sur un ecran 2x. */
.courbe canvas { display: block; width: 100%; height: 190px; }

.courbe-legende {
	display: flex; flex-wrap: wrap; gap: 4px 16px;
	padding: 5px 9px;
	border-top: 1px solid var(--bord-fin);
	background: var(--bloc);
	font-size: 11px;
}
.courbe-legende span { display: inline-flex; align-items: center; gap: 5px; }
.courbe-legende i {
	width: 14px; height: 3px; border-radius: 2px; flex: 0 0 auto;
}
.courbe-legende .dl i { background: var(--courbe-dl); }
.courbe-legende .ul i { background: var(--courbe-ul); }
.courbe-legende b { font-family: var(--mono); }

/* --------------------------------------------------------------------------
   11. Messages
   -------------------------------------------------------------------------- */
.aide { margin: 7px 0 0; font-size: 11px; line-height: 1.5; color: var(--attenue); }
.aide code { background: var(--alt); padding: 0 3px; border-radius: 2px; }

.message {
	padding: 8px 11px;
	border: 1px solid var(--bord-fin);
	border-radius: 4px;
	font-size: 12px;
	margin-bottom: 10px;
}
.message.ok     { background: var(--ok-fond);     border-color: var(--ok);     color: var(--texte); }
.message.alerte { background: var(--alerte-fond); border-color: var(--alerte); color: var(--texte); }
.message.ko     { background: var(--ko-fond);     border-color: var(--ko);     color: var(--texte); }

/* --------------------------------------------------------------------------
   12. Pied
   -------------------------------------------------------------------------- */
/* Le modele de dns.oxmo.org : un bloc de deux lignes a gauche, les pages de
   service a droite, separes par tout l'espace disponible. align-items sur
   center et non baseline -- le bloc de gauche fait deux lignes, la rangee de
   droite une seule, et c'est le milieu des deux qui doit coincider. */
.pied {
	margin-top: 14px;
	padding-top: 8px;
	border-top: 1px solid var(--bord-fin);
	font-size: 11px;
	color: var(--attenue);
	display: flex; flex-wrap: wrap; gap: 4px 14px;
	align-items: center; justify-content: space-between;
}
.pied-liens { display: flex; flex-wrap: wrap; gap: 4px 14px; }
.pied a { color: var(--attenue); text-decoration: underline; }
.pied a:hover { color: var(--texte); }

/* --------------------------------------------------------------------------
   13. Ecrans etroits
   -------------------------------------------------------------------------- */
@media (max-width: 1000px) {
	.tuiles { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 700px) {
	body { padding: 7px; }
	.tuiles { grid-template-columns: minmax(0, 1fr); grid-auto-rows: auto; }
	.colonnes > * { flex: 1 1 100%; }
	.adresse .actions { flex-direction: row; }
}
@media (max-width: 760px) {
	/* 16 px N'EST PAS UN CHOIX ESTHETIQUE. Safari iOS agrandit la page des
	   qu'un champ recoit le focus si sa police descend sous 16 px : la mise en
	   page se decale et il faut repincer pour retrouver le bouton. La valeur
	   est ecrite en pixels et non en rem pour qu'une taille par defaut reduite
	   chez le visiteur ne repasse pas sous le seuil. */
	input[type="text"], input[type="url"], input[type="number"], select, textarea {
		font-size: 16px;
	}
	/* CIBLES TACTILES. Mesure a 390 px avant correction : 26 px de haut pour
	   un lien de pied, 32 px pour un bouton de barre, contre 44 px
	   recommandes au doigt. Le texte reste a sa taille, c'est la zone
	   cliquable qui grandit -- grossir le texte aurait deforme la charte. */
	.pied { gap: 2px 14px; }
	.pied a { display: inline-block; padding: 12px 0; }

}
