/* Swiss / International direction: hairlines, square corners, strict type scale,
   one accent (signal red) reserved for "where I am on the map". */

:root {
  --paper: #f6f5f1;
  --card: #fdfcfa;
  --ink: #12161c;
  --muted: #5d646e;
  --rule: #d9d6ce;
  --accent: #c4301c;

  --font-sans: "Inter", system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-mono: "IBM Plex Mono", ui-monospace, "SFMono-Regular", Menlo, monospace;

  --bar-h: 56px;
  --inset-reserve: 260px;   /* space taken at the bottom right by the locator map */
  --gutter: clamp(16px, 4vw, 64px);
  --card-w: 440px;
  --ease: cubic-bezier(0.16, 1, 0.3, 1);
}

*, *::before, *::after { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font: 400 1rem/1.6 var(--font-sans);
  font-feature-settings: "tnum" 1, "ss01" 1;
  -webkit-font-smoothing: antialiased;
}
a { color: inherit; text-decoration-color: var(--accent); text-underline-offset: 3px; }
a:focus-visible, button:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
.skip { position: absolute; left: -999px; top: 8px; background: var(--ink); color: #fff; padding: 8px 12px; z-index: 300; }
.skip:focus { left: 8px; }

/* Header */
.bar {
  position: fixed; inset: 0 0 auto 0; z-index: 100;
  height: var(--bar-h);
  display: flex; align-items: center; justify-content: space-between;
  padding: 0 var(--gutter);
  background: rgba(246, 245, 241, 0.9);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--rule);
}
.brand { white-space: nowrap; font-weight: 600; letter-spacing: -0.01em; text-decoration: none; }
.bar-actions { display: flex; gap: 8px; }

.nav-link {
  margin-right: 8px; padding: 9px 4px;
  font: 500 0.8125rem/1 var(--font-sans); color: var(--ink); text-decoration: none;
  border-bottom: 1px solid transparent; transition: border-color 0.2s var(--ease);
}
.nav-link:hover, .nav-link:focus-visible { border-bottom-color: var(--accent); }

/* Buttons */
.btn {
  white-space: nowrap;
  display: inline-block;
  padding: 9px 16px;
  font: 500 0.8125rem/1 var(--font-sans);
  letter-spacing: 0.01em;
  text-decoration: none;
  border: 1px solid var(--ink);
  transition: background 0.2s var(--ease), color 0.2s var(--ease), transform 0.2s var(--ease);
}
.btn-solid { background: var(--ink); color: #fff; }
.btn-solid:hover { background: var(--accent); border-color: var(--accent); }
.btn-ghost { background: transparent; color: var(--ink); }
.btn-ghost:hover { background: var(--ink); color: #fff; }

/* Night sky behind the globe (stars drawn by js/stars.js) */
#stars {
  position: fixed; inset: 0; z-index: 0; width: 100%; height: 100%;
  background: radial-gradient(ellipse at 50% 38%, #12295c 0%, #0a1838 42%, #050c22 78%, #02050f 100%);
}

/* Map: transparent so the sky shows around the globe */
#map { position: fixed; inset: 0; z-index: 1; background: transparent; }
/* Still frame of the map, held while the relief is switched on or off underneath (js/app.js) */
.still { position: fixed; inset: 0; z-index: 2; width: 100%; height: 100%; pointer-events: none; opacity: 0; }
.maplibregl-ctrl-attrib { font-size: 10px; }

/* Story */
#story { position: relative; z-index: 10; pointer-events: none; }
/* Desktop: each card has a resting place, centred in the window. When scrolling stops near it, the browser
   eases the card there itself (scroll snapping runs off the main thread, so it stays smooth during flights). */
@media (min-width: 900px) {
  html.story-page { scroll-snap-type: y proximity; }
  html.story-page .card { scroll-snap-align: center; }
}
.step {
  min-height: 100vh;
  display: flex; align-items: center;
  padding: calc(var(--bar-h) + 24px) var(--gutter) 48px;
}
.card {
  pointer-events: auto;
  width: min(var(--card-w), 100%);
  background: var(--card);
  border: 1px solid var(--ink);
  padding: 28px 28px 26px;
  position: relative;
  opacity: 0.35;
  transform: translateY(12px);
  transition: opacity 0.6s var(--ease), transform 0.6s var(--ease);
}
.card-wide { --card-w: 520px; }
.step.is-active .card { opacity: 1; transform: none; }

/* Chapter number, set in the margin of the card */
.step[data-n]::before { content: none; }
.card::before {
  content: attr(data-n);
  position: absolute; top: -1px; right: -1px;
  font: 500 0.6875rem/1 var(--font-mono);
  background: var(--ink); color: #fff;
  padding: 6px 8px;
}

.logo { display: block; height: var(--h, 32px); width: auto; max-width: 78%; margin: 0 0 18px; object-fit: contain; object-position: left center; }

.eyebrow {
  margin: 0 0 14px;
  font: 500 0.625rem/1.5 var(--font-mono);
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--muted);
  padding-right: 36px;
  white-space: nowrap;          /* year, institution and place stay on one line */
}
h1, h2 { margin: 0 0 12px; font-weight: 600; letter-spacing: -0.02em; line-height: 1.12; }
h1 { font-size: clamp(2.5rem, 6vw, 3.75rem); letter-spacing: -0.035em; }
h2 { font-size: clamp(1.4rem, 2.4vw, 1.75rem); }
.card p { margin: 0 0 12px; }
.lead { font-size: 1.0625rem; line-height: 1.55; }
.note { font-size: 0.8125rem; color: var(--muted); }
.formula { font: 500 0.9375rem/1.4 var(--font-mono); padding: 10px 12px; margin: 4px 0 14px !important; background: var(--paper); border-left: 3px solid var(--accent); }
.hint { margin: 18px 0 0 !important; font: 500 0.6875rem/1 var(--font-mono); letter-spacing: 0.06em; text-transform: uppercase; color: var(--muted); }
.cta { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 18px; }

.links { list-style: none; margin: 14px 0 0; padding: 12px 0 0; border-top: 1px solid var(--rule); font-size: 0.875rem; }
.links li + li { margin-top: 6px; }
.links.inline { display: flex; flex-wrap: wrap; gap: 4px 18px; }
.links.inline li + li { margin-top: 0; }
.plain { margin: 6px 0 0; padding: 0; list-style: none; }
.plain li { padding: 10px 0; border-top: 1px solid var(--rule); font-size: 0.9375rem; }
.plain li:first-child { border-top: 0; padding-top: 0; }

/* Quotes */
.quote { margin: 4px 0 12px; font-size: 1.1875rem; line-height: 1.45; font-weight: 500; letter-spacing: -0.01em; padding-left: 16px; border-left: 3px solid var(--accent); }
.quote-end { font-weight: 600; }
.byline { font-size: 0.8125rem; color: var(--muted); margin: 14px 0 16px !important; }
.pull { margin: 16px 0 0; padding: 12px 14px; font-size: 0.875rem; line-height: 1.5; background: var(--paper); border-left: 3px solid var(--accent); }
.pull cite { display: block; margin-top: 6px; font: 500 0.6875rem/1 var(--font-mono); letter-spacing: 0.06em; text-transform: uppercase; color: var(--muted); font-style: normal; }

/* Lite YouTube embed: the iframe replaces the launcher button (never nested in it) */
.video {
  position: relative; display: block; width: 100%;
  aspect-ratio: 16 / 9; margin: 14px 0 0;
  border: 1px solid var(--ink); background: #000; overflow: hidden;
}
.video .launch {
  position: absolute; inset: 0; width: 100%; height: 100%; padding: 0; border: 0;
  background: #000 center / cover no-repeat; cursor: pointer;
}
.video .launch::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(to top, rgba(0,0,0,0.55), transparent 55%);
}
.video .play {
  position: absolute; left: 12px; bottom: 12px; z-index: 1;
  width: 0; height: 0;
  border-left: 14px solid #fff; border-top: 9px solid transparent; border-bottom: 9px solid transparent;
  filter: drop-shadow(0 1px 2px rgba(0,0,0,0.5));
}
.video .cap { position: absolute; left: 38px; right: 12px; bottom: 9px; z-index: 1; color: #fff; font: 500 0.75rem/1.3 var(--font-sans); text-align: left; }
.video .launch:hover .play { border-left-color: var(--accent); }
.video .vt { display: none; }
.hint-mobile { display: none; }
.video iframe { position: absolute; inset: 0; z-index: 2; width: 100%; height: 100%; border: 0; }

/* Scroll reminder: appears after 2 s of stillness at the top of the page */
.scrollhint {
  position: fixed; left: 50%; bottom: 64px; z-index: 45;
  display: flex; flex-direction: column; align-items: center; gap: 8px;
  padding: 10px 18px 12px; cursor: pointer;
  background: rgba(5, 12, 34, 0.82); border: 1px solid rgba(255, 255, 255, 0.28);
  color: #fff; font: 500 0.6875rem/1 var(--font-mono); letter-spacing: 0.14em; text-transform: uppercase;
  opacity: 0; transform: translate(-50%, 8px); pointer-events: none;
  transition: opacity 0.6s var(--ease), transform 0.6s var(--ease);
}
.scrollhint.is-visible { opacity: 1; transform: translate(-50%, 0); pointer-events: auto; }
.scrollhint i {
  width: 12px; height: 12px;
  border-right: 2px solid currentColor; border-bottom: 2px solid currentColor;
  transform: rotate(45deg); animation: nudge 1.6s var(--ease) infinite;
}
@keyframes nudge { 0%, 100% { transform: translateY(0) rotate(45deg); } 50% { transform: translateY(7px) rotate(45deg); } }

/* Locator map (bottom right): where the current chapter is */
.inset {
  position: fixed; right: 16px; bottom: 44px; width: 330px; height: 186px; z-index: 40;
  border: 1px solid var(--ink); background: var(--paper);
  box-shadow: 0 8px 28px rgba(0, 0, 0, 0.28);
  opacity: 0; transform: translateY(10px); pointer-events: none;
  transition: opacity 0.5s var(--ease), transform 0.5s var(--ease);
}
.inset.is-visible { opacity: 1; transform: none; }
.inset::after {
  content: "Location"; position: absolute; left: -1px; top: -1px;
  padding: 4px 8px; background: var(--ink); color: #fff;
  font: 500 0.625rem/1 var(--font-mono); letter-spacing: 0.08em; text-transform: uppercase;
}
.inset canvas { display: block; }

/* Chapter rail: every chapter labelled "year · place"; the current one opaque, the others translucent */
.rail {
  position: fixed; right: 18px;
  top: calc(var(--bar-h) + (100vh - var(--bar-h) - var(--inset-reserve)) / 2); transform: translateY(-50%);
  z-index: 50; display: flex; flex-direction: column; align-items: flex-end; gap: 5px;
  padding: 6px 0 6px 14px; cursor: grab; touch-action: none; user-select: none; -webkit-user-select: none;
}
.rail.is-scrubbing { cursor: grabbing; }
/* Desktop: a soft shade down the whole right edge, darkest at the edge and fading to nothing, so the chapter
   labels stand out over any map without a visible box */
@media (min-width: 900px) {
  html.story-page #map::after {      /* inside the map: above the tiles, below the map's own controls (sources) */
    content: ""; position: absolute; z-index: 1; top: 0; right: 0; bottom: 0; width: 360px; pointer-events: none;
    background: linear-gradient(to left, rgba(8, 14, 28, 0.52) 0%, rgba(8, 14, 28, 0.3) 38%, rgba(8, 14, 28, 0.1) 72%, rgba(8, 14, 28, 0) 100%);
  }
}
.rail button {
  display: flex; align-items: center; gap: 8px; padding: 0; border: 0; background: none;
  cursor: pointer; opacity: 0.6;
  transition: opacity 0.3s var(--ease);
}
.rail button:hover, .rail button:focus-visible { opacity: 0.85; }
.rail button.is-active { opacity: 1; }
.rail .lbl {
  padding: 3px 7px; white-space: nowrap;
  font: 500 0.6875rem/1.2 var(--font-mono); letter-spacing: 0.04em;
  background: rgba(246, 245, 241, 0.94); color: var(--ink);
  border: 1px solid var(--rule);
}
.rail button.is-active .lbl { background: var(--ink); color: #fff; border-color: var(--ink); }
.rail .dot {
  width: 9px; height: 9px; border-radius: 50%; flex: none;
  background: rgba(246, 245, 241, 0.94); border: 1px solid var(--ink);
  transition: background 0.3s var(--ease), transform 0.3s var(--ease);
}
.rail button.is-active .dot { background: var(--accent); border-color: var(--accent); transform: scale(1.3); }
@media (max-width: 1199px) {
  .rail button:not(.is-active) .lbl { display: none; }   /* narrow desktop: only the current label */
}
@media (max-height: 640px) { .rail { gap: 3px; } .rail .lbl { padding: 2px 6px; } }

/* Map markers */
.pin { width: 12px; height: 12px; border-radius: 50%; background: var(--ink); border: 2px solid var(--paper); }
.pin.is-current { background: var(--accent); }
.pin.is-current::after {
  content: ""; position: absolute; inset: -9px; border-radius: 50%;
  border: 1px solid var(--accent); animation: ping 2.2s var(--ease) infinite;
}
.pin:not(.is-current) .pin-label { display: none; }
.pin-label {
  position: absolute; left: 16px; top: -3px; white-space: nowrap;
  font: 500 0.6875rem/1 var(--font-mono); letter-spacing: 0.04em;
  background: var(--paper); border: 1px solid var(--ink); padding: 4px 6px;
}
@keyframes ping { 0% { transform: scale(0.6); opacity: 1; } 100% { transform: scale(1.5); opacity: 0; } }

.foot { position: relative; z-index: 10; padding: 28px var(--gutter); font: 400 0.75rem/1.4 var(--font-mono); color: var(--muted); background: var(--paper); border-top: 1px solid var(--rule); }

.sr-only { position: absolute; width: 1px; height: 1px; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.short { display: none; }
.alt { display: none; }

/* Contact page */
.contact-page h1 { margin-bottom: 8px; }
.contact-direct { margin-top: 28px; padding-top: 20px; border-top: 1px solid var(--ink); }
.mail-row { display: flex; flex-wrap: wrap; align-items: center; gap: 14px; margin: 4px 0 10px; }
.big-mail {
  font: 600 clamp(1.45rem, 5.2vw, 2.25rem)/1.15 var(--font-sans); letter-spacing: -0.02em;
  color: var(--ink); text-decoration: none; border-bottom: 2px solid var(--accent); overflow-wrap: anywhere;
}
.big-mail:hover { color: var(--accent); }
.contact-list { list-style: none; margin: 22px 0 0; padding: 0; border-top: 1px solid var(--rule); }
.contact-list a {
  display: flex; justify-content: space-between; gap: 16px; padding: 13px 0; text-decoration: none;
  border-bottom: 1px solid var(--rule); transition: padding 0.2s var(--ease);
}
.contact-list a:hover { padding-left: 8px; }
.contact-list .k { font: 500 0.6875rem/1.6 var(--font-mono); letter-spacing: 0.08em; text-transform: uppercase; color: var(--muted); }
.contact-list .v { font-weight: 500; overflow-wrap: anywhere; text-align: right; }

.contact-form { margin-top: 44px; padding-top: 20px; border-top: 1px solid var(--rule); }
.contact-form form { margin-top: 18px; max-width: 520px; }
.contact-form label { display: block; margin: 14px 0 6px; font: 500 0.6875rem/1 var(--font-mono); letter-spacing: 0.08em; text-transform: uppercase; }
.contact-form .req { color: var(--muted); letter-spacing: 0.04em; text-transform: none; margin-left: 6px; }
.contact-form input[type="text"], .contact-form input[type="email"], .contact-form textarea {
  width: 100%; padding: 11px 12px; font: 400 1rem/1.4 var(--font-sans); color: var(--ink);
  background: var(--card); border: 1px solid var(--ink); border-radius: 0; resize: vertical;
}
.contact-form input:focus-visible, .contact-form textarea:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.contact-form .hp { position: absolute; left: -9999px; width: 1px; height: 1px; opacity: 0; }
.form-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 14px; margin-top: 18px; }
.form-actions .btn { padding: 12px 22px; cursor: pointer; }
.status { margin: 0; font-size: 0.875rem; }
.status[data-kind="error"] { color: var(--accent); }
.note.small { margin-top: 14px; font-size: 0.75rem; }

/* Portfolio page */
.page { max-width: 760px; margin: 0 auto; padding: calc(var(--bar-h) + 56px) var(--gutter) 80px; }
.page h1 { font-size: clamp(2rem, 5vw, 3rem); }
.page section { margin-top: 48px; padding-top: 20px; border-top: 1px solid var(--ink); }
.page section h2 { margin-bottom: 8px; }
.page .eyebrow { padding-right: 0; }

@media (max-width: 1199px) { .card-wide { --card-w: 440px; } }

/* Mobile (up to 899px): the chapters are a horizontal strip of cards along the bottom, one card in
   the middle with its neighbours peeking in from both sides; the map fills the rest of the screen.
   Swiping the strip changes chapter, a fast swipe can skip several. The page itself does not scroll.
   Type is kept small so a card fits without scrolling; a few long ones may scroll vertically, never sideways. */
@media (max-width: 899px) {
  :root { --m-card: min(84vw, 440px); }
  html.story-page, html.story-page body { height: 100%; overflow: hidden; overscroll-behavior: none; }
  .rail, .inset, .scrollhint, .foot { display: none; }
  .hint-desktop { display: none; }
  .hint-mobile { display: inline; }
  .long { display: none; }
  .short { display: inline; }

  /* header: brand, Portfolio, Contact, Resume */
  .bar { padding: 0 14px; }
  .bar-actions { gap: 4px; align-items: center; }
  .bar-actions .btn { padding: 8px 10px; font-size: 0.75rem; }
  .nav-link { margin-right: 0; padding: 8px 6px; font-size: 0.75rem; }
  .btn-contact { border-color: transparent; background: none; padding: 8px 6px; }
  .brand { font-size: 0.9375rem; }

  /* sources: top right, under the header, folded to the "i" button */
  .maplibregl-ctrl-top-right { top: calc(var(--bar-h) + 4px); right: 2px; }
  .maplibregl-ctrl-attrib.maplibregl-compact-show { max-width: calc(100vw - 8px); }
  .maplibregl-ctrl-attrib .maplibregl-ctrl-attrib-inner { white-space: nowrap; font-size: min(10px, calc((100vw - 64px) / 37)); }
  .long-attrib .maplibregl-ctrl-attrib .maplibregl-ctrl-attrib-inner { white-space: normal; font-size: 9px; }   /* imagery adds long credits */
  html:not(.attrib-ready) .maplibregl-ctrl-attrib-inner { display: none; }   /* never shown open before the script has folded it */

  #story {
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 10;
    display: flex; align-items: flex-end;
    overflow-x: auto; overflow-y: hidden;
    scroll-snap-type: x mandatory; overscroll-behavior-x: contain;
    -webkit-overflow-scrolling: touch; scrollbar-width: none;
    padding: 0 calc((100vw - var(--m-card)) / 2) calc(12px + env(safe-area-inset-bottom, 0px));
    pointer-events: auto;
  }
  #story::-webkit-scrollbar { display: none; }
  .step { flex: 0 0 var(--m-card); min-height: 0; padding: 0 6px; align-items: flex-end; scroll-snap-align: center; }

  .card, .card-wide {
    --card-w: 100%; width: 100%; min-width: 0;
    max-height: 54vh; max-height: min(54dvh, 480px);
    overflow-x: hidden; overflow-y: auto; overflow-wrap: anywhere;
    padding: 14px 16px 14px;
    opacity: 0.55; transform: scale(0.96); transform-origin: bottom center;
    scrollbar-width: thin; scrollbar-color: var(--rule) transparent;
  }
  .step.tall .card { max-height: 62vh; max-height: min(62dvh, 520px); }   /* the few denser cards get more room */
  .step.is-active .card { opacity: 1; transform: none; }
  .card::before { padding: 5px 7px; font-size: 0.625rem; }

  /* small type */
  .eyebrow { margin-bottom: 8px; padding-right: 28px; font-size: 0.625rem; line-height: 1.4; letter-spacing: 0.02em; }
  .eyebrow .org, .eyebrow .opt, .note.todo { display: none; }
  .eyebrow .alt { display: inline; }                 /* the logo already names the institution */
  .card h1 { margin-bottom: 8px; font-size: clamp(1.7rem, 8vw, 2.1rem); }
  .card h2 { margin-bottom: 8px; font-size: 1.0625rem; line-height: 1.2; }
  .card p { margin-bottom: 8px; font-size: 0.8125rem; line-height: 1.5; }
  .card .lead { font-size: 0.875rem; }
  .note { font-size: 0.6875rem; }
  .card p.hint { margin-top: 12px !important; font-size: min(11px, 2.9vw); line-height: 1.4; letter-spacing: 0.03em; white-space: nowrap; }   /* one line at any phone width */
  .logo { height: calc(var(--h, 32px) * 0.72); margin-bottom: 10px; }
  .formula { margin: 2px 0 10px !important; padding: 7px 9px; font-size: 0.6875rem; overflow-wrap: anywhere; }
  .links { margin-top: 8px; padding-top: 8px; font-size: 0.75rem; }
  .links li + li { margin-top: 4px; }
  .plain li { padding: 7px 0; font-size: 0.8125rem; }
  .cta { gap: 6px; margin-top: 10px; }
  .card .btn { padding: 8px 12px; font-size: 0.75rem; }
  .quote { margin-bottom: 8px; padding-left: 12px; font-size: 0.9375rem; line-height: 1.4; }
  .quote-end { font-size: 0.8125rem; }
  .byline { margin: 8px 0 10px !important; font-size: 0.6875rem; }
  .pull { margin-top: 10px; padding: 8px 10px; font-size: 0.75rem; }
  .pull cite { font-size: 0.5625rem; }
  .pin-label-left { left: auto; right: 16px; }   /* keeps labels near the right edge on screen */

  /* Videos: a small thumbnail beside the title; tapping opens the player in place */
  .video {
    display: flex; align-items: center; gap: 10px; aspect-ratio: auto;
    margin-top: 8px; padding: 5px; background: var(--paper); cursor: pointer;
  }
  .video .launch { position: relative; inset: auto; flex: 0 0 80px; width: 80px; height: auto; aspect-ratio: 16 / 9; }
  .video .cap { display: none; }
  .video .play { left: 6px; bottom: 6px; border-left-width: 8px; border-top-width: 5px; border-bottom-width: 5px; }
  .video .vt { display: block; flex: 1; font: 500 0.75rem/1.3 var(--font-sans); }
  .video.is-playing { display: block; padding: 0; aspect-ratio: 16 / 9; background: #000; }

  /* contact page */
  .page { padding-top: calc(var(--bar-h) + 28px); }
  .contact-list a { padding: 11px 0; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .card { transition: none; opacity: 1; transform: none; }
  .pin.is-current::after { animation: none; }
  .scrollhint i { animation: none; }
}
