/* ==========================================================================
   Fondations partagées
   --------------------------------------------------------------------------
   Base CSS commune à tous les thèmes : reset léger, accessibilité, typographie
   HTML native, gestion du mode couleur et rendu impression.
   ========================================================================== */

/* Reset minimal : assez pour stabiliser le rendu sans effacer les styles natifs utiles. */
* {
  box-sizing: border-box;
}

/* Le color-scheme suit le mode choisi par l'utilisateur ou la préférence système. */
html {
  min-height: 100%;
  color-scheme: light;
  background: var(--color-bg);
}

/* Mode sombre forc? : informe le navigateur des contr?les et couleurs natives attendues. */
html[data-color-mode='dark'] {
  color-scheme: dark;
}

/* Mode sombre syst?me : utilis? uniquement tant que le site n'a pas de choix explicite. */
@media (prefers-color-scheme: dark) {
  html:not([data-color-mode]) {
    color-scheme: dark;
  }
}

/* Document : supprime les marges natives et garantit une hauteur pleine page. */
html,
body {
  margin: 0;
  min-height: 100%;
}

/* Typographie de base pilotée par les variables exposées par chaque thème. */
body {
  color: var(--color-text);
  background: var(--color-bg);
  font-family: var(--font-body);
  font-size: 1rem;
  line-height: 1.6;
}

/* Liens accessibles : couleur thème + soulignement seulement à l'interaction. */
a {
  color: var(--color-accent);
  text-decoration: none;
  text-underline-offset: 0.2em;
}

/* Interaction lien : le soulignement appara?t seulement au survol ou focus clavier. */
a:hover,
a:focus-visible {
  color: var(--color-accent-hover);
  text-decoration: underline;
}

/* Focus clavier visible et cohérent avec la couleur d'accent du thème. */
:focus-visible {
  outline: 2px solid var(--color-focus);
  outline-offset: 3px;
}

/* Titres génériques : les pages et articles peuvent ensuite préciser leur mise en forme. */
h1,
h2,
/* H3 g?n?rique : niveau de titre compact. */
h3 {
  color: var(--color-text);
  font-family: var(--font-heading);
  line-height: 1.25;
  text-wrap: balance;
}

/* H1 g?n?rique : taille fluide utilis?e hors variantes sp?cifiques de th?me. */
h1 {
  margin-block: 0 1.5rem;
  font-size: clamp(2rem, 6vw, 2.75rem);
}

/* H2 g?n?rique : rythme vertical des sous-sections. */
h2 {
  margin-block: 2rem 0.75rem;
}

h3 {
  margin-block: 1.5rem 0.5rem;
}

/* Paragraphes g?n?riques : couleur secondaire par d?faut. */
p {
  color: var(--color-text-muted);
}

/* Listes g?n?riques : retrait lisible sans d?pendre du navigateur. */
ul,
ol {
  padding-inline-start: 1.25rem;
}

/* Items de liste : respiration verticale minimale. */
li {
  margin-block: 0.5rem;
}

/* Images natives : emp?chent tout d?bordement horizontal par d?faut. */
img {
  max-width: 100%;
}

/* Contr?les de formulaire : h?ritent de la police du th?me. */
button,
input,
select,
textarea {
  font: inherit;
}

/* Classe utilitaire pour le texte lisible par lecteur d'écran uniquement. */
.visually-hidden {
  position: absolute !important;
  width: 1px !important;
  height: 1px !important;
  padding: 0 !important;
  margin: -1px !important;
  overflow: hidden !important;
  clip: rect(0, 0, 0, 0) !important;
  white-space: nowrap !important;
  border: 0 !important;
}

/* Code natif : police monospace fournie par le th?me actif. */
pre,
code {
  font-family: var(--font-mono);
}

/* Respect des préférences utilisateur : pas d'animations forcées. */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    scroll-behavior: auto !important;
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* Version imprimable : contraste maximal, pas d'éléments interactifs. */
/* Impression : force un rendu clair et retire les ?l?ments purement interactifs. */
@media print {
  /* Variables d'impression : contraste maximal noir sur blanc. */
  :root {
    --color-bg: #ffffff;
    --color-surface: #ffffff;
    --color-surface-alt: #ffffff;
    --color-text: #000000;
    --color-text-muted: #222222;
    --color-border: #777777;
    --color-accent: #000000;
    --color-accent-hover: #000000;
  }

  /* ?l?ments non imprimables : effets d'?cran et switch de th?me. */
  body::before,
  .color-mode-switch {
    display: none !important;
  }
}

/* ==========================================================================
   Layout de lecture partagé
   --------------------------------------------------------------------------
   Rendu commun des pages et des articles après transformation Markdown par
   Astro : largeur de lecture, typographie d'article, tableaux, images, code et
   zoom. Les thèmes gardent la main via les variables CSS.
   ========================================================================== */

/* Conteneur principal : largeur globale et respiration verticale. */
.site-main {
  width: min(100% - 2rem, var(--content-width));
  margin: 0 auto;
  padding-block: var(--space-page) calc(var(--space-page) * 2);
}

/* Les articles utilisent une largeur de lecture dédiée, souvent plus étroite. */
.site-main--article {
  max-width: var(--reading-width);
}

/* Base typographique du contenu Markdown rendu par Astro. */
.article-content {
  font-size: 1.05rem;
}

/* Rythme vertical commun des blocs Markdown principaux. */
.article-content > :where(p, ul, ol, pre, blockquote, table, details, figure) {
  margin-block: 1.15rem;
}

/* Hiérarchie de titres dans les articles, indépendante du header de page. */
.article-content :where(h1, h2, h3, h4, h5, h6) {
  color: var(--color-text);
  line-height: 1.2;
}

/* Sous-titres d'article : marge haute suffisante pour rythmer la lecture. */
.article-content :where(h2, h3, h4, h5, h6) {
  margin-block: 2.5rem 0.8rem;
}

/* H2 article : niveau de section principal dans le Markdown. */
.article-content h2 {
  font-size: clamp(1.55rem, 4vw, 2rem);
}

/* H3 article : sous-section compacte. */
.article-content h3 {
  font-size: clamp(1.25rem, 3vw, 1.55rem);
}

/* H4 article : titre discret de niveau profond. */
.article-content h4 {
  font-size: 1.1rem;
}

/* H5/H6 article : niveaux rares, rendus comme intertitres techniques. */
.article-content :where(h5, h6) {
  font-size: 1rem;
  letter-spacing: 0.02em;
  text-transform: uppercase;
}

/* Paragraphe d'article : interligne confortable pour la lecture longue. */
.article-content p {
  line-height: 1.75;
}

/* Liens d'article : accent th?matique et soulignement lisible. */
.article-content a {
  color: var(--color-accent);
  text-decoration-thickness: 0.08em;
  text-underline-offset: 0.18em;
}

/* Interaction lien d'article : couleur d'accent renforc?e. */
.article-content a:hover {
  color: var(--color-accent-hover);
}

/* Liens externes : petit indicateur visuel sans modifier le Markdown source. */
.article-content a.external-link::after {
  content: '';
  display: inline-block;
  width: 0.82em;
  height: 0.82em;
  margin-inline-start: 0.22em;
  background: currentColor;
  text-decoration: none;
  vertical-align: -0.02em;
  mask: var(--icon-external-link) center / contain no-repeat;
  -webkit-mask: var(--icon-external-link) center / contain no-repeat;
}

/* Liens GitHub : icône dédiée et suppression de l'indicateur externe générique. */
.article-content a.github-link::before {
  content: '';
  display: inline-block;
  width: 1em;
  height: 1em;
  margin-inline-end: 0.28em;
  background: currentColor;
  vertical-align: -0.12em;
  mask: var(--icon-github) center / contain no-repeat;
  -webkit-mask: var(--icon-github) center / contain no-repeat;
}

/* Liens GitHub : retire l'ic?ne externe g?n?rique pour ?viter le doublon. */
.article-content a.github-link::after {
  content: none;
}

/* Listes, citations, séparateurs et code inline : couverture Markdown de base. */
/* Listes Markdown : retrait commun des listes ordonn?es et non ordonn?es. */
.article-content :where(ul, ol) {
  padding-inline-start: 1.5rem;
}

/* Listes imbriqu?es : rythme r?duit pour rester group?es. */
.article-content :where(ul, ol) :where(ul, ol) {
  margin-block: 0.35rem;
}

/* Item Markdown : respiration verticale l?g?re. */
.article-content li {
  margin-block: 0.35rem;
}

/* Strong Markdown : renforce aussi la couleur, pas seulement le poids. */
.article-content strong {
  color: var(--color-text);
  font-weight: 700;
}

/* Citation Markdown : filet d'accent et surface secondaire. */
.article-content blockquote {
  margin-inline: 0;
  padding: 0.25rem 1rem;
  border-inline-start: 4px solid var(--color-accent);
  background: var(--color-surface-alt);
}

/* S?parateur Markdown : filet horizontal discret. */
.article-content hr {
  margin-block: 2.5rem;
  border: 0;
  border-top: 1px solid var(--color-border);
}

/* Code inline : capsule lisible sans prendre le style des blocs de code. */
.article-content :not(pre) > code {
  padding: 0.1em 0.35em;
  background: var(--color-surface-alt);
  border: 1px solid var(--color-border);
  border-radius: 4px;
  font-size: 0.9em;
}

/* Figures générées automatiquement autour des images seules, avec légende issue du alt. */
.article-figure {
  display: grid;
  justify-items: center;
  gap: 0.65rem;
  margin-inline: auto;
}

/* L?gende d'image : texte secondaire centr? sous la figure. */
.article-figure figcaption {
  max-width: min(100%, var(--reading-width));
  color: var(--color-text-muted);
  font-size: 0.9rem;
  line-height: 1.55;
  text-align: center;
}

/* Images d'article : dimensions conservées, centrage, lazy-loading côté HTML. */
.article-content img,
.article-image {
  display: block;
  width: min(100%, var(--reading-width));
  height: auto;
  margin: 1.5rem auto;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-card);
}

/* Image dans figure : la figure porte d?j? les marges. */
.article-figure .article-image {
  margin: 0;
}

/* Variantes de cadrage selon l'orientation détectée de l'image. */
/* Image portrait : limite la hauteur pour rester visible sans scroll excessif. */
.article-image--portrait {
  width: auto;
  max-width: min(100%, 34rem);
  max-height: 72vh;
  object-fit: contain;
}

/* Image paysage : hauteur born?e avec conservation du ratio. */
.article-image--landscape {
  max-height: 72vh;
  object-fit: contain;
}

/* Image zoomable : curseur explicite pour annoncer l'interaction. */
.article-image--zoomable {
  cursor: zoom-in;
}

/* Image zoomable au survol : bordure accentu?e. */
.article-image--zoomable:hover {
  border-color: var(--color-accent);
}

/* Médias embarqués Markdown/HTML : vidéos et iframes restent fluides sur mobile. */
.article-content video,
/* Iframe Markdown/HTML : ratio 16/9 pour embeds vid?o et d?mos. */
.article-content iframe {
  display: block;
  width: min(100%, var(--reading-width));
  max-width: 100%;
  margin: 1.5rem auto;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-card);
}

/* Vid?o Markdown/HTML : ratio natif et fond noir. */
.article-content video {
  height: auto;
  background: #000;
}

.article-content iframe {
  aspect-ratio: 16 / 9;
  height: auto;
  background: var(--color-surface-alt);
}

/* Tableaux Markdown : scroll horizontal plutôt qu'écrasement sur mobile. */
.article-content table {
  display: block;
  width: max-content;
  max-width: 100%;
  overflow-x: auto;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-card);
  border-spacing: 0;
  border-collapse: separate;
  background: var(--color-surface);
  box-shadow: var(--shadow-card);
}

/* Cellules de tableau : padding et bordures communes. */
.article-content th,
.article-content td {
  padding: 0.75rem 1rem;
  border-block-end: 1px solid var(--color-border);
  text-align: left;
  vertical-align: top;
}

/* En-t?te de tableau : surface secondaire et texte renforc?. */
.article-content th {
  color: var(--color-text);
  background: var(--color-surface-alt);
  font-weight: 700;
}

/* Derni?re ligne de tableau : supprime la bordure basse finale. */
.article-content tr:last-child > :where(th, td) {
  border-block-end: 0;
}

/* Colonnes de tableau : s?paration verticale entre cellules. */
.article-content th:not(:last-child),
.article-content td:not(:last-child) {
  border-inline-end: 1px solid var(--color-border);
}

/* Blocs details/summary natifs, pour documenter des sections repliables. */
.article-content details {
  padding: 1rem;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-card);
  background: var(--color-surface);
  box-shadow: var(--shadow-card);
}

/* Summary natif : indique l'interaction d'ouverture. */
.article-content summary {
  cursor: pointer;
  color: var(--color-text);
  font-weight: 700;
}

/* Details : ?vite une marge basse doubl?e sur le dernier enfant. */
.article-content details > :last-child {
  margin-block-end: 0;
}

/* Fallback pour les blocs pre simples, avant enrichissement JS éventuel. */
/* Pr?format? natif : fallback des blocs de code avant enrichissement JS. */
pre {
  overflow: auto;
  max-width: 100%;
  padding: 1rem;
  color: var(--color-code-text);
  background: var(--color-code-bg);
  border: 1px solid var(--color-code-border);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-card);
  font-size: 0.9rem;
  line-height: 1.55;
}

/* Bloc de code enrichi par JS : nom du langage + bouton copier. */
.code-block {
  margin-block: 1.15rem;
  border: 1px solid var(--color-code-border);
  border-radius: var(--radius-card);
  overflow: hidden;
  background: var(--color-code-bg);
  box-shadow: var(--shadow-card);
}

/* Bloc de code dans article : m?me rythme que les blocs Markdown. */
.article-content > .code-block {
  margin-block: 1.15rem;
}

/* En-t?te de bloc de code : langage ? gauche, bouton copier ? droite. */
.code-block-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.45rem 0.65rem;
  color: var(--color-code-text);
  background: color-mix(in srgb, var(--color-code-bg) 88%, var(--color-text));
  border-block-end: 1px solid var(--color-code-border);
  font-family: var(--font-mono);
  font-size: 0.75rem;
}

/* Nom du langage : secondaire pour ne pas concurrencer le code. */
.code-block-language {
  color: color-mix(in srgb, var(--color-code-text) 78%, transparent);
}

/* Bouton copier : contr?le discret mais accessible. */
.code-block-copy {
  padding: 0.25rem 0.55rem;
  color: var(--color-code-text);
  background: transparent;
  border: 1px solid color-mix(in srgb, var(--color-code-text) 30%, transparent);
  border-radius: var(--radius-control);
  cursor: pointer;
  font: inherit;
}

/* Bouton copier au survol : bordure renforc?e. */
.code-block-copy:hover {
  border-color: var(--color-code-text);
}

/* Pre enrichi : retire les styles d?j? port?s par le conteneur code-block. */
.code-block pre {
  margin: 0;
  border: 0;
  border-radius: 0;
  box-shadow: none;
}

/* Overlay de zoom image : activé par public/scripts/image-zoom.js. */
/* ?tat zoom ouvert : bloque le scroll de la page. */
.image-zoom-open {
  overflow: hidden;
}

/* Overlay masqu? : vrai retrait du flux d'affichage. */
.image-zoom[hidden] {
  display: none;
}

/* Overlay zoom : calque plein ?cran centr?. */
.image-zoom {
  position: fixed;
  z-index: 1000;
  inset: 0;
  display: grid;
  place-items: center;
  padding: 1.25rem;
  background: color-mix(in srgb, var(--color-bg) 18%, rgba(0, 0, 0, 0.88));
}

/* Figure zoom?e : image et l?gende centr?es. */
.image-zoom-figure {
  display: grid;
  justify-items: center;
  gap: 0.75rem;
  max-width: min(100%, 1200px);
  margin: 0;
}

/* Image zoom?e : taille maximale contr?l?e dans la fen?tre. */
.image-zoom-image {
  max-width: min(100%, 1200px);
  max-height: 84vh;
  width: auto;
  height: auto;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-card);
  box-shadow: 0 1.25rem 4rem rgba(0, 0, 0, 0.45);
}

/* L?gende zoom?e : lisible sur fond sombre. */
.image-zoom-caption {
  max-width: min(100%, var(--reading-width));
  color: #ffffff;
  font-size: 0.95rem;
  line-height: 1.5;
  text-align: center;
}

/* Bouton fermeture zoom : position fixe en haut ? droite. */
.image-zoom-close {
  position: fixed;
  inset-block-start: 1rem;
  inset-inline-end: 1rem;
  display: grid;
  place-items: center;
  width: 2.5rem;
  height: 2.5rem;
  color: #ffffff;
  background: rgba(0, 0, 0, 0.48);
  border: 1px solid rgba(255, 255, 255, 0.4);
  border-radius: var(--radius-control);
  cursor: pointer;
  font: 1.6rem/1 var(--font-body);
}

/* Fermeture zoom au survol : fond plus opaque. */
.image-zoom-close:hover {
  background: rgba(0, 0, 0, 0.68);
}

/* Ajustements de lecture mobile : plus compact, sans changer la hiérarchie. */
@media (max-width: 760px) {
  /* Mobile main : largeur plus compacte et rythme vertical r?duit. */
  .site-main {
    width: min(100% - 1.25rem, var(--content-width));
    padding-block: 1.25rem 3rem;
  }

  /* Mobile article : taille l?g?rement r?duite pour petits ?crans. */
  .article-content {
    font-size: 1rem;
  }
}

/* ==========================================================================
   Composants partagés
   --------------------------------------------------------------------------
   Structure UI commune aux thèmes : header, navigation, footer, listes
   d'articles, tags, couvertures, navigation d'article et pagination.
   ========================================================================== */

/* Header commun : calque au-dessus des effets de fond éventuels des thèmes. */
.site-header {
  position: relative;
  z-index: 1;
  border-bottom: 1px solid var(--color-border);
  background: var(--color-surface);
}

/* Navigation desktop : identité à gauche, liens et actions à droite. */
.site-nav {
  width: min(100% - 2rem, var(--content-width));
  margin: 0 auto;
  display: flex;
  gap: 1.5rem;
  align-items: center;
  justify-content: space-between;
  padding-block: 1rem;
}

/* Identité du site : titre cliquable et baseline optionnelle. */
.site-identity {
  min-width: 0;
}

/* Wrapper H1 de marque : garde la typographie du lien sans ajouter de style propre. */
.brand-heading {
  margin: 0;
  font: inherit;
  line-height: inherit;
}

/* Lien de marque : identit? textuelle principale du site. */
.brand {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  color: var(--color-text);
  font-family: var(--font-heading);
  font-size: clamp(1.25rem, 3vw, 1.75rem);
  font-weight: 700;
  letter-spacing: 0.04em;
}

/* Baseline : phrase courte optionnelle sous la marque. */
.site-tagline {
  margin: 0.2rem 0 0;
  color: var(--color-text-muted);
  font-family: var(--font-mono);
}

/* Zone d'actions : liens principaux et switch light/dark. */
.site-nav-actions,
.site-links,
/* Actions utilitaires : switch de th?me et ajouts ?ventuels propres aux th?mes. */
.site-utility-actions {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
}

/* Conteneur d'actions : regroupe navigation et utilitaires ? droite du header. */
.site-nav-actions {
  gap: 1rem;
  justify-content: flex-end;
}

.site-utility-actions {
  flex: 0 0 auto;
  gap: 0.65rem;
}

/* Liens de navigation : état courant via aria-current. */
.site-links {
  gap: 0.75rem 1.25rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

/* Items de navigation : neutralise les marges de liste. */
.site-links li {
  margin: 0;
}

/* Lien de navigation : grande zone cliquable et ?tat courant possible. */
.site-links a {
  display: inline-flex;
  min-height: 2.75rem;
  align-items: center;
  color: var(--color-text-muted);
  border-bottom: 2px solid transparent;
}

/* ?tats de navigation : survol, focus clavier et page active. */
.site-links a:hover,
.site-links a:focus-visible,
.site-links a[aria-current='page'] {
  color: var(--color-accent);
  border-bottom-color: var(--color-accent);
  text-decoration: none;
}

/* Switch de mode couleur : l'état visuel est piloté par data-color-mode sur html. */
.color-mode-switch {
  display: inline-grid;
  width: 2.25rem;
  height: 2.25rem;
  padding: 0.4rem;
  place-items: center;
  color: var(--color-text);
  background: transparent;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-control);
  cursor: pointer;
}

/* Ic?ne du switch : les deux pictogrammes partagent la m?me cellule. */
.color-mode-icon {
  grid-area: 1 / 1;
  width: 100%;
  height: 100%;
  background: currentColor;
}

/* Ic?ne soleil : masque SVG fourni par le th?me actif. */
.color-mode-icon-sun {
  mask: var(--icon-color-mode-sun) center / contain no-repeat;
  -webkit-mask: var(--icon-color-mode-sun) center / contain no-repeat;
}

/* Ic?ne lune : masque SVG fourni par le th?me actif. */
.color-mode-icon-moon {
  mask: var(--icon-color-mode-moon) center / contain no-repeat;
  -webkit-mask: var(--icon-color-mode-moon) center / contain no-repeat;
}

/* Ic?ne visible : affiche lune ou soleil selon le mode courant. */
html[data-color-mode='dark'] .color-mode-icon-sun,
html:not([data-color-mode='dark']) .color-mode-icon-moon {
  display: none;
}

/* Interaction du switch : accentue le contr?le sans changer sa taille. */
.color-mode-switch:hover {
  color: var(--color-accent);
  border-color: var(--color-accent);
}

/* Footer : liste flexible pour conserver RSS et crédit sur petits écrans. */
.site-footer {
  position: relative;
  z-index: 1;
  width: min(100% - 2rem, var(--content-width));
  margin: 0 auto;
  padding-block: 1.25rem 2rem;
  border-top: 1px solid var(--color-border);
}

/* Liste du footer : ligne flexible pour RSS et cr?dit. */
.site-footer ul {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.75rem 1.25rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

/* Items du footer : autorise les longs liens ? revenir ? la ligne. */
.site-footer li {
  min-width: 0;
  margin: 0;
}

/* S?parateur du footer : caract?re d?coratif entre les liens. */
.site-footer .footer-separator {
  color: var(--color-text-muted);
  font-weight: 700;
}

/* Liens enrichis du footer : icône RSS thémable et icône projet globale. */
.rss-link,
/* Lien propuls? par : peut se replier proprement sur plusieurs lignes. */
.powered-link {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  max-width: 100%;
  overflow-wrap: anywhere;
}

.powered-link {
  flex-wrap: wrap;
}

/* Icône RSS : sa forme vient du thème via --icon-rss. */
/* Bo?te d'ic?ne RSS : taille align?e sur le texte courant. */
.rss-icon {
  display: inline-block;
  flex: 0 0 auto;
  width: 1em;
  height: 1em;
}

/* Couleur RSS : orange par d?faut, surchargeable par le th?me. */
.rss-icon {
  color: var(--color-rss, #f26522);
}

/* Icône "Propulsé par" : globale, volontairement indépendante du thème. */
.powered-icon {
  flex: 0 0 auto;
  width: var(--powered-icon-size, 1.15em);
  height: var(--powered-icon-size, 1.15em);
  border-radius: var(--powered-icon-radius, 0.25rem);
  object-fit: cover;
}

/* Liste d'articles : base carte simple, ensuite spécialisée par chaque thème. */
.post-list {
  display: grid;
  gap: 1.25rem;
  margin: 1.5rem 0;
  padding: 0;
  list-style: none;
}

/* Carte article : conteneur générique avec surface, bordure et ombre thémables. */
.post-card {
  margin: 0;
  padding: 1.25rem;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-card);
}

/* Contenu de carte : autorise les textes longs ? se r?duire dans les grilles. */
.post-card-content {
  min-width: 0;
}

/* Titre de carte : marge commune avant sp?cialisation de th?me. */
.post-title {
  margin-block: 0 0.5rem;
}

/* Description de carte : texte r?sum?, robuste aux mots longs. */
.post-description {
  margin-block: 0.5rem;
  max-width: 100%;
  overflow-wrap: anywhere;
}

/* Pied de carte : date, séparateur et lien de lecture sur une ligne souple. */
.post-card-footer {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.5rem 0.85rem;
  margin-block-start: 0.75rem;
}

/* ?l?ments du pied de carte : supprime les marges internes parasites. */
.post-card-footer .post-meta,
.post-card-footer /* Lien lire la suite : accent typographique commun aux cartes. */
.read-more {
  margin: 0;
}

/* S?parateur de carte : ponctuation visuelle entre date et lien. */
.post-card-footer-separator {
  color: var(--color-text-muted);
}

/* Métadonnées d'article : date de publication et éventuelle mise à jour. */
.post-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem 1rem;
  margin-block: 0.5rem;
  color: var(--color-text-muted);
  font-size: 0.925rem;
}

/* Date : renforce l?g?rement la valeur temporelle. */
.post-meta time {
  color: var(--color-text);
  font-weight: 600;
}

/* Tags : l'accent visuel vient de src/config/tags.ts via data-accent. */
.post-category,
.tag-chip {
  display: inline-flex;
  align-items: center;
  min-height: 2rem;
  padding: 0.2rem 0.65rem;
  color: var(--tag-accent, var(--color-accent));
  background: var(--color-surface-alt);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-control);
  font-size: 0.875rem;
  font-weight: 600;
  line-height: 1.2;
}

/* Accents de tags : variables CSS d?riv?es de la configuration TypeScript. */
[data-accent='violet'] { --tag-accent: var(--color-tag-violet, var(--color-accent)); }
[data-accent='blue'] { --tag-accent: var(--color-tag-blue, var(--color-accent)); }
[data-accent='orange'] { --tag-accent: var(--color-tag-orange, var(--color-accent)); }

/* Tag dans une carte : espace sous le chip lorsqu'il est isol?. */
.post-category {
  margin-block-end: 0.75rem;
}

/* Liste de tags dans les cartes et pages d'article. */
/* Liste de tags d'une carte : chips horizontaux sans puces. */
.post-card-tags {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.45rem;
  margin: 0 0 0.75rem;
  padding: 0;
  list-style: none;
  list-style-type: none;
}

/* Item de tag de carte : neutralise le comportement de liste. */
.post-card-tags li {
  display: inline-flex;
  margin: 0;
  padding: 0;
  list-style: none;
}

/* Tag dans liste horizontale : retire la marge pr?vue pour le cas isol?. */
.post-card-tags .post-category {
  margin-block-end: 0;
}

.read-more {
  display: inline-flex;
  margin-block-start: 0.5rem;
  font-weight: 700;
}

/* Pages tags : index simple et nuage pondéré par nombre d'articles. */
.tag-list {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.5rem;
  margin-block: 1rem 0;
}

/* Libell? de liste de tags : annonce les chips sur une page article. */
.tag-list-label {
  color: var(--color-text-muted);
  font-size: 0.875rem;
  font-weight: 700;
}

/* Listes de tags : m?me base flexible pour article, index et nuage. */
.tag-list ul,
.tag-index,
.tag-cloud {
  display: flex;
  flex-wrap: wrap;
  gap: 0.45rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

/* Items de tags : supprime les marges de liste natives. */
.tag-list li,
.tag-index li,
/* Placement d'un tag du nuage : colonnes/lignes inject?es par Astro. */
.tag-cloud li {
  margin: 0;
}

/* Interaction tag : surface invers?e l?g?re au survol/focus. */
.tag-chip:hover,
.tag-chip:focus-visible {
  color: var(--tag-accent, var(--color-accent-hover));
  background: var(--color-surface);
}

/* Index de tags simple : espacement d?di? quand il est utilis?. */
.tag-index {
  gap: 0.65rem;
  margin-block: 1.5rem 2rem;
}

/* Nuage de tags desktop : placement logique par variables inline calculées côté Astro. */
.tag-cloud {
  display: grid;
  grid-template-columns: repeat(7, max-content);
  align-items: center;
  justify-content: center;
  gap: 0.65rem 0.9rem;
  max-width: 40rem;
  margin-block: 1.5rem 2rem;
}

.tag-cloud li {
  grid-column: var(--tag-column);
  grid-row: var(--tag-row);
  justify-self: center;
}

/* Tag pond?r? : taille calcul?e selon le nombre d'articles. */
.tag-cloud-link {
  gap: 0.45em;
  min-height: calc(2rem + var(--tag-weight, 3) * 0.22rem);
  padding: 0.22em 0.42em 0.22em 0.7em;
  font-size: calc(0.8rem + var(--tag-weight, 3) * 0.16rem);
  font-weight: calc(500 + var(--tag-weight, 3) * 80);
}

/* Compteur de tag : pastille indiquant le nombre d'articles associ?s. */
.tag-count {
  display: inline-grid;
  min-width: calc(1.1rem + var(--tag-weight, 3) * 0.08rem);
  height: calc(1.1rem + var(--tag-weight, 3) * 0.08rem);
  padding: 0 0.35em;
  place-items: center;
  color: var(--color-surface);
  background: var(--tag-accent, var(--color-accent));
  border-radius: 999px;
  font-size: 0.72em;
  font-weight: 700;
  line-height: 1;
}

/* Mobile : le nuage redevient une grille simple pour éviter l'overflow. */
@media (max-width: 760px) {
  .tag-cloud {
    display: grid;
    grid-template-columns: repeat(2, max-content);
    width: 100%;
    max-width: 100%;
    justify-content: flex-start;
    gap: 0.55rem;
  }

  /* Mobile tag cloud item : retour au flux naturel de la grille. */
  .tag-cloud li {
    grid-column: auto;
    grid-row: auto;
    max-width: 100%;
  }

  /* Mobile tag cloud link : ?vite les d?bordements de libell?s longs. */
  .tag-cloud-link {
    max-width: 100%;
    overflow-wrap: anywhere;
  }
}

/* Couvertures : ratio commun 1200x630 pour homogénéiser les listes. */
.post-cover-wrapper {
  margin-block-end: 1rem;
}

/* Lien de couverture : rend l'image enti?re cliquable dans les listes. */
.cover-link {
  display: block;
}

/* Image de couverture : base responsive commune. */
.post-cover {
  display: block;
  width: 100%;
  height: auto;
  object-fit: cover;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-card);
}

/* Ratio de couverture : format social 1200x630 utilis? par les articles. */
.post-cover {
  aspect-ratio: 1200 / 630;
}

/* Navigation de fin d'article : précédent/suivant avec cartes symétriques. */
/* Lien retour : s?paration nette apr?s le contenu article. */
.back-link {
  margin-block-start: 2.5rem;
  padding-block-start: 1rem;
  border-top: 1px solid var(--color-border);
}

.article-navigation {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1rem;
  margin-block-start: 2.5rem;
  padding-block-start: 1.25rem;
  border-top: 1px solid var(--color-border);
}

/* Carte de navigation article : surface cliquable pour pr?c?dent/suivant. */
.article-navigation-link {
  display: flex;
  min-height: 100%;
  flex-direction: column;
  gap: 0.35rem;
  padding: 1rem;
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-card);
}

/* Carte article plus ancien : align?e ? droite sur desktop. */
.article-navigation-link--older {
  text-align: right;
}

/* Libell? pr?c?dent/suivant : information secondaire. */
.article-navigation-label {
  color: var(--color-text-muted);
  font-size: 0.85rem;
  font-weight: 700;
}

/* Titre pr?c?dent/suivant : texte principal du lien. */
.article-navigation-title {
  color: var(--color-text);
  font-family: var(--font-heading);
  font-weight: 700;
}

/* Interaction navigation article : bordure accentu?e. */
.article-navigation-link:hover,
.article-navigation-link:focus-visible {
  border-color: var(--color-accent);
  text-decoration: none;
}

/* Interaction titre navigation : accent sur le texte principal. */
.article-navigation-link:hover .article-navigation-title,
.article-navigation-link:focus-visible .article-navigation-title {
  color: var(--color-accent);
}

/* Pagination des listes d'articles. */
.pagination {
  margin-block-start: 2rem;
}

/* Liste de pagination : aligne pr?c?dent, ?tat courant et suivant. */
.pagination-list {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 0.75rem 1rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

/* Item de pagination : neutralise les marges de liste. */
.pagination-list li {
  margin: 0;
}

/* ?tat courant de pagination : texte secondaire non cliquable. */
.pagination-current {
  color: var(--color-text-muted);
}

/* Mobile global des composants : header compact et navigation d'article empilée. */
@media (max-width: 760px) {
  /* Mobile header : empile identit? et actions. */
  .site-nav {
    width: min(100% - 1.25rem, var(--content-width));
    flex-direction: column;
    align-items: flex-start;
    gap: 0.75rem;
  }

  /* Mobile actions : garde liens et switch sur la m?me ligne. */
  .site-nav-actions {
    width: 100%;
    align-items: center;
    flex-direction: row;
    flex-wrap: nowrap;
    gap: 0.35rem;
    justify-content: flex-start;
  }

  /* Mobile liens : pas de retour ligne pour pr?server le header compact. */
  .site-links {
    flex: 0 1 auto;
    flex-wrap: nowrap;
    min-width: 0;
    gap: 0.45rem;
  }

  /* Mobile lien de navigation : hauteur et taille r?duites. */
  .site-links a {
    min-height: 2rem;
    font-size: 0.9rem;
  }

  /* Mobile utilitaires : restent coll?s aux liens principaux. */
  .site-utility-actions {
    flex: 0 0 auto;
    flex-wrap: nowrap;
    margin-inline-start: 0;
    gap: 0.3rem;
  }

  /* Mobile switch : bouton plus petit. */
  .color-mode-switch {
    width: 1.75rem;
    height: 1.75rem;
    padding: 0.32rem;
  }

  /* Mobile carte : padding r?duit pour maximiser la largeur utile. */
  .post-card {
    padding: 1rem;
  }

  /* Mobile navigation article : cartes empil?es. */
  .article-navigation {
    grid-template-columns: 1fr;
  }

  /* Mobile carte plus ancien : retour ? l'alignement gauche. */
  .article-navigation-link--older {
    text-align: left;
  }

  /* Mobile footer : m?me largeur compacte que le contenu. */
  .site-footer {
    width: min(100% - 1.25rem, var(--content-width));
  }
}

/* ==========================================================================
   Thème terminal
   --------------------------------------------------------------------------
   Thème personnel inspiré d'une interface console : monospace, contours nets,
   curseur lumineux, léger effet CRT et cartes d'articles très structurées.
   La base fonctionnelle reste dans src/themes/shared/.
   ========================================================================== */

/* Police locale du thème : chargée via la route /theme-assets pour rester isolée du public global. */
@font-face {
  font-family: 'IBM Plex Mono Local';
  src: url('/blog/theme-assets/terminal/fonts/ibm-plex-mono-light.woff2') format('woff2');
  font-style: normal;
  font-weight: 300;
  font-display: swap;
}

/* Jetons du mode clair : palette volontairement froide, lisible et moins saturée. */
:root {
  --color-bg: #eef3f4;
  --color-surface: #f8fbfb;
  --color-surface-alt: #e2eaeb;
  --color-text: #10212a;
  --color-text-muted: #496879;
  --color-border: #9eb2bb;
  --color-accent: #477900;
  --color-accent-hover: #315500;
  --color-focus: #315500;
  --color-brand: #315500;
  --color-tag-violet: #76479e;
  --color-tag-blue: #176a94;
  --color-tag-orange: #985100;
  --color-rss: #985100;
  --icon-rss: url('/blog/theme-assets/terminal/icons/rss.svg');
  --icon-external-link: url('/blog/theme-assets/terminal/icons/external-link.svg');
  --icon-github: url('/blog/theme-assets/terminal/icons/github.svg');
  --icon-color-mode-sun: url('/blog/theme-assets/terminal/icons/sun.svg');
  --icon-color-mode-moon: url('/blog/theme-assets/terminal/icons/moon.svg');
  --powered-icon-size: 1.1em;
  --powered-icon-radius: 0;
  --color-code-bg: #101b22;
  --color-code-text: #eaf5f7;
  --color-code-border: #385363;
  --font-body: 'IBM Plex Mono Local', ui-monospace, 'Cascadia Mono', 'SFMono-Regular', Menlo, Consolas, monospace;
  --font-heading: var(--font-body);
  --font-mono: var(--font-body);
  --content-width: 92rem;
  --reading-width: 52rem;
  --radius-card: 0;
  --radius-control: 2px;
  --shadow-card: none;
  --space-page: 2.25rem;
  --crt-scanline-opacity: 0.025;
  --crt-vignette-opacity: 0.04;
  --crt-halo-opacity: 0.03;
}

/* L'icône RSS est intégrée au thème pour pouvoir changer de style sans toucher aux composants. */
.rss-icon::before {
  content: '';
  display: block;
  width: 100%;
  height: 100%;
  background: currentColor;
  mask: var(--icon-rss) center / contain no-repeat;
  -webkit-mask: var(--icon-rss) center / contain no-repeat;
}

/* Palette sombre : c'est le rendu principal du thème terminal. */
:root[data-color-mode='dark'] {
  --color-bg: #03090d;
  --color-surface: #071016;
  --color-surface-alt: #0b1720;
  --color-text: #e8edf0;
  --color-text-muted: #83a4bd;
  --color-border: #243c4b;
  --color-accent: #9bd14b;
  --color-accent-hover: #c2ed82;
  --color-focus: #b6e86e;
  --color-brand: #d8e9c3;
  --color-tag-violet: #cf8cff;
  --color-tag-blue: #62c7ff;
  --color-tag-orange: #ffad5c;
  --color-rss: #ffad5c;
  --color-code-bg: #02070a;
  --color-code-text: #dcebf1;
  --color-code-border: #294755;
  --crt-scanline-opacity: 0.09;
  --crt-vignette-opacity: 0.22;
  --crt-halo-opacity: 0.12;
}

/* Si aucun choix utilisateur n'est stocké, on suit la préférence système. */
@media (prefers-color-scheme: dark) {
  :root:not([data-color-mode]) {
    --color-bg: #03090d;
    --color-surface: #071016;
    --color-surface-alt: #0b1720;
    --color-text: #e8edf0;
    --color-text-muted: #83a4bd;
    --color-border: #243c4b;
    --color-accent: #9bd14b;
    --color-accent-hover: #c2ed82;
    --color-focus: #b6e86e;
    --color-brand: #d8e9c3;
    --color-tag-violet: #cf8cff;
    --color-tag-blue: #62c7ff;
    --color-tag-orange: #ffad5c;
    --color-rss: #ffad5c;
    --color-code-bg: #02070a;
    --color-code-text: #dcebf1;
    --color-code-border: #294755;
    --crt-scanline-opacity: 0.09;
    --crt-vignette-opacity: 0.22;
    --crt-halo-opacity: 0.12;
  }
}

/* Effet global : halo haut discret et base visuelle type écran. */
body {
  position: relative;
  min-height: 100vh;
  background-image: radial-gradient(circle at 50% 0%, color-mix(in srgb, var(--color-accent) 5%, transparent), transparent 42rem);
}

/* Calque CRT non interactif : scanlines, halo et vignette réglés par variables. */
body::before {
  content: '';
  position: fixed;
  z-index: 0;
  inset: 0;
  pointer-events: none;
  background:
    repeating-linear-gradient(to bottom, transparent 0 2px, rgb(0 0 0 / var(--crt-scanline-opacity)) 2px 3px),
    radial-gradient(circle at 50% 0%, color-mix(in srgb, var(--color-accent) calc(var(--crt-halo-opacity) * 100%), transparent), transparent 38rem),
    radial-gradient(ellipse at center, transparent 48%, rgb(0 7 11 / var(--crt-vignette-opacity)) 100%);
}

/* Header semi-transparent pour laisser vivre l'effet CRT sans gêner la lecture. */
.site-header {
  background: color-mix(in srgb, var(--color-bg) 94%, transparent);
}

/* Largeur terminal : plus large que le thème par défaut, mais bornée pour rester lisible. */
.site-nav,
.site-main,
/* Footer : align? sur le bloc d'articles plut?t que sur la pleine largeur. */
.site-footer {
  width: min(100% - 6.75rem, var(--content-width));
}

/* Navigation : respiration verticale type banni?re de terminal. */
.site-nav {
  padding-block: 2.1rem 1.6rem;
}

/* Marque principale : pas de soulignement au survol, pour garder l'effet "titre console". */
.brand {
  color: var(--color-brand);
  font-weight: 400;
}

.brand:hover,
.brand:focus-visible {
  color: var(--color-brand);
  text-decoration: none;
}

/* Curseur de console placé après le titre, avec trame et halo léger. */
.brand::after {
  content: '';
  width: 0.48em;
  height: 1.05em;
  margin-inline-start: 0.12em;
  background:
    repeating-linear-gradient(
      to bottom,
      rgb(255 255 255 / 0.1) 0 1px,
      transparent 1px 3px
    ),
    var(--color-accent);
  box-shadow:
    0 0 0.18rem color-mix(in srgb, var(--color-accent) 70%, transparent),
    0 0 0.55rem color-mix(in srgb, var(--color-accent) 38%, transparent);
  animation: terminal-cursor-blink 1.15s steps(1, end) infinite;
}

/* Clignotement volontairement lent, désactivé pour les utilisateurs réduisant les animations. */
@keyframes terminal-cursor-blink {
  0%,
  46% {
    opacity: 1;
  }

  47%,
  82% {
    opacity: 0;
  }

  83%,
  100% {
    opacity: 1;
  }
}

@media (prefers-reduced-motion: reduce) {
  .brand::after {
    animation: none;
  }
}

/* Calques de contenu : plac?s au-dessus du fond CRT. */
.site-main,
.site-footer {
  position: relative;
  z-index: 1;
  border-top: 0;
  padding-block-start: 1.8rem;
}

/* Main : r?duit l'espace avant le footer pour un rendu compact. */
.site-main {
  padding-block-end: 1.35rem;
}

.site-footer {
  width: min(100% - 6.75rem, 78rem);
  padding-block-start: 0.75rem;
}

/* Footer interne : liens resserr?s fa?on barre de statut. */
.site-footer ul {
  gap: 0.75rem;
}

/* Prompt terminal propre au thème : absent du HTML commun, injecté comme décor CSS. */
.site-utility-actions::before {
  content: '>_';
  flex: 0 0 auto;
  color: var(--color-accent);
  font-family: var(--font-mono);
  font-weight: 700;
}

/* Titre de section façon invite Markdown : # Articles, # Tags, # À propos. */
.article-index-title {
  width: min(100%, 78rem);
  margin-inline: auto;
  margin-block: 0 1.35rem;
  color: var(--color-text);
  font-family: var(--font-heading);
  font-size: clamp(2rem, 6vw, 2.75rem);
  font-weight: 400;
  line-height: 1.25;
  letter-spacing: 0;
  text-wrap: balance;
}

/* Pr?fixe de titre : convention Markdown/console conserv?e en CSS. */
.article-index-title::before {
  content: '# ';
  color: var(--color-accent);
}

/* Liste d'articles en bloc central compact, proche d'un panneau de terminal. */
.post-list {
  width: min(100%, 78rem);
  margin-inline: auto;
  gap: 0;
  border: 1px solid var(--color-border);
}

/* Pages de lecture et pages simples : m?me colonne que la liste terminal. */
.article-content,
.site-main > h1,
.site-main > .tag-index,
.site-main > .tag-cloud,
.site-main > .back-link {
  width: min(100%, 78rem);
  margin-inline: auto;
}

/* Les cartes fusionnent visuellement avec la liste : séparation par traits plutôt que par ombres. */
.post-card {
  padding: 0;
  border: 0;
  border-bottom: 1px solid var(--color-border);
  background: transparent;
}

/* Derni?re carte : pas de double bordure en bas de liste. */
.post-card:last-child {
  border-bottom: 0;
}

/* Sur desktop, la couverture devient une colonne fixe à gauche du résumé. */
.post-card[data-has-cover='true'] {
  display: grid;
  grid-template-columns: minmax(15rem, 29%) minmax(0, 1fr);
}

/* Contenu de carte : espace interne variable selon la largeur. */
.post-card-content {
  align-self: center;
  padding: clamp(1.25rem, 3vw, 2.25rem);
}

/* Carte sans image : limite la largeur du texte pour garder la lisibilit?. */
.post-card[data-has-cover='false'] .post-card-content {
  max-width: 64rem;
}

/* Couverture : occupe toute la hauteur de la ligne d'article. */
.post-card .post-cover-wrapper {
  min-height: 100%;
  margin: 0;
}

/* Lien/image de couverture : hauteur pleine sur desktop. */
.post-card .cover-link,
.post-card .post-cover {
  height: 100%;
}

/* Image de carte : fusionn?e avec le cadre de liste. */
.post-card .post-cover {
  border-block: 0;
  border-inline-start: 0;
  border-radius: 0;
}

/* Lien de titre : blanc/texte par d?faut pour rester sobre. */
.post-title a {
  color: var(--color-text);
}

/* Titre de carte : taille ma?tris?e pour ?viter l'effet console g?ante. */
.post-title {
  font-size: clamp(1.25rem, 2.2vw, 1.55rem);
  font-weight: 400;
}

/* Interaction de titre : accent vert sans soulignement impos?. */
.post-title a:hover,
.post-title a:focus-visible {
  color: var(--color-accent);
}

/* Tags rectangulaires : style console, sans pilule arrondie. */
.post-category,
.tag-chip,
.color-mode-switch {
  border-radius: 0;
}

.post-category {
  padding: 0.1rem 0.38rem;
  background: transparent;
  border: 1px solid currentColor;
}

/* Liste de tags : toujours horizontale et flexible. */
.post-card-tags {
  display: flex;
  flex-direction: row;
  align-items: center;
  flex-wrap: wrap;
  gap: 0.45rem;
  list-style: none;
}

/* Items de tags : neutralise les puces h?rit?es. */
.post-card-tags li {
  display: inline-flex;
  list-style: none;
}

/* Nuage de tags plus compact que le style partagé, tout en gardant la pondération. */
.tag-cloud {
  max-width: 44rem;
  row-gap: 0.95rem;
}

.tag-cloud-link {
  padding: 0.16em 0.42em 0.16em 0.58em;
}

/* Pied de carte : date et lecture utilisent l'accent terminal. */
.post-card-footer .post-meta time,
.post-card-footer .read-more {
  color: var(--color-accent);
  font-weight: 400;
}

/* S?parateur de pied : secondaire, lisible mais discret. */
.post-card-footer-separator {
  color: var(--color-text-muted);
}

/* Le switch doit rester discret : il accompagne la navigation, il ne pilote pas toute la page visuellement. */
.color-mode-switch {
  color: var(--color-text-muted);
  background: transparent;
  border-color: transparent;
}

.color-mode-switch:hover,
.color-mode-switch:focus-visible {
  color: var(--color-accent);
  border-color: var(--color-border);
}

/* Titres des pages simples et articles : même convention visuelle que la page d'accueil. */
/* Pr?fixe # des pages simples et articles. */
.site-main > h1::before,
.article-content h1::before {
  content: '# ';
  color: var(--color-accent);
}

/* Citation : filet renforc? pour tenir dans l'univers terminal. */
.article-content blockquote {
  border-inline-start-width: 2px;
}

/* Navigation entre articles : petites cartes sobres, compatibles avec la grille terminal. */
.article-navigation {
  width: min(100%, 78rem);
  margin-inline: auto;
  margin-block-start: 2rem;
  padding-block-start: 0.9rem;
  gap: 0.75rem;
}

.article-navigation-link {
  gap: 0.2rem;
  padding: 0.72rem 0.85rem;
  background: var(--color-surface);
  box-shadow: none;
}

/* Libell? pr?c?dent/suivant : tr?s petit pour rester secondaire. */
.article-navigation-label {
  font-size: 0.78rem;
  font-weight: 400;
}

/* Titre pr?c?dent/suivant : m?me taille que le libell? demand?. */
.article-navigation-title {
  font-size: 0.78rem;
  font-weight: 400;
  line-height: 1.35;
}

/* Responsive mobile : priorité à éviter l'écrasement des cartes et l'overflow horizontal. */
@media (max-width: 760px) {
  .site-nav,
  .site-main {
    width: min(100% - 1.25rem, var(--content-width));
  }

  .site-footer {
    width: min(100% - 1.25rem, 78rem);
  }

  .site-nav {
    padding-block: 1.25rem;
  }

  .site-nav-actions {
    flex-direction: row;
    align-items: center;
    justify-content: flex-start;
    gap: 0.65rem;
  }

  .site-links {
    gap: 0.5rem 0.8rem;
  }

  .site-utility-actions {
    margin-inline-start: 0;
    gap: 0.45rem;
  }

  .color-mode-switch {
    flex: 0 0 auto;
  }

  .post-card[data-has-cover='true'] {
    display: block;
  }

  .post-card .post-cover-wrapper,
  .post-card .cover-link {
    min-height: 0;
    height: auto;
  }

  .post-card .post-cover {
    display: block;
    width: 100%;
    height: auto;
    aspect-ratio: 1200 / 630;
  }

  .post-card-content {
    padding: 1rem;
  }

  .tag-cloud {
    display: grid;
    grid-template-columns: repeat(2, max-content);
    justify-content: start;
    gap: 0.45rem;
  }

  .tag-cloud li {
    grid-column: auto;
    grid-row: auto;
  }

  .tag-cloud-link {
    min-height: 1.7rem;
    padding: 0.12em 0.32em 0.12em 0.42em;
    font-size: calc(0.78rem + var(--tag-weight, 3) * 0.08rem);
  }

  .tag-count {
    min-width: 1.1rem;
    height: 1.1rem;
    padding-inline: 0.25em;
  }

  .site-footer ul {
    gap: 0.5rem 0.75rem;
  }

  .site-footer li:has(.powered-link) {
    flex-basis: 100%;
  }

  .powered-link {
    font-size: 0.85rem;
  }

  .article-navigation {
    width: 100%;
  }
}

/* Impression : on retire l'habillage écran, inutile sur papier. */
@media print {
  body {
    background-image: none;
  }
}
