/* ═══════════════════════════════════════════════════════════════════════════
   TOM BERRUYER, PORTFOLIO
   Feuille de style unique. CSS pur, aucune dépendance, aucune compilation.

   « DOSSIER » : un portfolio composé comme une pièce d'archive. Papier chaud,
   encre noire, filets, colonne de marginalia, entrées numérotées.

   Le parti pris tient en une décision : le site est quasi monochrome pour que
   les IMAGES DE PROJET soient la seule couleur. Tout ce qui est peint ici est
   du papier, de l'encre, ou un filet.

   Sommaire
   1. Polices
   2. Variables
   3. Base
   4. Mise en page (.feuille, .marginalia)
   5. Typographie (.titre, .sous-titre, .intitule…)
   6. Blocs de contenu (fiches, listes, planches)
   7. En-tête et pied de page
   8. Étude de cas
   9. Impression
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── 1. POLICES ───────────────────────────────────────────────────────────
   Auto-hébergées, licences ouvertes (SIL OFL / Apache). Sous-ensemble latin.
   `font-display: swap` : le texte s'affiche tout de suite dans une police de
   secours, puis bascule. Mieux qu'une page blanche. */

@font-face {
  font-family: 'Instrument Serif';
  src: url('../fonts/serif.woff2') format('woff2');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'Instrument Serif';
  src: url('../fonts/serif-italic.woff2') format('woff2');
  font-weight: 400;
  font-style: italic;
  font-display: swap;
}
@font-face {
  font-family: 'Instrument Sans';
  src: url('../fonts/sans.woff2') format('woff2');
  font-weight: 400 700;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: 'JetBrains Mono';
  src: url('../fonts/mono.woff2') format('woff2');
  font-weight: 400 600;
  font-style: normal;
  font-display: swap;
}

/* ── 2. VARIABLES ───────────────────────────────────────────────────────── */

:root {
  /* Encres et papiers. Chauds, jamais neutres : un gris pur ferait écran. */
  --papier: #f2efe8;
  --encre: #17150f;
  --encre-douce: #6b665a;
  --filet: #cec8b9;
  /* Un seul accent, employé comme un tampon : numéros, survol. Jamais en aplat. */
  --marque: #a8331a;

  --serif: 'Instrument Serif', 'Times New Roman', serif;
  --sans: 'Instrument Sans', system-ui, -apple-system, sans-serif;
  --mono: 'JetBrains Mono', ui-monospace, 'SF Mono', monospace;

  /* Échelle. Les bornes basses valent pour le mobile, les hautes pour le grand
     écran ; entre les deux, la taille suit la largeur de la fenêtre.

     Le display est aussi borné par la HAUTEUR : sans cela, deux lignes à 200px
     débordent d'un portable en paysage. */
  --display: clamp(3.5rem, min(13vw, 19vh), 12.5rem);
  --t-titre: clamp(2.5rem, 5.5vw, 5.5rem);
  --t-sous-titre: clamp(1.875rem, 3.5vw, 3.5rem);
  --t-intertitre: clamp(1.75rem, 3vw, 2.75rem);
  --t-chapo: clamp(1.25rem, 1.6vw, 1.625rem);
  --t-corps: 1.0625rem;
  --t-intitule: 0.75rem;

  --gouttiere: clamp(1.25rem, 4vw, 4.5rem);
  --colonne-marge: 7.5rem;
  /* Mesure de lecture en ch : c'est le nombre de signes par ligne qui gouverne
     la lisibilité, pas une largeur en pixels. */
  --mesure: 66ch;
}

/* ── 3. BASE ────────────────────────────────────────────────────────────── */

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

html {
  scroll-behavior: smooth;
  scroll-padding-top: 5rem;
  /* Chiffres tabulaires : le site est plein de dates, de numéros d'entrée et de
     tableaux. Ils doivent s'aligner d'une ligne à l'autre. */
  font-variant-numeric: tabular-nums;
}

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

body {
  margin: 0;
  background-color: var(--papier);
  color: var(--encre);
  font-family: var(--sans);
  font-size: var(--t-corps);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  /* Le grain. Un bruit très faible qui empêche l'aplat de papier de paraître
     numérique. Purement décoratif, donc en fond. */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='120' height='120' filter='url(%23n)' opacity='0.035'/%3E%3C/svg%3E");
}

h1,
h2,
h3,
h4,
p,
ul,
ol,
dl,
dd,
figure,
blockquote {
  margin: 0;
  padding: 0;
}

h1,
h2,
h3,
h4 {
  font-weight: 400;
  text-wrap: balance;
}

p {
  text-wrap: pretty;
}

ul,
ol {
  list-style: none;
}

a {
  color: inherit;
  text-decoration: none;
}

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

::selection {
  background-color: var(--encre);
  color: var(--papier);
}

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

/* Lien d'évitement : invisible jusqu'à la tabulation. */
.evitement {
  position: absolute;
  left: -9999px;
}
.evitement:focus {
  position: fixed;
  top: 1rem;
  left: 1rem;
  z-index: 50;
  padding: 0.5rem 1rem;
  background: var(--encre);
  color: var(--papier);
  left: 1rem;
}

/* Réservé aux lecteurs d'écran. */
.lecteur-seul {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* ── 4. MISE EN PAGE ────────────────────────────────────────────────────── */

/* La feuille. Marges franches, largeur plafonnée. */
.feuille {
  width: 100%;
  max-width: 96rem;
  margin-inline: auto;
  padding-inline: var(--gouttiere);
}

/* LA MARGINALIA : le geste structurant.
   Une colonne étroite à gauche porte le numéro et l'intitulé, le contenu occupe
   le reste. C'est la mise en page d'une édition critique : l'appareil dans la
   marge, le texte au centre.
   Sous 60rem la marge passe AU-DESSUS du contenu ; elle ne se comprime pas. */
.marginalia {
  display: grid;
  grid-template-columns: var(--colonne-marge) minmax(0, 1fr);
  column-gap: var(--gouttiere);
  align-items: start;
  padding-block: 2.5rem;
}

@media (width < 60rem) {
  .marginalia {
    grid-template-columns: minmax(0, 1fr);
    row-gap: 0.75rem;
  }
  .marginalia > .appareil {
    display: flex;
    align-items: baseline;
    gap: 0.75rem;
  }
}

/* Le numéro d'entrée, en serif et en vermillon. */
.numero {
  display: block;
  font-family: var(--serif);
  font-size: 2.25rem;
  line-height: 1;
  color: var(--marque);
}

@media (width < 60rem) {
  .numero {
    font-size: 1.5rem;
  }
}

/* Filet. La seule séparation employée dans tout le site : pas d'ombre, pas de
   carte, pas de coin arrondi. */
.filet {
  border: 0;
  border-top: 1px solid var(--filet);
  margin: 0;
}

.mesure {
  max-width: var(--mesure);
}

/* ── 5. TYPOGRAPHIE ─────────────────────────────────────────────────────── */

/* Les interlignages sont calés sur les métriques réelles d'Instrument Serif :
   son encre occupe 0,955 em (ascendante 0,74 + descendante 0,215). En dessous
   de cette valeur, la boîte de ligne rogne les jambages. */

.display {
  font-family: var(--serif);
  font-size: var(--display);
  line-height: 0.9;
  letter-spacing: -0.02em;
}

/* h2 : titres de section */
.titre {
  font-family: var(--serif);
  font-size: var(--t-titre);
  line-height: 1;
  letter-spacing: -0.015em;
}

/* h3 : titres de projet. Un palier franc sous le titre de section : sans lui,
   les deux niveaux pèsent le même poids et la hiérarchie ne se lit plus. */
.sous-titre {
  font-family: var(--serif);
  font-size: var(--t-sous-titre);
  line-height: 1.02;
  letter-spacing: -0.01em;
}

.intertitre {
  font-family: var(--serif);
  font-size: var(--t-intertitre);
  line-height: 1.2;
}

.chapo {
  font-size: var(--t-chapo);
  line-height: 1.45;
}

/* Intitulé d'appareil : mono, capitales, très interlettré. Sert à tout ce qui
   n'est pas du contenu : labels, numéros, légendes, années. */
.intitule {
  font-family: var(--mono);
  font-size: var(--t-intitule);
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--encre-douce);
  line-height: 1.4;
}

/* Valeurs de fiche composées en mono, mais en casse normale. */
.valeur-mono {
  font-family: var(--mono);
  font-size: var(--t-intitule);
  font-weight: 500;
  color: var(--encre);
}

.doux {
  color: var(--encre-douce);
}

.italique {
  font-style: italic;
  color: var(--encre-douce);
}

/* Barre de séparation des énumérations. L'espace insécable qui la précède est
   dans le HTML : sans lui, un repli de ligne pose la barre en tête de ligne. */
.barre {
  color: var(--filet);
}

a.lien:hover,
a:hover .survol-marque {
  color: var(--marque);
}

/* Lien souligné d'un filet, pour les appels à l'action. */
.lien-souligne {
  display: inline-block;
  border-bottom: 1px solid var(--encre);
  padding-bottom: 0.25rem;
  color: var(--encre);
}
.lien-souligne:hover {
  border-color: var(--marque);
  color: var(--marque);
}

/* Petite flèche de sortie, après un lien externe. */
.flexterne {
  font-size: 0.5em;
  margin-left: 0.25rem;
  color: var(--encre-douce);
}
a:hover .flexterne {
  color: var(--marque);
}

/* ── 6. BLOCS DE CONTENU ────────────────────────────────────────────────── */

/* Ligne de fiche : intitulé à gauche, valeur à droite, filet dessous.
   Un tableau, pas une carte. */
.fiche {
  margin: 0;
}
.fiche > div {
  display: grid;
  grid-template-columns: 7rem minmax(0, 1fr);
  align-items: baseline;
  column-gap: 1rem;
  padding-block: 0.75rem;
  border-bottom: 1px solid var(--filet);
}
@media (width >= 40rem) {
  .fiche > div {
    grid-template-columns: 9rem minmax(0, 1fr);
  }
}
.fiche dd {
  margin: 0;
}
.fiche .serif {
  font-family: var(--serif);
  font-size: 1.5rem;
  line-height: 1.2;
}
@media (width >= 40rem) {
  .fiche .serif {
    font-size: 1.75rem;
  }
}

/* Liste réglée : une entrée par ligne, un filet dessous. Sur deux colonnes dès
   qu'il y a la place. Sert aux softskills, outils, langues, compétences. */
.liste-reglee {
  display: grid;
  column-gap: 2rem;
}
.liste-reglee > li {
  padding-block: 0.75rem;
  border-bottom: 1px solid var(--filet);
}
@media (width >= 40rem) {
  .liste-reglee.deux-colonnes {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .liste-reglee.trois-colonnes {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
}

/* Entrée avec vignette (outils, inspirations). */
.avec-vignette {
  display: flex;
  align-items: center;
  gap: 1rem;
}
.avec-vignette img {
  flex-shrink: 0;
  object-fit: contain;
}
.avec-vignette .cadre {
  border: 1px solid var(--filet);
  object-fit: cover;
}

/* Ligne à deux bouts : le libellé à gauche, la valeur à droite. */
.deux-bouts {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
}

/* Entrée de projet sur l'accueil : image à gauche, fiche à droite. */
.entree-projet {
  display: grid;
  gap: 2rem;
  align-items: start;
  margin-top: 2rem;
}
@media (width >= 64rem) {
  .entree-projet {
    grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
    gap: 3rem;
  }
}

/* Vignette de projet. Format commun 3/2 avec recadrage ancré EN HAUT : ce sont
   des captures d'interface, et c'est leur en-tête qui les rend
   identifiables. Un recadrage centré les décapiterait. */
.vignette {
  width: 100%;
  aspect-ratio: 3 / 2;
  object-fit: cover;
  object-position: top;
  border: 1px solid var(--filet);
}

/* Toute l'entrée est cliquable, via un pseudo-élément posé sur le titre.
   Un seul lien vers la cible, donc pas de doublon pour les lecteurs d'écran. */
.entree {
  position: relative;
}
.entree .zone-cliquable::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 10;
}
.entree:hover .survol-marque {
  color: var(--marque);
}

/* Planche : une image et sa légende en mono, posée sur le papier.
   Pas de bandeau, pas de fond. */
.planche {
  margin-block: 0;
}
.planche img {
  width: 100%;
  border: 1px solid var(--filet);
}
.planche.pleine-largeur img {
  border: 0;
  max-height: 62svh;
  object-fit: cover;
  object-position: center;
}
.planche figcaption {
  display: flex;
  gap: 1rem;
  margin-top: 0.75rem;
}
.planche figcaption .legende {
  text-transform: none;
  letter-spacing: normal;
}

/* Expérience du CV : repères et identité à gauche, récit à droite. */
.experience {
  display: grid;
  gap: 1.5rem;
  padding-block: 2rem;
}
.experience + .experience {
  border-top: 1px solid var(--filet);
}
@media (width >= 64rem) {
  .experience {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.4fr);
    gap: 3rem;
  }
}
.experience .recit {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
}

/* Diplôme : intitulé et date sur une ligne, école dessous. */
.diplome {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: baseline;
  column-gap: 1.5rem;
  row-gap: 0.25rem;
  padding-block: 1rem;
  border-bottom: 1px solid var(--filet);
}

/* Grille à deux colonnes générique. */
.duo {
  display: grid;
  gap: 2.5rem;
}
@media (width >= 40rem) {
  .duo {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

.pile {
  display: flex;
  flex-direction: column;
  gap: 2.5rem;
}

/* Portrait et aptitudes, côte à côte. */
.bloc-portrait {
  display: grid;
  gap: 2.5rem;
  align-items: start;
}
@media (width >= 40rem) {
  .bloc-portrait {
    grid-template-columns: 14rem minmax(0, 1fr);
  }
}
.bloc-portrait img {
  width: 100%;
  border: 1px solid var(--filet);
}

/* Énumération en ligne : les mots-clés du hero. L'espace avant la barre est
   insécable (dans le HTML), celui d'après vient du column-gap. */
.enumeration {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  column-gap: 0.5rem;
  row-gap: 0.5rem;
}

/* Les deux lignes du titre d'accueil, empilées. */
.ligne {
  display: block;
}

/* Fiche du projet, en tête de sa page : plus étroite que la pleine largeur. */
.fiche-etroite {
  max-width: 42rem;
}

/* Intitulé d'encart : en encre pleine, contrairement aux autres intitulés. */
.intitule-fort {
  color: var(--encre);
}

/* Bloc « projet suivant » : un filet d'encre en haut, cliquable en entier. */
.suite {
  display: block;
  border-top: 1px solid var(--encre);
  padding-top: 1.5rem;
}
.suite .marginalia {
  padding-block: 0 2.5rem;
}

/* Espacements utilitaires, volontairement peu nombreux. */
.mt-1 { margin-top: 0.25rem; }
.mt-2 { margin-top: 0.75rem; }
.mt-3 { margin-top: 1rem; }
.mt-4 { margin-top: 1.25rem; }
.mt-5 { margin-top: 1.5rem; }
.mt-6 { margin-top: 2rem; }
.mt-8 { margin-top: 3rem; }
.mt-10 { margin-top: 4rem; }
.pt-6 { padding-top: 2rem; }
.pt-8 { padding-top: 3rem; }
.pb-6 { padding-bottom: 2rem; }

/* ── 7. EN-TÊTE ET PIED DE PAGE ─────────────────────────────────────────── */

/* Pas de barre flottante : une ligne d'appareil en haut de la feuille, sous un
   filet, comme la tête d'un document. Elle défile avec la page ; rien ne
   recouvre jamais le contenu. */
.tete {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  column-gap: 2rem;
  row-gap: 0.5rem;
  padding-block: 1rem;
  border-bottom: 1px solid var(--encre);
}

.signature {
  font-family: var(--serif);
  font-size: 1.5rem;
  line-height: 1;
}

.tete nav ul {
  display: flex;
  gap: 1.5rem;
}

.tete .groupe-droite {
  display: flex;
  align-items: baseline;
  gap: 1.5rem;
}
@media (width >= 40rem) {
  .tete .groupe-droite {
    gap: 2rem;
  }
}

.selecteur-langue ul {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
}
.selecteur-langue li {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
}
.selecteur-langue [aria-current] {
  color: var(--encre);
}
.selecteur-langue a:hover {
  color: var(--encre);
}

.pied {
  margin-top: 8rem;
}
.pied > div {
  border-top: 1px solid var(--encre);
  padding-top: 1.5rem;
  padding-bottom: 4rem;
}

/* ── 8. ÉTUDE DE CAS ────────────────────────────────────────────────────── */

/* Le texte est composé sur une mesure étroite, avec les titres de section en
   serif. Les planches, elles, s'échappent de la mesure : c'est ce contraste
   largeur-de-texte / largeur-d'image qui donne le rythme. */
.etude {
  max-width: var(--mesure);
}

.etude > * + * {
  margin-top: 1.35em;
}

.etude h2 {
  max-width: none;
  margin-top: 4rem;
  font-family: var(--serif);
  font-size: var(--t-intertitre);
  line-height: 1.2;
}

/* Un filet fin sous chaque titre de section : l'article se lit comme une suite
   de sections, pas comme un bloc continu. */
.etude h2::after {
  content: '';
  display: block;
  margin-top: 0.75rem;
  border-top: 1px solid var(--filet);
}

.etude h3 {
  margin-top: 2.5rem;
  font-family: var(--mono);
  font-size: var(--t-intitule);
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--encre-douce);
}

.etude p {
  line-height: 1.65;
}

.etude strong {
  font-weight: 600;
}

.etude a {
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.2em;
}
.etude a:hover {
  color: var(--marque);
}

/* Encart d'analyse : un intitulé, un texte, un filet à gauche.
   Pas de carte, un renfoncement. */
.encart {
  margin-top: 2rem;
  border-left: 2px solid var(--marque);
  padding-left: 1.5rem;
}
.encart p:first-child {
  color: var(--encre);
}

/* Renvoi vers une source externe. Composé comme une note de référence : un
   filet, un intitulé, une flèche. Pas un bouton, le site n'en a pas. */
.renvoi {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1.5rem;
  margin-top: 2rem;
  padding-block: 0.75rem;
  border-top: 1px solid var(--encre);
  font-family: var(--mono);
  font-size: var(--t-intitule);
  font-weight: 500;
  letter-spacing: 0.06em;
  color: var(--encre);
  text-decoration: none;
}
.renvoi:hover {
  border-color: var(--marque);
  color: var(--marque);
}

/* Les planches sortent de la mesure. Bornée en vw : à une valeur fixe, la
   planche dépassait la feuille autour de 960px et provoquait un défilement
   horizontal. */
.etude figure {
  margin-block: 3rem;
  width: min(100%, 68rem);
}
@media (width >= 60rem) {
  .etude figure {
    width: calc(100% + min(12rem, 8vw));
  }
}

/* Citation de témoignage. */
.temoignage p {
  font-family: var(--serif);
  font-size: clamp(1.5rem, 2.6vw, 2.25rem);
  line-height: 1.2;
  font-style: italic;
  max-width: var(--mesure);
}
.temoignage footer {
  margin-top: 2rem;
}

/* ── 9. IMPRESSION ──────────────────────────────────────────────────────── */

@media print {
  .tete nav,
  .selecteur-langue,
  .evitement {
    display: none;
  }
  body {
    background: #fff;
    background-image: none;
  }
  .marginalia {
    grid-template-columns: minmax(0, 1fr);
  }
  a {
    text-decoration: none;
  }
}
