/* ==========================================================================
   Neomyrma — feuille de style unique du site.

   Les chemins ci-dessous (polices) partent de CE fichier, situé dans
   /css. « ../assets/fonts/ » remonte donc d'un cran avant de redescendre.
   ========================================================================== */

@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url('../assets/fonts/inter-variable.woff2') format('woff2');
}

@font-face {
  font-family: 'Inter';
  font-style: italic;
  font-weight: 100 900;
  font-display: swap;
  src: url('../assets/fonts/inter-variable-italic.woff2') format('woff2');
}

@font-face {
  font-family: 'Space Mono';
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url('../assets/fonts/space-mono-400.woff2') format('woff2');
}

@font-face {
  font-family: 'Space Mono';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('../assets/fonts/space-mono-700.woff2') format('woff2');
}
/* ==========================================================================
   Neomyrma — feuille de style
   Registre visuel : grille de wireframe. Fond blanc, filets d'un pixel,
   tout le contenu réparti dans des cellules rectangulaires. Aucun arrondi,
   aucune ombre, aucun aplat décoratif : seules les lignes structurent.
   Une seule couleur d'encre, le vert forêt sombre.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Polices — servies par le site lui-même (public/fonts/), jamais par un
   tiers : aucune requête sortante, donc aucune adresse IP de visiteur
   transmise ailleurs, et la politique de sécurité reste fermée.

   Inter pour tout le texte lu, Space Mono pour ce qui relève de l'appareil :
   références de cellule, dates, compteurs, horloge. La séparation des deux
   est ce qui fait tenir la grille — l'une lit, l'autre indexe.
   -------------------------------------------------------------------------- */









:root {
  /* Une seule encre. Tous les filets, tous les textes, tous les aplats
     sombres en sortent — c'est ce qui donne au document son unité. */
  --ink: #0a3a2a;
  --paper: #ffffff;

  /* Déclinaisons de l'encre. Elles ne sont PAS des couleurs de plus : ce
     sont la même, à des opacités différentes sur le papier blanc. */
  /* Encre atténuée, réservée aux SEULES étiquettes d'appareil : la clé
     d'une métadonnée, un compteur, un intitulé de colonne. Le corps de
     texte, lui, est en encre pleine — un paragraphe explicatif n'a aucune
     raison d'être délavé. Vérifiée à 4,7:1 sur le papier, au-dessus du
     seuil AA (à 55 % elle tombait à 3,3:1, illisible aux petites tailles
     où elle servait justement). */
  --ink-70: rgba(10, 58, 42, 0.70);
  --ink-12: rgba(10, 58, 42, 0.12);
  --ink-06: rgba(10, 58, 42, 0.06);

  /* Sur les cellules pleines (encre), le texte repasse en papier. */
  --on-ink: #ffffff;
  --on-ink-muted: rgba(255, 255, 255, 0.66);

  /* Couleur d'action. Deux valeurs, et la raison tient au contraste :
     du blanc sur #e65100 ne donne que 3,75:1, en dessous du seuil de
     4,5:1 exigé pour du petit texte. L'orange pur reste donc réservé à
     ce qui ne porte pas de texte — filets, flèches, voyants — où le
     seuil est de 3:1 et où il passe (3,75:1 sur blanc). Dès qu'une
     surface orange doit porter un libellé blanc, c'est --action-deep
     qui sert : même famille, 5,1:1. */
  --action: #e65100;
  --action-deep: #c04500;

  --danger: #8c2f1c;

  --line: 1px solid var(--ink);
  --line-thin: 1px solid var(--ink-12);
  /* Filet clair, pour les séparations à l'intérieur des blocs pleins. */
  --line-light: 1px solid rgba(255, 255, 255, 0.30);

  --gap: 20px;          /* Blanc entre les blocs */
  --pad: 18px;          /* Respiration à l'intérieur d'une cellule */
  --max-width: 1240px;

  --font-sans: 'Inter', system-ui, -apple-system, Helvetica, Arial, sans-serif;
  --font-mono: 'Space Mono', ui-monospace, 'SFMono-Regular', Menlo, Consolas, monospace;
}

* {
  box-sizing: border-box;
}

/* « hidden » doit primer sur toute règle d'affichage écrite ici, sans quoi
   une entrée filtrée resterait visible. */
[hidden] {
  display: none !important;
}

html {
  scroll-behavior: smooth;
  background: var(--paper);
}

body {
  margin: 0;
  padding: var(--gap);
  /* Trame de points à 4 % d'encre : elle ne se voit que dans les blancs
     entre les blocs et autour du document, puisque les cellules sont
     opaques. Assez pour que la page ne soit plus un vide, assez peu pour
     ne jamais concurrencer le texte.
     « background-attachment: fixed » est volontairement évité : il force
     le navigateur à repeindre la trame à chaque défilement. */
  background-color: var(--paper);
  background-image: radial-gradient(circle, rgba(10, 58, 42, 0.04) 1px, transparent 1px);
  background-size: 7px 7px;
  color: var(--ink);
  font-family: var(--font-sans);
  font-size: 15px;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
}

/* --------------------------------------------------------------------------
   Le document : trois blocs encadrés, séparés par du blanc — en-tête,
   corps, pied. Chacun porte son propre filet, comme les trois cartouches
   d'un plan.
   -------------------------------------------------------------------------- */

.frame {
  max-width: var(--max-width);
  margin: 0 auto;
}

.frame-inner {
  display: block;
}

/* Un bloc encadré. Les cellules qu'il contient ne portent qu'un filet
   intérieur, jamais un contour complet : deux filets adjacents feraient
   une ligne de deux pixels, et toute la grille s'épaissirait par endroits. */
.block {
  border: var(--line);
  margin-bottom: var(--gap);
}

/* Toutes les cellules du document sont OPAQUES. La trame de points du
   corps de page (voir « body » plus haut) ne doit se voir que dans les
   blancs : la marge autour du document et les gouttières entre les
   blocs. Dès qu'un bloc porte du texte, il est posé sur un aplat de
   papier plein — la même couleur que le fond, mais sans motif, pour que
   rien ne vienne texturer ce qui se lit.
   Sans cette règle, un bloc simplement encadré laisse passer la trame :
   c'est le fond du corps de page qui transparaît, faute de fond à lui.
   Toute nouvelle cellule ajoutée au site doit rejoindre cette liste. */
.intro-block,
.hero,
.community,
.list-header,
.post-grid,
.orientation,
.article-header,
.article-body,
.share-block,
.species-legend,
.species-toolbar,
.species-group,
.species-breadcrumb,
.species-page-head,
.species-page-section,
.species-page-back,
.species-apercu-note,
.site-footer,
.flash,
.form-card,
.table-scroll,
.post-table,
.empty-state,
.thumb-preview,
.block {
  background: var(--paper);
}

/* --------------------------------------------------------------------------
   Typographie
   -------------------------------------------------------------------------- */

h1, h2, h3, h4 {
  margin: 0 0 12px;
  font-family: var(--font-sans);
  font-weight: 500;
  line-height: 1.18;
  letter-spacing: -0.02em;
  color: var(--ink);
}

h1 { font-size: clamp(1.5rem, 2.6vw, 2rem); }
h2 { font-size: 1.1rem; }
h3 { font-size: 1rem; }

p {
  margin: 0 0 15px;
  max-width: 68ch;
}

p:last-child {
  margin-bottom: 0;
}

/* « max-width: 68ch » est une largeur de confort de LECTURE : elle n'a
   rien à faire sur un paragraphe qui sert de cellule. Sans cette
   exception, le filet d'une cellule s'arrêtait au milieu de la rangée —
   la ligne sous les filtres, par exemple, ne fermait pas la dernière
   case. */
.filter-status,
.community-label,
.share-block > p,
.footer-legal,
.footer-admin,
.species-page-back,
.article-meta,
.article-tag,
.hero-kicker,
.orientation-count,
.header-note-name,
/* Le bloc « rien à afficher » centre son texte. Sans cette exception, le
   paragraphe restait une colonne de 68ch calée à gauche, et le texte se
   centrait DANS cette colonne — donc à un tiers de la cellule, pas au
   milieu. Le décalage se mesurait à 329 px sur un écran de 1280. */
.empty-state p {
  max-width: none;
}

a {
  color: var(--ink);
  text-decoration: none;
  text-underline-offset: 3px;
}

a:hover {
  text-decoration: underline;
}

:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 1px;
}

.skip-link {
  position: fixed;
  top: var(--gap);
  left: -9999px;
  z-index: 100;
  padding: 10px 16px;
  background: var(--ink);
  color: var(--paper);
  font-family: var(--font-mono);
  font-size: 0.8rem;
}

.skip-link:focus {
  left: var(--gap);
  text-decoration: none;
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

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

/* --------------------------------------------------------------------------
   Barre d'administration — une bande pleine au-dessus du document
   -------------------------------------------------------------------------- */

.admin-bar {
  max-width: var(--max-width);
  margin: 0 auto var(--gap);
  background: var(--ink);
  color: var(--on-ink);
  font-family: var(--font-mono);
  font-size: 0.72rem;
}

.admin-bar-inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 9px var(--pad);
}

.admin-bar a,
.admin-bar button.link-button {
  margin-right: 18px;
  color: var(--on-ink);
  font: inherit;
  text-decoration: underline;
}

.admin-bar form {
  display: inline;
}

/* --------------------------------------------------------------------------
   En-tête : le cartouche du haut de plan.
   À gauche, deux cellules empilées — le nom du site, puis la navigation.
   À droite, une cellule pleine hauteur qui porte la phrase de présentation.
   -------------------------------------------------------------------------- */

/* En-tête inversé : le bloc entier est un aplat d'encre. C'est l'ancrage
   visuel du haut de page — les séparations intérieures passent donc en
   filet clair, sans quoi elles seraient invisibles. */
.site-header {
  border: var(--line);
  margin-bottom: var(--gap);
  background: var(--ink);
  color: var(--paper);
}

.site-header .header-identity,
.site-header .site-title,
.site-header .site-nav > a,
.site-header .nav-trigger {
  border-color: rgba(255, 255, 255, 0.30);
}

/* La règle globale « a { color: var(--ink) } » est plus spécifique que la
   couleur héritée du bloc : sans cette reprise, le nom du site et les
   entrées de navigation resteraient en encre sur l'encre, donc
   invisibles. */
.site-header .site-title,
.site-header .site-nav > a,
.site-header .nav-trigger {
  color: var(--paper);
}

/* Exception : le menu déroulant s'ouvre sur fond papier, il garde donc
   l'encre pour couleur de texte. */
.site-header .nav-menu a {
  color: var(--ink);
}

.site-header .nav-menu a:hover {
  color: var(--paper);
}

.site-header-inner {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(280px, 0.66fr);
}

.header-identity {
  display: flex;
  flex-direction: column;
  border-right: var(--line);
  min-width: 0;
}

.site-title {
  display: block;
  padding: 11px var(--pad);
  border-bottom: var(--line);
  font-family: var(--font-mono);
  font-size: 0.86rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

.site-title:hover {
  text-decoration: none;
  background: var(--paper);
  color: var(--ink);
}

.site-tagline {
  margin: 6px 0 0;
  padding: 0;
  max-width: none;
  font-size: 0.9rem;
  line-height: 1.45;
  color: var(--paper);
}

.header-note {
  padding: 11px var(--pad);
}

.header-note-name {
  margin: 0;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

/* ---- Navigation : des cases jointives, séparées par un filet ---- */

.site-nav {
  display: flex;
  flex-wrap: wrap;
  flex: 1 1 auto;
  align-items: stretch;
}

.site-nav > a,
.nav-trigger {
  display: flex;
  align-items: center;
  gap: 7px;
  padding: 10px var(--pad);
  border-right: var(--line);
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.site-nav > a:hover,
.nav-trigger:hover {
  text-decoration: none;
  background: rgba(255, 255, 255, 0.12);
}

/* L'onglet courant est une case pleine. L'en-tête étant lui-même en
   encre, c'est l'inverse qui s'applique : papier plein, texte encre. */
.site-nav > a.is-current,
.nav-trigger.is-current {
  background: var(--paper);
  color: var(--ink);
}

.nav-dropdown {
  position: relative;
  display: flex;
}

.nav-caret {
  width: 9px;
  height: 9px;
  flex: none;
}

.nav-menu {
  position: absolute;
  top: 100%;
  /* Aligné sur le bord droit : c'est la dernière case de la navigation,
     un alignement à gauche la ferait déborder de la fenêtre — et un menu
     invisible compte quand même dans la largeur de la page. */
  right: -1px;
  min-width: 250px;
  margin: 0;
  padding: 0;
  list-style: none;
  background: var(--paper);
  border: var(--line);
  visibility: hidden;
  opacity: 0;
  transition: opacity 0.12s ease, visibility 0.12s;
  z-index: 20;
}

.nav-dropdown:hover .nav-menu,
.nav-dropdown:focus-within .nav-menu,
.nav-dropdown.is-open .nav-menu {
  visibility: visible;
  opacity: 1;
}

.nav-menu li + li {
  border-top: var(--line);
}

.nav-menu a {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  padding: 10px var(--pad);
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.nav-menu a:hover {
  text-decoration: none;
  background: var(--ink);
  color: var(--paper);
}

.nav-menu-count {
  font-size: 0.68rem;
  color: var(--ink-70);
}

.nav-menu a:hover .nav-menu-count {
  color: var(--on-ink-muted);
}

/* --------------------------------------------------------------------------
   Corps
   -------------------------------------------------------------------------- */

main {
  display: block;
}

/* Un bloc de texte encadré, cellule pleine largeur. */
.intro-block {
  border: var(--line);
  margin-bottom: var(--gap);
  padding: var(--pad);
}

.intro-block h1 {
  margin-bottom: 10px;
}

.intro-block p {
  color: var(--ink);
}

.lead-under-title {
  margin-top: 0;
  color: var(--ink);
}

/* --------------------------------------------------------------------------
   Bandeau d'accueil : deux cellules côte à côte — le texte à gauche, le
   visuel à droite sur fond d'encre, comme la planche de référence.
   -------------------------------------------------------------------------- */

.hero {
  border: var(--line);
  border-bottom: 0;
}

.hero-inner {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 0.92fr);
  align-items: stretch;
}

.hero-text {
  padding: var(--pad);
  border-right: var(--line);
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.hero-kicker {
  margin: 0 0 22px;
  font-family: var(--font-mono);
  font-size: 0.68rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-70);
}

.hero-title {
  margin: 0 0 14px;
  font-size: clamp(1.7rem, 3.4vw, 2.5rem);
  font-weight: 500;
  letter-spacing: -0.03em;
}

.hero-lead {
  margin: 0;
  max-width: 52ch;
  color: var(--ink);
}

/* La cellule média : fond de papier plein, visuel centré avec de la
   marge. C'est la grille qui structure l'espace, pas un aplat. */
.hero-media {
  background: var(--paper);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--pad);
  min-height: 300px;
}

/* L'illustration de marque : fond transparent, deux couleurs, posée
   directement sur le papier. Pas de filet autour — ce n'est pas une
   photo dans un cadre, c'est un dessin détouré ; l'encadrer ferait
   apparaître une boîte vide autour des pattes. */
.hero-illustration {
  display: block;
  width: 100%;
  max-width: 460px;
  height: auto;
  max-height: 340px;
  object-fit: contain;
}

/* --------------------------------------------------------------------------
   Bande communauté : une rangée de cellules sous le bandeau
   -------------------------------------------------------------------------- */

.community {
  border: var(--line);
  margin-bottom: var(--gap);
}

.community-inner {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
}

.community-text {
  margin: 0;
  padding: var(--pad);
  border-right: var(--line);
  max-width: none;
  font-size: 0.9rem;
  color: var(--ink);
}

/* Colonne de droite en deux cellules empilées — même découpe que dans
   l'en-tête, où le nom du site surmonte la navigation. */
.community-side {
  display: flex;
  flex-direction: column;
}

.community-label {
  margin: 0;
  padding: 11px var(--pad);
  border-bottom: var(--line);
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

.community-actions {
  display: flex;
  flex: 1 1 auto;
}

/* Dans cette bande, les trois liens sont des cellules jointives de pleine
   hauteur : le bouton Discord perd son filet propre, celui de la cellule
   suffit. */
.community-actions .btn,
.community-actions .social-link {
  padding: 12px var(--pad);
  border: 0;
  border-right: var(--line);
}

.community-actions > :last-child {
  border-right: 0;
}

.social-link,
.community-actions .btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  padding: 12px var(--pad);
  border-right: var(--line);
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  white-space: nowrap;
}

.social-link:last-child {
  border-right: 0;
}

.social-link:hover {
  text-decoration: none;
  background: var(--ink);
  color: var(--paper);
}

.icon {
  width: 14px;
  height: 14px;
  flex: none;
  fill: currentColor;
}

/* --------------------------------------------------------------------------
   En-tête de liste et filtres
   -------------------------------------------------------------------------- */

.list-header {
  border: var(--line);
  border-bottom: 0;
}

/* En-tête de section : une cellule pleine, texte en papier. C'est la
   même case partout — liste d'articles, légende de la liste d'espèces,
   groupe d'espèces, section d'une fiche, bloc de partage — pour qu'on
   reconnaisse d'un coup d'œil où commence une section. */
.section-title,
.species-legend-title,
.share-block > p {
  margin: 0;
  padding: 10px var(--pad);
  background: var(--ink);
  color: var(--paper);
  /* Filet blanc : quand la puce active, elle aussi pleine, se trouve juste
     en dessous, les deux cellules se souderaient sans lui. Sur les puces
     blanches voisines, il ne se voit pas. */
  border-bottom: 1px solid var(--paper);
  font-family: var(--font-mono);
  font-size: 0.72rem;
  font-weight: 400;
  letter-spacing: 0.16em;
  text-transform: uppercase;
}

/* Puces de filtre : des cases jointives. Sur l'accueil ce sont de vrais
   liens — sans JavaScript, chacun mène à sa page de catégorie. Avec
   JavaScript, le clic est intercepté, la liste filtrée sur place, et la
   sélection recopiée dans l'adresse (?cat=guides, public/js/filtres.js) :
   elle se partage et se met en favori comme un vrai lien. */
.filter-bar {
  display: flex;
  flex-wrap: wrap;
}

.filter-chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 9px var(--pad);
  border: 0;
  border-right: var(--line);
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-mono);
  font-size: 0.7rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  line-height: 1.3;
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
}

.filter-chip:hover {
  text-decoration: none;
  background: var(--ink-06);
}

/* Filtre actif : cellule pleine, en encre. L'orange reste réservé aux
   points d'action à proprement parler — le bouton Discord, la flèche
   d'un bouton de fiche au survol, le repère de la ligne d'état. */
.filter-chip.is-active {
  background: var(--ink);
  color: var(--paper);
}

.filter-count {
  font-size: 0.68rem;
  color: var(--ink-70);
}

.filter-chip.is-active .filter-count {
  color: var(--on-ink-muted);
}

/* La ligne d'état du filtrage, signalée par un carré orange. Le texte
   reste en encre : de l'orange sur blanc ne donne que 3,75:1, ce qui
   suffit pour un repère mais pas pour du texte. */
.filter-status::before {
  content: '';
  display: inline-block;
  width: 7px;
  height: 7px;
  margin-right: 9px;
  vertical-align: 0.04em;
  background: var(--action);
}

.filter-status:empty::before {
  display: none;
}

.filter-status {
  margin: 0;
  padding: 8px var(--pad);
  border-top: var(--line);
  min-height: 1.2em;
  font-family: var(--font-mono);
  font-size: 0.7rem;
  color: var(--ink-70);
}

/* --------------------------------------------------------------------------
   Liste d'articles : une rangée de cellules par publication —
   index, visuel, texte.
   -------------------------------------------------------------------------- */

.post-grid {
  border: var(--line);
  border-bottom: 0;
  margin-bottom: var(--gap);
}

.post-card {
  display: grid;
  grid-template-columns: 54px minmax(0, 360px) minmax(0, 1fr);
  border-bottom: var(--line);
}

.post-card-index {
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: var(--pad) 0;
  border-right: var(--line);
  font-family: var(--font-mono);
  font-size: 0.72rem;
  color: var(--ink-70);
  transition: background 0.12s ease, color 0.12s ease;
}

/* Au survol de la rangée, la cellule d'index s'allume : c'est le repère
   qui dit quelle fiche est visée, sans rien déplacer dans la grille. */
.post-card:hover .post-card-index {
  background: var(--action);
  color: var(--paper);
}

.post-card-media {
  /* La photo est posée dans sa cellule, avec de la marge autour et un
     filet net — pas d'aplat de fond, pas de surbrillance. Centrée, parce
     que la hauteur de la rangée est dictée par la colonne de texte. */
  display: flex;
  align-items: center;
  padding: var(--pad);
  border-right: var(--line);
  background: var(--paper);
}

.post-card-media:hover {
  text-decoration: none;
}

.post-card-image {
  display: block;
  width: 100%;
  border: var(--line);
  /* Le format d'enregistrement des photos (1200×630), respecté à toutes
     les largeurs d'écran. Pas de « height: 100% » : la hauteur de la
     rangée est dictée par la colonne de texte, et étirer la photo dessus
     la recadrerait différemment d'une rangée à l'autre. Le fond d'encre
     de la cellule occupe ce qui reste. */
  aspect-ratio: 1200 / 630;
  object-fit: cover;
}

/* Rembourrage plus généreux que dans les autres cellules : c'est ce qui
   décolle le texte de la photo et du filet. « margin-top: auto » sur le
   pied de fiche aligne les boutons en bas de rangée, quelle que soit la
   longueur du résumé. */
.post-card-body {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  padding: calc(var(--pad) * 1.5) calc(var(--pad) * 1.6);
  min-width: 0;
}

.post-card-title {
  margin: 0 0 10px;
  font-size: 1.15rem;
  font-weight: 500;
  letter-spacing: -0.02em;
}

/* ---- Métadonnées en cellules de registre ---- */

.data-tags {
  display: flex;
  flex-wrap: wrap;
  margin: 0 0 14px;
  padding: 0;
  list-style: none;
  border: var(--line-thin);
}

.data-tag {
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
  padding: 4px 10px;
  border-right: var(--line-thin);
  font-family: var(--font-mono);
  font-size: 0.66rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  white-space: nowrap;
}

.data-tag:last-child {
  border-right: 0;
}

.data-tag-key {
  color: var(--ink-70);
}

.post-card-excerpt {
  margin: 0 0 16px;
  max-width: 62ch;
  color: var(--ink);
}

.card-actions {
  width: 100%;
  margin-top: auto;
  padding-top: 14px;
  border-top: var(--line-thin);
}

/* --------------------------------------------------------------------------
   Boutons — des cases, comme le reste
   -------------------------------------------------------------------------- */

.btn {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  padding: 9px 16px;
  border: var(--line);
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  line-height: 1.2;
  cursor: pointer;
}

.btn:hover {
  text-decoration: none;
  background: var(--ink);
  color: var(--paper);
}

/* Bouton principal — cellule pleine en encre. C'est celui des formulaires
   de publication : « Enregistrer », « Se connecter ». */
.btn-primary {
  background: var(--ink);
  border-color: var(--ink);
  color: var(--paper);
}

.btn-primary:hover {
  background: var(--paper);
  color: var(--ink);
}

/* Le bouton Discord, et lui seul, est en orange plein.
   À savoir : du blanc sur #e65100 mesure 3,79:1, sous le seuil AA de
   4,5:1 pour un texte de cette taille. C'est un choix assumé sur ce seul
   bouton, dont le sens est aussi porté par son icône et sa position — et
   la raison pour laquelle l'orange est ici cantonné à lui, plutôt
   qu'appliqué à tous les boutons principaux, y compris ceux des
   formulaires. Pour revenir à une valeur conforme, remplacer var(--action)
   par var(--action-deep) ci-dessous : même famille, 5,1:1. */
.community-actions .btn-primary {
  background: var(--action);
  border-color: var(--action);
  color: var(--paper);
}

.community-actions .btn-primary:hover {
  background: var(--action-deep);
  border-color: var(--action-deep);
  color: var(--paper);
}

.btn-danger {
  border-color: var(--danger);
  color: var(--danger);
}

.btn-danger:hover {
  background: var(--danger);
  border-color: var(--danger);
  color: var(--paper);
}

.btn-small {
  padding: 7px 13px;
  font-size: 0.68rem;
}

.link-button {
  padding: 0;
  border: 0;
  background: none;
  color: var(--ink);
  font: inherit;
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* Le bouton d'une fiche reste sobre au repos — filet et libellé en encre.
   Au survol de la fiche entière, sa flèche passe à l'orange ; au survol
   du bouton lui-même, c'est le fond qui bascule. */
.post-card:hover .btn-more {
  border-color: var(--action);
}

.post-card:hover .btn-more span {
  color: var(--action);
}

.btn-more:hover,
.post-card:hover .btn-more:hover {
  background: var(--action-deep);
  border-color: var(--action-deep);
  color: var(--paper);
}

.btn-more:hover span,
.post-card:hover .btn-more:hover span {
  color: var(--paper);
}

/* --------------------------------------------------------------------------
   Page d'orientation d'une rubrique
   -------------------------------------------------------------------------- */

.orientation {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  border: var(--line);
  border-right: 0;
  margin-bottom: var(--gap);
}

.orientation-block {
  display: flex;
  flex-direction: column;
  padding: var(--pad);
  border-right: var(--line);
}

.orientation-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  padding-bottom: 9px;
  margin-bottom: 12px;
  border-bottom: var(--line);
}

.orientation-title {
  margin: 0;
  font-size: 0.98rem;
  font-weight: 500;
}

.orientation-count {
  margin: 0;
  font-family: var(--font-mono);
  font-size: 0.66rem;
  text-transform: uppercase;
  color: var(--ink-70);
  white-space: nowrap;
}

.orientation-intro {
  margin: 0 0 16px;
  font-size: 0.88rem;
  color: var(--ink);
}

.orientation-list {
  list-style: none;
  margin: 0 0 18px;
  padding: 0;
  border-top: var(--line-thin);
}

.orientation-item {
  display: flex;
  gap: 12px;
  padding: 9px 0;
  border-bottom: var(--line-thin);
}

.orientation-thumb {
  flex: 0 0 68px;
  display: block;
}

.orientation-thumb img {
  border: var(--line-thin);
}

.orientation-thumb img {
  display: block;
  width: 100%;
  aspect-ratio: 1200 / 630;
  object-fit: cover;
}

.orientation-item-body {
  min-width: 0;
}

.orientation-item-title {
  margin: 0 0 2px;
  font-size: 0.88rem;
  font-weight: 400;
}

.orientation-item-date {
  margin: 0;
  font-family: var(--font-mono);
  font-size: 0.64rem;
  text-transform: uppercase;
  color: var(--ink-70);
}

.orientation-more {
  margin-top: auto;
  align-self: flex-start;
}

/* --------------------------------------------------------------------------
   Article
   -------------------------------------------------------------------------- */

.article-header {
  border: var(--line);
  border-bottom: 0;
  padding: var(--pad);
}

.article-tag {
  display: block;
  margin-bottom: 10px;
  font-family: var(--font-mono);
  font-size: 0.68rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-70);
}

.article-header h1 {
  margin: 0 0 10px;
}

.article-meta {
  margin: 0;
  font-family: var(--font-mono);
  font-size: 0.7rem;
  text-transform: uppercase;
  color: var(--ink-70);
}

.article-hero {
  display: block;
  width: 100%;
  aspect-ratio: 1200 / 630;
  object-fit: cover;
  border: var(--line);
  border-bottom: 0;
}

.article-body {
  border: var(--line);
  padding: var(--pad);
  margin-bottom: var(--gap);
  font-size: 1rem;
}

.article-body > *:last-child {
  margin-bottom: 0;
}

.article-body h2 {
  margin: 28px 0 10px;
  padding-bottom: 7px;
  border-bottom: var(--line-thin);
}

.article-body ul {
  list-style: none;
  margin: 0 0 15px;
  padding: 0;
}

.article-body ul li {
  position: relative;
  padding-left: 18px;
  margin-bottom: 5px;
}

/* Puce carrée pleine — la seule marque décorative du document. */
.article-body ul li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0.58em;
  width: 6px;
  height: 6px;
  background: var(--ink);
}

.article-body ol {
  padding-left: 20px;
}

.article-body blockquote {
  margin: 22px 0;
  padding: 12px 18px;
  border-left: 3px solid var(--ink);
  background: var(--ink-06);
  color: var(--ink);
}

.article-body code {
  padding: 1px 5px;
  background: var(--ink-06);
  font-family: var(--font-mono);
  font-size: 0.88em;
}

.share-block {
  border: var(--line);
  margin-bottom: var(--gap);
}

.share-block > p {
  margin: 0;
}

.share-links {
  display: flex;
  flex-wrap: wrap;
}

.share-links a,
.share-links button {
  padding: 10px var(--pad);
  border: 0;
  border-right: var(--line);
  background: var(--paper);
  color: var(--ink);
  font-family: var(--font-mono);
  font-size: 0.7rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  cursor: pointer;
}

.share-links a:hover,
.share-links button:hover {
  text-decoration: none;
  background: var(--ink);
  color: var(--paper);
}

.back-link {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

/* --------------------------------------------------------------------------
   Liste des espèces
   -------------------------------------------------------------------------- */

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

.taxon {
  font-style: italic;
}

.species-disclaimer {
  margin-top: 14px;
  padding-top: 12px;
  border-top: var(--line-thin);
  font-size: 0.86rem;
  color: var(--ink);
}

.species-legend {
  border: var(--line);
  margin-bottom: var(--gap);
}

.species-legend-title {
  margin: 0;
}

.species-legend-list {
  margin: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
}

.species-legend-item {
  padding: 14px var(--pad);
  border-right: var(--line-thin);
}

.species-legend-item:last-child {
  border-right: 0;
}

.species-legend-item dt {
  font-family: var(--font-mono);
  font-size: 0.74rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.species-legend-item dd {
  margin: 5px 0 0;
  font-size: 0.82rem;
  color: var(--ink);
}

.species-mark {
  display: inline-block;
  min-width: 1.1em;
  text-align: center;
  font-weight: 700;
}

.species-icon {
  width: 0.9em;
  height: 0.9em;
  vertical-align: -0.1em;
}

/* ---- Barre d'outils : trois axes de tri qui se combinent ---- */

.species-toolbar {
  border: var(--line);
  margin-bottom: var(--gap);
}

.species-search {
  display: flex;
  align-items: stretch;
  border-bottom: var(--line);
}

.species-search-label {
  display: flex;
  align-items: center;
  flex: 0 0 118px;
  padding: 0 var(--pad);
  border-right: var(--line);
  font-family: var(--font-mono);
  font-size: 0.68rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-70);
}

.species-search-input {
  flex: 1 1 auto;
  min-width: 0;
  padding: 11px var(--pad);
  border: 0;
  background: var(--paper);
  font-family: var(--font-mono);
  font-size: 0.82rem;
  color: var(--ink);
}

.species-search-input:focus {
  outline: none;
  background: var(--ink-06);
}

.species-filter-row {
  display: flex;
  align-items: stretch;
  border-bottom: var(--line);
}

.species-filter-row:last-of-type {
  border-bottom: 0;
}

.species-filter-legend {
  display: flex;
  align-items: center;
  flex: 0 0 118px;
  padding: 0 var(--pad);
  border-right: var(--line);
  font-family: var(--font-mono);
  font-size: 0.68rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-70);
}

.species-filter-row .filter-bar {
  flex: 1 1 auto;
  min-width: 0;
}

.species-toolbar .filter-status {
  border-top: var(--line);
}

/* ---- Groupes ---- */

.species-group {
  border: var(--line);
  margin-bottom: var(--gap);
}

.species-group-title {
  display: flex;
  align-items: center;
  gap: var(--pad);
  margin: 0;
  padding: 0 var(--pad) 0 0;
  background: var(--ink);
  color: var(--paper);
  font-size: 0.96rem;
  font-weight: 500;
}

/* Le badge du numéro s'inverse : sur un en-tête devenu plein, un aplat
   d'encre sur l'encre ne se verrait plus. */
.species-group-number {
  display: flex;
  align-items: center;
  align-self: stretch;
  padding: 10px var(--pad);
  border-right: var(--line-light);
  background: transparent;
  color: var(--paper);
  font-family: var(--font-mono);
  font-size: 0.66rem;
  font-weight: 400;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  white-space: nowrap;
}

.species-group-intro {
  margin: 0;
  padding: 12px var(--pad);
  border-bottom: var(--line-thin);
  max-width: none;
  font-size: 0.86rem;
  color: var(--ink);
}

/* ---- Lignes dépliables ---- */

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

.species-item {
  border-bottom: var(--line-thin);
}

.species-item:last-child {
  border-bottom: 0;
}

.species-summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  padding: 9px var(--pad);
  cursor: pointer;
  list-style: none;
}

.species-summary::-webkit-details-marker {
  display: none;
}

.species-summary::marker {
  content: '';
}

.species-summary:hover {
  background: var(--ink-06);
}

.species-name {
  font-size: 0.95rem;
}

/* Voyant d'ouverture : un carré creux qui se remplit quand la fiche est
   dépliée. Le pseudo-élément n'est pas dans le DOM et l'état ouvert/fermé
   est déjà porté par <details> : rien à annoncer en plus. */
.species-name::before {
  content: '';
  display: inline-block;
  width: 7px;
  height: 7px;
  margin-right: 11px;
  vertical-align: 0.06em;
  border: 1px solid var(--ink);
}

.species-details[open] .species-name::before {
  background: var(--ink);
}

.species-marks {
  flex-shrink: 0;
  font-family: var(--font-mono);
  font-size: 0.86rem;
  white-space: nowrap;
}

.species-panel {
  padding: 0 var(--pad) var(--pad) 46px;
}

.species-note {
  margin: 0 0 14px;
  padding: 9px 14px;
  border-left: 3px solid var(--ink);
  background: var(--ink-06);
  max-width: none;
  font-size: 0.88rem;
}

/* Les filets de cette grille ne sont PAS des bordures de cellule mais le
   fond du conteneur, laissé visible par une gouttière d'un pixel. Avec
   des bordures, une grille qui passe à la ligne double le trait là où
   une cellule finit une rangée sans être la dernière — c'était visible à
   1024 px depuis l'ajout d'une sixième source. Ici, le trait est unique
   par construction, horizontalement comme verticalement, quel que soit
   le nombre de cellules et de rangées.
   Les cellules portent leur propre fond de papier : c'est lui qui laisse
   la gouttière apparaître, et il satisfait au passage la règle des
   cellules opaques. */
.species-links {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  /* Le nombre de colonnes est FIXÉ, et toujours un diviseur du nombre de
     sources (6 → 6, 3, 2, 1). Avec « auto-fit », la grille tombait sur
     5 colonnes vers 1024 px : la dernière rangée restait incomplète et
     laissait voir le fond du conteneur là où il n'y avait pas de cellule.
     Si une source est ajoutée ou retirée un jour, ces quatre valeurs sont
     à revoir en même temps. */
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: 1px;
  background: var(--ink-12);
  border: var(--line-thin);
}

@media (max-width: 1180px) {
  .species-links { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

@media (max-width: 700px) {
  .species-links { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 430px) {
  .species-links { grid-template-columns: minmax(0, 1fr); }
}

.species-links li {
  background: var(--paper);
}

.species-link {
  display: block;
  height: 100%;
  padding: 9px 12px;
}

.species-link:hover {
  text-decoration: none;
  background: var(--ink);
  color: var(--paper);
}

.species-link-name {
  display: block;
  font-family: var(--font-mono);
  font-size: 0.72rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.species-link-hint {
  display: block;
  margin-top: 2px;
  font-size: 0.72rem;
  color: var(--ink);
}

.species-link:hover .species-link-hint {
  color: var(--on-ink-muted);
}

/* Source qui N'A PAS de page pour ce taxon. La cellule garde sa place
   dans la grille — retirer la ligne ferait croire à un oubli, et laisser
   un lien de recherche qui ne trouve rien ferait croire à une panne.
   Ce n'est pas un <a> : rien à cliquer, rien dans le parcours au
   clavier, et pas de survol qui promettrait une destination. */
.species-link-absent {
  cursor: default;
  color: var(--ink-70);
}

.species-link-absent .species-link-hint {
  color: var(--ink-70);
  font-style: italic;
}

.species-share {
  display: flex;
  align-items: center;
  gap: 18px;
  flex-wrap: wrap;
  margin: 14px 0 0;
  font-family: var(--font-mono);
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
}

.species-copy {
  font: inherit;
}

/* ---- Page d'une seule espèce ---- */

.species-page {
  display: block;
}

.species-breadcrumb {
  padding: 9px var(--pad);
  border: var(--line);
  border-bottom: 0;
  font-family: var(--font-mono);
  font-size: 0.68rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-70);
}

.species-breadcrumb-sep {
  margin: 0 8px;
}

.species-page-head {
  padding: var(--pad);
  border: var(--line);
  border-bottom: 0;
}

.species-page-title {
  margin: 0 0 12px;
}

.species-page-status,
.species-page-flag {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  margin: 0 8px 0 0;
  padding: 5px 12px;
  border: var(--line);
  font-family: var(--font-mono);
  font-size: 0.7rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.species-page-section {
  border: var(--line);
  border-bottom: 0;
}

/* Le corps de la section : c'est lui qui porte le rembourrage, l'en-tête
   allant d'un filet à l'autre. */
.species-page-body {
  padding: var(--pad);
}

.species-page-back {
  margin: 0;
  padding: var(--pad);
  border: var(--line);
  margin-bottom: var(--gap);
}

.species-apercu-note {
  margin: 0 0 var(--gap);
  padding: 12px var(--pad);
  border: var(--line);
  max-width: none;
  font-size: 0.82rem;
  color: var(--ink);
}

.species-apercu-note code {
  font-family: var(--font-mono);
}

/* --------------------------------------------------------------------------
   Pied de page : deux cellules fines — l'horloge d'un côté, la mention de
   droit d'auteur de l'autre. Le bloc de navigation le précède.
   -------------------------------------------------------------------------- */

.site-footer {
  border: var(--line);
}

.site-footer-main .site-footer-inner {
  display: grid;
  grid-template-columns: minmax(240px, 1.4fr) repeat(auto-fit, minmax(170px, 1fr));
}

.footer-brand,
.footer-col {
  padding: var(--pad);
  border-right: var(--line);
}

.footer-col:last-child {
  border-right: 0;
}

.footer-name {
  margin: 0 0 8px;
  font-family: var(--font-mono);
  font-size: 0.76rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.footer-desc {
  margin: 0;
  max-width: 46ch;
  font-size: 0.84rem;
  color: var(--ink);
}

.footer-heading {
  margin: 0 0 10px;
  font-family: var(--font-mono);
  font-size: 0.66rem;
  font-weight: 400;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-70);
}

.footer-list {
  list-style: none;
  margin: 0;
  padding: 0;
  font-size: 0.84rem;
}

.footer-list li {
  margin-bottom: 5px;
}

.footer-sub a {
  padding-left: 14px;
  color: var(--ink-70);
}

.site-footer-bottom {
  border-top: var(--line);
}

.site-footer-bottom .site-footer-inner {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
}

.footer-legal,
.footer-admin {
  margin: 0;
  padding: 9px var(--pad);
  font-family: var(--font-mono);
  font-size: 0.7rem;
  color: var(--ink-70);
}

.footer-legal {
  border-right: var(--line);
}

/* L'horloge : la date est écrite par le serveur, l'heure ajoutée par
   public/js/horloge.js. Sans JavaScript, la date reste — mais pas une
   heure figée, qui serait fausse dès la seconde suivante. */
.clock {
  font-variant-numeric: tabular-nums;
}

/* --------------------------------------------------------------------------
   Messages, formulaires, tableaux (administration)
   -------------------------------------------------------------------------- */

.flash {
  margin: 0 0 var(--gap);
  padding: 11px var(--pad);
  border: var(--line);
  border-left-width: 3px;
  font-size: 0.88rem;
}

.flash-error {
  border-color: var(--danger);
  color: var(--danger);
}

.error-list {
  margin: 0 0 var(--gap);
  padding: 12px 18px 12px 34px;
  border: 1px solid var(--danger);
  border-left-width: 3px;
  color: var(--danger);
  font-size: 0.88rem;
}

.form-card {
  border: var(--line);
  padding: var(--pad);
  margin-bottom: var(--gap);
}

.form-card.narrow {
  max-width: 460px;
}

.login-wrapper {
  display: flex;
  justify-content: center;
}

.form-field {
  margin-bottom: 18px;
}

.form-field label {
  display: block;
  margin-bottom: 6px;
  font-family: var(--font-mono);
  font-size: 0.68rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-70);
}

.form-field .hint {
  display: block;
  margin-top: 4px;
  font-family: var(--font-sans);
  font-size: 0.8rem;
  letter-spacing: 0;
  text-transform: none;
  color: var(--ink);
}

.form-field input,
.form-field select,
.form-field textarea {
  width: 100%;
  padding: 9px 12px;
  border: var(--line);
  background: var(--paper);
  font-family: var(--font-sans);
  font-size: 0.92rem;
  color: var(--ink);
}

.form-field textarea {
  min-height: 220px;
  font-family: var(--font-mono);
  font-size: 0.84rem;
}

.form-field textarea.textarea-short {
  min-height: 76px;
  font-family: var(--font-sans);
  font-size: 0.92rem;
}

.form-field input:focus,
.form-field select:focus,
.form-field textarea:focus {
  outline: none;
  background: var(--ink-06);
}

.checkbox-field {
  display: flex;
  align-items: center;
  gap: 10px;
  cursor: pointer;
  font-family: var(--font-sans);
  font-size: 0.92rem;
  letter-spacing: 0;
  text-transform: none;
  color: var(--ink);
}

.checkbox-field input {
  width: auto;
  margin: 0;
  accent-color: var(--ink);
}

.form-details {
  margin-bottom: 20px;
  padding: 14px var(--pad);
  border: var(--line-thin);
}

.form-details > summary {
  cursor: pointer;
  font-family: var(--font-mono);
  font-size: 0.74rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.form-details-intro {
  margin: 12px 0 18px;
}

.form-derived {
  margin: 0 0 6px;
  font-family: var(--font-mono);
  font-size: 0.74rem;
  word-break: break-all;
}

.form-actions {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
}

.dashboard-header {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  padding: var(--pad);
  border: var(--line);
  margin-bottom: var(--gap);
}

/* Les tableaux de l'administration. Cinq colonnes ne tiennent pas dans
   360 px : sans précaution, c'est la PAGE ENTIÈRE qui prenait la largeur
   du tableau et défilait latéralement — mesuré à +136 px sur le tableau
   de bord et +171 px sur la page des comptes.
   Le défilement est confié à un conteneur, et non au tableau lui-même :
   « display: block » sur un <table> le ferait bien défiler, mais la
   structure de tableau reconstruite à l'intérieur se calerait sur la
   largeur de son contenu — sur grand écran, les filets d'en-tête
   s'arrêtaient alors au milieu de la rangée. */
.table-scroll {
  overflow-x: auto;
  margin-bottom: var(--gap);
  background: var(--paper);
}

.post-table {
  width: 100%;
  /* En deçà, les colonnes se compriment jusqu'à l'illisible : mieux vaut
     faire défiler le tableau que d'empiler un mot par ligne. */
  min-width: 620px;
  border-collapse: collapse;
  border: var(--line);
  margin-bottom: 0;
  font-size: 0.86rem;
}

.post-table th,
.post-table td {
  padding: 9px 12px;
  text-align: left;
  border-bottom: var(--line-thin);
  border-right: var(--line-thin);
  vertical-align: top;
}

.post-table th:last-child,
.post-table td:last-child {
  border-right: 0;
}

.post-table th {
  font-family: var(--font-mono);
  font-size: 0.66rem;
  font-weight: 400;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-70);
  border-bottom: var(--line);
}

.status-badge {
  display: inline-block;
  padding: 2px 8px;
  border: var(--line);
  font-family: var(--font-mono);
  font-size: 0.64rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.status-published {
  background: var(--ink);
  color: var(--paper);
}

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

.table-actions form {
  display: inline;
}

.empty-state {
  padding: 40px var(--pad);
  border: var(--line);
  margin-bottom: var(--gap);
  text-align: center;
  font-family: var(--font-mono);
  font-size: 0.8rem;
  color: var(--ink);
}

/* Date de dernière mise à jour d'une page fixe. Elle reprend la cellule
   du lien de retour — même filet, même rembourrage — mais en registre de
   note : c'est une mention de bas de page, pas une action. */
.page-updated {
  font-family: var(--font-mono);
  font-size: 0.72rem;
  color: var(--ink-70);
}

.thumb-preview {
  margin-top: 10px;
  max-width: 320px;
  border: var(--line);
}

/* --------------------------------------------------------------------------
   Utilitaires
   La politique de sécurité interdit les styles écrits dans les balises
   (style="..."), vecteur classique d'injection : tout passe par une classe.
   -------------------------------------------------------------------------- */

.is-hidden { display: none !important; }
.no-margin { margin: 0; }
.no-margin-top { margin-top: 0; }
.space-below { margin-bottom: var(--gap); }
.field-spacer { margin-top: 8px; }

/* --------------------------------------------------------------------------
   Écrans étroits — la grille se replie en colonnes empilées, mais les
   filets restent : c'est eux qui font le document.
   -------------------------------------------------------------------------- */

@media (max-width: 900px) {
  :root {
    --gap: 12px;
    --pad: 14px;
  }

  .site-header-inner,
  .hero-inner,
  .community-inner {
    grid-template-columns: minmax(0, 1fr);
  }

  .header-identity,
  .hero-text,
  .community-text {
    border-right: 0;
    border-bottom: var(--line);
  }

  .hero-media {
    min-height: 240px;
    padding: 18px;
  }

  .community-actions {
    flex-wrap: wrap;
  }

  /* Le bouton Discord est repris avec les autres : quand la rangée passe
     à la ligne, chaque cellule a besoin de son filet inférieur. */
  .community-actions .btn,
  .social-link {
    flex: 1 1 auto;
    border-bottom: var(--line);
  }

  .post-card {
    grid-template-columns: 42px minmax(0, 1fr);
  }

  .post-card-media {
    grid-column: 2;
    border-right: 0;
    border-bottom: var(--line);
  }

  .post-card-body {
    grid-column: 2;
  }

  .post-card-index {
    grid-row: 1 / span 2;
  }

  .site-footer-main .site-footer-inner,
  .site-footer-bottom .site-footer-inner {
    grid-template-columns: minmax(0, 1fr);
  }

  .footer-brand,
  .footer-col,
  .footer-legal {
    border-right: 0;
    border-bottom: var(--line);
  }

  .footer-col:last-child {
    border-bottom: 0;
  }

  .species-search,
  .species-filter-row {
    display: block;
  }

  .species-search-label,
  .species-filter-legend {
    display: block;
    padding: 7px var(--pad);
    border-right: 0;
    border-bottom: var(--line-thin);
  }

  .species-legend-item {
    border-right: 0;
    border-bottom: var(--line-thin);
  }

  .species-legend-item:last-child {
    border-bottom: 0;
  }

  .species-panel {
    padding-left: var(--pad);
  }

  .orientation {
    grid-template-columns: minmax(0, 1fr);
    border-right: var(--line);
  }

  .orientation-block {
    border-right: 0;
    border-bottom: var(--line);
  }

  .orientation-block:last-child {
    border-bottom: 0;
  }
}
