/* styles.css
   All colors and fonts live in the variables below so the look can be swapped
   later. The starfield's own colors live at the top of starfield.js. */

/* Fonts are self-hosted from /fonts (no third-party requests). Both are
   variable fonts, Latin subset, SIL Open Font License (see fonts/OFL-*.txt).
   display.woff2 = Cormorant Garamond, body.woff2 = Inter.
   To swap a font, replace the file and keep the name. */
@font-face {
  font-family: "Site Display";
  src: url("fonts/display.woff2") format("woff2");
  font-weight: 300 700;
  font-display: swap;
}

@font-face {
  font-family: "Site Body";
  src: url("fonts/body.woff2") format("woff2");
  font-weight: 100 900;
  font-display: swap;
}

:root {
  /* Palette: deep navy, soft starlight, one rose accent */
  --bg: #050814;
  --ink: #eceff7;
  --ink-dim: #b3bacd;
  --accent: #e3a9b3;
  --accent-ink: #26131b;                     /* text on an accent background */
  --accent-glow: rgba(227, 169, 179, 0.7);
  --line: rgba(232, 236, 245, 0.18);
  --panel: rgba(10, 15, 34, 0.72);
  --panel-solid: rgba(9, 13, 30, 0.95);
  --backdrop: rgba(4, 6, 15, 0.6);
  --star-glow: rgba(232, 236, 245, 0.5);
  --text-halo: 0 0 14px rgba(5, 8, 20, 0.95), 0 0 4px rgba(5, 8, 20, 0.9);
  --figure-fill: #080b18;
  --figure-rim: rgba(236, 239, 247, 0.6);

  /* Era tints: nearly clear in the open future, closer and warmer toward the
     past. Each is a soft radial wash over the starfield. */
  --era-future: radial-gradient(ellipse at 50% 55%, rgba(20, 30, 70, 0.10), rgba(8, 12, 30, 0.05));
  --era-now: radial-gradient(ellipse at 50% 55%, rgba(30, 44, 90, 0.34), rgba(14, 22, 50, 0.22));
  --era-college: radial-gradient(ellipse at 50% 55%, rgba(48, 50, 104, 0.48), rgba(22, 26, 62, 0.36));
  --era-beneath: radial-gradient(ellipse at 50% 60%, rgba(96, 58, 84, 0.62), rgba(44, 26, 50, 0.5));
  --era-edge: rgba(236, 239, 247, 0.10);
  --detail-bg: radial-gradient(ellipse at 50% 40%, rgba(52, 50, 108, 0.55), rgba(18, 20, 50, 0.72));

  /* Type */
  --font-body: "Site Body", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --font-display: "Site Display", Georgia, "Times New Roman", serif;

  /* Geometry. --zoom-factor and --nav-count are set from main.js. */
  --zoom-factor: 3.5;
  --era-radius: 28px;
  --nav-count: 4;
  --nav-col: 7.5rem;
}

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

html, body {
  margin: 0;
  height: 100%;
  overflow: hidden;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-body);
  line-height: 1.5;
}

button { font: inherit; color: inherit; }

[hidden] { display: none !important; }

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

.placeholder { font-style: italic; opacity: 0.7; }

.btn {
  border: 1px solid var(--line);
  background: transparent;
  padding: 0.55rem 1.1rem;
  border-radius: 999px;
  cursor: pointer;
}

.btn:hover { border-color: var(--accent); }

.btn--primary { border-color: var(--accent); color: var(--accent); }

/* ----- Layers ----- */

/* Stack, back to front: sky, eras, fixed UI, panel. */

#sky {
  position: fixed;
  inset: 0;
  width: 100%;
  height: 100%;
  z-index: 0;
  pointer-events: none;
}

#stage {
  position: fixed;
  inset: 0;
  overflow: hidden;
  z-index: 2;
}

.site-header,
.position,
.era-nav,
.zoom-controls { z-index: 3; }

/* ----- Eras -----
   Every era is a full-viewport box scaled around the center. Each earlier era
   sits in the middle of the one around it at 1 / --zoom-factor of its size. */

.era {
  position: absolute;
  inset: 0;
  transform-origin: 50% 50%;
  pointer-events: none;
}

.era.is-active { pointer-events: auto; }

/* The eras have no boxes of their own: the cosmos drawn in starfield.js
   (Earth, the Moon, the solar system) shows where you are. */

.era__head {
  position: absolute;
  top: 13%;
  left: 50%;
  transform: translateX(-50%);
  width: min(42rem, 64%);
  text-align: center;
}

.era__title {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(2.1rem, 4.8vw, 3.5rem);
  line-height: 1.1;
  letter-spacing: 0.01em;
  text-shadow: var(--text-halo);
}

.era__title:focus { outline: none; }

.era__subtitle {
  margin: 0.35rem 0 0;
  color: var(--ink-dim);
  font-size: clamp(0.95rem, 1.5vw, 1.15rem);
}

.era__back {
  margin-top: 0.9rem;
  font-size: 0.85rem;
  background: var(--panel-solid);
}

/* The era's NASA photograph: faint, behind the generative stars' glow and
   all text. --sky-opacity is tuned per era (bright images get less). */
.era__sky {
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background-position: center;
  background-size: cover;
  background-repeat: no-repeat;
  opacity: calc(var(--sky-opacity, 0.4) * var(--sky-fade, 1));
  pointer-events: none;
  /* Soft edges, so the photo never reads as a box. */
  -webkit-mask-image: radial-gradient(ellipse at center, #000 45%, transparent 85%);
  mask-image: radial-gradient(ellipse at center, #000 45%, transparent 85%);
}

.era[data-era="future"]  { --sky-opacity: 0.55; }
.era[data-era="now"]     { --sky-opacity: 0.34; }
.era[data-era="college"] { --sky-opacity: 0.3; }
.era[data-era="personal"] { --sky-opacity: 0.32; }

/* The window in the middle of each era where the next-earlier era shows.
   Clicking it zooms in. */
.era__portal {
  position: absolute;
  left: 50%;
  top: 50%;
  /* A circle around Earth at the centre of the view. */
  width: calc(min(100vw, 100vh) / var(--zoom-factor));
  height: calc(min(100vw, 100vh) / var(--zoom-factor));
  transform: translate(-50%, -50%);
  background: transparent;
  border: 1px solid transparent;
  border-radius: 50%;
  cursor: zoom-in;
  transition: border-color 0.2s;
}

.era__portal:hover { border-color: rgba(227, 169, 179, 0.45); }

/* Personal items stay hidden until the visitor crosses the wall. */
body:not(.wall-crossed) .era[data-era="personal"] :is(.item, .era__back) { visibility: hidden; }

/* ----- Items ----- */

/* Each item is a card: a quiet labelled button. (A glowing dot above a
   label read as a location pin on the map.) */
.item {
  position: absolute;
  width: min(15rem, 28vw);
  transform: translate(-50%, -50%);
  padding: 0.55rem 0.9rem;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 12px;
  text-align: center;
  text-shadow: var(--text-halo);
  cursor: pointer;
  transition: opacity 0.3s, border-color 0.2s, box-shadow 0.3s, background 0.2s;
}

.item:hover,
.item.is-selected {
  border-color: var(--accent);
  background: var(--panel-solid);
}

.item:hover .item__title,
.item.is-selected .item__title { color: var(--accent); }

/* A card a link pointed to, on arrival (main.js pointOut). */
.item.is-pointed {
  border-color: var(--accent);
  box-shadow: 0 0 16px rgba(227, 169, 179, 0.45);
}

.item__parent {
  display: block;
  margin-bottom: 0.15rem;
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--accent);
}

.item__title {
  display: block;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 1.2rem;
  line-height: 1.2;
  transition: color 0.2s;
}

.item__summary {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  margin-top: 0.25rem;
  font-size: 0.85rem;
  line-height: 1.35;
  color: var(--ink-dim);
}

/* ----- Header: identity + contact ----- */

.site-header {
  position: fixed;
  top: 1.25rem;
  left: 1.5rem;
  max-width: min(22rem, 30vw);
}

.site-header,
.position { text-shadow: var(--text-halo); }

.identity {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 2rem;
  line-height: 1.15;
}

/* One line on who she is, right under the name. */
.identity__tagline {
  margin: 0.15rem 0 0.45rem;
  font-size: 0.85rem;
  line-height: 1.4;
  color: var(--ink);
}

/* What she's looking for, under the tagline. */
.identity__seeking {
  margin: -0.2rem 0 0.5rem;
  font-size: 0.8rem;
  line-height: 1.4;
  font-style: italic;
  color: var(--accent);
}

.identity__seeking:empty { display: none; }

/* Where and when she can start, under the seeking line. */
.identity__availability {
  margin: -0.35rem 0 0.5rem;
  font-size: 0.78rem;
  line-height: 1.4;
  color: var(--ink-dim);
}

.identity__availability:empty { display: none; }

.identity__pronouns {
  font-family: var(--font-body);
  font-size: 0.85rem;
  color: var(--ink-dim);
  margin-left: 0.35rem;
}

.identity__full {
  margin: 0.1rem 0 0.35rem;
  font-size: 0.9rem;
  color: var(--ink-dim);
}

.contact {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0 0.9rem;
  font-size: 0.8rem;
  color: var(--ink-dim);
}

.contact a { color: var(--ink); text-decoration-color: var(--line); }
.contact a:hover { text-decoration-color: var(--accent); }

/* ----- Resume link: top right, in every era ----- */

.resume-link {
  position: fixed;
  top: 1.25rem;
  right: 1.5rem;
  z-index: 3;
  padding: 0.45rem 1rem;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: var(--panel);
  color: var(--ink);
  font-size: 0.82rem;
  text-decoration: none;
  text-shadow: var(--text-halo);
}

.resume-link:hover { border-color: var(--accent); color: var(--accent); }

/* ----- Position indicator + hint ----- */

.position {
  position: fixed;
  top: 1.25rem;
  right: 1.5rem;
  max-width: min(18rem, 30vw);
  text-align: right;
  font-size: 0.9rem;
  line-height: 1.3;
}

.position__label {
  display: block;
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink-dim);
}

.position__era {
  display: block;
  font-family: var(--font-display);
  font-size: 1.15rem;
  color: var(--accent);
}

.position__sub { display: block; color: var(--ink-dim); }

.position__sky {
  margin: 0.3rem 0 0;
  font-size: 0.68rem;
  color: var(--ink-dim);
  opacity: 0.8;
}

/* ----- Era navigation: a timeline along the bottom, past on the left ----- */

.era-nav {
  position: fixed;
  left: 50%;
  bottom: 1.1rem;
  transform: translateX(-50%);
  --pos: 0;
}

.era-nav__track {
  position: relative;
  display: block;
  height: 2px;
  margin: 0 calc(var(--nav-col) / 2) 0.35rem;
  background: var(--line);
}

.era-nav__marker {
  position: absolute;
  top: 50%;
  left: 0;
  width: 10px;
  height: 10px;
  margin: -5px 0 0 -5px;
  border-radius: 50%;
  background: var(--accent);
  transform: translateX(calc(var(--pos) * var(--nav-col)));
}

.era-nav__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(var(--nav-count), var(--nav-col));
}

.era-nav__btn {
  display: block;
  width: 100%;
  padding: 0.25rem;
  background: none;
  border: 0;
  font-size: 0.85rem;
  color: var(--ink-dim);
  cursor: pointer;
}

.era-nav__btn:hover,
.era-nav__btn[aria-current] { color: var(--ink); }

/* ----- Zoom buttons ----- */

.zoom-controls {
  position: fixed;
  right: 1.5rem;
  bottom: 1.25rem;
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}

.zoom-btn {
  width: 2.5rem;
  height: 2.5rem;
  border-radius: 50%;
  border: 1px solid var(--line);
  background: var(--panel);
  font-size: 1.25rem;
  line-height: 1;
  cursor: pointer;
}

.zoom-btn:hover { border-color: var(--accent); }

.zoom-btn[aria-disabled="true"] { opacity: 0.35; cursor: default; }

/* A speech bubble beside each zoom button, its tail pointing at the button. */
.zoom-row {
  position: relative;
  display: flex;
  justify-content: flex-end;
}

.zoom-bubble {
  position: absolute;
  right: calc(100% + 0.7rem);
  top: 50%;
  transform: translateY(-50%);
  width: max-content;
  white-space: nowrap;                /* one line on desktop; phones may wrap */
  padding: 0.35rem 0.75rem;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--panel-solid);
  font-size: 0.8rem;
  line-height: 1.3;
  text-align: right;
  color: var(--ink);
  cursor: pointer;
  transition: border-color 0.2s, color 0.2s;
}

/* The tail: a small diamond tucked half under the bubble's right edge. */
.zoom-bubble::after {
  content: "";
  position: absolute;
  right: -5px;
  top: 50%;
  width: 8px;
  height: 8px;
  margin-top: -4px;
  background: inherit;
  border-top: 1px solid var(--line);
  border-right: 1px solid var(--line);
  transform: rotate(45deg);
}

.zoom-bubble:hover,
.zoom-row:has(.zoom-btn:hover) .zoom-bubble { border-color: var(--accent); color: var(--accent); }
.zoom-bubble:hover::after,
.zoom-row:has(.zoom-btn:hover) .zoom-bubble::after { border-color: var(--accent); }

/* Medium screens: the timeline is wide enough to reach the bottom-right
   corner, so the buttons and their bubbles sit just above it. */
@media (min-width: 701px) and (max-width: 1200px) {
  .zoom-controls { bottom: 4.6rem; }
}

/* ----- Zoom hint: first visit only, beside the buttons ----- */

.zoom-hint {
  position: fixed;
  right: 1.5rem;
  bottom: 7.1rem;                     /* just above the + and − buttons */
  z-index: 3;
  max-width: 17rem;
  margin: 0;
  text-align: right;
  font-size: 0.95rem;
  line-height: 1.4;
  text-shadow: var(--text-halo);
  pointer-events: none;
  opacity: 0;
  transform: translateY(0.5rem);
  transition: opacity 0.6s ease, transform 0.6s ease;
}

.zoom-hint.is-shown { opacity: 1; transform: none; }

.zoom-hint__how { display: block; color: var(--ink); }
.zoom-hint__buttons { display: block; margin-top: 0.2rem; color: var(--ink-dim); }

/* While the hint shows, the buttons it points to glow softly. */
body.hint-on .zoom-btn {
  border-color: var(--accent);
  box-shadow: 0 0 12px rgba(227, 169, 179, 0.35);
}

.zoom-btn { transition: border-color 0.4s, box-shadow 0.4s; }

/* ----- Item panel ----- */

.panel {
  position: fixed;
  top: 7rem;
  right: 1.5rem;
  max-height: calc(100vh - 13rem);
  width: min(26rem, calc(100vw - 3rem));
  z-index: 4;
  overflow-y: auto;
  padding: 1.5rem 1.5rem 2rem;
  background: var(--panel-solid);
  border: 1px solid var(--line);
  border-radius: 16px;
  opacity: 0;
  transform: translateX(1rem);
  transition: opacity 0.25s, transform 0.25s;
}

.panel.is-open { opacity: 1; transform: none; }

/* Opened from a right-hand item, the panel sits on the left. */
.panel.panel--left {
  right: auto;
  left: 1.5rem;
  top: 11rem;                            /* below the header; main.js fits it exactly */
  max-height: calc(100vh - 17rem);
  transform: translateX(-1rem);
}
.panel.panel--left.is-open { transform: none; }

.panel__close {
  position: absolute;
  top: 0.75rem;
  right: 0.75rem;
  width: 2rem;
  height: 2rem;
  border: 0;
  border-radius: 50%;
  background: none;
  font-size: 1.4rem;
  line-height: 1;
  color: var(--ink-dim);
  cursor: pointer;
}

.panel__close:hover { color: var(--ink); }

.panel__era {
  margin: 0;
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink-dim);
}

.panel__parent {
  margin: 0.2rem 0 0;
  font-size: 0.75rem;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--accent);
}

.panel__parent:empty { display: none; }

.panel__title {
  margin: 0.3rem 2rem 0.5rem 0;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: 1.6rem;
  line-height: 1.2;
}

.panel__title:focus { outline: none; }

.panel__summary { margin: 0 0 1rem; color: var(--ink-dim); }

.panel__body p { margin: 0 0 1rem; }

.panel__links {
  list-style: none;
  margin: 0 0 1rem;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.panel__links a { display: inline-block; text-decoration: none; font-size: 0.9rem; }

.panel__children h3 {
  margin: 1.5rem 0 0.5rem;
  font-size: 0.75rem;
  font-weight: 400;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink-dim);
}

.panel__children .btn { margin: 0 0.4rem 0.4rem 0; }

.panel__back { margin-top: 1.5rem; }

/* ----- The wall prompt ----- */

.wall {
  max-width: min(34rem, calc(100vw - 2rem));
  max-height: calc(100vh - 2rem);
  overflow-y: auto;
  padding: 2rem;
  border: 1px solid var(--line);
  border-radius: 16px;
  background: var(--panel-solid);
  color: var(--ink);
  text-align: center;
}

.wall::backdrop { background: var(--backdrop); }

.wall__title {
  margin: 0 0 1rem;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 1.6rem;
  line-height: 1.2;
}

.wall__note {
  text-align: left;
  font-size: 0.95rem;
  line-height: 1.6;
  color: var(--ink);
}

.wall__note p { margin: 0 0 0.9rem; }

.wall__text {
  margin: 0 0 1.5rem;
  font-family: var(--font-display);
  font-size: 1.35rem;
  line-height: 1.35;
}

.wall__actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.75rem;
}

/* ----- The figure: someone looking up at the sky -----
   --figure-h is set from main.js. It shrinks toward the future. */

.figure {
  --figure-h: 50px;
  position: fixed;
  left: 2rem;
  bottom: 1.4rem;
  z-index: 3;
  pointer-events: none;
}

.figure__svg {
  display: block;
  height: var(--figure-h);
  width: auto;
  overflow: visible;
  fill: var(--figure-fill);
  stroke: var(--figure-rim);
  stroke-width: 1;
  vector-effect: non-scaling-stroke;
  filter: drop-shadow(0 0 6px rgba(227, 169, 179, 0.25));
}

.figure__svg * { vector-effect: non-scaling-stroke; }

/* A faint strip of ground light under their feet. */
.figure__ground {
  position: absolute;
  left: 50%;
  bottom: -2px;
  width: calc(var(--figure-h) * 1.6 + 24px);
  height: 1px;
  transform: translateX(-50%);
  background: linear-gradient(90deg, transparent, rgba(236, 239, 247, 0.35), transparent);
}

/* ----- The opening line ----- */

.opening {
  position: fixed;
  inset: 0;
  z-index: 6;
  pointer-events: none;                 /* clicks and scrolls go straight through */
  display: grid;
  place-items: center;
  padding: 2rem;
  background: rgba(5, 8, 20, 0.86);
  opacity: 0;
  transition: opacity 0.9s ease;
}

.opening.is-shown { opacity: 1; }

.opening__inner { max-width: 34rem; }

/* The introduction, then the quote below it. */
.opening__intro {
  margin: 0 0 1.6rem;
  text-align: center;
  font-size: clamp(1rem, 1.6vw, 1.15rem);
  line-height: 1.55;
  color: var(--ink);
  text-shadow: var(--text-halo);
}

.opening__intro:empty { display: none; }

.opening__line {
  margin: 0;
  text-align: center;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(1.5rem, 3.2vw, 2.3rem);
  line-height: 1.3;
  text-shadow: var(--text-halo);
}

.noscript {
  position: fixed;
  inset: 0;
  display: grid;
  place-items: center;
  z-index: 4;
}

/* ----- Sub-zoom: an item's own sky (e.g. coursework) -----
   main.js scales and moves this layer out of the item's star. */

#world {
  position: absolute;
  inset: 0;
  transform-origin: 50% 50%;
}

.detail {
  position: fixed;
  inset: 0;
  z-index: 2;
  transform-origin: 50% 50%;
  border-radius: var(--era-radius);
  background: var(--detail-bg);
  box-shadow: inset 0 0 0 1px var(--era-edge);
  visibility: hidden;
  opacity: 0;
  /* Fade the scrolling list out before it reaches the header and timeline.
     (On the outer layer: a mask on the scroller would move with its content.) */
  -webkit-mask-image: linear-gradient(to bottom, transparent 0, transparent 6.5rem, #000 9.5rem, #000 calc(100% - 8.5rem), transparent calc(100% - 5rem));
  mask-image: linear-gradient(to bottom, transparent 0, transparent 6.5rem, #000 9.5rem, #000 calc(100% - 8.5rem), transparent calc(100% - 5rem));
}

/* The scrolling part. */
.detail__scroll {
  position: absolute;
  inset: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 9.5rem 1.5rem 8.5rem;
  scrollbar-width: thin;
  scrollbar-color: var(--line) transparent;
}

.detail__inner {
  max-width: 70rem;
  margin: 0 auto;
  text-align: center;
}

.detail__back { font-size: 0.85rem; margin-bottom: 1.25rem; }

.detail__title {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(2rem, 4.5vw, 3.2rem);
  line-height: 1.1;
  text-shadow: var(--text-halo);
}

.detail__title:focus { outline: none; }

.detail__subtitle {
  margin: 0.35rem 0 0;
  color: var(--ink-dim);
}

.detail__stats {
  list-style: none;
  margin: 1rem 0 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.4rem;
}

.detail__stats li {
  padding: 0.15rem 0.7rem;
  border: 1px solid var(--line);
  border-radius: 999px;
  font-size: 0.8rem;
  color: var(--ink);
  background: var(--panel);
}

.detail__groups {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(17rem, 1fr));
  gap: 2rem 2.75rem;
  margin-top: 2.5rem;
  text-align: left;
}

.cluster__label {
  margin: 0 0 0.6rem;
  font-size: 0.75rem;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--accent);
}

.cluster__list {
  position: relative;
  list-style: none;
  margin: 0;
  padding: 0 0 0 1.2rem;
}

.course {
  position: relative;
  padding: 0.4rem 0;
  text-shadow: var(--text-halo);
}

.course__star {
  position: absolute;
  left: -0.85rem;
  top: 0.85rem;
  width: 7px;
  height: 7px;
  margin: -3.5px 0 0 -3.5px;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 0 8px 2px var(--star-glow);
}

.course__top {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 0.75rem;
}

.course__name {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 1.1rem;
  line-height: 1.25;
}

.course__grade {
  flex: none;
  font-size: 0.85rem;
  font-weight: 500;
  color: var(--accent);
}

.course__meta {
  display: block;
  font-size: 0.78rem;
  color: var(--ink-dim);
}

body.is-fading .detail { opacity: 0 !important; transition: opacity 0.16s ease; }

/* Items that open a sub-zoom say so. */
.item--zoomable { cursor: zoom-in; }

.item--zoomable::after {
  content: "Zoom in";
  display: block;
  margin-top: 0.2rem;
  font-size: 0.66rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink-dim);
}

/* ----- Accessibility helpers ----- */

/* Visible to screen readers only. */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* Focus rings: one clear style everywhere, drawn outside the control. */
.item:focus-visible,
.era__portal:focus-visible,
.era-nav__btn:focus-visible,
.zoom-btn:focus-visible,
.btn:focus-visible,
.panel__close:focus-visible,
.resume-link:focus-visible,
.contact a:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}

.item:focus-visible .item__title { color: var(--accent); }
.era__portal:focus-visible { border-color: var(--accent); }

/* The map owns touch gestures (pinch and swipe move through time). */
#stage { touch-action: none; }
html, body { overscroll-behavior: none; }

/* ----- Reduced motion: fades instead of zooms ----- */

#stage { transition: opacity 0.16s ease; }

body.is-fading #stage { opacity: 0; }

@media (prefers-reduced-motion: reduce) {
  .panel { transform: none; }
}

/* ----- Short screens: drop item summaries so items don't collide ----- */

@media (max-height: 640px) {
  .item__summary { display: none; }
  .era__head { top: 11%; }
}

/* ----- Phones and narrow windows ----- */

@media (max-width: 700px) {
  :root { --nav-col: 5.2rem; }

  .site-header { top: 0.75rem; left: 1rem; max-width: 58vw; }
  .identity { font-size: 1.45rem; }
  .identity__tagline { font-size: 0.72rem; margin: 0.4rem 0 0.3rem; }
  .identity__seeking { font-size: 0.72rem; margin-top: -0.15rem; }
  .identity__availability { font-size: 0.7rem; }
  /* Below the name, the header can use the full width: the Resume button
     only shares the first line. */
  .site-header { max-width: calc(100vw - 2rem); }
  .identity { max-width: calc(100vw - 8rem); }
  /* In Now the header is taller, so the era title sits a little lower. */
  .era[data-era="now"] .era__head { top: 23.5%; }
  .identity__full { display: none; }   /* the name and tagline say enough on a phone */

  /* The timeline already shows where you are; keep the label for screen
     readers only, so the top of a small screen stays clear. */
  .position > [role="status"] {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
  }
  .identity__pronouns { font-size: 0.75rem; }
  .identity__full { font-size: 0.8rem; margin-bottom: 0.2rem; }
  .contact { font-size: 0.72rem; gap: 0 0.6rem; }

  .position { top: 0.75rem; right: 1rem; max-width: 38vw; font-size: 0.8rem; }
  .resume-link { top: 0.85rem; right: 1rem; padding: 0.35rem 0.8rem; font-size: 0.75rem; }
  .position__label { font-size: 0.65rem; }
  .position__era { font-size: 1rem; }

  .era__head { top: 17%; width: 70%; }
  .era__title { font-size: 1.9rem; }
  .era__subtitle { font-size: 0.9rem; }
  .era__back { font-size: 0.78rem; padding: 0.4rem 0.8rem; }

  .item { width: 31vw; padding: 0.4rem 0.45rem; }
  .item__title { font-size: 0.98rem; }
  .item__summary { display: none; }
  .item__parent { font-size: 0.66rem; }

  .zoom-bubble { white-space: normal; max-width: min(13rem, 58vw); font-size: 0.74rem; padding: 0.3rem 0.6rem; }

  .era-nav { bottom: 0.6rem; }
  .era-nav__btn { font-size: 0.72rem; line-height: 1.2; }

  .zoom-controls { right: 1rem; bottom: 4.4rem; }
  .zoom-btn { width: 2.25rem; height: 2.25rem; font-size: 1.1rem; }

  .figure { left: 1.1rem; bottom: 4.6rem; }

  /* In a sub-zoom the list needs the width; its back button and the
     timeline are the way out. */
  body.in-detail .zoom-controls,
  body.in-detail .figure { visibility: hidden; }
  .detail__scroll { padding: 8.5rem 1rem 6rem; }
  .figure__svg { height: calc(var(--figure-h) * 0.7); }

  /* The panel becomes a sheet along the bottom. */
  .panel,
  .panel.panel--left {
    top: auto;
    left: 0.5rem;
    right: 0.5rem;
    bottom: 0.5rem;
    width: auto;
    max-height: 72vh;
    padding: 1.25rem 1.25rem 1.5rem;
    transform: translateY(1rem);
  }
  .panel.is-open { transform: none; }
}

/* ----- Decluttering (owner, 2026-09-30) ----- */

/* Titles only on the map; the summary is in the item's panel (and still
   read to screen readers as the item's description). */
.item__summary { display: none !important; }

/* The "You are in" box repeated the big era title and the timeline. It stays
   for screen readers only. */
.position {
  position: absolute !important;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

/* A slimmer header: name and pronouns everywhere. The tagline and contact
   links belong to Now, the present-day self, and fade out elsewhere. */
.identity__full { display: none; }

.identity__tagline,
.identity__seeking,
.identity__availability,
.contact { transition: opacity 0.35s ease, visibility 0.35s; }

body:not([data-era="now"]) .identity__tagline,
body:not([data-era="now"]) .identity__seeking,
body:not([data-era="now"]) .identity__availability,
body:not([data-era="now"]) .contact {
  opacity: 0;
  visibility: hidden;
}

/* Short phones: in Now, the header (name, tagline, availability) fills the
   top, so the era title gives way; the timeline still marks Now. */
@media (max-width: 700px) and (max-height: 700px) {
  .era[data-era="now"] .era__head { display: none; }
  /* No room for the zoom bubbles; the buttons remain. */
  .zoom-bubble { display: none; }
}

/* Short windows of any width: the bubbles would sit on the items. */
@media (max-height: 650px) {
  .zoom-bubble { display: none; }
}

/* The first-visit hint needs the room of a wide screen; elsewhere it would
   sit on the cards, and the zoom bubbles already say what + and - do. */
@media (max-width: 1200px) {
  .zoom-hint { display: none; }
}
