/* =========================================================================
   blog.css · styles propres au blog (prose des articles).

   Le thème et l'accessibilité PARTAGÉS (theme.css + a11y.css, servis depuis
   assets.nelsonboruchowitch.com) fournissent déjà : les tokens :root
   (--primary #70BD95, --bg-panel #253446, --text-light, --border…), .pe-header
   + .logo/nav, le <body>, .btn, .copy-btn, le mode clair/sombre (data-theme) et
   TOUS les réglages « Confort de lecture » (data-a11y-*, dont la largeur réduite
   qui ramène .content à 72ch). On ne les redéfinit jamais ici.

   Ce fichier n'ajoute que :
     1. quelques utilitaires que le blog ne charge pas depuis composants
        (repris tels quels de composants/assets/css/base.css) ;
     2. la base du conteneur d'article .content / .blog-post ;
     3. la prose Markdown (titres, paragraphes, listes, citations, images,
        tables, code). Les BLOCS DE CODE (palette, jetons .hl-*, badge de
        langage, boutons) viennent de la feuille PARTAGÉE code.css, commune au
        blog et aux pages de composants/. Zéro dépendance.
   ========================================================================= */

/* --- 0. Tokens présents dans composants/tokens.css mais ABSENTS du thème
   partagé (theme.css). Sans eux, var(--g-text)/(--g-fill) sont invalides et
   cassent le contour :focus-visible, le skip-link, etc. On les redéclare ici. */
:root {
    --g-fill: #2c7a56;
    --g-text: var(--primary);
    --mono: ui-monospace, "Cascadia Code", "Consolas", monospace;
}
[data-theme="light"] { --g-text: #2a6e4e; }

/* --- 1. Utilitaires repris de base.css (non chargé sur le blog) ----------- */
html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
    *, *::before, *::after {
        animation-duration: .01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: .01ms !important;
    }
}

:focus-visible { outline: 3px solid var(--g-text); outline-offset: 2px; border-radius: 4px; }
#contenu:focus { outline: none; }

.skip-link {
    position: absolute; top: -48px; left: 8px; z-index: 2000;
    padding: 8px 16px; background: var(--g-fill); color: #fff;
    border-radius: var(--radius); transition: top .2s ease;
}
.skip-link:focus { top: 8px; text-decoration: none; }

.sr-only {
    position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
    overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

footer {
    padding: 18px; text-align: center;
    background: var(--bg-sidebar); border-top: 1px solid var(--border);
}
footer p { margin: 0; font-size: 13px; color: var(--text-dim); }
.copyright-symbol { color: var(--g-text); }

/* Repris de composants/assets/css/header.css (non chargé sur le blog).
   INDISPENSABLE : sans width:auto, le thème force height:40px et l'attribut
   width="1140" étire le logo. */
#toolbar { display: flex; align-items: center; }
#toolbar .btn { color: var(--text-dim); }
#toolbar .btn:hover { color: var(--text-light); }
/* Logo : dimensions de composants (height 40px) mais en COULEUR (on annule le
   filtre monochrome du thème). */
.pe-header .logo img { width: auto; height: 40px; filter: none; }
[data-theme="light"] .pe-header .logo img { filter: none; }
.pe-header .crumb { color: var(--text-dim); font-weight: 500; font-size: 13px; }
.pe-header .crumb a { color: var(--text-dim); }
.pe-header .crumb a:hover { color: var(--primary); text-decoration: none; }
.pe-header .crumb .sep { color: var(--border-light); margin: 0 2px; }

/* --- Sélecteur de langue : menu déroulant identique à composants (i18n.js),
   en <details> (ouvre/ferme SANS JS ; sur le listing, blog.js ajoute la
   fermeture au clic extérieur/Échap). Présent sur le listing ET sur les pages
   d'article traduites -> stylé ici (blog.css est chargé partout). PAS un <nav>
   -> échappe à .pe-header nav { margin-left:auto / display:none }. */
.lang-switch { position: relative; display: inline-block; margin-left: 6px; }
@media (max-width: 768px) { .pe-header #toolbar { margin-left: auto; } }  /* nav Portfolio masquée -> pousse toolbar+langue à droite */
.lang-switch__toggle {
    display: inline-flex; align-items: center; gap: 6px; list-style: none;
    font: inherit; font-size: 13px; color: var(--text-dim); cursor: pointer;
    padding: 6px 8px; border-radius: 8px; line-height: 1; user-select: none;
}
.lang-switch__toggle::-webkit-details-marker { display: none; }
.lang-switch__toggle::marker { content: ""; }
.lang-switch__toggle:hover { color: var(--text-light); background: color-mix(in srgb, currentColor 10%, transparent); }
.lang-switch__flag { width: 19px; height: 13px; border-radius: 2px; overflow: hidden; display: inline-block; flex: 0 0 auto; box-shadow: 0 0 0 1px rgba(0,0,0,.18); }
.lang-switch__flag svg { display: block; width: 100%; height: 100%; }
.lang-switch__code { font-weight: 600; letter-spacing: .03em; }
.lang-switch__chev { font-size: 10px; opacity: .7; transition: transform .15s; }
.lang-switch[open] .lang-switch__chev { transform: rotate(180deg); }
.lang-switch__menu {
    position: absolute; top: calc(100% + 6px); right: 0; min-width: 176px;
    margin: 0; padding: 5px; list-style: none; background: var(--bg-sidebar);
    border: 1px solid var(--border); border-radius: 10px;
    box-shadow: 0 8px 24px rgba(0,0,0,.28); z-index: 1000;
}
.lang-switch__opt {
    display: flex; align-items: center; gap: 9px; width: 100%;
    font: inherit; font-size: 13px; color: var(--text-light);
    padding: 7px 9px; border-radius: 6px;
}
.lang-switch__opt:hover, .lang-switch__opt:focus-visible { background: color-mix(in srgb, var(--text-light) 12%, transparent); text-decoration: none; outline: none; }
.lang-switch__opt[aria-current="page"] { font-weight: 700; }
.lang-switch__name { white-space: nowrap; }
.lang-switch__check { margin-left: auto; opacity: .85; color: var(--primary); }

/* --- 2. Conteneur d'article ---------------------------------------------- */
/* .content garde min-width:0 (comme layout.css) ; la largeur réduite a11y
   (html[data-a11y-width="narrow"] .content { max-width:72ch }) reste prioritaire. */
.content { min-width: 0; }

.blog-post {
    max-width: 78ch;   /* la largeur réduite a11y ramène .content à 72ch */
    margin: 0 auto;
    /* width:100% est INDISPENSABLE (bug mobile corrigé le 2026-09-06) : .blog-post est un
       ÉLÉMENT DE GRILLE (.blog-layout) et « margin: 0 auto » lui retire l'étirement
       automatique. Sans largeur explicite, il se dimensionne alors « au plus juste » de
       son contenu : la plus longue ligne de code ou le plus large tableau (~677 px)
       l'emportait sur la colonne (412 px sur un téléphone), la page débordait et le
       navigateur mobile dézoomait tout (en-tête et sommaire à moitié de largeur).
       Avec 100 %, l'article prend la colonne, plafonnée à 78ch : identique sur PC. */
    width: 100%;
    padding: clamp(28px, 5vw, 56px) 22px 96px;
    /* La racine du thème est à 14px : 1.0062rem ≈ 16px, confort long-form.
       Le zoom a11y (data-a11y-text L/XL) et la largeur réduite (72ch) restent actifs. */
    font-size: 1.0062rem;
    line-height: 1.75;
    color: var(--text-light);
}

/* En-tête d'article */
.post-head { margin-bottom: 40px; }
.back-to-blog { display: inline-flex; align-items: center; gap: 5px; font-size: 13px; color: var(--text-dim); margin-bottom: 20px; }
.back-to-blog:hover { color: var(--primary); text-decoration: none; }

/* Navigation entre articles (bas de page) */
.post-nav { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; margin-top: 56px; padding-top: 28px; border-top: 1px solid var(--border); }
.post-nav__link { display: flex; flex-direction: column; gap: 4px; padding: 14px 16px; border: 1px solid var(--border); border-radius: 12px; background: var(--bg-sidebar); transition: border-color var(--tr), transform var(--tr); }
.post-nav__link:hover { border-color: var(--primary-dim); transform: translateY(-2px); text-decoration: none; }
.post-nav__next { text-align: right; }
.post-nav__dir { font-size: 12px; color: var(--text-dim); }
.post-nav__title { font-size: 14px; font-weight: 600; color: var(--text-light); }
@media (max-width: 560px) { .post-nav { grid-template-columns: 1fr; } }
.post-meta {
    display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
    font-size: 13px; color: var(--text-dim); margin: 0 0 14px;
}
.post-meta time { color: var(--text-dim); }
.post-meta__sep { color: var(--border-light); }
.blog-post h1 {
    /* En « em », donc RELATIF au corps de l'article (1.0062rem) et non a la
       racine du site : la hierarchie reste solidaire du texte. Avant, le
       corps avait ete monte a 1.0062rem sans que les titres suivent, et le
       h1 ne valait plus que 1,48 fois le texte courant. */
    font-size: clamp(1.8em, 4.5vw, 2.4em);
    font-weight: 800; letter-spacing: -.02em; line-height: 1.15;
    color: var(--text-light); margin: 0 0 18px;
}
.post-tags { display: flex; flex-wrap: wrap; gap: 8px; }
.post-tag {
    font-size: 12px; font-weight: 600; color: var(--g-text);
    background: var(--primary-glow); border: 1px solid rgba(112, 189, 149, .3);
    border-radius: 999px; padding: 3px 11px;
}

/* --- 3. Prose Markdown ---------------------------------------------------- */
.blog-post h2 {
    font-size: clamp(1.5em, 3vw, 1.7em); font-weight: 800; letter-spacing: -.01em;
    color: var(--text-light); margin: 48px 0 14px; scroll-margin-top: 76px;
}
.blog-post h3 {
    font-size: 1.21em; font-weight: 700; color: var(--text-light);
    margin: 32px 0 10px; scroll-margin-top: 76px;
}
.blog-post h4 { font-size: 1.08em; font-weight: 700; color: var(--text-light); margin: 24px 0 8px; }

.blog-post p { margin: 0 0 18px; }
.blog-post :is(ul, ol) { margin: 0 0 18px; padding-left: 26px; }
.blog-post li { margin: 6px 0; }
.blog-post li::marker { color: var(--primary); }

.blog-post a { color: var(--primary); text-decoration: underline; text-underline-offset: 2px; text-decoration-thickness: 1px; }
.blog-post a:hover { color: var(--primary-dim); }
.blog-post strong { color: var(--text-light); font-weight: 700; }
.blog-post em { color: var(--text-light); }
.blog-post hr { border: 0; border-top: 1px solid var(--border); margin: 40px 0; }

.blog-post blockquote {
    margin: 0 0 22px; padding: 2px 18px; color: var(--text-dim);
    border-left: 3px solid var(--primary); background: var(--primary-glow);
    border-radius: 0 8px 8px 0;
}
.blog-post blockquote p { margin: 14px 0; }

/* Images / figures (le build ajoute width/height + loading="lazy") */
.blog-post figure { margin: 0 0 26px; }
.blog-post img {
    display: block; max-width: 100%; height: auto;
    border-radius: 12px; border: 1px solid var(--border);
}
.blog-post figcaption {
    margin-top: 9px; font-size: 12.5px; color: var(--text-dim);
    text-align: center; line-height: 1.55;
}

/* Code inline */
.blog-post code {
    font-family: 'Consolas', ui-monospace, 'SFMono-Regular', Menlo, monospace;
    font-size: .92em; color: var(--g-text);
    background: var(--primary-glow); border: 1px solid rgba(112, 189, 149, .22);
    border-radius: 5px; padding: 1px 6px;
}

/* Blocs de code · la palette, les jetons .hl-*, le badge de langage et les
   commandes (Copier, sélecteur Power Fx) vivent dans la feuille PARTAGÉE
   assets.nelsonboruchowitch.com/css/code.css, commune au blog et aux pages de
   composants/. On n'ajoute ici que la mise en page propre à la prose. */
.blog-post .code-block { margin: 0 0 24px; }
.blog-post .code-wrapper { border: 1px solid var(--border); }
.blog-post .code-wrapper pre { padding: 16px 18px; }
.blog-post .code-wrapper pre code {
    font-family: 'Consolas', ui-monospace, 'SFMono-Regular', Menlo, monospace;
    font-size: 0.8312rem; line-height: 1.6; white-space: pre;
}

/* Tables (Markdown -> <table>, enveloppée dans .table-wrap au build) */
.blog-post .table-wrap {
    overflow-x: auto; border: 1px solid var(--border);
    border-radius: 12px; margin: 0 0 24px; -webkit-overflow-scrolling: touch;
}
.blog-post table { width: 100%; border-collapse: collapse; font-size: .92em; min-width: 460px; }
.blog-post th {
    text-align: left; font-size: 11px; font-weight: 700; letter-spacing: .05em;
    text-transform: uppercase; color: var(--text-dim); background: var(--bg-panel);
    padding: 10px 14px; border-bottom: 1px solid var(--border); white-space: nowrap;
}
.blog-post td {
    padding: 11px 14px; border-bottom: 1px solid var(--border);
    color: var(--text-dim); vertical-align: top; line-height: 1.55;
}
.blog-post tbody tr { background: var(--bg-sidebar); }
.blog-post tbody tr:nth-child(even) { background: var(--bg-dark); }
[data-theme="light"] .blog-post tbody tr:nth-child(even) { background: var(--bg-panel); }
.blog-post tr:last-child td { border-bottom: none; }
.blog-post table code { white-space: nowrap; background: transparent; border: 0; padding: 0; }

/* ================================================================
   Mise en page des articles longs · ajoute le 2026-08-27
   Colonne de sommaire + bandeaux de partie. Produits par le
   generateur (lib/parties.mjs), pas ecrits dans les articles.
   ================================================================ */


.partie{margin:52px 0 28px;padding:18px 20px;border:1px solid var(--border);border-left:4px solid var(--primary);border-radius:10px;background:var(--bg-panel)}
.partie__num{margin:0 0 7px;font-family:var(--mono);font-size:11.5px;letter-spacing:.09em;text-transform:uppercase;color:var(--text-dim)}
.blog-post h2.partie__titre{margin:0 0 9px;padding:0;border:0;font-size:1.35em;line-height:1.3}
.partie__lead{margin:0;font-size:13.5px;line-height:1.6;color:var(--text-dim)}
.partie__lead code{font-family:var(--mono);font-size:12px}
.partie{scroll-margin-top:80px}
.blog-layout{max-width:1180px;margin:0 auto;display:grid;grid-template-columns:220px minmax(0,1fr);gap:40px;align-items:start}
.toc{position:sticky;top:72px;align-self:start;min-width:0;padding-top:clamp(28px,5vw,56px);max-height:calc(100vh - 96px);overflow-y:auto;scrollbar-width:thin}
.toc h2{margin:0 0 10px;padding-left:12px;border:0;font-size:10px;font-weight:700;letter-spacing:.14em;text-transform:uppercase;color:var(--text-dim)}
.toc__groupe{margin:16px 0 5px;padding-left:12px;font-size:11px;font-weight:700;letter-spacing:.06em;color:var(--text-dim);opacity:.75}
.toc__groupe:first-of-type{margin-top:0}
.toc ul{margin:0 0 4px;padding:0;list-style:none;display:flex;flex-direction:column;gap:2px}
.toc li{margin:0}
.toc a{display:block;padding:7px 12px;border-left:2px solid var(--border);font-size:13px;line-height:1.35;color:var(--text-dim);text-decoration:none;transition:color .18s ease,border-color .18s ease,background-color .18s ease}
.toc a:hover{color:var(--text-light);border-left-color:var(--border-light)}
.toc a.active{color:var(--text-light);border-left-color:var(--primary);font-weight:600;background:var(--primary-glow)}
@media (max-width:980px){
.blog-layout{grid-template-columns:1fr;gap:0}
.toc{position:static;padding:18px 22px 0}
.toc ul{flex-direction:row;flex-wrap:wrap;gap:6px}
.toc a{border-left:0;border:1px solid var(--border);border-radius:999px;padding:5px 11px}
}

/* Sommaire sur un ecran COURT (2026-08-27).
   Sur un grand ecran, rien ne change : le sommaire garde ses espacements.
   En dessous de 820 px de hauteur utile, il depassait et sa fin etait coupee
   tant qu'on n'avait pas fait defiler la colonne. Plutot que de couper, on
   compacte. Le defilement interne reste en dernier recours. */
@media (max-height: 920px) {
    .toc { padding-top: 16px }
    .toc h2 { margin-bottom: 6px }
    .toc__groupe { margin: 10px 0 3px }
    .toc ul { gap: 1px }
    .toc a { padding: 5px 12px; font-size: 12.5px }
}
