/* Neutral layout, one centred column (max 700px), original fonts.
   Opening the dates panel splits the viewport 1/2 info, 1/2 panel.
   Every value the scaffold panel (js/scaffold.js) can change is a
   variable in :root below. */

:root {
  --text: #111;
  --muted: #666;
  --line: #e2e2e2;     /* image placeholder (no lines are drawn any more) */
  --bg: #fff;
  --hover: #f5f5f5;
  /* Dates panel */
  --panel-bg: #f1eee9;  /* tour drawer card: warm grey */
  --panel-gap: 12px;   /* space around the floating panel card */
  --panel-pad: 32px;   /* inner padding of the panel card */

  /* Frosted glass: nav bar */
  --nav-glass: color-mix(in srgb, var(--bg) 70%, transparent);
  --nav-blur: 16px;
  --sheet: #170713;       /* contact box + full-screen sheet share this, so the grow reads as one object */
  --sheet-text: #ffffff;  /* text on the contact box/sheet */
  --sheet-muted: #c9c4c7; /* labels on the contact box/sheet */

  /* Fonts — originally Cossette Texte / Hubot Sans / Archivo / Chivo Mono;
     accent + mono switched to Cossette Texte via the scaffold (2026-10-13) */
  --display: 'Cossette Texte', -apple-system, sans-serif;
  --accent:  'Cossette Texte', -apple-system, sans-serif;
  --body:    'Archivo', -apple-system, sans-serif;
  --mono:    'Cossette Texte', -apple-system, sans-serif;
  --display-weight: 400;
  --accent-weight: 900;

  /* Spacing + roundness */
  --section-space: 100px;  /* vertical padding of each section */
  --radius-card: 24px;     /* hero image, contact box */
  --radius-control: 12px;  /* buttons */
  --page-blur: 6px;        /* info side while the dates panel is open */
  --hero-tilt: 0.75deg;    /* hero image rotation (0deg = straight) */
  --tape-tilt: -1.25deg;   /* ticker rotation (0deg = straight) */
  --drawably-stroke: var(--text);   /* hand-drawn accents (js/drawably-setup.js) */
  --drawably-fill: var(--text);
  --drawably-width: 1.5;
  --tape-from: #6b5bff;    /* ticker text gradient: blue-purple → */
  --tape-mid: #ff2e88;     /* red-magenta → */
  --tape-to: #3dffd0;      /* aquamarine */
  --tape-pad: 24px;        /* ticker inner padding left/right */

  --max: 700px;
  --gutter: 20px;
  --nav-h: 52px;
  --ease: 0.35s cubic-bezier(0.22, 1, 0.36, 1);
}

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

html {
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--nav-h) + 16px);   /* anchor jumps clear the sticky nav */
}

body {
  background: var(--bg);
  color: var(--text);
  font-family: var(--body);
  font-size: 16px;
  line-height: 1.5;
}

a { color: inherit; }
button { font: inherit; color: inherit; background: none; border: none; cursor: pointer; }

.container {
  max-width: var(--max);
  margin: 0 auto;
  padding: 0 var(--gutter);
}

.muted { color: var(--muted); }

/* ── Split layout ──────────────────────────────── */
/* Closed: the page fills the width and the panel has zero basis.
   Open: both take half. The info column keeps its 700px max and
   re-centres inside its half, so it slides left as the panel grows. */
.layout {
  display: flex;
  align-items: flex-start;
  min-height: 100vh;
}

.page {
  flex: 1 1 0;
  min-width: 0;
  transition: filter var(--ease);
}
/* Panel open: the info side is blurred and inert (main.js sets `inert`) */
.layout.panel-open .page {
  filter: blur(var(--page-blur));
  pointer-events: none;
  user-select: none;
}

.panel {
  flex: 0 0 0;
  min-width: 0;
  position: sticky;
  top: 0;
  height: 100vh;
  overflow: hidden;
  display: flex;
  background: var(--bg);
  transition: flex-basis var(--ease), padding var(--ease);
}

.layout.panel-open .panel {
  flex-basis: 50%;
  padding: var(--panel-gap) var(--panel-gap) var(--panel-gap) 0;
}

/* While the dates panel is open only the panel scrolls; the info side stays
   put. (The gutter keeps the layout from shifting when the scrollbar goes.) */
html { scrollbar-gutter: stable; }
body.panel-lock { overflow: hidden; }

/* The visible panel: a rounded card floating inside the half. */
.panel-card {
  position: relative;
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  background: var(--panel-bg);
  border-radius: var(--radius-card);
}
/* Row hover in the panel: a darker shade of the card's own colour (same hue,
   saturation only nudged up so it stays a warm grey, not a tan) */
.panel a.show:hover { background: oklch(from var(--panel-bg) calc(l - 0.06) calc(c * 1.5) h); }

/* ── Nav ───────────────────────────────────────── */
.site-header {
  position: sticky;
  top: 0;
  z-index: 10;
  background: var(--nav-glass);
  -webkit-backdrop-filter: blur(var(--nav-blur)) saturate(1.4);
  backdrop-filter: blur(var(--nav-blur)) saturate(1.4);
}

.nav {
  height: var(--nav-h);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}

.nav-name { font-weight: 600; text-decoration: none; white-space: nowrap; }
.nav-name:focus-visible { outline: none; }   /* the pen underline shows focus */

.nav-links { list-style: none; display: flex; gap: 20px; }
.nav-links a { text-decoration: none; }
.nav-links a:focus-visible { outline: none; }   /* the pen underline shows focus */

/* ── Hero ──────────────────────────────────────── */
.hero { padding: var(--section-space) 0 calc(var(--section-space) * 0.6); }

.hero h1 { font-size: 2rem; line-height: 1.2; font-weight: 600; }
.hero-sub { color: var(--muted); margin-top: 4px; }

.hero-media {
  position: relative;
  border-radius: var(--radius-card);
  margin-top: 24px;
  aspect-ratio: 3 / 2;
  overflow: hidden;
  background: var(--line);
  transform: rotate(var(--hero-tilt));
  touch-action: manipulation;
}
.hero-media.ripple-ready { cursor: pointer; }
.hero-media:focus-visible { outline: 2px solid var(--text); outline-offset: 2px; }

.hero-media img,
.ripple-canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  filter: grayscale(1);   /* all hero photos in black and white */
}

/* "1 / 5" hint, top right of the photo */
.ripple-count {
  position: absolute;
  top: 12px;
  right: 12px;
  z-index: 2;
  padding: 4px 9px;
  border-radius: 999px;
  background: rgba(0, 0, 0, 0.32);
  -webkit-backdrop-filter: blur(8px);
          backdrop-filter: blur(8px);
  color: #fff;
  font-family: var(--mono);
  font-size: 0.6875rem;
  letter-spacing: 0.08em;
  font-variant-numeric: tabular-nums;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.6s ease;
}
/* Flashed after each click (js/ripple-transition.js), then fades */
.ripple-count.is-visible { opacity: 1; transition-duration: 0.2s; }

/* "Click" hint in the middle of the hover peek; position and opacity are set
   per frame by js/ripple-transition.js */
.ripple-hint {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 2;
  padding: 4px 10px;
  border-radius: 999px;
  background: rgba(0, 0, 0, 0.32);
  -webkit-backdrop-filter: blur(8px);
          backdrop-filter: blur(8px);
  color: #fff;
  font-family: var(--mono);
  font-size: 0.6875rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  white-space: nowrap;
  pointer-events: none;
  opacity: 0;
}

/* Grungy edge: pen outline in the page colour over the edge of the photo
   and of the dates panel card (js/drawably-setup.js). On the photo it sits
   above the image and canvas but below the hints; on the card, above the
   scrolling rows and the sticky year row. */
.hero-media,
.panel-card {
  --drawably-stroke: var(--bg);
  --drawably-width: 3;
}
.hero-media > .drawably-svg { z-index: 1; }
.panel-card > .drawably-svg { z-index: 3; }
/* …but the tab, year and Tickets underlines inside the card keep the ink colour */
.panel-head,
.panel-body {
  --drawably-stroke: var(--text);
  --drawably-width: 1.5;
}

/* ── Margin doodles (js/drawably-setup.js) ─────── */
/* Random pen doodles either side of the column, re-drawn each page load.
   Purely decorative: never catch the pointer. */
main { position: relative; }
.doodles {
  position: absolute;
  inset: 0;
  overflow: hidden;                 /* never cause sideways scrolling */
  pointer-events: none;
  z-index: 1;
}
.doodle {
  position: absolute;
  --drawably-stroke: var(--muted);
  --drawably-width: 1.5;
}

/* Contact sheet: a fragment of a huge zigzag doodle behind the details */
.sheet-scribble {
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: 0.4;
  --drawably-stroke: var(--sheet-muted);
  --drawably-width: 2.5;
}
.contact-sheet-inner { position: relative; z-index: 1; }

/* Canvas fades in over the still once WebGL is ready */
.ripple-canvas { opacity: 0; transition: opacity 0.3s; }
.hero-media.ripple-ready .ripple-canvas { opacity: 1; }

/* ── Ticker ────────────────────────────────────── */
/* Its own rounded card, sitting directly under the hero photo with no gap.
   Content is built twice over in js/main.js; the track slides -50% for a
   seamless loop. */
.tape {
  /* Tilted like a strip of tape stuck across the photo's bottom edge;
     drawn above the photo so the overlapping end stays clean. */
  position: relative;
  z-index: 3;
  transform: rotate(var(--tape-tilt));
  background: var(--sheet);
  color: var(--sheet-muted);
  /* Pen outline in the box's own colour, on the edge, so it reads as a
     rough hand-cut edge (js/drawably-setup.js) */
  --drawably-stroke: var(--sheet);
  --drawably-width: 2.5;
  padding: 18px var(--tape-pad);
  white-space: nowrap;
}

/* The scrolling text is clipped here, inside the padding, so it never
   runs into the rounded ends. */
.tape-window {
  position: relative;
  overflow: hidden;
  /* Neon gradient on the text without touching the strip's colour: inside
     this isolated layer, white text on black is multiplied by the --tape-*
     gradient (black stays black); the layer is then screened onto the strip,
     where black drops out, leaving only the coloured text on --sheet. */
  isolation: isolate;
  background: #000;
  mix-blend-mode: screen;
}
.tape-window::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg in oklab, var(--tape-from), var(--tape-mid), var(--tape-to));
  mix-blend-mode: multiply;
  pointer-events: none;
}

.tape-track {
  display: inline-flex;
  animation: ticker 40s linear infinite;
}
.tape:hover .tape-track { animation-play-state: paused; }

.tape-track span {
  color: #fff;
  font-family: var(--mono);
  font-size: 0.75rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  padding: 0 20px;
}
.tape-track .tape-sep { padding: 0; }

@keyframes ticker {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}

/* ── Kinetic text reveal (js/kinetic-text-reveal.js) ── */
/* Each segment sits in a clipping mask and slides/blurs in with its own
   --ktr-delay. The padding/negative margin give descenders room inside the
   mask without changing line height; top alignment stops the clipped
   inline-blocks from raising the line (their baseline is their bottom edge). */
.ktr-mask {
  display: inline-block;
  overflow: hidden;
  vertical-align: top;
  padding-bottom: 0.12em;
  margin-bottom: -0.12em;
}
.ktr-word { display: inline-block; white-space: nowrap; vertical-align: top; }
.ktr-seg {
  display: inline-block;
  will-change: transform, opacity, filter;
  transition:
    opacity var(--ktr-duration, 0.72s) cubic-bezier(0.22, 1, 0.36, 1) var(--ktr-delay, 0s),
    transform var(--ktr-duration, 0.72s) cubic-bezier(0.22, 1, 0.36, 1) var(--ktr-delay, 0s),
    filter var(--ktr-duration, 0.72s) cubic-bezier(0.22, 1, 0.36, 1) var(--ktr-delay, 0s);
}
.ktr:not(.is-revealed) .ktr-seg {
  opacity: 0;
  transform: translate(var(--ktr-x, 0), var(--ktr-y, 20px));
  filter: blur(var(--ktr-blur, 6px));
}

/* ── Sections ──────────────────────────────────── */
.section { padding: var(--section-space) 0; }
.section h2 { font-size: 1.25rem; font-weight: 600; margin-bottom: 16px; }

/* ── Show rows (shared by page + panel) ────────── */
.shows { list-style: none; }

.show {
  display: grid;
  grid-template-columns: 76px 1fr auto;
  gap: 16px;
  column-gap: 36px;          /* breathing room between date block and show */
  align-items: center;
  padding: 14px 12px;
  margin: 0 -12px;
  border-radius: var(--radius-control);
  text-decoration: none;
}

a.show { transition: background-color 0.25s ease; }
a.show:hover { background: var(--hover); }
a.show:hover .show-action { text-decoration: underline; }

/* Elastic hover: the date and text slide in a little with a springy
   overshoot (the text trails the date slightly); Tickets nudges inward. */
a.show > * {
  transition: transform 0.55s cubic-bezier(0.34, 1.56, 0.64, 1);
}
a.show > :nth-child(2) { transition-delay: 0.03s; }
a.show:hover > :nth-child(1),
a.show:hover > :nth-child(2) { transform: translateX(var(--row-shift, 6px)); }
a.show:hover > .show-action { transform: translateX(calc(var(--row-shift, 6px) * -0.5)); }

/* Date block: large day in the display face, month/weekday stacked small */
.show-date {
  display: flex;
  align-items: center;
  gap: 8px;
  white-space: nowrap;
}
.show-day {
  font-family: var(--display);
  font-size: 2rem;
  line-height: 1;
  min-width: 1.15em;         /* 1- and 2-digit days line up… */
  text-align: right;         /* …right-aligned against the month */
  font-variant-numeric: tabular-nums;
  color: var(--text);
}
.show-dm {
  display: flex;
  flex-direction: column;
  font-family: var(--mono);
  font-size: 0.6875rem;
  line-height: 1.25;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted);
}
.show-dm span:first-child { color: var(--text); }
.show.is-past .show-day,
.show.is-past .show-dm span:first-child { color: var(--muted); }
.show-project { font-weight: 500; display: block; }
.show-place { color: var(--muted); font-size: 0.875rem; display: block; }
.show-action { font-size: 0.875rem; white-space: nowrap; }
.show-action.is-pending { color: var(--muted); }
.show.is-cancelled .show-project { text-decoration: line-through; color: var(--muted); }

.tour-note { margin: -8px 0 16px; color: var(--muted); font-size: 0.875rem; }   /* "No new dates announced yet." */

.panel-open-btn {
  margin-top: 20px;
  padding: 10px 16px;
  background: var(--hover);
  border-radius: var(--radius-control);
}
.panel-open-btn:hover { background: var(--text); color: var(--bg); }

/* ── Hand-drawn accents (vendor/drawably) ──────── */
/* Keep the site's own type and colours on decorated elements. */
.drawably-host,
.drawably-button { font-family: inherit; }
/* Dates button: the pen outline replaces the grey fill */
.panel-open-btn.drawably-button,
.panel-open-btn.drawably-button:hover {
  gap: 0.3em;                /* its flex layout drops the space before the arrow */
  padding: 10px 16px;
  background: none;
  border-radius: 0;
  color: var(--text);
}
/* Hover-only pen underlines: nav links and archive years (also shown on
   keyboard focus and on the current year) */
.pen-hover .drawably-svg { opacity: 0; transition: opacity 0.15s ease; }
.pen-hover:hover .drawably-svg,
.pen-hover:focus-visible .drawably-svg,
.year-jump a[aria-current="true"] .drawably-svg { opacity: 1; }
/* Tickets: the pen underline replaces the text underline */
a.show:hover .show-action.drawably-underline { text-decoration: none; }

/* ── Panel ─────────────────────────────────────── */
.panel-head {
  flex: none;
  height: var(--nav-h);
  display: flex;
  align-items: stretch;
  justify-content: space-between;
  padding: 8px var(--panel-pad) 0;
}

.tabs { display: flex; align-items: center; gap: 20px; }   /* tabs hug their text, so the pen underline sits right under it */

.tabs [role="tab"] {
  color: var(--muted);
  white-space: nowrap;
}
.tabs [role="tab"][aria-selected="true"] {
  color: var(--text);
}
.tabs [role="tab"]:focus { outline: none; }
.tabs [role="tab"]:focus-visible { outline: 2px solid var(--text); outline-offset: -2px; }
.tabs .count { font-size: 0.8125rem; color: var(--muted); }

/* Same round button as the contact sheet's ✕, tinted for the light card.
   Pinned in the card's corner with the same gap above and to the right
   (8px also centres it on the tabs). */
.panel-close {
  position: absolute;
  top: 8px;
  right: 8px;
  z-index: 1;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  font-size: 1rem;
  color: var(--text);
  background: color-mix(in srgb, var(--text) 7%, transparent);
  transition: background 0.2s;
}
.panel-close:hover { background: color-mix(in srgb, var(--text) 13%, transparent); }
.panel-close:focus-visible { outline: 2px solid var(--text); outline-offset: 2px; }

.panel-body {
  flex: 1;
  overflow-y: auto;
  padding: 24px var(--panel-pad) 48px;
  overscroll-behavior: contain;
}

/* Keep the panel content at a readable width while the panel animates
   open, so rows don't reflow through every intermediate width. */
.panel-head, .panel-body { min-width: min(320px, 100vw); }

.year-jump {
  /* One row, pinned to the top of the archive while it scrolls; scrolls
     sideways if the years don't fit. Bleeds to the card edges so rows
     pass cleanly underneath. */
  position: sticky;
  top: -24px;                      /* = .panel-body top padding */
  z-index: 2;
  display: flex;
  gap: 16px;
  overflow-x: auto;
  scrollbar-width: none;
  margin: -24px calc(-1 * var(--panel-pad)) 8px;
  padding: 24px var(--panel-pad) 14px;
  background: var(--panel-bg);
  font-size: 0.875rem;
  white-space: nowrap;
}
.year-jump::-webkit-scrollbar { display: none; }
.year-jump a { color: var(--muted); text-decoration: none; }
.year-jump a:hover { color: var(--text); }
.year-jump a[aria-current="true"] { color: var(--text); }
.year-jump a:focus-visible { outline: none; color: var(--text); }

.year-heading {
  font-size: 1rem;
  font-weight: 600;
  padding: 24px 0 8px;
}
.year-heading:first-child { padding-top: 0; }

/* ── Footer + contact (minimal state) ──────────── */
.footer { padding-top: var(--section-space); }

.contact-box {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: baseline;
  gap: 16px;
  padding: 24px 20px;
  background: var(--sheet);
  color: var(--sheet-text);
  border-radius: var(--radius-card);
}
.contact-box-sub { color: var(--sheet-text); font-size: 1rem; }
.contact-box-icon { font-size: 1.25rem; line-height: 1; color: var(--sheet-muted); }

/* Scroll room after the box: scrolling through it grows the sheet.
   JS reads its height as the length of the grow (see contact-sheet.js). */
.contact-runway { height: calc(80vh + 40px); }

/* ── Contact sheet (full viewport) ─────────────── */
/* Fixed over everything; JS sets clip-path from the box's on-screen
   rectangle (progress 0) to the full viewport (progress 1). Invisible
   until scrolling starts the grow. */
.contact-sheet {
  position: fixed;
  inset: 0;
  z-index: 50;
  background: var(--sheet);
  color: var(--sheet-text);
  display: flex;
  align-items: center;
  visibility: hidden;
  pointer-events: none;
}
.contact-sheet.is-growing { visibility: visible; }
/* Never over the dates panel */
.layout.panel-open ~ .contact-sheet { visibility: hidden; }

/* The box's label carried on the growing sheet (js/contact-sheet.js sets
   --hint-x/-y/-w to the shape's left edge, vertical centre and width). */
.sheet-hint {
  position: absolute;
  left: var(--hint-x, 0);
  top: var(--hint-y, 0);
  width: var(--hint-w, 100%);
  transform: translateY(-50%);
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: baseline;
  gap: 16px;
  padding: 0 20px;
  opacity: var(--hint-opacity, 1);
  pointer-events: none;
}
.sheet-hint-sub { color: var(--sheet-text); font-family: var(--mono); font-size: 1rem; }
.hint-a { color: var(--sheet-text); }
.hint-b { color: var(--sheet-text); }
.sheet-hint .contact-box-icon { color: var(--sheet-text); }
.contact-sheet.is-growing .sheet-hint .contact-box-icon { animation: hint-bob 1.4s ease-in-out infinite; }
@keyframes hint-bob {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(4px); }
}
/* The sheet takes over from the box the moment it starts growing. */
.contact-box.is-covered { visibility: hidden; }
.contact-sheet.is-full { pointer-events: auto; }

.contact-sheet-inner {
  width: 100%;
  opacity: var(--content, 0);
  transform: translateY(calc((1 - var(--content, 0)) * 16px));
}

.contact-sheet-inner h2 {
  font-size: 2rem;
  font-weight: 600;
  line-height: 1.2;
  padding-bottom: 24px;
  margin-bottom: 32px;
}

.contact-quote { margin: 0 0 40px; }
.contact-quote blockquote {
  font-family: var(--body);
  font-weight: 300;
  font-size: clamp(1.625rem, 3.8vw, 2.375rem);
  line-height: 1.15;
  letter-spacing: -0.02em;
  color: var(--sheet-text);
  --drawably-stroke: var(--sheet-text);
  --drawably-width: 1.75;
}
/* Hand-drawn quote marks (js/drawably-setup.js), sat in the text line */
.pen-quote {
  position: relative;
  display: inline-block;
  width: 0.6em;
  height: 0.5em;
  vertical-align: 0.35em;
}
.pen-quote--open { margin-right: 0.2em; }
.pen-quote--close { margin-left: 0.15em; }
/* They follow the quote's word-by-word reveal: open first, close at the end */
.ktr .pen-quote { opacity: 0; transition: opacity 0.4s ease; }
.ktr.is-revealed .pen-quote { opacity: 1; }
.ktr.is-revealed .pen-quote--close { transition-delay: 0.9s; }
.contact-quote figcaption {
  margin-top: 16px;
  font-family: var(--mono);
  font-size: 0.75rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--sheet-muted);
}

.contact-email {
  position: relative;
  font-size: 1.25rem;
  color: var(--sheet-text);
  text-decoration: none;              /* pen underline on hover instead */
  --drawably-stroke: var(--sheet-text);
}
.contact-email:focus-visible { outline: none; }
/* Instagram: no underline at rest, pen underline on hover like the email */
.contact-meta a {
  color: inherit;
  text-decoration: none;
  --drawably-stroke: var(--sheet-muted);
}
.contact-meta a:focus-visible { outline: none; }
/* Little caption that slides in beside the address on hover / focus */
.contact-email::after {
  content: attr(data-hint);
  position: absolute;
  left: 100%;
  top: 50%;
  margin-left: 14px;
  font-family: var(--mono);
  font-size: 0.6875rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--sheet-muted);
  pointer-events: none;
  opacity: 0;
  transform: translate(-6px, -50%);
  transition: opacity 0.2s ease, transform 0.35s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.contact-email:is(:hover, :focus-visible)::after {
  opacity: 1;
  transform: translate(0, -50%);
}

/* Close: scrolls back so the sheet shrinks into the box (contact-sheet.js).
   Fades in with the details; clickable once the sheet is full screen. */
.contact-close {
  position: absolute;
  top: 20px;
  right: 20px;
  z-index: 2;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  font-size: 1rem;
  color: var(--sheet-text);
  background: color-mix(in srgb, var(--sheet-text) 12%, transparent);
  opacity: var(--content, 0);
  transition: background 0.2s;
}
.contact-close:hover { background: color-mix(in srgb, var(--sheet-text) 22%, transparent); }
.contact-close:focus-visible { outline: 2px solid var(--sheet-text); outline-offset: 2px; }

.contact-meta {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 8px 16px;
  margin-top: 48px;
  padding-top: 16px;
  font-size: 0.875rem;
  color: var(--sheet-muted);
}
.contact-social { display: flex; gap: 16px; }

/* ── Typography (original font roles) ──────────── */
/* Display: Cossette Texte for names and headings. Accent: Hubot Sans Black
   for the surname, as in the original hero pairing. Body: Archivo.
   Mono: Chivo Mono for dates, labels and small meta. */
.nav-name,
.hero h1,
.section h2,
.contact-sheet-inner h2,
.year-heading {
  font-family: var(--display);
  font-weight: var(--display-weight);
}

.hero h1 .name-last,
.contact-sheet-inner h2 .name-last {
  font-family: var(--accent);
  font-weight: var(--accent-weight);
}

.hero-sub,
.show-place,
.show-action,
.tabs .count,
.year-jump,
.contact-box-sub,
.contact-meta {
  font-family: var(--mono);
}

/* ── Narrow screens ────────────────────────────── */
/* No room to split: the panel slides over the page full-width instead. */
@media (max-width: 800px) {
  .panel,
  .layout.panel-open .panel {
    position: fixed;
    inset: 0;
    z-index: 20;
    height: auto;
    flex: none;
    transform: translateX(100%);
    transition: transform var(--ease);
  }
  .layout.panel-open .panel { transform: none; padding: var(--panel-gap); }
}

@media (max-width: 520px) {
  .show { grid-template-columns: 68px 1fr; gap: 4px 20px; }
  .show-date { grid-row: 1 / span 2; }
  .show-action { grid-column: 2; justify-self: start; }   /* hug the word, so its pen underline does too */
  /* Hero photo fills most of the screen; each photo's focal point
     (data-focus in index.html) keeps Mats in the cropped frame */
  .hero-media { aspect-ratio: auto; height: 64vh; height: 64svh; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .ktr-seg { transition-duration: 0.01s !important; transition-delay: 0s !important; }
  .sheet-hint .contact-box-icon { animation: none !important; }
  .contact-email::after { transform: translate(0, -50%); transition: opacity 0.2s ease; }
  a.show > * { transition: none; }
  .ktr:not(.is-revealed) .ktr-seg { transform: none; filter: none; }
  .tape-track { animation: none; }
  .panel { transition: none !important; }
}

/* Phosphor icons inline with text */
.ph { vertical-align: -0.125em; }
.contact-box-icon.ph { display: inline-block; }
