/* ═══════════════════════════════════════════════════════════════
   FEUILLE DE STYLE

   Parti pris : un index, pas une page de vente.

   Aucune page ne s'ouvre sur un héros. Pas de slogan, pas de bouton
   d'appel à l'action, pas de carte, pas de couleur d'accent. Le contenu
   commence à la première ligne et se lit comme un document : une colonne
   de dates à gauche, l'objet à droite, des filets d'un pixel pour séparer.

   Le corps de texte est petit (15 px) et la densité forte, à l'inverse
   des gabarits de portfolio qui gonflent le titre pour compenser le peu
   qu'ils ont à dire. Ici c'est le contenu qui porte, donc la mise en page
   se retire.

   Deux familles, une seule superfamille :
     IBM Plex Sans   texte
     IBM Plex Mono   dates, étiquettes, chiffres, code
   ═══════════════════════════════════════════════════════════════ */

:root {
    --bg: #fdfdfc;
    --bg-2: #f5f5f3;
    --fg: #14140f;
    --fg-2: #46463f;
    --fg-3: #636359;
    --fg-4: #75756b;
    --rule: #e4e4df;
    --rule-2: #cfcfc7;

    --sans: 'IBM Plex Sans', system-ui, -apple-system, sans-serif;
    --mono: 'IBM Plex Mono', ui-monospace, 'Cascadia Mono', Menlo, monospace;

    --page: 860px;
    --label: 116px;
    --gap: 2rem;
}

*,
*::before,
*::after {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

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

body {
    font-family: var(--sans);
    font-size: 15px;
    line-height: 1.62;
    color: var(--fg-2);
    background: var(--bg);
    -webkit-font-smoothing: antialiased;
    font-variant-numeric: tabular-nums;
}

img {
    display: block;
    max-width: 100%;
}

/* Le lien est un lien : souligné, de la couleur du texte. Pas de bleu,
   pas de bouton, pas de pastille. */
a {
    color: var(--fg);
    text-decoration: underline;
    text-decoration-thickness: 1px;
    text-decoration-color: var(--rule-2);
    text-underline-offset: 2px;
    transition: text-decoration-color .1s ease;
}

a:hover {
    text-decoration-color: var(--fg);
}

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

::selection {
    background: var(--fg);
    color: var(--bg);
}

/* ═══════════════════════════════════════
   TYPOGRAPHIE
   ═══════════════════════════════════════ */

h1,
h2,
h3,
h4 {
    font-family: var(--sans);
    font-weight: 600;
    color: var(--fg);
    line-height: 1.35;
    letter-spacing: -.011em;
}

/* Le h1 reste un titre, jamais une affiche : pas de « landing page ».
   Il est en revanche le seul point d'accroche de la page, donc il doit se
   distinguer du corps. En dessous de 1,5 rem l'oeil n'a plus rien ou se poser
   et la sobriete se lit comme une page inachevee. */
h1 {
    font-size: 1.65rem;
    line-height: 1.24;
    letter-spacing: -.018em;
    text-wrap: balance;
}

h2 {
    font-size: .95rem;
}

h3 {
    font-size: .95rem;
}

h4 {
    font-size: .95rem;
}

p {
    text-wrap: pretty;
}

strong {
    color: var(--fg);
    font-weight: 500;
}

.lead {
    color: var(--fg-2);
    max-width: 62ch;
}

.small {
    font-size: .87rem;
}

.dim {
    color: var(--fg-3);
}

.mono,
.when,
.org,
.label,
.breadcrumb,
.post-date,
.post-meta,
.chip,
.facts dt {
    font-family: var(--mono);
    font-variant-ligatures: none;
}

/* ═══════════════════════════════════════
   STRUCTURE
   ═══════════════════════════════════════ */

.shell {
    width: 100%;
    max-width: var(--page);
    margin-inline: auto;
    padding-inline: 26px;
}

section {
    padding-block: 2.6rem;
}

section:first-of-type {
    padding-top: 3.5rem;
}

section + section {
    border-top: 1px solid var(--rule);
}

/* Bloc à étiquette : colonne mono à gauche, contenu à droite.
   C'est la seule structure du site, réemployée partout. */
.block {
    display: grid;
    grid-template-columns: var(--label) minmax(0, 1fr);
    gap: 0 var(--gap);
}

.label {
    font-size: .72rem;
    color: var(--fg-4);
    letter-spacing: .01em;
    padding-top: .22rem;
}

/* Portrait : cale sur la largeur exacte de la colonne d'etiquette, donc aucune
   structure en plus. Le fichier reste en couleur ; la desaturation est ici pour
   qu'une seule ligne suffise a la retirer. */
.portrait {
    display: block;
    width: var(--label);
    height: var(--label);
    object-fit: cover;
    filter: grayscale(1);
    margin-bottom: .8rem;
}

@media (max-width: 680px) {
    .block {
        grid-template-columns: minmax(0, 1fr);
        gap: .8rem;
    }
}

.skip-link {
    position: absolute;
    top: -60px;
    left: 26px;
    z-index: 10;
    background: var(--fg);
    color: var(--bg);
    padding: 8px 14px;
    font-size: .87rem;
    text-decoration: none;
}

.skip-link:focus {
    top: 8px;
    color: var(--bg);
}

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

/* ═══════════════════════════════════════
   EN-TÊTE
   Une ligne. Le nom à gauche, les rubriques à droite, un filet dessous.
   ═══════════════════════════════════════ */

.site-header {
    border-bottom: 1px solid var(--rule);
    background: var(--bg);
}

.site-header nav {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: .4rem 1.15rem;
    padding-block: 1.05rem;
}

.brand {
    font-weight: 600;
    color: var(--fg);
    text-decoration: none;
    margin-right: auto;
    white-space: nowrap;
}

.nav-links {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: .4rem 1.15rem;
    font-family: var(--mono);
    font-size: .78rem;
}

.nav-links a {
    color: var(--fg-3);
    text-decoration: none;
}

.nav-links a:hover {
    color: var(--fg);
}

.nav-links a[aria-current="page"] {
    color: var(--fg);
    text-decoration: underline;
    text-decoration-color: var(--rule-2);
    text-underline-offset: 3px;
}

/* ═══════════════════════════════════════
   LISTE D'ENTRÉES
   Date en mono à gauche, objet à droite. C'est la forme principale du
   site : elle se lit en diagonale et n'a rien à décorer.
   ═══════════════════════════════════════ */

.rows {
    display: flex;
    flex-direction: column;
}

/* Une ligne n'a plus de colonne de date : dans un bloc elle formait un
   troisieme retrait, et sa largeur fixe laissait entre la date et le titre un
   vide qui changeait a chaque entree. Date, titre et corps partagent le meme
   bord gauche, la date ouvre la ligne de titre. */
.row {
    padding-block: 1.15rem;
    border-top: 1px solid var(--rule);
}

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

.row:last-child {
    padding-bottom: 0;
}

.when {
    font-size: .72rem;
    color: var(--fg-4);
    white-space: nowrap;
}

.row-title {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: .1rem .6rem;
}

.org {
    font-size: .78rem;
    color: var(--fg-3);
}

.row p {
    margin-top: .3rem;
    max-width: 62ch;
}

.bullets {
    list-style: none;
    margin-top: .5rem;
    display: flex;
    flex-direction: column;
    gap: .3rem;
    max-width: 62ch;
}

.bullets li {
    position: relative;
    padding-left: .95rem;
}

.bullets li::before {
    content: "·";
    position: absolute;
    left: .1rem;
    color: var(--fg-4);
}

/* Étiquettes de technologie : du texte séparé par des virgules aurait
   suffi, mais le mono aligné sous l'entrée donne le même service en se
   distinguant du texte courant. Pas d'encadré, pas de fond. */
/* Pointeur d'etude de cas : ferme la ligne en disant ce qu'il y a derriere le
   lien. Sans lui le titre sert seul d'invitation, et un titre se lit comme une
   etiquette, pas comme une porte. */
.lead-on {
    margin-top: .8rem;
}

.chips {
    list-style: none;
    display: flex;
    flex-wrap: wrap;
    gap: .1rem .6rem;
    margin-top: .55rem;
    font-family: var(--mono);
    font-size: .72rem;
    color: var(--fg-4);
}

/* ═══════════════════════════════════════
   TABLEAU DE DÉFINITIONS
   ═══════════════════════════════════════ */

.defs > div {
    display: grid;
    grid-template-columns: 96px minmax(0, 1fr);
    gap: 0 var(--gap);
    padding-block: .8rem;
    border-top: 1px solid var(--rule);
}

.defs > div:first-child {
    border-top: 0;
    padding-top: 0;
}

.defs dt {
    font-family: var(--mono);
    font-size: .72rem;
    color: var(--fg-4);
    padding-top: .22rem;
}

.defs dd {
    color: var(--fg-2);
}

@media (max-width: 680px) {
    .defs > div {
        grid-template-columns: minmax(0, 1fr);
        gap: .2rem;
    }
}

/* ═══════════════════════════════════════
   DOCUMENT LONG — études de cas et notes
   ═══════════════════════════════════════ */

.doc {
    max-width: 62ch;
}

.doc > * + * {
    margin-top: 1rem;
}

.doc h2 {
    margin-top: 2.6rem;
    padding-top: 1.1rem;
    border-top: 1px solid var(--rule);
}

.doc h2:first-child {
    margin-top: 0;
    padding-top: 0;
    border-top: 0;
}

.doc h3 {
    margin-top: 1.8rem;
    color: var(--fg-2);
    font-weight: 500;
}

.doc ul:not(.chips):not(.bullets) {
    list-style: none;
    display: flex;
    flex-direction: column;
    gap: .3rem;
}

.doc ul:not(.chips):not(.bullets) li {
    position: relative;
    padding-left: .95rem;
}

.doc ul:not(.chips):not(.bullets) li::before {
    content: "·";
    position: absolute;
    left: .1rem;
    color: var(--fg-4);
}

code {
    font-family: var(--mono);
    font-size: .86em;
    color: var(--fg);
    background: var(--bg-2);
    padding: 0 3px;
}

pre {
    background: var(--bg-2);
    border: 1px solid var(--rule);
    padding: .9rem 1rem;
    overflow-x: auto;
    font-family: var(--mono);
    font-size: .78rem;
    line-height: 1.65;
}

pre code {
    background: none;
    padding: 0;
    font-size: inherit;
}

.note {
    border-left: 2px solid var(--rule-2);
    padding: .1rem 0 .1rem 1rem;
    color: var(--fg-3);
    font-size: .87rem;
}

.note-label {
    display: block;
    font-family: var(--mono);
    font-size: .72rem;
    color: var(--fg-4);
    margin-bottom: .3rem;
}

figure {
    margin-block: 1.6rem;
}

figure img {
    width: 100%;
    border: 1px solid var(--rule);
}

figcaption {
    font-family: var(--mono);
    font-size: .72rem;
    color: var(--fg-4);
    margin-top: .5rem;
}

.breadcrumb {
    font-size: .72rem;
    color: var(--fg-4);
    margin-bottom: 1.4rem;
}

.breadcrumb a {
    color: var(--fg-3);
    text-decoration: none;
}

.breadcrumb a:hover {
    color: var(--fg);
    text-decoration: underline;
}

/* 240px de minimum plutot que 160 : sur la mesure du document, 160 donne
   trois colonnes et laisse le quatrieme fait orphelin sur une deuxieme
   ligne. Deux colonnes par deux se referment proprement. */
.facts {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
    gap: .9rem var(--gap);
    padding-block: 1rem;
    border-top: 1px solid var(--rule);
    border-bottom: 1px solid var(--rule);
    margin-bottom: 2rem;
}

.facts dt {
    font-size: .72rem;
    color: var(--fg-4);
    margin-bottom: .18rem;
}

.facts dd {
    font-size: .87rem;
    color: var(--fg);
}

/* ═══════════════════════════════════════
   DÉMONSTRATION D'ARRONDI TVA
   Une table de calcul, pas une illustration : le lecteur change les
   montants et voit l'écart apparaître. Rendue comme une feuille de
   calcul sobre, sans couleur ni encadré.
   ═══════════════════════════════════════ */

.demo {
    margin-block: 1.6rem;
    font-family: var(--mono);
    font-size: .78rem;
    border-top: 1px solid var(--fg);
}

.demo-head {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    gap: .3rem 1rem;
    padding-block: .55rem;
    border-bottom: 1px solid var(--rule);
    font-size: .72rem;
    color: var(--fg-4);
}

.demo-line {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 88px 50px;
    gap: .6rem;
    align-items: center;
    padding-block: .38rem;
    border-bottom: 1px solid var(--rule);
}

.demo-line > span:first-child {
    font-family: var(--sans);
    font-size: .87rem;
    color: var(--fg-2);
}

.demo input {
    font-family: var(--mono);
    font-variant-numeric: tabular-nums;
    font-size: .78rem;
    text-align: right;
    padding: 3px 6px;
    border: 1px solid var(--rule-2);
    background: var(--bg);
    color: var(--fg);
    width: 100%;
}

.demo input:focus {
    outline: none;
    border-color: var(--fg);
}

.demo-rate {
    text-align: right;
    color: var(--fg-4);
}

.demo-results {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
    gap: .8rem var(--gap);
    padding-block: .85rem;
    border-bottom: 1px solid var(--rule);
}

/* Seule taille du site hors echelle : la colonne du tableau de resultats est
   calibree au caractere pres, et des .68rem l'etiquette passe sur deux lignes
   et desaligne les trois montants. Verifie au rendu. */
.demo-results dt {
    font-size: .67rem;
    color: var(--fg-4);
    margin-bottom: .2rem;
}

.demo-results dd {
    font-size: 1rem;
    color: var(--fg);
}

.demo-verdict {
    padding-block: .7rem;
    font-family: var(--sans);
    font-size: .87rem;
    color: var(--fg-3);
    max-width: 62ch;
}

.demo-verdict strong {
    font-family: var(--mono);
    font-size: .78rem;
}

@media (max-width: 520px) {
    .demo-line {
        grid-template-columns: minmax(0, 1fr) 74px 44px;
        gap: .4rem;
    }
}

/* ═══════════════════════════════════════
   NOTES
   ═══════════════════════════════════════ */

.post-list {
    display: flex;
    flex-direction: column;
}

.post-item {
    display: grid;
    grid-template-columns: var(--label) minmax(0, 1fr);
    gap: 0 var(--gap);
    padding-block: 1.15rem;
    border-top: 1px solid var(--rule);
    text-decoration: none;
    color: inherit;
}

.post-item:first-child {
    border-top: 0;
    padding-top: 0;
}

.post-item:hover h3 {
    text-decoration: underline;
    text-underline-offset: 3px;
}

.post-date {
    font-size: .72rem;
    color: var(--fg-4);
    padding-top: .28rem;
}

.post-item p {
    margin-top: .3rem;
    max-width: 62ch;
}

.post-meta {
    font-size: .72rem;
    color: var(--fg-4);
    margin-bottom: 2rem;
    padding-bottom: 1rem;
    border-bottom: 1px solid var(--rule);
}

@media (max-width: 680px) {
    .post-item {
        grid-template-columns: minmax(0, 1fr);
        gap: .25rem;
    }

    .post-date {
        padding-top: 0;
    }
}

/* ═══════════════════════════════════════
   PIED DE PAGE
   ═══════════════════════════════════════ */

.site-footer {
    border-top: 1px solid var(--rule);
    padding-block: 1.6rem 2.4rem;
    font-family: var(--mono);
    font-size: .72rem;
    color: var(--fg-4);
}

.footer-line {
    display: flex;
    flex-wrap: wrap;
    gap: .35rem 1.15rem;
}

.site-footer a {
    color: var(--fg-3);
    text-decoration: none;
}

.site-footer a:hover {
    color: var(--fg);
    text-decoration: underline;
    text-underline-offset: 3px;
}

@media (prefers-reduced-motion: reduce) {

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