/* ═══════════════════════════════════════════════════════════════
   site-chrome.css — the homepage header and footer, on their own.

   The nav bar, the mobile drawer and the site footer were written inside
   the homepage's style block, where nothing else needed them. The CV pages
   need the same chrome, so the rules live here now and are pulled in by
   every standalone page that is not index.html.

   Everything resolves against the tokens the pages already declare —
   --bg / --ink / --muted / --line / the font trio — plus the accent ladder
   from /theme.css. Nothing here hardcodes a colour a page might want to
   change. --maxw is read with a fallback so a page can narrow the footer to
   its own column without having to declare the token.
   ═══════════════════════════════════════════════════════════════ */

/* ───── nav ───── */
nav.top{
  position:sticky;top:10px;z-index:50;
  display:flex;align-items:center;justify-content:space-between;
  width:calc(100% - 28px);max-width:var(--chrome-navw,1412px);margin:10px auto 0;
  padding:10px 14px 10px 18px;
  background:rgba(244,241,232,.82);backdrop-filter:blur(18px);-webkit-backdrop-filter:blur(18px);
  border:1px solid rgba(27,26,24,.12);border-radius:18px;
  box-shadow:0 16px 38px -32px rgba(27,26,24,.65),inset 0 1px 0 rgba(255,255,255,.55);
}
.logo{display:flex;align-items:center;gap:12px;font-family:var(--font-serif);font-weight:500;font-size:22px;position:relative}
.logo-face{
  position:relative;flex-shrink:0;
  width:40px;align-self:stretch;
  pointer-events:none;
  display:inline-flex;
  margin-right:9px;
}
.logo-face .mask{
  /* left edge sits on the pill's own left edge, so the radius below traces
     the pill's bottom-left corner exactly — otherwise the shoulder paints
     into the notch the rounded corner leaves behind */
  position:absolute;
  left:-15px;right:-10px;
  top:-38px;
  bottom:0;
  overflow:hidden;
  border-bottom-left-radius:14px;   /* same as .logo-mk */
  pointer-events:none;
}
.logo-face .mask img{
  /* anchored to the slot side, so widening the mask leftward for the clip
     leaves the face itself exactly where it was */
  position:absolute;
  right:0;bottom:0;
  width:61px;height:auto;
  filter:drop-shadow(0 3px 4px rgba(0,0,0,.38));
  -webkit-user-drag:none;user-select:none;
}
.logo-mk{
  height:44px;padding:0 16px 0 15px;border-radius:14px 17px 13px 14px;
  border:var(--mk-edge);
  /* The mark used to be near-black end to end, and the avatar's dark
     turtleneck dissolved into it — the face read as a head floating on
     nothing. It runs a dark four-hue ramp now, 137° of hue across 160px:
     slate blue under the face, through indigo and violet, down to a deep
     plum behind the wordmark. The ramp also darkens as it goes, which is the
     part that earns its keep twice — the lit end is where the silhouette
     needs a wall to stand against, the dark end is where the cream wordmark
     and the terracotta "s" need one to read off, and orange on violet is the
     better pairing anyway. Every hue is an offset from --accent-h rather
     than a literal, so recolouring the site rotates the whole ramp with it
     and the mark never falls out of family. The radial lifts the bottom-left
     corner, where the shoulders sit. */
  background:var(--mk-ramp);
  color:var(--bg);
  display:inline-flex;align-items:center;
  /* Quicksand plutôt que Space Mono, mesuré le 05/09/2026 à 22 px : la hampe
     passe de 1,70 px à 1,35 px — c'est la police la plus légère des trois
     candidates — et ses terminaisons sont arrondies, exactement comme le
     `stroke-linecap:round` du glyphe qui termine le mot. Les deux formes
     viennent enfin du même geste.
     L'approche tombe de -.055em à -.02em : -.055 avait été réglée pour une
     chasse fixe de monospace, une proportionnelle s'y écrase. */
  font-family:'Quicksand',var(--font-body);font-weight:400;font-size:22px;letter-spacing:-.02em;line-height:1;
  position:relative;
  text-decoration:none;
  overflow:visible;
  box-shadow:0 8px 20px -14px rgba(27,26,24,.8),inset 0 1px 0 rgba(255,255,255,.1);
  transition:transform .22s ease,box-shadow .22s ease;
}
.logo-mk:hover{transform:translateY(-1px);box-shadow:0 13px 25px -15px rgba(27,26,24,.85),inset 0 1px 0 rgba(255,255,255,.12)}
.logo-mk .s{
  /* Hauteur d'x mesurée à 22 px : Quicksand 11,40, Fraunces italique 9,90.
     Il faut donc 1,15em à Fraunces pour poser son x sur celui des autres —
     l'ancien 1,05em valait contre Space Mono, dont l'x était plus bas.
     Le poids descend de 460 à 310 : à 1,15em cela donne une hampe d'environ
     1,50 px contre 1,35 px pour Quicksand. Ces 11 % de plus ne sont pas une
     erreur mais une compensation optique — le « s » est en terracotta sur la
     rampe sombre, les autres lettres en crème, et un trait moins contrasté
     paraît plus fin à épaisseur égale.
     Le décalage vertical a d'abord été ESTIMÉ à -.075em — « la boîte de 1,15em
     doit s'enfoncer de la moitié de son surplus » — et l'estimation était
     fausse de 0,55 px : le « s » flottait au-dessus de la ligne de pied.
     Mesuré à 22 px, bande d'x de « mir » : 41,00 → 53,00. Le « s » tenait
     40,45 → 52,45, la bonne hauteur au mauvais endroit. -.050em le pose
     exactement sur les deux lignes. */
  color:var(--accent);font-family:var(--font-serif);font-size:1.15em;font-style:italic;font-weight:310;
  letter-spacing:-.02em;margin-right:1px;
  /* Pas de translateY : `align-self:baseline` pose le « s » sur la ligne de
     pied de « mir » quel que soit le corps. Un décalage en em, lui, ne tenait
     qu'à une taille — réglé à 22 px il ratait de 1,06 px les 23 px du logo
     sous 900 px, parce que le centrage flex se fait dans une boîte de 44 px
     fixe : la lettre grandit, la boîte non, et le décalage ne suit pas. */
  align-self:baseline;
}
.logo-mk .miro{color:var(--bg);font-weight:400;align-self:baseline}
/* Le mot, centré dans la pastille.
   `align-self:baseline` aligne les trois éléments ENTRE EUX — c'est ce qui pose
   le « s » et le glyphe sur les lignes de « mir » à n'importe quel corps — mais
   il colle aussi le groupe au bord HAUT du conteneur, parce qu'un élément
   flex aligné sur la ligne de pied part du cross-start. Mesuré sur la capture :
   l'encre du mot occupait 8..22 dans une pastille de 44, soit 6,5 px au-dessus
   du centre. Avant le passage à baseline elle était centrée ; c'est donc une
   régression, pas un défaut d'origine.

   Une marge haute égale sur les trois décale le groupe entier d'autant, sans
   rien changer à leur alignement mutuel. Le portrait, lui, garde le
   `align-items:center` du conteneur et ne bouge pas.

   En px et non en em : la pastille fait 44 px aux DEUX corps (22 px dans la
   barre, 23 px sous 900 px), donc l'écart à combler est une distance fixe, pas
   une fraction du corps.

   7 px, et pas 6,5 : la valeur a été balayée sur des captures aux deux corps.
   5,5 et 6,5 font retomber le glyphe une ligne plus haut que les lettres à
   23 px — l'arrondi sous-pixel tombe du mauvais côté — tandis que 6 et 7
   gardent m, s et le bol sur les mêmes lignes partout. Des deux, 7 pose l'encre
   0,5 px SOUS le centre plutôt que dessus, ce qui est le bon côté de l'erreur
   pour un mot qui n'a que des ascendantes et aucune descendante. */
.logo-mk .s,
.logo-mk .miro,
.logo-mk .logo-o{margin-top:7px}
/* Le sélecteur porte le même préfixe `:is(...)` que la règle générique des
   icônes plus bas dans ce fichier. Ce n'est pas de la décoration : `:is()`
   prend le poids de son argument le plus fort, donc
   `:is(nav.top, .drawer, .site-footer) .ic` pèse (0,2,1) et l'emportait sur
   `.logo-mk .logo-o` à (0,2,0) — le glyphe du logo repartait à 1em et 1,7 de
   trait sur toutes les pages sauf l'accueil, qui n'a pas cette règle.
   Mesuré : 22 px au lieu de 15,75, trait 1,7 au lieu de 2,057. */
:is(nav.top, .drawer, .site-footer) .logo-mk .logo-o{
  /* Le glyphe doit peser et mesurer comme un « o » de la police, pas comme une
     icône posée à côté. Tout est calculé, rien n'est à l'œil.

     Le bol du dessin occupe 19 × 16 unités du viewBox de 24 (axes des traits).
     Le « o » de Quicksand à 22 px fait 11,10 × 11,70 px d'encre, hampe 1,35 px.
     On cherche l'échelle s telle que le trait rendu vaille 1,35 :
        trait rendu = stroke-width × s,  bol = (19 + sw) s × (16 + sw) s
     → s = .576, stroke-width = 2.344, largeur de boîte = 24 s = .628em.

     PREMIÈRE VERSION, corrigée : on avait ajusté le bol sur l'ENCRE du « o »
     (11,10 × 11,70) par moyenne géométrique, ce qui donnait 12,29 × 10,56. Un
     bol de 10,56 dans une bande d'x de 12,00 laisse 1,4 px de vide réparti en
     haut et en bas, et l'œil ne lit pas « un peu plus court » : il lit « c'est
     remonté ». C'est le seul défaut que le partage égal ne pouvait pas cacher.

     La contrainte qui compte n'est donc pas l'encre du « o » mais les DEUX
     LIGNES du mot — la ligne de pied et la ligne d'x, celles sur lesquelles m,
     i et r posent leurs traits plats. Mesuré à 22 px : 53,00 et 41,00, soit une
     bande de 12,00 — mais 12,00 est la valeur ARRONDIE que rend
     `actualBoundingBoxAscent` ; au balayage de pixels à 10×, la hauteur d'x de
     Quicksand vaut 11,40. Bâtir le bol sur 12,00 le faisait déborder d'un pixel
     en haut aux 23 px du logo mobile — vu sur la capture, pas déduit. On vise
     donc 11,70 : le débord d'un rond sur la ligne d'x, ce que fait n'importe
     quel « o » de fonderie. La valeur finale, 11,85, a été trouvée en lisant
     les PIXELS de deux captures du logo rendu, pas en calculant : 12,00
     débordait d'un pixel en haut à 23 px, 11,70 en manquait un en bas à 22 px.
     (16 + sw)·s = 11,85 avec sw·s = 1,35 donne s = .6563, stroke-width 2.057,
     boîte .716em — et les deux tailles tombent alors sur les mêmes lignes.

     Le bol y gagne ses deux lignes et perd sur la largeur : 14,00 contre 11,10
     d'encre au « o ». C'est assumé — un glyphe trop large se lit comme un
     parti pris de dessin, un glyphe qui flotte se lit comme un bug. Il reste
     d'ailleurs à 5 % de la CHASSE du « o » (13,29), donc le mot garde son pas.
     Pour rappel, avant toute mesure la boîte valait .85em : le bol était 45 %
     plus large et 18 % plus haut qu'un « o », et son trait 1,32 px contre 1,70
     aux lettres — trop gros ET trop maigre à la fois.

     stroke-width est en unités de viewBox, donc il suit la taille du texte tout
     seul : à 23 px sous 900 px de large, le rapport tient sans autre règle. */
  width:.716em;height:.716em;margin-left:.017em;
  stroke-width:2.057;
  /* `align-self:baseline` amène le bas de la BOÎTE sur la ligne de pied. Le bas
     du BOL est plus haut : il reste sous lui H × (2 − sw/2)/24 = .0298em de
     vide, qu'on rattrape en descendant le tout d'autant.
     C'est un `transform` et non une marge négative : sur un élément remplacé,
     Chrome prend le bas de la boîte comme ligne de pied et ignore la marge —
     essayé, mesuré, le bol restait 0,66 px trop haut.
     Tout est en em et plus rien ne dépend du centrage flex, donc le calage vaut
     aussi bien à 22 px qu'aux 23 px du logo sous 900 px. */
  align-self:baseline;transform:translateY(.029em);
  color:var(--bg);overflow:visible;
}
.logo-mk::after{
  content:"";position:absolute;right:-7px;bottom:-5px;width:15px;height:15px;border-radius:4px 5px 4px 5px;
  background:var(--accent);
  border:1px solid oklch(var(--accent-deep-lch) / .25);
  box-shadow:0 4px 8px -4px rgba(0,0,0,.6);transform:rotate(3deg);
}

.nav-r{display:flex;align-items:center;gap:20px}
.nav-r a{
  font-family:var(--font-mono);font-size:12.5px;font-weight:500;letter-spacing:.015em;
  text-decoration:none;color:var(--ink-2);
}
.nav-r>a:not(.nav-cta){position:relative;padding:10px 0}
.nav-r>a:not(.nav-cta)::after{
  content:"";position:absolute;left:0;right:100%;bottom:5px;height:1px;background:var(--accent);
  transition:right .22s ease;
}
.nav-r>a:not(.nav-cta):hover::after{right:0}
.nav-r a:hover{color:var(--accent)}
/* The call to action is an <a> everywhere it appears — a mail client on the
   homepage, the CV's own PDF on the CV — but not always inside `.nav-r`, so
   this rule states the whole type ramp rather than leaning on `.nav-r a`
   above. The appearance/cursor pair is left in place: it costs nothing, and
   the rule carried a <button> until the CV's print dialog became a file. */
.nav-cta{
  appearance:none;cursor:pointer;
  font-family:var(--font-mono);font-size:12px;font-weight:500;letter-spacing:.2px;
  padding:10px 14px;border-radius:14px;border:0;
  display:inline-flex;align-items:center;gap:8px;
  background:var(--ink);color:var(--bg) !important;text-decoration:none;
  transition:all .2s;
}
.nav-cta:hover{background:var(--accent)}
/* A label that gives up its verb once the bar gets narrow. The homepage sends
   its contact pill to the drawer below 640px; the CV's download cannot go with
   it — handing over the PDF is what the page is for, and on a phone it is the
   only way to get one — so it keeps the icon and the noun and drops the rest. */
.nav-cta .nb-short{display:none}
/* A link that leaves the page is a pill, so it doesn't read as another
   in-page anchor like workflow/stack/agents. */
.nav-r>a.nav-pill{
  position:static;padding:7px 12px;border-radius:999px;
  display:inline-flex;align-items:center;gap:6px;
  border:1px solid var(--line-2);background:rgba(255,255,255,.4);
  transition:background .2s,border-color .2s,color .2s;
}
.nav-r>a.nav-pill::after{content:none}
.nav-r>a.nav-pill:hover{background:var(--ink);color:var(--bg)}
.nav-pill .ic{width:12px;height:12px}

/* ───── mobile/tablet drawer ───── */
.nav-burger{
  display:none; flex-direction:column; justify-content:center; gap:5px;
  width:40px; height:40px; border:1px solid transparent; border-radius:12px;background:transparent; cursor:pointer;
  padding:0; margin-right:8px; position:relative; z-index:95;align-items:center;
  transition:background .2s,border-color .2s;
}
.nav-burger span{
  display:block; width:23px; height:2px; border-radius:2px;
  background:var(--ink); transition:all .3s cubic-bezier(.4,.8,.3,1);
  transform-origin:center;
}
.nav-burger span:nth-child(2){width:17px;transform:translateX(-3px)}
.nav-burger:hover{background:rgba(27,26,24,.05);border-color:var(--line)}
.nav-burger:hover span{ background:var(--accent) }
.nav-burger.open span:nth-child(1){ transform:translateY(7px) rotate(45deg) }
.nav-burger.open span:nth-child(2){ opacity:0; transform:translateX(-3px) scaleX(0) }
.nav-burger.open span:nth-child(3){ transform:translateY(-7px) rotate(-45deg) }

.drawer-overlay{
  position:fixed; inset:0; z-index:80;
  background:oklch(0.18 0.02 60 / .5); backdrop-filter:blur(6px);
  -webkit-backdrop-filter:blur(6px);
  opacity:0; visibility:hidden;
  transition:opacity .4s ease, visibility 0s linear .4s;
}
.drawer-overlay.open{ opacity:1; visibility:visible; transition:opacity .4s ease; }

.drawer{
  position:fixed; top:0; left:0; bottom:0; z-index:90;
  width:min(440px,91vw);
  background:
    radial-gradient(480px 340px at -5% 4%,oklch(var(--accent-wash-lch) / .72),transparent 64%),
    linear-gradient(160deg,rgba(255,255,255,.22),transparent 52%),var(--bg);
  transform:translateX(-110%);
  transition:transform .45s cubic-bezier(.4,.8,.25,1);
  display:flex; flex-direction:column; overflow-y:auto;
  box-shadow:22px 0 80px -32px rgba(27,26,24,.55);
}
.drawer.open{ transform:translateX(0) }
.drawer::after{
  content:""; position:fixed; top:0; right:0; bottom:0; width:2px;
  background:linear-gradient(180deg,var(--accent) 0 34%,var(--accent-mid) 34% 68%,var(--ink) 68% 100%);
}
.drawer-head{
  display:flex; align-items:center; gap:4px; padding:28px 28px 24px;
  border-bottom:1px solid var(--line-2);
}
.drawer-head .logo-mk{flex-shrink:0}
.drawer-head .logo-mk .s{color:var(--accent)}
.drawer-head .logo-mk .miro{color:var(--bg)}
.drawer-close{
  margin-left:auto; width:42px; height:42px; border-radius:13px;
  border:1px solid var(--line-2); background:var(--bg); color:var(--ink-2);
  font-size:15px; cursor:pointer; display:grid; place-items:center;
  transition:all .2s;
}
.drawer-close:hover{ border-color:var(--accent); color:var(--accent); background:oklch(var(--accent-lch) / .08) }

.drawer-links{
  display:flex; flex-direction:column; gap:0; padding:18px 28px 28px; flex:1;
}
/* The CV's "download as PDF" is a button, not a link — same row, same rhythm,
   so the selectors below accept either element. */
.drawer-links a,.drawer-links button{
  display:flex; align-items:center; min-height:82px;padding:18px 46px 18px 48px;border-radius:0;
  border:0;border-bottom:1px solid var(--line);background:transparent;width:100%;text-align:left;
  font-family:var(--font-serif); font-size:clamp(31px,8vw,42px);font-weight:420;letter-spacing:-.035em;line-height:1;
  text-decoration:none; color:var(--ink);cursor:pointer;
  transition:all .2s; position:relative; overflow:hidden;
}
.drawer-links :is(a,button)::before{
  content:attr(data-index);position:absolute;left:1px;top:24px;width:auto;height:auto;
  background:transparent;border-radius:0;transform:none;
  font-family:var(--font-mono);font-size:9px;font-weight:500;letter-spacing:.16em;color:var(--accent);
  transition:transform .25s cubic-bezier(.4,.8,.3,1),color .2s;
}
.drawer-links :is(a,button):not(.drawer-cta)::after{
  content:"→";position:absolute;right:3px;top:50%;transform:translate(-8px,-50%);opacity:0;
  font-family:var(--font-mono);font-size:17px;color:var(--accent);transition:opacity .2s,transform .25s;
}
.drawer-links :is(a,button):hover::before{transform:translateX(4px);color:var(--ink)}
.drawer-links :is(a,button):not(.drawer-cta):hover::after{opacity:1;transform:translate(0,-50%)}
.drawer-links :is(a,button):hover{background:transparent;color:var(--accent);padding-left:56px}
.drawer-links .drawer-cta{
  margin-top:26px;min-height:58px;justify-content:center;gap:10px;
  background:var(--ink); color:var(--bg) !important; border-radius:16px;border-bottom:0;
  font-family:var(--font-mono);font-size:12px;font-weight:600;letter-spacing:.02em;padding:16px;
}
.drawer-links .drawer-cta::before{ display:none }
.drawer-links .drawer-cta:hover{
  background:var(--accent); color:#fff !important;
  transform:translateY(-1px);padding-left:16px;
  box-shadow:0 6px 20px -8px oklch(var(--accent-lch) / .4);
}

/* ───── footer — the same editorial system, with room for the names to lead ───── */
.site-footer{
  width:calc(100% - 64px);max-width:var(--maxw,1240px);margin:18px auto 28px;padding:42px 0 0;
  border-top:1px solid var(--ink);color:var(--ink);
}
.footer-main{
  display:grid;grid-template-columns:minmax(230px,.8fr) minmax(360px,1.2fr) auto;
  align-items:end;gap:34px;padding-bottom:38px;
}
.footer-brand{display:flex;flex-direction:column;align-items:flex-start;gap:17px}
.footer-brand-note{
  max-width:34ch;margin:0;color:var(--muted);font-size:12px;line-height:1.6;
}
.footer-title{
  margin:0;font-family:var(--font-serif);font-size:clamp(35px,4.4vw,62px);font-weight:400;
  line-height:.93;letter-spacing:-.045em;
}
.footer-title em{font-weight:300;color:var(--accent);font-style:italic}
.footer-contact{
  display:inline-flex;align-items:center;gap:11px;justify-self:end;min-height:50px;padding:11px 20px;
  border:1px solid var(--ink);border-radius:999px;background:var(--ink);color:var(--bg);
  font-family:var(--font-mono);font-size:12px;letter-spacing:.02em;text-decoration:none;
  transition:background .2s,border-color .2s,transform .2s;
}
.footer-contact:hover{background:var(--accent);border-color:var(--accent);transform:translateY(-2px)}
.footer-nav{
  display:grid;grid-template-columns:repeat(4,1fr);border-top:1px solid var(--line-2);border-bottom:1px solid var(--line-2);
}
.footer-nav a{
  position:relative;display:flex;flex-direction:column;justify-content:space-between;gap:24px;min-height:136px;
  padding:18px 20px 20px;color:var(--ink);text-decoration:none;border-right:1px solid var(--line-2);
  transition:color .2s,background .2s;
}
.footer-nav a:last-child{border-right:0}
.footer-nav span{font-family:var(--font-mono);font-size:8px;letter-spacing:.14em;color:var(--accent)}
.footer-nav strong{
  font-family:var(--font-serif);font-size:clamp(26px,3vw,38px);font-weight:430;line-height:1;
  letter-spacing:-.035em;
}
.footer-nav a::after{
  content:"↗";position:absolute;right:18px;top:15px;font-family:var(--font-mono);font-size:14px;
  color:var(--muted);transition:transform .2s,color .2s;
}
.footer-nav a:hover{background:oklch(var(--accent-wash-lch) / .42);color:var(--accent)}
.footer-nav a:hover::after{color:var(--accent);transform:translate(2px,-2px)}
.footer-bottom{
  display:flex;justify-content:space-between;gap:24px;padding:20px 0 0;
  font-family:var(--font-mono);font-size:9px;line-height:1.5;letter-spacing:.08em;text-transform:uppercase;color:var(--muted);
}
/* The door to the panel. It keeps to --faint and to the corner: whoever needs
   it knows what it is, and to everyone else it is a footer link onto a gate
   they have no key for. The lock is /api/site-admin, never this link — so
   naming it costs nothing. */
.footer-key{
  align-self:center;flex:0 0 auto;
  padding:0 2px;color:var(--faint);text-decoration:none;line-height:1;
  opacity:.55;transition:opacity .25s,color .25s;
}
.footer-key:hover,.footer-key:focus-visible{opacity:1;color:var(--accent)}
.footer-bottom a{color:inherit;text-decoration:none}.footer-bottom a:hover{color:var(--accent)}
.footer-made{display:inline-flex;align-items:center;gap:6px}
/* The name is set as a signature rather than as more of the copyright line:
   a shade darker than the grey around it, and the mark stands between the
   given name and the family name — where a monogram goes — instead of
   trailing the sentence like a full stop. */
.fm-sig{display:inline-flex;align-items:center;gap:.3em;white-space:nowrap;color:var(--ink-2)}
/* Centred on the window, not on the box. Inside the 24×24 viewBox the window
   runs x 2–21, y 6–22 — its centre is (11.5, 14) while the box's is (12, 12),
   because the top-right corner is given up to the spark. The glyph moves back
   by (+0.5, −2) units so it sits in the line rather than below it. */
.ic-craft{
  width:2em;height:2em;color:var(--accent);stroke-width:1.5;
  translate:.038em -.153em;padding-bottom:2px;
  transition:transform .4s cubic-bezier(.2,.75,.2,1),filter .4s;
}
.footer-made:hover .ic-craft{transform:rotate(-8deg) scale(1.08);filter:drop-shadow(0 0 7px oklch(var(--accent-lch) / .4))}
@media (prefers-reduced-motion:reduce){
  .ic-craft{transition:none}
  .footer-made:hover .ic-craft{transform:none}
}
/* Language, as two badges rather than a dropdown. With two languages a menu
   is a click spent on nothing: both fit in the footer line, the one you are
   reading is filled, the other is the click. The homepage swaps its copy in
   place and uses <button aria-pressed>; the CV keeps one document per
   language and uses <a aria-current> — both are styled here, so the markup
   is free to say which of the two it is. */
.footer-langs{display:inline-flex;align-items:center;gap:4px}
.lang-badge{
  appearance:none;cursor:pointer;padding:4px 9px;
  display:inline-flex;align-items:center;text-decoration:none;
  border:1px solid var(--line-2);border-radius:999px;background:transparent;
  font-family:var(--font-mono);font-size:9px;letter-spacing:.08em;text-transform:uppercase;color:var(--muted);
  transition:background .2s,border-color .2s,color .2s;
}
.lang-badge:hover{color:var(--ink);border-color:var(--accent)}
.lang-badge[aria-pressed="true"],.lang-badge[aria-current="page"]{
  background:var(--accent);border-color:var(--accent);color:#fff;cursor:default;
}

/* ───── inline icons ─────
   Sized and coloured by the text they sit in, so a link never has to know
   which icon it carries. Scoped to the chrome: a page that already styles an
   `.ic` of its own keeps it. */
:is(nav.top,.drawer,.site-footer) .ic{
  width:1em;height:1em;flex-shrink:0;vertical-align:-.12em;
  fill:none;stroke:currentColor;stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round;
}
/* the pill-shaped actions run on a mono label of 10–12px; an icon at 1em there
   is smaller than the letters beside it, so this family sizes in px instead */
.nav-cta .ic{width:14px;height:14px}
.footer-contact .ic{width:16px;height:16px}
/* And the signature mark, which is not an inline icon at all but a glyph
   standing in for a monogram. Its own rule above asks for 2em and never got
   it: :is() takes the specificity of its heaviest argument, so the scoped
   rule directly above this one counts as nav.top .ic — one class and one
   type over a bare .ic-craft, which loses. Naming both classes on the
   element outranks it, and the mark is the two-em monogram again. */
.footer-made .ic.ic-craft{width:2em;height:2em}

/* ───── responsive ───── */
@media (max-width:1100px){
  .nav-burger{display:flex}
  .nav-r a:not(.nav-cta){display:none}
  .nav-r{gap:12px}
}
@media (max-width:760px){
  .nav-burger{min-width:42px;min-height:42px}
}
@media (max-width:720px){
  nav.top{
    top:8px;width:calc(100% - 16px);margin:8px auto 0;min-height:68px;
    padding:11px max(12px,env(safe-area-inset-right)) 11px max(12px,env(safe-area-inset-left));
    border-radius:18px;
    background:oklch(0.96 0.018 78);backdrop-filter:none;-webkit-backdrop-filter:none;
    box-shadow:none;
  }
  .nav-burger{width:44px;height:44px;margin:-6px 2px -6px -8px;align-items:center;border-radius:14px}
  .nav-burger:active{background:var(--bg-2)}
  .logo{gap:8px}.logo-mk{height:44px;font-size:23px;border-radius:14px 17px 13px 14px}
  .drawer{width:min(400px,94vw);padding-bottom:env(safe-area-inset-bottom)}
  .drawer-links a,.drawer-links button{min-height:78px}
}
@media (max-width:900px){
  .footer-main{grid-template-columns:1fr auto}.footer-title{grid-column:1 / -1;grid-row:1}
  .footer-brand{grid-column:1;grid-row:2}.footer-contact{grid-column:2;grid-row:2}
}
@media (max-width:640px){
  .nav-cta{padding:10px 12px}
  .nav-cta .nb-full{display:none}
  .nav-cta .nb-short{display:inline}
  .site-footer{width:calc(100% - 36px);margin-top:12px;padding-top:28px}
  .footer-main{display:flex;flex-direction:column;align-items:flex-start;gap:24px;padding-bottom:28px}
  .footer-title{font-size:clamp(38px,12vw,52px)}
  .footer-brand-note{font-size:12.5px}.footer-contact{justify-self:auto}
  .footer-nav{grid-template-columns:1fr 1fr}
  .footer-nav a{min-height:112px;padding:15px 15px 17px}
  .footer-nav a:nth-child(2){border-right:0}.footer-nav a:nth-child(-n+2){border-bottom:1px solid var(--line-2)}
  .footer-nav strong{font-size:29px}
  .footer-bottom{align-items:flex-start;flex-direction:column;gap:8px;padding-bottom:max(24px,env(safe-area-inset-bottom))}
  .lang-badge{min-height:34px;padding:7px 15px;font-size:10px}
  .footer-key{align-self:flex-start;display:inline-flex;align-items:center;min-height:32px}
}

/* The chrome belongs to the screen. On paper the document is the page. */
@media print{
  nav.top,.drawer,.drawer-overlay,.site-footer{display:none !important}
}
