/* ================================================================
   Family Research Archive. Shared Stylesheet
   Apollo. Shuttle. Station.
   All 8 family pages share this file.
   Page-specific CSS stays in each page's own <style> block.
================================================================ */

/* ── Design tokens ─────────────────────────────────────────── */
:root {
  --navy:       #060d1f;
  --navy2:      #0b1530;
  --gold:       #c8a96e;
  --gold2:      #e8c98e;
  --blue:       #7eb8d4;
  --rose:       #d4827e;
  --white:      #f0ead8;
  --dim:        #8899aa;
  --text:       #dce6f0;
  --text-muted: #8ba3b8;
  --border:     rgba(126, 184, 212, 0.15);
  --font-serif: 'EB Garamond', Georgia, serif;
  --font-sans:  'Inter', system-ui, sans-serif;

  /* Aliases kept for backward compat, point at canonical tokens */
  --navy-mid:   #0b1530;
  --accent:     #7eb8d4;
  --accent-dim: #4a7fa0;
  --serif:      'EB Garamond', Georgia, serif;
  --sans:       'Inter', system-ui, sans-serif;
}

/* ── Reset ─────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

/* ── Responsive image safeguard ────────────────────────────────
   Base rule so NO image can ever render wider than its container and
   spill off the right edge of a phone screen. Image height stays at the
   default (auto) here, so aspect ratio is preserved; the few elements
   that crop to a fixed height (.person-card img, .title-portrait img)
   use higher-specificity selectors and are unaffected. Mirrors the
   existing @media print rule. Without this, any inline figure or bare
   <img> not wrapped in a .photo-card / .key-photo / grid was free to
   overflow on mobile. */
img { max-width: 100%; }

/* ── Base ──────────────────────────────────────────────────── */
body {
  background: var(--navy);
  color: var(--text);
  font-family: var(--font-sans);
  font-size: 16px;
  line-height: 1.7;
  min-height: 100vh;
}

/* ── Fixed nav ─────────────────────────────────────────────── */
nav {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 100;
  height: 52px;
  display: flex;
  align-items: center;
  padding: 0 1.5rem;
  background: rgba(6,13,31,0.85);
  backdrop-filter: blur(16px);
  border-bottom: 1px solid rgba(200,169,110,0.15);
  gap: 0.25rem;
}
nav .site-title {
  font-family: var(--font-serif);
  font-size: 1.1rem;
  color: var(--gold);
  white-space: nowrap;
  margin-right: 1.5rem;
  letter-spacing: 0.02em;
}
nav a {
  color: var(--dim);
  text-decoration: none;
  font-size: 0.78rem;
  font-weight: 500;
  padding: 0.35rem 0.75rem;
  border-radius: 4px;
  transition: color 0.2s, background 0.2s;
  letter-spacing: 0.03em;
  text-transform: uppercase;
}
nav a:hover { color: var(--gold); background: rgba(200,169,110,0.08); }
nav a.active { color: var(--gold); }

/* ── Starfield ─────────────────────────────────────────────── */
.starfield {
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  overflow: hidden;
}
.star {
  position: absolute;
  background: white;
  border-radius: 50%;
  opacity: 0;
}
@media (prefers-reduced-motion: no-preference) {
  .star { animation: twinkle var(--duration) ease-in-out infinite alternate; }
}
@keyframes twinkle {
  0%   { opacity: 0.1; transform: scale(0.8); }
  100% { opacity: var(--max-opacity); transform: scale(1.2); }
}

/* ── Shooting star ─────────────────────────────────────────── */
.shooting-star {
  position: fixed;
  width: 3px;
  height: 3px;
  background: white;
  border-radius: 50%;
  pointer-events: none;
  z-index: 1;
  opacity: 0;
  box-shadow: 0 0 6px 2px rgba(255,255,255,0.8);
}
.shooting-star::after {
  content: '';
  position: absolute;
  width: 80px;
  height: 2px;
  top: 50%;
  left: 50%;
  background: linear-gradient(to right, transparent, rgba(255,255,255,0.7));
  transform: translate(-100%, -50%) rotate(24deg);
  transform-origin: right center;
}
@media (prefers-reduced-motion: no-preference) {
  @keyframes shoot {
    0%   { opacity: 0; transform: translate(0, 0); }
    3%   { opacity: 1; }
    60%  { opacity: 0.8; }
    100% { opacity: 0; transform: translate(400px, 180px); }
  }
}

/* ── Main content wrapper ──────────────────────────────────── */
#content {
  max-width: 900px;
  margin: 0 auto;
  padding: 72px 2rem 3rem;
  position: relative;
  z-index: 1;
}

/* ── Typography ────────────────────────────────────────────── */
h1 {
  font-family: var(--font-serif);
  font-size: 2.2rem;
  color: #fff;
  margin-bottom: 0.25rem;
}
.tagline {
  font-family: var(--font-serif);
  font-size: 1.1rem;
  color: var(--gold);
  margin-bottom: 0.5rem;
}
.subtitle {
  color: var(--text-muted);
  font-size: 0.9rem;
  margin-bottom: 3rem;
}
.back {
  font-size: 0.85rem;
  color: var(--accent-dim);
  text-decoration: none;
  display: inline-block;
  margin-bottom: 2rem;
}
.back:hover { color: var(--accent); }

blockquote {
  border-left: 3px solid var(--gold);
  padding-left: 1rem;
  margin: 1rem 0;
  font-style: italic;
  color: var(--text-muted);
}

/* ── Sections ──────────────────────────────────────────────── */
.section { margin-bottom: 3rem; }
.section h2 {
  font-family: var(--font-serif);
  font-size: 1.4rem;
  color: var(--gold);
  margin-bottom: 1rem;
  padding-bottom: 0.5rem;
  border-bottom: 1px solid var(--border);
}
.section h3 {
  font-family: var(--font-serif);
  font-size: 1.1rem;
  color: #fff;
  margin: 1.5rem 0 0.75rem;
}
.section p {
  margin-bottom: 0.75rem;
  font-size: 0.95rem;
}

/* ── Timeline ──────────────────────────────────────────────── */
.timeline { margin-bottom: 3rem; }
.timeline h2 {
  font-family: var(--font-serif);
  font-size: 1.4rem;
  color: var(--gold);
  margin-bottom: 1.5rem;
  padding-bottom: 0.5rem;
  border-bottom: 1px solid var(--border);
}
.timeline-item {
  display: flex;
  gap: 1.5rem;
  margin-bottom: 1.5rem;
  padding-bottom: 1.5rem;
  border-bottom: 1px solid rgba(126,184,212,0.06);
}
.timeline-item:last-child { border-bottom: none; }
.timeline-year {
  font-family: var(--font-sans);
  font-size: 0.8rem;
  font-weight: 500;
  color: var(--accent);
  min-width: 90px;
  padding-top: 0.15rem;
  flex-shrink: 0;
}
.timeline-desc {
  font-size: 0.92rem;
  line-height: 1.65;
}
.timeline-detail {
  font-size: 0.82rem;
  color: var(--text-muted);
  margin-top: 0.35rem;
  line-height: 1.55;
}
.timeline-source {
  font-size: 0.72rem;
  color: var(--text-muted);
  margin-top: 0.35rem;
  font-style: italic;
}

/* ── Highlight box ─────────────────────────────────────────── */
.highlight {
  background: rgba(200, 169, 110, 0.08);
  border: 1px solid rgba(200, 169, 110, 0.2);
  border-radius: 6px;
  padding: 1.25rem;
  margin: 1rem 0;
}
.highlight strong { color: var(--gold); }

/* ── Gap block (profile page variant) ──────────────────────── */
.gap-block {
  background: rgba(126, 184, 212, 0.06);
  border: 1px dashed var(--accent-dim);
  border-radius: 6px;
  padding: 1.25rem;
  margin: 1.5rem 0;
}
.gap-block strong { color: var(--accent); }

/* Timeline gap marker (promoted, first-class): a dashed accent row that sits
   inline in a .timeline in its correct chronological position, flagging a
   documented jump in the record. Pairs a year column (aligned with
   .timeline-year) with a plain-language "what we have / what we are missing /
   best channel" body. Added 2026-06-27 (review-features phase 2B). */
.gap-block.timeline-gap {
  display: flex;
  gap: 1.5rem;
}
.gap-block-year {
  font-family: var(--font-sans);
  font-size: 0.8rem;
  font-weight: 500;
  color: var(--accent);
  min-width: 90px;
  flex-shrink: 0;
  padding-top: 0.15rem;
}
.gap-block-body { flex: 1; min-width: 0; }
.gap-block-label {
  display: inline-block;
  font-family: var(--font-sans);
  font-size: 0.62rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--accent);
  border: 1px solid var(--accent-dim);
  border-radius: 3px;
  padding: 0.1rem 0.5rem;
  margin-bottom: 0.7rem;
}
.gap-block-line {
  font-size: 0.85rem;
  line-height: 1.6;
  margin: 0.35rem 0;
  color: var(--text);
}
.gap-block-key { color: var(--accent); font-weight: 600; }
@media (max-width: 600px) {
  .gap-block.timeline-gap { flex-direction: column; gap: 0.4rem; }
}

/* "Still seeking" open-question helpers: standardize the per-person
   "What We're Still Looking For" lists and the research-page master roll-up.
   Each open question (a .highlight box) is paired with the channel most likely
   to answer it, plus one help cue that routes family feedback to the existing
   corrections email. Added 2026-06-27 (review-features phase 2B). */
.seek-channel {
  display: block;
  font-size: 0.82rem;
  color: var(--text-muted);
  margin-top: 0.5rem;
}
.seek-channel-key { color: var(--accent); font-weight: 600; }
.seek-help {
  margin-top: 1.25rem;
  font-size: 0.85rem;
  color: var(--text-muted);
}
.seek-help a { color: var(--accent); text-decoration: none; }
.seek-help a:hover { text-decoration: underline; }

/* ── Title block with portrait ─────────────────────────────── */
.title-block {
  display: flex;
  gap: 2rem;
  align-items: flex-start;
  flex-wrap: nowrap;
  margin-bottom: 1rem;
}
@media (max-width: 500px) {
  .title-block { flex-wrap: wrap; }
}
.title-portrait { flex: 0 0 auto; }
.title-portrait img {
  width: 180px;
  max-height: 200px;
  object-fit: cover;
  object-position: top;
  border-radius: 6px;
  border: 1px solid var(--border);
}
.title-portrait-caption {
  font-size: 0.72rem;
  color: var(--text-muted);
  margin-top: 0.4rem;
  text-align: center;
}

/* ── Photo grid ────────────────────────────────────────────── */
.photo-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 1.5rem;
  margin-bottom: 2rem;
}
.photo-card {
  background: var(--navy2);
  border: 1px solid var(--border);
  border-radius: 6px;
  overflow: hidden;
}
.photo-card img {
  width: 100%;
  height: auto;
  display: block;
  cursor: zoom-in;
}
.photo-card .caption {
  padding: 1rem;
  font-size: 0.85rem;
  color: var(--text-muted);
  line-height: 1.5;
}
.photo-card .caption strong { color: var(--text); }

/* ── Clipping grid ─────────────────────────────────────────── */
.clipping-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1rem;
  margin-bottom: 2rem;
}
.clipping-card {
  background: var(--navy2);
  border: 1px solid var(--border);
  border-radius: 6px;
  overflow: hidden;
}
.clipping-card img { width: 100%; display: block; }
.clipping-caption {
  padding: 0.6rem;
  font-size: 0.75rem;
  color: var(--text-muted);
  line-height: 1.4;
}
.clipping-caption strong { color: var(--text); font-size: 0.8rem; }
.clipping-date { color: var(--accent); font-size: 0.7rem; }

/* ── Artifact card ─────────────────────────────────────────── */
.artifact-card {
  background: var(--navy2);
  border: 1px solid var(--border);
  border-radius: 6px;
  overflow: hidden;
  margin-bottom: 2rem;
}
.artifact-card img {
  width: 100%;
  height: auto;
  display: block;
  cursor: zoom-in;
}
.artifact-card .artifact-body { padding: 1.5rem; }
.artifact-card .artifact-body h3 {
  font-family: var(--font-serif);
  font-size: 1.1rem;
  color: #fff;
  margin-bottom: 0.75rem;
}
.artifact-card .artifact-body p {
  font-size: 0.92rem;
  margin-bottom: 0.75rem;
}
.artifact-card .artifact-meta {
  font-size: 0.8rem;
  color: var(--text-muted);
  margin-top: 1rem;
  padding-top: 0.75rem;
  border-top: 1px solid var(--border);
}
.artifact-card .artifact-meta a { color: var(--accent-dim); text-decoration: none; }
.artifact-card .artifact-meta a:hover { color: var(--accent); }

/* ── Key photo (full-width featured) ───────────────────────── */
.key-photo { margin-bottom: 2rem; }
.key-photo img {
  width: 100%;
  height: auto;
  display: block;
  border-radius: 6px;
  border: 1px solid var(--border);
}
.key-photo-caption {
  padding: 0.75rem 0 0;
  font-size: 0.85rem;
  color: var(--text-muted);
  line-height: 1.5;
}
/* Portrait variant: caps a tall portrait so it does not render full-bleed,
   matching the scale of the page's photo-card portraits. Centered block. */
.key-photo.portrait {
  max-width: 360px;
  margin-left: auto;
  margin-right: auto;
}
.key-photo.portrait .key-photo-caption { text-align: center; }
/* Document variant: caps a tall record scan (e.g. a border manifest) so it
   reads as a document on the page, not a full-bleed hero. Click-to-expand
   via the lightbox still serves the full-resolution scan. Centered block. */
.key-photo.document {
  max-width: 420px;
  margin-left: auto;
  margin-right: auto;
}
.key-photo.document img {
  width: auto;
  max-width: 100%;
  max-height: 460px;
  margin: 0 auto;
  cursor: zoom-in;
}
.key-photo.document .key-photo-caption { text-align: center; }

/* ── Footer ────────────────────────────────────────────────── */
footer {
  text-align: center;
  padding: 3rem 2rem;
  color: var(--text-muted);
  font-size: 0.8rem;
  font-style: italic;
  border-top: 1px solid var(--border);
}

/* ── Auth gate ─────────────────────────────────────────────── */
#gate {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
  position: relative;
  z-index: 1;
}
#gate-box {
  text-align: center;
  max-width: 400px;
  padding: 2rem;
}
#gate-box h1 {
  font-family: var(--font-serif);
  font-size: 1.5rem;
  color: #fff;
  margin-bottom: 0.5rem;
}
#gate-box p { color: var(--text-muted); font-size: 0.9rem; margin-bottom: 1.5rem; }
#gate-box input {
  width: 100%;
  padding: 0.75rem 1rem;
  background: var(--navy2);
  border: 1px solid var(--border);
  border-radius: 6px;
  color: var(--text);
  font-family: var(--font-sans);
  font-size: 0.95rem;
  text-align: center;
  margin-bottom: 0.75rem;
}
#gate-box input:focus { outline: none; border-color: var(--accent-dim); }
#gate-box button {
  padding: 0.75rem 2rem;
  background: var(--accent-dim);
  color: #fff;
  border: none;
  border-radius: 6px;
  font-family: var(--font-sans);
  cursor: pointer;
}
#gate-box button:hover { background: var(--accent); }
#gate-error { color: #e57373; font-size: 0.85rem; margin-top: 0.5rem; display: none; }

/* ── Overlay gate (timeline/network style) ─────────────────── */
#gate.overlay-gate {
  position: fixed;
  inset: 0;
  height: auto;
  z-index: 1000;
  background: rgba(6,13,31,0.97);
  backdrop-filter: blur(12px);
  justify-content: center;
  align-items: center;
}
#gate-box.overlay-box {
  padding: 3rem 2.5rem;
  border: 1px solid rgba(200,169,110,0.25);
  border-radius: 12px;
  background: rgba(11,21,48,0.8);
  max-width: 400px;
  width: 90%;
}
#gate-box.overlay-box h2 {
  font-family: var(--font-serif);
  font-size: 1.6rem;
  color: var(--gold);
  margin-bottom: 0.5rem;
}
#gate-input {
  width: 100%;
  padding: 0.75rem 1rem;
  border: 1px solid rgba(200,169,110,0.3);
  border-radius: 6px;
  background: rgba(6,13,31,0.8);
  color: var(--white);
  font-size: 1rem;
  font-family: var(--font-sans);
  outline: none;
  margin-bottom: 1rem;
  text-align: center;
  letter-spacing: 0.15em;
}
#gate-input:focus { border-color: var(--gold); }
#gate-btn {
  width: 100%;
  padding: 0.75rem;
  background: var(--gold);
  color: var(--navy);
  border: none;
  border-radius: 6px;
  font-size: 1rem;
  font-weight: 600;
  font-family: var(--font-sans);
  cursor: pointer;
  transition: background 0.2s;
}
#gate-btn:hover { background: var(--gold2); }
#gate-err {
  margin-top: 0.75rem;
  font-size: 0.82rem;
  color: var(--rose);
  min-height: 1.2em;
}

/* ── Lightbox ──────────────────────────────────────────────── */
.lightbox-overlay {
  position: fixed;
  top: 0; left: 0;
  width: 100vw;
  height: 100vh;
  background: rgba(0,0,0,0.92);
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  z-index: 9999;
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.3s ease, visibility 0.3s ease;
  cursor: pointer;
}
.lightbox-overlay.active { opacity: 1; visibility: visible; }
.lightbox-overlay img {
  max-width: 90vw;
  max-height: 85vh;
  object-fit: contain;
  border-radius: 4px;
  cursor: default;
}
.lightbox-caption {
  max-width: 90vw;
  padding: 1rem 0 0;
  font-size: 0.85rem;
  color: var(--text-muted);
  line-height: 1.5;
  text-align: center;
  cursor: default;
}
.lightbox-caption strong { color: var(--text); }
.lightbox-close {
  position: absolute;
  top: 1.5rem;
  right: 2rem;
  color: #fff;
  font-size: 2rem;
  cursor: pointer;
  opacity: 0.7;
  transition: opacity 0.2s;
  background: none;
  border: none;
  font-family: var(--font-sans);
}
.lightbox-close:hover { opacity: 1; }
#content img[src*="/photos/"] { cursor: zoom-in; }

/* ── Fade-in animation ─────────────────────────────────────── */
.fade-in {
  opacity: 1;
  transform: none;
  transition: opacity 0.6s ease, transform 0.6s ease;
}
.fade-in.hidden {
  opacity: 0;
  transform: translateY(20px);
}
.fade-in.visible {
  opacity: 1;
  transform: translateY(0);
}
@media (prefers-reduced-motion: reduce) {
  .fade-in { opacity: 1; transform: none; transition: none; }
  .fade-in.hidden { opacity: 1; transform: none; }
}

/* ── Page TOC (horizontal sticky bar) ─────────────────────── */
.page-toc {
  position: sticky;
  top: 52px;
  z-index: 90;
  background: rgba(6,13,31,0.92);
  backdrop-filter: blur(12px);
  border-bottom: 1px solid rgba(200,169,110,0.12);
  padding: 0.5rem 0;
  margin: 0 -2rem 2rem;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: thin;
  scrollbar-color: var(--accent-dim) transparent;
}
.page-toc::-webkit-scrollbar { height: 3px; }
.page-toc::-webkit-scrollbar-thumb { background: var(--accent-dim); border-radius: 3px; }
.page-toc::-webkit-scrollbar-track { background: transparent; }
.page-toc-inner {
  display: flex;
  gap: 0.15rem;
  padding: 0 2rem;
  white-space: nowrap;
  min-width: min-content;
}
.page-toc a {
  color: var(--dim);
  text-decoration: none;
  font-family: var(--font-sans);
  font-size: 0.7rem;
  font-weight: 500;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  padding: 0.3rem 0.6rem;
  border-radius: 4px;
  transition: color 0.2s, background 0.2s;
  flex-shrink: 0;
}
.page-toc a:hover { color: var(--gold); background: rgba(200,169,110,0.08); }
.page-toc a.toc-sub {
  font-size: 0.65rem;
  color: var(--text-muted);
  opacity: 0.7;
  padding: 0.25rem 0.5rem;
}
.page-toc a.toc-sub:hover { opacity: 1; color: var(--gold); }
@media (max-width: 600px) {
  .page-toc { margin: 0 -1rem 1.5rem; }
  .page-toc-inner { padding: 0 1rem; }
}

/* ── Scroll offset for anchor links ───────────────────────── */
[id] { scroll-margin-top: 110px; }

/* ── Misc shared helpers ───────────────────────────────────── */
.updated { font-size: 0.75rem; color: var(--accent-dim); margin-top: 0.5rem; }
.doc-ref { font-size: 0.72rem; color: var(--accent-dim); margin-top: 0.2rem; font-family: monospace; }

/* ── Stats grid (shared across all pages) ─────────────────── */
.stats-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 1rem;
  margin: 2rem 0;
}
.stat-card {
  background: var(--navy2);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 1.25rem;
  text-align: center;
}
.stat-card .stat-num {
  font-family: var(--font-serif, 'EB Garamond', serif);
  font-size: 2rem;
  color: var(--gold);
}
.stat-card .stat-label {
  font-size: 0.78rem;
  color: var(--text-muted);
  margin-top: 0.25rem;
}

/* ── Public page: hero & sections ─────────────────────────── */
.page-wrap { position: relative; z-index: 1; max-width: 760px; margin: 0 auto; padding: 0 2rem; }
.site-header { padding: 5rem 0 4rem; text-align: center; border-bottom: 1px solid var(--border); }
.header-emblem { display: inline-block; width: 48px; height: 48px; margin-bottom: 1.75rem; opacity: 0.6; animation: spin-slow 60s linear infinite; }
@keyframes spin-slow { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }
.site-title-hero { font-family: var(--font-serif, var(--serif)); font-size: clamp(2rem, 5vw, 3rem); font-weight: 600; color: var(--gold); letter-spacing: 0.01em; line-height: 1.2; margin-bottom: 0.75rem; animation: title-glow 4s ease-in-out infinite alternate; }
@keyframes title-glow { 0% { text-shadow: 0 0 10px rgba(200,169,110,0.1); } 100% { text-shadow: 0 0 30px rgba(200,169,110,0.25); } }
.site-subtitle { font-family: var(--font-serif, var(--serif)); font-size: 1.15rem; font-weight: 400; font-style: italic; color: #fff; max-width: 520px; margin: 0 auto 0.5rem; line-height: 1.5; }
.site-subtitle-small { font-family: var(--font-sans, var(--sans)); font-size: 0.82rem; font-weight: 300; color: var(--text-muted); letter-spacing: 0.08em; text-transform: uppercase; max-width: 520px; margin: 0 auto; line-height: 1.6; }

.section { padding: 3.5rem 0; border-bottom: 1px solid var(--border); }
.section:last-of-type { border-bottom: none; }
.section-label { font-family: var(--font-sans, var(--sans)); font-size: 0.72rem; font-weight: 500; letter-spacing: 0.18em; text-transform: uppercase; color: var(--accent); margin-bottom: 1.25rem; }
.section-heading { font-family: var(--font-serif, var(--serif)); font-size: clamp(1.4rem, 3vw, 1.75rem); font-weight: 600; color: #fff; line-height: 1.3; margin-bottom: 1.25rem; }
.section p { font-size: 1rem; color: var(--text); line-height: 1.8; margin-bottom: 1rem; }
.section p:last-child { margin-bottom: 0; }

.researcher-card { background: var(--navy2, var(--navy-mid)); border: 1px solid var(--border); border-radius: 6px; padding: 2rem 2.25rem; margin-top: 1rem; transition: border-color 0.3s; }
.researcher-card:hover { border-color: rgba(126, 184, 212, 0.3); }

/* ── Fade-in on scroll ────────────────────────────────────── */
.reveal { opacity: 0; transform: translateY(30px); transition: opacity 0.8s ease, transform 0.8s ease; }
.reveal.visible { opacity: 1; transform: translateY(0); }

/* ── Document feature (inline document thumbnail + blurb) ───── */
/* A compact figure that pairs a document's first-page thumbnail with a
   short "what this is" blurb and a link to the source. Used to give a
   face to a document a section refers to, instead of a bare text link.
   The thumbnail links out to the authoritative source (e.g. the NTRS
   citation page); it is not wired to the photo lightbox. */
.doc-feature {
  display: flex;
  gap: 1.25rem;
  align-items: flex-start;
  background: var(--navy2);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 1rem;
  margin: 0 0 1.75rem;
}
.doc-feature .doc-feature-thumb { flex: 0 0 150px; display: block; }
.doc-feature .doc-feature-thumb img {
  width: 150px;
  height: auto;
  display: block;
  border: 1px solid var(--border);
  border-radius: 4px;
}
.doc-feature .doc-feature-body { font-size: 0.84rem; color: var(--text-muted); line-height: 1.55; }
.doc-feature .doc-feature-body strong { color: var(--text); }
.doc-feature .doc-feature-label {
  display: block;
  font-family: var(--font-sans);
  font-size: 0.65rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 0.4rem;
}
.doc-feature .doc-feature-src { margin-top: 0.5rem; font-size: 0.78rem; }
.doc-feature .doc-feature-src a { color: var(--accent); text-decoration: none; }
.doc-feature .doc-feature-src a:hover { text-decoration: underline; }

/* ── Documents archive gallery ─────────────────────────────────
   The centerpiece records gallery (background page "Documents and
   Records"). Larger than the clipping grid so a church act or a manifest
   is legible at a glance. Records are grouped under small eyebrow labels.
   Each thumbnail opens full size in the photo lightbox; a "View the
   original" link points to the authoritative archive copy. */
.archive-group-label {
  font-family: var(--font-sans);
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent);
  margin: 2rem 0 0.85rem;
  padding-bottom: 0.4rem;
  border-bottom: 1px solid var(--border);
}
.archive-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1.25rem;
  margin-bottom: 1.5rem;
}
.archive-card {
  background: var(--navy2);
  border: 1px solid var(--border);
  border-radius: 6px;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}
.archive-card img {
  width: 100%;
  height: 210px;
  object-fit: cover;
  object-position: top center;
  display: block;
  cursor: zoom-in;
  border-bottom: 1px solid var(--border);
}
.archive-caption {
  padding: 0.85rem 0.9rem 0.95rem;
  font-size: 0.8rem;
  color: var(--text-muted);
  line-height: 1.55;
  display: flex;
  flex-direction: column;
  gap: 0.55rem;
  flex: 1;
}
.archive-caption strong { color: var(--text); }
.archive-card .archive-src { margin-top: auto; font-size: 0.78rem; }
.archive-card .archive-src a { color: var(--accent); text-decoration: none; }
.archive-card .archive-src a:hover { text-decoration: underline; }

/* ── Responsive breakpoints ────────────────────────────────── */
@media (max-width: 600px) {
  .clipping-grid { grid-template-columns: repeat(2, 1fr) !important; }
  .archive-grid  { grid-template-columns: 1fr !important; }
  .photo-grid    { grid-template-columns: 1fr; }
  .stats-grid    { grid-template-columns: repeat(2, 1fr); }
  .doc-feature   { flex-direction: column; align-items: center; text-align: center; }
  .doc-feature .doc-feature-thumb { flex: none; }
}
@media (min-width: 601px) and (max-width: 820px) {
  .archive-grid  { grid-template-columns: repeat(2, 1fr); }
}

/* ── Nav tools: Print + Download-PDF icon controls (screen only) ──
   Two compact icon buttons pinned flush to the top-right of the fixed
   nav row via margin-left:auto, vertically centered by the nav's
   align-items:center. The SVG glyphs use currentColor so they match the
   nav palette. Hidden in print via the @media print block (and via the
   generic .no-print hook). */
.nav-tools {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 0.15rem;
  flex-shrink: 0;
}
.nav-icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  padding: 0;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 6px;
  color: var(--dim);
  cursor: pointer;
  transition: color 0.2s, border-color 0.2s, background 0.2s;
}
.nav-icon-btn svg {
  width: 17px;
  height: 17px;
  display: block;
  stroke: currentColor;
  fill: none;
}
.nav-icon-btn:hover { color: var(--gold); border-color: var(--border); background: rgba(200,169,110,0.08); }

/* ── Mobile nav: tap-to-open hamburger menu ─────────────────────
   Replaces the old `nav { overflow-x: auto }` approach, which turned the
   fixed bar into a non-obvious horizontal scroll and left the right-hand
   links plus BOTH the print and PDF icon controls off-screen and
   unreachable on a phone. The hamburger (injected by js/export.js, which
   adds the `.js-nav` class and the `.nav-toggle` button) opens a vertical
   panel that exposes EVERY link and both icon tools.

   Active at <= 960px so phones in either orientation and portrait tablets
   get the menu; desktop (> 960px) keeps the original single-row nav
   unchanged. If JavaScript does not run, the no-JS fallback simply lets
   the nav wrap to multiple rows so nothing is ever unreachable. */
.nav-toggle { display: none; }
.nav-toggle svg { width: 24px; height: 24px; display: block; stroke: currentColor; fill: none; }

@media (max-width: 960px) {
  /* No-JS fallback: wrap so every item stays reachable. */
  nav { flex-wrap: wrap; height: auto; min-height: 52px; row-gap: 0.1rem; align-content: center; }

  /* JS hamburger active: collapsed bar is a tidy 52px row. */
  nav.js-nav {
    flex-wrap: wrap;
    height: 52px;
    overflow: hidden;
    padding: 0 1rem;
    align-items: center;
  }
  nav.js-nav .site-title { margin-right: 0; }
  nav.js-nav .nav-toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    margin-left: auto;
    width: 40px;
    height: 40px;
    padding: 0;
    background: transparent;
    border: 1px solid transparent;
    border-radius: 6px;
    color: var(--dim);
    cursor: pointer;
    transition: color 0.2s, border-color 0.2s, background 0.2s;
  }
  nav.js-nav .nav-toggle:hover { color: var(--gold); border-color: var(--border); background: rgba(200,169,110,0.08); }

  /* Links + the icon-tools cluster collapse onto full-width rows,
     hidden until the menu is opened. */
  nav.js-nav > a,
  nav.js-nav .nav-tools {
    flex-basis: 100%;
    display: none;
  }

  /* Opened panel. */
  nav.js-nav.nav-open {
    height: auto;
    max-height: calc(100vh - 0px);
    overflow-y: auto;
    -webkit-overflow-scrolling: touch;
    padding-bottom: 0.6rem;
    background: rgba(6,13,31,0.98);
    border-bottom: 1px solid rgba(200,169,110,0.25);
  }
  nav.js-nav.nav-open .nav-toggle { color: var(--gold); }
  nav.js-nav.nav-open > a {
    display: block;
    width: 100%;
    padding: 0.7rem 0.5rem;
    font-size: 0.9rem;
    border-top: 1px solid rgba(126,184,212,0.08);
  }
  nav.js-nav.nav-open .nav-tools {
    display: flex;
    width: 100%;
    margin-left: 0;
    gap: 0.6rem;
    padding: 0.7rem 0.25rem 0.2rem;
    border-top: 1px solid rgba(126,184,212,0.08);
  }
  nav.js-nav.nav-open .nav-icon-btn {
    width: auto;
    height: auto;
    padding: 0.45rem 0.7rem;
    border: 1px solid var(--border);
  }
}

/* ── Footer legal notice ───────────────────────────────────────
   Three-line copyright / confidentiality notice carried in every
   family-page footer, with the Terms and Privacy link to legal.html. */
.footer-notice {
  max-width: 720px;
  margin: 0 auto 1rem;
  font-style: normal;
  font-size: 0.72rem;
  line-height: 1.6;
  color: var(--text-muted);
}
.footer-notice a { color: var(--accent); text-decoration: none; }
.footer-notice a:hover { text-decoration: underline; }
.footer-research a { color: var(--gold); text-decoration: none; }
footer a[href^="mailto:"] { color: var(--accent); text-decoration: none; }

/* Print-only running notice (used on the interactive timeline page) */
.print-only { display: none; }

/* Print-only full-caption span (injected by js/export.js on beforeprint for
   link-out items whose full text lives in a `title` attribute). Hidden on
   screen as a defensive measure in case afterprint never fires; shown only in
   the @media print block below. */
.print-fullcaption { display: none; }

/* ── Inline source-citation tags (added 2026-06-28) ──
   Bracketed source-id tokens such as [FAM-LUNCH-AUNTS-2026-06-28] are wrapped
   in <span class="src-cite">…</span> so they stay in the HTML source (the
   phantom-citation audit in scripts/audit-family-pages.py parses them, and
   they preserve provenance) while rendering INVISIBLE to readers on both the
   screen and the generated PDFs. Reinforced with !important in the @media
   print block below so the PDF export (which emulates print media) hides them
   too. Do NOT remove the tokens from the HTML. they are load-bearing for the
   audit and the record. */
.src-cite { display: none; }

/* ── Person gallery (added 2026-06-27, gallery-expansion) ──
   Reusable gallery used on the person pages. A "featured" grid
   (photo-grid for photographs, clipping-grid for document thumbnails)
   is followed by the rest of the set rendered inline in the same grid.
   Galleries are ALWAYS fully expanded. the earlier show-more/<details>
   collapse pattern was removed 2026-06-27 so every item is visible. The
   lightbox binds to every /photos/ image at load, and document
   thumbnails wrap in an <a> to their source (NTRS/NARA/govinfo URL or a
   hosted copy). */
.gallery-intro {
  font-size: 0.9rem;
  color: var(--text-muted);
  line-height: 1.6;
  margin-bottom: 1.25rem;
  max-width: 62ch;
}

/* ── Print / PDF view (newspaper-style) ────────────────────────
   Strips interactive chrome, hides pointer-stub (.see-elsewhere)
   sections and landing site-map tiles, promotes the H1 to a clean
   document title, enforces tidy page breaks, and keeps the legal
   footer notice on the printout. */
@media print {
  /* Hide navigation, controls, gates, lightbox, and all buttons */
  nav, .page-toc, .print-btn, .nav-tools, .no-print,
  #gate, #gate-box, #lightbox, .lightbox-overlay,
  .shooting-star, #shootingStar,
  .skip-link, .minimap, #minimap, #controls, .timeline-controls,
  #lane-labels, #zoom-controls, #hover-tooltip, button { display: none !important; }

  /* Pointer-stub sections whose only purpose is to refer elsewhere */
  .see-elsewhere { display: none !important; }

  /* Inline source-citation tags stay hidden in the PDF export */
  .src-cite { display: none !important; }

  /* Landing site-map tiles are navigation only */
  .docs-list { display: none !important; }

  /* Show the print-only running notice */
  .print-only { display: block !important; }

  html, body { background: #fff !important; color: #000 !important; }
  .starfield, .star { display: none !important; }

  #content {
    max-width: 100% !important;
    padding: 0 !important;
    margin: 0 !important;
    color: #000 !important;
  }

  h1, h2, h3, h4, strong { color: #000 !important; }
  a { color: #000 !important; text-decoration: none !important; }

  /* H1 reads as the document title at the top of the printed page */
  #content h1 { font-size: 22pt; margin: 0 0 0.5rem; }
  .tagline, .subtitle { color: #333 !important; }

  /* Clean page breaks: never split these blocks across pages */
  .timeline-item, .photo-card, .doc-feature, figure, .key-photo,
  .highlight, .clipping-card, .archive-card, blockquote, .gap-block {
    break-inside: avoid;
    page-break-inside: avoid;
  }
  /* Archive grid prints two-up so each record scan stays legible. */
  .archive-grid { grid-template-columns: repeat(2, 1fr) !important; }
  .archive-card img { height: auto !important; max-height: 3in; object-fit: contain !important; }
  h2, h3 { break-after: avoid; page-break-after: avoid; }

  /* Images print at a reasonable size */
  img { max-width: 100% !important; height: auto !important; }
  .key-photo img, .clipping-card img, .photo-card img,
  .title-portrait img, .doc-feature-thumb img { max-height: 3.5in; width: auto; }

  /* Captions print in FULL. js/export.js swaps the short on-screen caption for
     the full text on beforeprint (and restores it on afterprint). These rules
     make sure nothing truncates, clamps, or dims the full caption on paper:
     force legible dark text (the on-screen captions use a muted gray that is
     near-invisible on white), remove any height/line clamp, and reveal the
     injected print-only span carrying the link-out full text. */
  .photo-card .caption, .photo-card .caption *,
  .key-photo-caption, .key-photo-caption *,
  .clipping-caption, .clipping-caption *,
  .archive-caption, .archive-caption *,
  .clipping-date,
  .doc-feature-body, .doc-feature-body *,
  .origins-map-caption,
  .print-fullcaption, .print-fullcaption * {
    color: #000 !important;
    overflow: visible !important;
    max-height: none !important;
    -webkit-line-clamp: none !important;
  }
  .print-fullcaption {
    display: block !important;
    margin-top: 0.35rem;
  }
  /* Cards must not vertically clip a now-taller full caption. */
  .photo-card, .clipping-card, .key-photo, .archive-card { overflow: visible !important; }

  /* Keep the legal footer notice on every printout */
  footer {
    display: block !important;
    border-top: 1px solid #999 !important;
    color: #000 !important;
    padding: 1rem 0 !important;
    text-align: center;
  }
  .footer-notice { color: #000 !important; font-size: 8pt; max-width: 100%; }
  .footer-notice a { color: #000 !important; }
  .footer-research { display: none !important; }
  footer a { color: #000 !important; }

  @page { margin: 0.6in; }
  /* Interactive map embeds don't print (would render blank). */
  .map-embed { display: none !important; }
}

/* Responsive map embed (Google Maps iframe). Design-system compliant: no inline
   iframe sizing, scales to the container width on phones via an aspect box. */
.map-embed {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 10;
  margin: 1.25rem 0 0.5rem;
  border-radius: 6px;
  overflow: hidden;
  border: 1px solid var(--border);
}
.map-embed iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
}
.map-embed-caption {
  font-family: var(--sans);
  font-size: 0.82rem;
  color: var(--text-muted);
  margin: 0.5rem 0 1rem;
}

/* Stylized antique-atlas origins map. Pure inline SVG built by
   scripts/generate-origins-map.py (no iframe / JS / external call), so unlike the
   old Google-Maps .map-embed it scales to the column, prints in the family PDF,
   and matches the heirloom parchment/sepia/gold palette. */
.origins-map {
  margin: 1.5rem 0 0.75rem;
}
.origins-map svg {
  display: block;
  width: 100%;
  height: auto;
  border-radius: 8px;
}
.origins-map-caption {
  font-family: var(--sans);
  font-size: 0.82rem;
  color: var(--text-muted);
  margin: 0.5rem 0 1rem;
  line-height: 1.5;
}

/* ── Family Tree (generate-pedigree-svg.py, v2 heirloom redesign) ──────
   The tree is deterministic inline SVG: parchment "clipping" cards pinned to
   the dark board, joined by warm sepia/gold marriage bars and drop lines.
   Dark ink on light cards reads cleanly on screen AND in the landscape PDF.
   Ink/sepia/parchment palette is local to the tree (the rest of the archive
   stays on the blue-on-navy system). */
/* DECEASED (baseline, most cards): aged-parchment "old document" card. */
/* DECEASED (baseline, the majority): aged-parchment CREAM card. */
.pedigree-svg .ped-card {
  fill: #f3e9d2;                 /* aged parchment cream */
  stroke: #8a7350;               /* sepia/ink border */
  stroke-width: 1.5;
}
/* LIVING: a soft SAGE-GREEN fill with a forest-green border. The green fill is
   the at-a-glance "alive" signal (green = living); the card body also carries a
   green small-caps "Living" label. No dot. Death years are never shown. */
.pedigree-svg .ped-card.ped-living {
  fill: #d9e4cf;                 /* soft sage green */
  stroke: #5f7345;               /* forest-green border */
  stroke-width: 2;
}
.pedigree-svg .ped-name {
  font-family: var(--serif);
  font-size: 14.5px;
  font-weight: 600;
  fill: #2b2118;                 /* deep ink (AA on cream/sage/slate/tan) */
}
.pedigree-svg .ped-meta {
  font-family: var(--serif);
  font-style: italic;
  font-size: 11px;
  fill: #6b5a44;                 /* sepia */
}
.pedigree-svg .ped-meta-living {
  fill: #3f5230;                 /* deep forest green on the sage card */
  font-style: normal;
  font-weight: 600;
  font-variant: small-caps;
  letter-spacing: 0.08em;
}
.pedigree-svg .ped-place {
  font-family: var(--serif);
  font-style: italic;
  font-size: 10.5px;
  fill: #7a6850;                 /* sepia, slightly lighter than the date line */
}
.pedigree-svg .ped-note {
  font-family: var(--serif);
  font-style: italic;
  font-size: 9.5px;
  fill: #8a7355;
}
/* COUNT CHIP: a warm TAN/GOLD pill for collapsed sibling sets. A genuinely
   different colour from the cream/sage/slate cards so it never reads as a
   person. */
.pedigree-svg .ped-chip {
  fill: #e8d3a8;                 /* warm tan/gold */
  stroke: #c8a96e;               /* gold border */
  stroke-width: 1.4;
}
.pedigree-svg .ped-chip-text {
  font-family: var(--serif);
  font-style: italic;
  font-size: 11px;
  fill: #5d4d39;                 /* deep sepia (AA on tan) */
}
.pedigree-svg .ped-link {
  fill: none;
  stroke: #a98c5f;               /* warm sepia/gold, readable on dark */
  stroke-width: 1.6;
  opacity: 0.9;
}
.pedigree-svg .ped-marriage {
  stroke: #c8a96e;               /* gold marriage bar */
  stroke-width: 2.2;
  opacity: 0.95;
}
/* UNDOCUMENTED LINE-END: a muted SLATE-GREY card standing in for unknown
   parents above a line-end. Slate fill + dashed grey border read as "we don't
   know who came before" and stay clearly distinct from the cream/sage/tan
   cards. Lightly faded, but kept legible. */
.pedigree-svg .ped-ghost { opacity: 0.78; }
.pedigree-svg .ped-ghost-card {
  fill: #d8dce0;                 /* muted slate grey */
  stroke: #9aa3ab;               /* dashed grey border */
  stroke-width: 1.3;
  stroke-dasharray: 5 3;
}
.pedigree-svg .ped-ghost-label {
  font-family: var(--serif);
  font-style: italic;
  font-size: 9.5px;
  fill: #3f464d;                 /* slate ink (AA on the slate-grey card) */
  letter-spacing: 0.03em;
}
/* MEXICO -> UNITED STATES border crossing: an engraved threshold line on the
   drop-line: a slim solid-gold horizontal rule broken at its midpoint by a gold
   diamond, with a parchment label badge below. Stays in the gold/sepia family
   palette (no blue-gray "water" connotation). */
.pedigree-svg .ped-cross-rule {
  stroke: #c8a96e;               /* solid gold threshold rule */
  stroke-width: 1.5;
  stroke-linecap: round;
  opacity: 0.95;
}
.pedigree-svg .ped-cross-diamond {
  fill: #c8a96e;                 /* gold diamond threshold marker */
  stroke: #8c6f3f;
  stroke-width: 0.6;
}
.pedigree-svg .ped-cross-badge {
  fill: #f4ecd8;
  stroke: #c8a96e;
  stroke-width: 1.4;
  filter: url(#ped-shadow);
}
.pedigree-svg .ped-cross-label {
  font-family: var(--serif);
  font-size: 11px;
  font-weight: 600;
  fill: #4a3a26;                 /* sepia ink, high contrast on parchment */
}
.pedigree-svg .ped-cross-sub {
  font-family: var(--serif);
  font-style: italic;
  font-size: 10px;
  fill: #6b5a44;
}
.pedigree-svg .ped-genlabel {
  font-family: var(--sans);
  font-size: 12px;
  font-weight: 600;
  fill: #b79a6a;                 /* readable sepia-gold on the dark field */
  letter-spacing: 0.10em;
}
.pedigree-svg .ped-genrule {
  stroke: #6b5a44;
  stroke-width: 1;
  stroke-dasharray: 2 6;
  opacity: 0.35;
}
.pedigree-svg .ped-cluster-title {
  font-family: var(--sans);
  font-size: 11px;
  font-weight: 600;
  fill: #b79a6a;
  letter-spacing: 0.08em;
}
/* Legend now renders real card/line samples (see build_legend); each entry uses
   the SAME class as the thing it represents, so only the text needs styling. */
.pedigree-svg .ped-leg-text {
  font-family: var(--sans);
  font-size: 11px;
  fill: #cbd6e2;
}
