@font-face { font-family: "Hanken Grotesk"; src: url(fonts/hanken-400-normal.woff2) format("woff2"); font-weight: 400; font-style: normal; font-display: swap; }
@font-face { font-family: "Hanken Grotesk"; src: url(fonts/hanken-400-italic.woff2) format("woff2"); font-weight: 400; font-style: italic; font-display: swap; }
@font-face { font-family: "Hanken Grotesk"; src: url(fonts/hanken-600-normal.woff2) format("woff2"); font-weight: 600; font-style: normal; font-display: swap; }
@font-face { font-family: "Hanken Grotesk"; src: url(fonts/hanken-latin-ext-600-normal.woff2) format("woff2"); font-weight: 600; unicode-range: U+0100-024F, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; font-display: swap; }
@font-face { font-family: "Hanken Grotesk"; src: url(fonts/hanken-latin-ext-400-normal.woff2) format("woff2"); font-weight: 400; unicode-range: U+0100-024F, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF; font-display: swap; }

:root {
  --bg: #fff;
  --ink: #111;
  --mute: #6f6f6f;
  --gut: 20px;
  --fs: 17px;               /* the one base size: sidebar, reel, details, Info */
  --lh: 1.38;
  --line-h: 44px;           /* one reel line, the snap unit: fixed, so sizes can change */
  --fs-0: var(--fs);        /* every reel line */
  --fs-3: 18px;             /* three lines from the centre */
  --fs-2: 19.5px;
  --fs-1: 21px;             /* next to the centre */
  --fs-on: 26px;            /* the line in the centre */
  /* extra space around the centre line, cumulative from the centre (lines
     are moved, not resized: the snap grid stays even) */
  --y1: 12px;
  --y2: 18px;
  --y3: 21px;
  --side-w: 220px;
  --ease: cubic-bezier(.16, 1, .3, 1);
  color-scheme: light;
}

* { box-sizing: border-box; }
html { -webkit-tap-highlight-color: transparent; -webkit-text-size-adjust: 100%; text-size-adjust: 100%; scrollbar-width: thin; scrollbar-color: #c9c9c9 transparent; }
body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font: 400 var(--fs)/var(--lh) "Hanken Grotesk", "Helvetica Neue", Arial, sans-serif;
  font-feature-settings: "tnum" 1, "kern" 1;
  -webkit-font-smoothing: antialiased;
}
::selection { background: var(--ink); color: var(--bg); }
a { color: inherit; text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 3px; text-decoration-color: #bdbdbd; }
a:hover { text-decoration-color: currentColor; }
button { font: inherit; color: inherit; background: none; border: 0; padding: 0; margin: 0; cursor: pointer; }
:focus-visible { outline: 1px solid var(--ink); outline-offset: 2px; }
h1, h2, p, ul, ol, figure { margin: 0; padding: 0; font-weight: 400; font-size: inherit; }
ul, ol { list-style: none; }
i { font-style: italic; }
.sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.ext { width: .62em; height: .62em; margin-left: .22em; vertical-align: .08em; }

/* ── sidebar: pages top-left, name and contact bottom-left ── */
.side { position: fixed; z-index: 5; inset: 0 auto 0 0; width: var(--side-w); padding: var(--gut); display: flex; flex-direction: column; gap: 22px; pointer-events: none; }
.side > * { pointer-events: auto; }
.pages { display: flex; gap: 14px; }
.pages a { text-decoration: none; color: var(--mute); }
.pages a[aria-current], .pages a:hover { color: var(--ink); }
.pages a[aria-current] { text-decoration: underline; text-decoration-color: currentColor; }
/* EN | FR, top right */
.langs { position: fixed; z-index: 5; top: var(--gut); right: var(--gut); color: var(--mute); }
.langs a { text-decoration: none; color: var(--mute); }
.langs a:hover, .langs [aria-current] { color: var(--ink); }
.langs .bar { color: var(--mute); padding: 0 .35em; white-space: pre; }
.sign { margin-top: auto; }
.sign a { text-decoration: none; color: var(--mute); }
.sign .name a { color: var(--ink); }                 /* the name stays black, and leads to Info */
.sign .name a:hover { text-decoration: underline; }
.sign a:hover { color: var(--ink); }

/* ── the index: a full-screen, looping reel ─────────────────── */
.p-index { overflow: hidden; }
.index { position: fixed; inset: 0; }
.reel {
  position: absolute; inset: 0;
  overflow-y: scroll;
  scroll-snap-type: y mandatory;
  scrollbar-width: none;
  overscroll-behavior: contain;
  outline: none;
  touch-action: pan-y;               /* no double-tap zoom, no tap delay */
  -webkit-user-select: none; user-select: none;
}
.reel::-webkit-scrollbar { display: none; }
.set { padding: calc(50vh - var(--line-h) / 2) 0; padding: calc(50lvh - var(--line-h) / 2) 0; }
.entry { scroll-snap-align: center; }
.entry[hidden] { display: none; }
.row {
  display: flex; align-items: center; justify-content: center;
  width: 100%; height: var(--line-h);
  padding: 0 calc(var(--gut) + var(--side-w));
  font-size: var(--fs-0); line-height: 1.2;
  -webkit-tap-highlight-color: transparent;
  text-align: center;
  color: var(--mute);
  /* site.js sets --y (spacing), --s (size) and --o (fade) by distance from the
     centre: transform and opacity only, so the phone never re-lays the page */
  opacity: var(--o, 0);
  transform: translateY(var(--y, 0px));
  transition: color .15s, opacity .3s var(--ease), transform .2s var(--ease);
}
.row .t { max-width: calc(100% / var(--s, 1)); white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  transform: scale(var(--s, 1)); transition: transform .2s var(--ease); }
/* a line spans the screen, but only its words take a click: empty space and
   the images behind do nothing */
.set, .entry, .row { pointer-events: none; }
.entry.near .row .t, .entry.near .row .d { pointer-events: auto; cursor: pointer; }
/* the highlight is typographic: the centre line largest and bold, three steps down on each side */
.entry.n1 .row { color: var(--ink); }
.entry.is-on .row { color: var(--ink); font-weight: 600; }
/* keyboard focus on the reel shows on the centre title, not as a frame round the screen;
   only once a key has been pressed, since the reel takes focus on load */
.kb .reel:focus-visible .entry.is-on .t { text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 5px; }
.row:focus-visible { outline: none; }   /* the reel shows keyboard focus on the centre title */
.more { display: none; }
/* News: the title on the left, the date on the right, on the details' measure */
.ln { display: flex; justify-content: space-between; align-items: baseline; gap: 24px; width: min(720px, 100%); }
.ln .t { text-align: left; transform-origin: left center; max-width: calc((100% - 7em) / var(--s, 1)); }
.ln .d { flex: none; font-weight: 400; color: var(--mute); font-variant-numeric: tabular-nums;
  transform: scale(var(--s, 1)); transform-origin: right center; transition: transform .2s var(--ease); }
.is-news .row { padding: 0 var(--gut); }
/* News reads like the Index: centred titles; the date is in the left column
   (computer) or the details (phone) */
.is-news .ln { justify-content: center; }
.is-news .ln .t { text-align: center; transform-origin: center; max-width: calc(100% / var(--s, 1)); }
.is-news .ln .d { display: none; }

/* the categories of the lines above, in and below the centre line, moving with the reel */
.cats {
  position: absolute; z-index: 2; left: var(--gut); top: 50%;
  height: calc(var(--line-h) * 9); transform: translateY(-50%);
  overflow: hidden;
  -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 12%, #000 88%, transparent 100%);
          mask-image: linear-gradient(to bottom, transparent 0, #000 12%, #000 88%, transparent 100%);
}
.cats.dates ol { will-change: transform; }         /* News: follows the scroll */
.cats li { height: var(--line-h); display: flex; align-items: center; }
.cat { color: var(--mute); text-underline-offset: 3px; text-decoration-thickness: 1px; transition: color .15s; }
.cat:hover, .cats li.mid .cat { color: var(--ink); }
/* Index: the list is fixed; the category of the centre line grows (from its left edge) */
.cats:not(.dates) { height: auto; -webkit-mask-image: none; mask-image: none; overflow: visible; }
.cats:not(.dates) .cat { display: block; transform-origin: left center; transition: transform .3s var(--ease), color .15s; }
.cats:not(.dates) li.mid .cat { transform: scale(1.24); }
.cats.filtered .cat { text-decoration: underline; }
/* opened: the category (or date) of the open line stays in the left column */
.index.open .cats li:not(.mid) { opacity: 0; transition: opacity .3s var(--ease); }
.cats.dates .cat { color: var(--mute); display: block; max-width: calc(var(--side-w) - 12px); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
/* News: nine places in the column, seven visible, following the same spacing */
.cats.dates { height: calc(var(--line-h) * 9); }
.cats.dates { -webkit-mask-image: linear-gradient(to bottom, transparent 0, transparent 4%, #000 14%, #000 86%, transparent 96%, transparent 100%);
                      mask-image: linear-gradient(to bottom, transparent 0, transparent 4%, #000 14%, #000 86%, transparent 96%, transparent 100%); }
.cats.dates li:nth-child(n) { transform: none; }
.cats.dates li:nth-child(4) { transform: translateY(calc(-1 * var(--y1))); }
.cats.dates li:nth-child(6) { transform: translateY(var(--y1)); }
.cats.dates li:nth-child(3) { transform: translateY(calc(-1 * var(--y2))); }
.cats.dates li:nth-child(7) { transform: translateY(var(--y2)); }
.cats.dates li:nth-child(2) { transform: translateY(calc(-1 * var(--y3))); }
.cats.dates li:nth-child(8) { transform: translateY(var(--y3)); }
.cats.dates li:nth-child(1) { transform: translateY(calc(-1 * var(--y3))); }
.cats.dates li:nth-child(9) { transform: translateY(var(--y3)); }
.cats.dates li.mid .cat { color: var(--ink); }
/* News: the place of the centre line grows too, from its left edge (its box is narrower so the larger text still fits the column) */
.cats.dates { width: calc(var(--side-w) - var(--gut)); }
.cats.dates .cat { max-width: calc((var(--side-w) - var(--gut) - 6px) / 1.24); transform-origin: left center; transition: transform .3s var(--ease), color .15s; }
.cats.dates li.mid .cat { transform: scale(1.24); }

/* images pop up behind the reel, placed on a column grid */
.pics { position: absolute; z-index: 0; inset: 0; overflow: hidden; pointer-events: none; }  /* own stacking context: an enlarged image never rises above the text */
.pic { position: absolute; transform-origin: 0 0; transition: transform .2s var(--ease), opacity .12s linear; }
/* the placeholder: a thin frame drawn edge by edge, then the picture over it */
.pic svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.pic path { fill: none; stroke: var(--ink); stroke-width: 1; vector-effect: non-scaling-stroke;
  stroke-dasharray: 1; stroke-dashoffset: 1; transition: stroke-dashoffset .22s cubic-bezier(.4, 0, .2, 1); }
.pic.drawn path { stroke-dashoffset: 0; }
.pic img { position: absolute; inset: 0; width: 100%; height: 100%; display: block; opacity: 0; transition: opacity .18s linear; }
.pic.shown img { opacity: 1; }
.pic svg { transition: opacity .18s linear; }
.pic.shown svg { opacity: 0; }   /* the frame was only a placeholder */
.pic.out { opacity: 0; }
.pic.big { transform: var(--zoom); z-index: 1; }
/* only a zoomed image comes in front of the text */
.pics.front { position: fixed; z-index: 6; }   /* above the reel and the side text (z 5) */

/* opened: the other lines fade, the details appear under the centre line */
.index.open .entry:not(.is-on) .row { opacity: 0; }
.index.open .pic.shown { opacity: .18; }
.index.open .pic.big { opacity: 1; }
.panel[hidden] { display: none; }   /* closed, it must not catch touches or the trackpad */
.panel {
  position: absolute; left: 50%; top: calc(50% + var(--line-h) / 2 + 18px);
  transform: translateX(-50%);
  width: min(720px, calc(100vw - 2 * var(--gut)));
  display: grid; grid-template-columns: minmax(0, 3fr) minmax(0, 2fr); column-gap: 48px;
  opacity: 0; transition: opacity .25s var(--ease);
}
.panel.in { opacity: 1; }
/* a long description scrolls inside the details (the reel stays put) */
.panel { max-height: calc(50vh - var(--line-h) / 2 - 36px); max-height: calc(50dvh - var(--line-h) / 2 - 36px);
  overflow-y: auto; overscroll-behavior: contain; scrollbar-width: thin; }
.panel .desc p + p { margin-top: .7em; }
@media (max-width: 860px) {
  .panel { max-height: calc(50vh - var(--line-h) / 2 - 36px - var(--reel-margin)); max-height: calc(50dvh - var(--line-h) / 2 - 36px - var(--reel-margin)); }
}
.panel .desc { text-align: left; }
.panel .facts { text-align: right; color: var(--mute); }
.panel .facts a { color: var(--ink); }
.panel p + p { margin-top: 2px; }
.panel .meta { color: var(--ink); }
.meta .y + .k::before, .meta .k + .p::before, .meta .y + .p::before { content: " · "; }
.facts .lab { color: var(--mute); margin-right: .5em; }

/* ── info page: the About text alone, on the details' measure ── */
.info { min-height: 100vh; min-height: 100dvh; display: grid; place-items: center; padding: 72px var(--gut); }
.about { width: min(720px, 100%); font-size: var(--fs-0); }
.about p + p { margin-top: .8em; }

/* ── narrow screens ──────────────────────────────────────────── */
/* computer: the left column already shows the category (Index) or the date
   (News), so the details leave it out; News titles are centred like the Index */
@media (min-width: 861px) {
  .p-index:not(.p-news) .panel .meta .k { display: none; }
  .p-news .panel .meta .p { display: none; }       /* the place is in the left column */
}
@media (max-width: 860px) {
  :root { --gut: 16px; }
  .side { width: auto; right: 0; gap: 12px; }
  .sign { display: flex; gap: 12px; }
  .row { padding: 0 var(--gut); }
  .cats { display: none; }
  .panel { grid-template-columns: minmax(0, 1fr); row-gap: 14px; }
  .panel .facts { text-align: left; }
  :root { --fs: 16px; --line-h: 44px; --fs-3: 16.5px; --fs-2: 17.5px; --fs-1: 18.5px; --fs-on: 21px;
          --y1: 9px; --y2: 14px; --y3: 16px;
          --reel-margin: 76px; }   /* the reel fades out before the pages and contact lines */
  /* 44 px tap targets for the pages and contact links */
  .pages a, .sign a, .sign .name, .langs a, .langs span { display: inline-flex; align-items: center; min-height: 44px; }
  .langs { top: 4px; right: var(--gut); }
  .side { padding-top: 4px; padding-bottom: 4px; }
}
@media (prefers-reduced-motion: reduce) { * { transition: none !important; } }
