/* Mapa de autores — Constelación nocturna del tango.
   Editorial atmosphere: 1940s Buenos Aires archive, brass on aged-paper black.
   Performance-conscious: minimal backdrop-filters, no mix-blend, no infinite loops. */

:root {
  /* Period palette — tonal sepia, slightly warmer */
  --p-origen:        #3e2218;
  --p-guardia-nueva: #6a4030;
  --p-edad-de-oro:   #b58862;
  --p-tardio:        #c69771;
  --p-vanguardia:    #8d3d2c;
  --p-contemporaneo: #8a7d74;
  /* Neutral "no data" swatch — desaturated, reads as unknown vs the gold edad-de-oro */
  --p-desconocido:   #5a5048;

  /* Role palette */
  --r-compositor:     #c69771;
  --r-letrista:       #e7dfd5;
  --r-cantor:         #8d3d2c;
  --r-orquesta:       #a87a55;
  --r-instrumentista: #6a4030;
  --r-otros:          #8a7d74;

  /* Community palette — one slot per Louvain community id (0 = biggest galaxy).
     Muted archival tones tuned in OKLCH (L 0.52–0.67, C ≥ 0.10) and validated
     against the night surface (#07050a): every color ≥ 3:1 contrast, adjacent
     pairs CVD-separated (worst ΔE 19.4). Communities beyond the 10 slots and
     isolated nodes (-1) share the neutral --c-none (same tone as
     --p-desconocido: "no galaxy" reads as no-data, not as an 11th color). */
  --c-0:    #bb8736; /* brass gold */
  --c-1:    #5382be; /* dusty blue */
  --c-2:    #b15c3d; /* terracotta */
  --c-3:    #5ea76f; /* sage */
  --c-4:    #c77596; /* dusty rose */
  --c-5:    #806eb3; /* muted violet */
  --c-6:    #93953e; /* olive */
  --c-7:    #0e9a94; /* teal */
  --c-8:    #a14b46; /* oxblood */
  --c-9:    #b37bb6; /* mauve */
  --c-none: #5a5048;

  /* Scene-specific palette */
  --night:    #07050a;
  --cordovan: #0e0809;
  --oxblood:  #1a0c0c;
  --brass:    #c9974a;
  --brass-2:  #d4a07a;
  --brass-3:  #8b5a2b;
}

/* Body opens up: the graph claims the entire viewport below the sticky header. */
body.page-graph { overflow: hidden; }
body.page-graph .site-main { padding-bottom: 0; }
body.page-graph .site-backdrop { display: none; }
body.page-graph .site-footer { display: none; }
body.page-graph .content-ad-slot { display: none; }

/* Reset the global `button` rule from site.css (min-height: 3rem ≈ 63px,
   padding: 0 1.2rem) so each graph button sizes to its own width/height. */
.graph-scene button { min-height: 0; padding: 0; }

/* ── Scene shell ──────────────────────────────────────────────────── */

.graph-scene {
  position: relative;
  height: calc(100dvh - var(--header-h, 4.2rem));
  min-height: 480px;
  overflow: hidden;
  background:
    radial-gradient(ellipse 70% 55% at 50% 48%, #1a0e12 0%, var(--cordovan) 42%, var(--night) 92%);
}

/* Single soft vignette over everything */
.graph-scene::after {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background:
    radial-gradient(ellipse 80% 70% at 50% 44%, transparent 42%, rgba(0,0,0,0.55) 100%);
  z-index: 2;
}

/* ── Decorative background: compass rings ─────────────────────────── */

.graph-compass {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  pointer-events: none;
  z-index: 1;
  opacity: 0.9;
}

/* The cytoscape canvas itself */
#graph-canvas {
  position: absolute; inset: 0;
  z-index: 2;
}

/* ── Editorial titlebar (top center) ──────────────────────────────── */

.graph-titlebar {
  position: absolute; top: 18px; left: 50%; transform: translateX(-50%);
  z-index: 5;
  display: flex; flex-direction: column; align-items: center;
  gap: 6px;
  pointer-events: none;
  text-align: center;
}
.graph-titlebar-eyebrow {
  display: inline-flex; align-items: center; gap: 14px;
  font-family: var(--font-ui);
  font-size: 9.5px; font-weight: 500;
  letter-spacing: 0.34em; text-transform: uppercase;
  color: var(--brass-2);
  opacity: 0.78;
}
.graph-titlebar-eyebrow .dash {
  display: inline-block;
  width: 32px; height: 1px;
  background: linear-gradient(90deg, transparent, var(--brass-2) 50%, transparent);
  opacity: 0.7;
}
.graph-counts {
  position: static; transform: none;
  background: transparent;
  border: 0;
  border-radius: 0;
  padding: 0;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  box-shadow: none;
  font-family: "Bodoni Moda", "Times New Roman", serif;
  font-style: italic;
  font-weight: 300;
  font-size: 13.5px;
  letter-spacing: 0.08em;
  color: var(--text-soft);
  text-transform: none;
}

/* ── Floating chrome panels ───────────────────────────────────────── */

.graph-chrome {
  position: absolute; z-index: 5; pointer-events: none;
}
.graph-chrome > * { pointer-events: auto; }

.graph-chrome.tl { top: 28px; left: 28px; width: 260px; }
.graph-chrome.tr { top: 28px; right: 28px; transition: right 460ms cubic-bezier(0.16, 1, 0.3, 1); }
/* Keep the zoom (+/−) controls reachable while the detail panel is open — slide
   them to the left edge of the 400px panel instead of letting it cover them.
   Below 720px the whole graph chrome is hidden (mobile fallback), so the panel is
   always its fixed 400px width when this offset applies. */
.graph-scene:has(#graph-panel.open) .graph-chrome.tr { right: 428px; }
.graph-chrome.bl { bottom: 28px; left: 28px; }
.graph-chrome.br { bottom: 28px; right: 28px; }

/* Zoom buttons — compact stacked +/− card matching the modecard vocabulary */
.graph-zoom {
  display: flex; flex-direction: column;
  background: rgba(10,6,8,0.82);
  border: 1px solid rgba(213,160,122,0.18);
  border-radius: 2px;
  box-shadow: 0 14px 32px rgba(0,0,0,0.42);
  overflow: hidden;
}
.graph-zoom button {
  width: 38px; height: 38px;
  display: inline-flex; align-items: center; justify-content: center;
  background: transparent; border: 0; outline: 0; cursor: pointer;
  font-family: "Bodoni Moda", "Times New Roman", serif;
  font-weight: 300;
  font-size: 22px;
  line-height: 1;
  color: var(--brass-2);
  transition: color 180ms ease, background-color 180ms ease;
}
.graph-zoom button + button {
  border-top: 1px solid rgba(213,160,122,0.16);
}
.graph-zoom button:hover { color: var(--brass); background: rgba(213,160,122,0.06); }
.graph-zoom button:active { background: rgba(213,160,122,0.12); }
.graph-zoom button:focus-visible {
  background: rgba(213,160,122,0.08);
  color: var(--brass);
}

/* Search — full override of site.css input defaults */
.graph-search-box {
  position: relative;
  border-bottom: 1px solid rgba(213,160,122,0.32);
  background: transparent;
  transition: border-color 220ms ease;
}
.graph-search-box::before {
  /* Decorative leading dash */
  content: "";
  position: absolute; left: 0; top: 50%; transform: translateY(-50%) scaleX(0.64);
  transform-origin: left center;
  width: 22px; height: 1px;
  background: var(--brass-2);
  opacity: 0.55;
  transition: transform 280ms cubic-bezier(0.16,1,0.3,1), opacity 220ms;
}
.graph-search-box:focus-within { border-bottom-color: var(--brass); }
.graph-search-box:focus-within::before {
  transform: translateY(-50%) scaleX(1);
  opacity: 1;
  background: var(--brass);
}
.graph-search-box input[type="text"] {
  /* Hard reset against site.css globals */
  width: 100%;
  min-height: 0;
  height: auto;
  padding: 9px 4px 10px 28px;
  margin: 0;
  background: transparent;
  border: 0;
  border-radius: 0;
  outline: 0;
  box-shadow: none;
  font-family: "Bodoni Moda", "Times New Roman", serif;
  font-style: italic;
  font-size: 16px;
  font-weight: 300;
  line-height: 1.1;
  color: var(--text-main);
  letter-spacing: 0.01em;
  appearance: none;
  -webkit-appearance: none;
  transition: none;
}
.graph-search-box input[type="text"]::placeholder {
  color: var(--text-muted);
  font-style: italic;
  opacity: 0.62;
  letter-spacing: 0.01em;
}
.graph-search-box input[type="text"]:focus {
  /* Override site.css :focus */
  border: 0;
  box-shadow: none;
  outline: 0;
}

#graph-autocomplete {
  margin-top: 6px;
  max-height: 380px; overflow-y: auto;
  background: rgba(10,6,8,0.96);
  border: 1px solid rgba(213,160,122,0.18);
  border-radius: 2px;
  display: none;
  box-shadow: 0 18px 42px rgba(0,0,0,0.55);
}
#graph-autocomplete.open { display: block; }
.graph-ac-item {
  position: relative;
  padding: 11px 16px;
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 12px;
  border-bottom: 1px solid rgba(213,160,122,0.08);
  cursor: pointer;
  transition: background-color 140ms ease;
}
.graph-ac-item::before {
  content: ""; position: absolute; left: 0; top: 50%;
  width: 14px; height: 1px; background: var(--brass);
  transform: translateY(-50%) scaleX(0);
  transform-origin: left center;
  transition: transform 240ms cubic-bezier(0.16,1,0.3,1);
}
.graph-ac-item:last-child { border-bottom: 0; }
.graph-ac-item:hover, .graph-ac-item.focused {
  background: rgba(213,160,122,0.05);
}
.graph-ac-item:hover::before, .graph-ac-item.focused::before { transform: translateY(-50%) scaleX(1); }
.graph-ac-item .ac-name {
  font-family: "Bodoni Moda", serif; font-style: italic;
  color: var(--text-main); font-size: 14px; line-height: 1.2;
  padding-left: 18px;
}
.graph-ac-item .ac-meta {
  font-family: var(--font-ui);
  font-size: 8.5px; letter-spacing: 0.24em; text-transform: uppercase;
  color: var(--brass-2);
  opacity: 0.7;
}

/* Mode card — tabs on top, legend list below, unified card */
.graph-modecard {
  background: rgba(10,6,8,0.82);
  border: 1px solid rgba(213,160,122,0.18);
  border-radius: 2px;
  box-shadow: 0 14px 32px rgba(0,0,0,0.42);
  min-width: 220px;
  position: relative;
  overflow: hidden;
}
.graph-modecard::before {
  content: "✦";
  position: absolute; top: 8px; right: 10px;
  font-size: 8px; color: var(--brass-2); opacity: 0.5;
  pointer-events: none;
  z-index: 2;
}

/* Tabs row (top of the card) */
.graph-modecard .graph-toggle {
  display: flex; gap: 0;
  background: transparent;
  border: 0;
  padding: 0;
  border-bottom: 1px solid rgba(213,160,122,0.16);
}
.graph-modecard .graph-toggle button {
  position: relative;
  flex: 1;
  background: transparent; border: 0; outline: 0; cursor: pointer;
  /* Sized for three tabs on one line (por época | por rol | por comunidad):
     tighter tracking + padding than the original two-tab row, nowrap so the
     longest label widens the card instead of wrapping to two lines. */
  padding: 12px 10px 13px;
  font-family: var(--font-ui); font-size: 9.5px;
  font-weight: 500;
  letter-spacing: 0.2em; text-transform: uppercase;
  white-space: nowrap;
  color: var(--text-muted);
  transition: color 220ms ease, background-color 220ms ease;
}
.graph-modecard .graph-toggle button::after {
  content: ""; position: absolute; left: 14px; right: 14px; bottom: -1px;
  height: 1px; background: var(--brass);
  transform: scaleX(0);
  transition: transform 280ms cubic-bezier(0.16,1,0.3,1);
}
/* Defensive: site.css's global button rule sets a display value, which beats
   the UA [hidden] style. graph.js hides the "por comunidad" tab via `hidden`
   when the payload predates the community field — honor it. */
.graph-modecard .graph-toggle button[hidden] { display: none; }
.graph-modecard .graph-toggle button:hover { color: var(--text-soft); }
.graph-modecard .graph-toggle button.active {
  color: var(--brass-2);
  background: rgba(213,160,122,0.04);
}
.graph-modecard .graph-toggle button.active::after { transform: scaleX(1); }

/* Density picker (bottom of the card, mirrors the mode tabs above the legend) */
.graph-modecard .graph-toggle-density {
  border-bottom: 0;
  border-top: 1px solid rgba(213,160,122,0.16);
}
.graph-modecard .graph-toggle-density button {
  padding: 10px 8px 11px;
  font-size: 8.5px;
  letter-spacing: 0.22em;
}
.graph-modecard .graph-toggle-density button.active::after {
  bottom: auto; top: -1px;
}

/* Legend list (bottom of the card) */
.graph-modecard .graph-legend {
  background: transparent;
  border: 0;
  border-radius: 0;
  padding: 13px 18px 14px;
  box-shadow: none;
  min-width: 0;
  position: relative;
}
/* The toggle now indicates the mode — title becomes redundant */
.graph-modecard .graph-legend .graph-legend-title { display: none; }

.graph-legend-row {
  display: flex; align-items: center; gap: 11px;
  font-family: "Bodoni Moda", serif;
  font-style: italic;
  font-size: 12.5px;
  padding: 3px 0;
  color: var(--text-soft);
  cursor: pointer;
  user-select: none;
  transition: color 180ms ease, opacity 180ms ease;
  outline: none;
}
.graph-legend-row:hover { color: var(--brass-2); }
.graph-legend-row:focus-visible { color: var(--brass-2); }
.graph-legend-row.disabled {
  color: var(--text-muted);
  opacity: 0.42;
  text-decoration: line-through;
  text-decoration-color: rgba(213,160,122,0.35);
  text-decoration-thickness: 1px;
}
.graph-legend-bulk {
  display: flex; align-items: center; gap: 7px;
  padding: 6px 0 1px;
  color: var(--text-muted);
}
.graph-legend-bulk button {
  background: none; border: 0; padding: 2px 0;
  font-family: inherit;
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-muted);
  cursor: pointer;
}
.graph-legend-bulk button:hover,
.graph-legend-bulk button:focus-visible { color: var(--brass-2); }

.graph-legend-swatch {
  width: 9px; height: 9px; border-radius: 50%;
  flex-shrink: 0;
  box-shadow: 0 0 0 1px rgba(213,160,122,0.30);
  transition: background-color 180ms ease, box-shadow 180ms ease, opacity 180ms ease;
}
.graph-legend-row.disabled .graph-legend-swatch {
  background: transparent !important;
  box-shadow: 0 0 0 1px rgba(213,160,122,0.22) inset;
}

/* Tooltip */
#graph-tooltip {
  position: absolute; z-index: 6;
  background: rgba(10,6,8,0.96);
  border: 1px solid rgba(213,160,122,0.20);
  border-radius: 2px;
  padding: 9px 13px 10px;
  box-shadow: 0 14px 32px rgba(0,0,0,0.55);
  pointer-events: none;
  opacity: 0;
  transform: translate(-50%, calc(-100% - 12px));
  transition: opacity 140ms ease;
  white-space: nowrap;
  display: flex;
  align-items: center;
  gap: 10px;
}
#graph-tooltip.visible { opacity: 1; }
#graph-tooltip .tt-avatar {
  flex: 0 0 auto;
  width: 64px; height: 64px;
  border-radius: 50%;
  object-fit: cover;
  background: rgba(213,160,122,0.10);
  box-shadow: 0 0 0 1px rgba(213,160,122,0.30);
}
#graph-tooltip .tt-avatar.empty { display: none; }
#graph-tooltip .tt-name {
  font-family: "Bodoni Moda", serif; font-style: italic;
  font-size: 14px; color: var(--text-main); line-height: 1.05;
}
#graph-tooltip .tt-meta {
  font-family: var(--font-ui); font-size: 8.5px;
  letter-spacing: 0.22em; text-transform: uppercase;
  color: var(--brass-2);
  margin-top: 4px;
  opacity: 0.78;
}

/* ── Side panel ───────────────────────────────────────────────────── */

#graph-panel {
  position: absolute; top: 0; right: 0; bottom: 0; z-index: 6;
  width: 400px; max-width: 92vw;
  background: rgba(10,7,8,0.97);
  border-left: 1px solid rgba(213,160,122,0.18);
  transform: translateX(105%);
  transition: transform 460ms cubic-bezier(0.16, 1, 0.3, 1);
  display: flex; flex-direction: column;
  box-shadow: -28px 0 64px rgba(0,0,0,0.55);
}
#graph-panel::before {
  content: ""; position: absolute; top: 14px; left: 14px; bottom: 14px; right: 14px;
  border: 1px solid rgba(213,160,122,0.08);
  pointer-events: none;
}
#graph-panel.open { transform: translateX(0); }

.graph-panel-close {
  position: absolute; top: 24px; right: 24px;
  width: 30px; height: 30px; border-radius: 50%;
  background: transparent;
  border: 1px solid rgba(213,160,122,0.22);
  color: var(--brass-2); cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  font-family: "Bodoni Moda", serif; font-size: 18px; line-height: 0;
  transition: background-color 200ms, border-color 200ms, color 200ms;
  z-index: 2;
}
.graph-panel-close:hover {
  background: rgba(213,160,122,0.10);
  border-color: var(--brass);
  color: var(--brass);
}

.graph-panel-scroll {
  overflow-y: auto; padding: 44px 36px 48px;
  flex: 1;
  scrollbar-width: thin;
  scrollbar-color: rgba(213,160,122,0.25) transparent;
}
.graph-panel-scroll::-webkit-scrollbar { width: 6px; }
.graph-panel-scroll::-webkit-scrollbar-thumb {
  background: rgba(213,160,122,0.25); border-radius: 3px;
}

.graph-panel-eyebrow {
  display: inline-flex; align-items: center; gap: 10px;
  font-family: var(--font-ui); font-weight: 500;
  font-size: 9px; letter-spacing: 0.30em; text-transform: uppercase;
  color: var(--brass);
  margin-bottom: 16px;
  opacity: 0.95;
}
.graph-panel-eyebrow::before {
  content: ""; display: inline-block;
  width: 18px; height: 1px;
  background: var(--brass);
  opacity: 0.7;
}

.graph-panel-name {
  font-family: "Bodoni Moda", "Times New Roman", serif;
  font-style: italic;
  font-weight: 400;
  font-size: 32px;
  line-height: 1.05;
  letter-spacing: -0.012em;
  color: var(--text-main);
  margin: 0 0 6px;
  text-wrap: balance;
}
.graph-panel-alias {
  font-family: var(--font-reading);
  font-style: italic;
  font-size: 13px;
  color: var(--text-muted);
  margin-bottom: 20px;
  opacity: 0.85;
}

.graph-panel-avatar {
  width: 90px; height: 90px; border-radius: 50%;
  background: var(--bg-soft);
  border: 1px solid rgba(213,160,122,0.30);
  outline: 3px solid rgba(213,160,122,0.06);
  outline-offset: 3px;
  object-fit: cover;
  margin-bottom: 22px;
  filter: saturate(0.88) contrast(1.08);
  box-shadow: 0 10px 26px rgba(0,0,0,0.4);
}
.graph-panel-avatar-fallback {
  width: 90px; height: 90px; border-radius: 50%;
  background: linear-gradient(135deg, #1a0e0e, #0d0708);
  border: 1px solid rgba(213,160,122,0.30);
  outline: 3px solid rgba(213,160,122,0.06);
  outline-offset: 3px;
  display: flex; align-items: center; justify-content: center;
  font-family: "Bodoni Moda", serif; font-style: italic;
  font-size: 34px; color: var(--brass-2);
  margin-bottom: 22px;
  box-shadow: 0 10px 26px rgba(0,0,0,0.4);
}

.graph-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 20px; }
.graph-chip {
  display: inline-flex; align-items: center; gap: 7px;
  font-family: var(--font-ui);
  font-size: 9.5px; font-weight: 500;
  letter-spacing: 0.18em; text-transform: uppercase;
  padding: 5px 11px;
  border-radius: 999px;
  background: rgba(213,160,122,0.06);
  color: var(--text-soft);
  border: 1px solid rgba(213,160,122,0.14);
}
.graph-chip-dot {
  width: 7px; height: 7px; border-radius: 50%;
}

.graph-panel-bio {
  font-family: var(--font-reading);
  font-size: 14.5px;
  line-height: 1.65;
  color: var(--text-soft);
  margin: 22px 0 26px;
  text-wrap: pretty;
}
.graph-panel-bio::first-letter {
  font-family: "Bodoni Moda", serif;
  font-style: italic;
  font-size: 2.4em;
  line-height: 0.95;
  float: left;
  margin: 0.04em 0.08em 0 0;
  color: var(--brass-2);
}

.graph-section-title {
  display: flex; align-items: center; gap: 12px;
  font-family: var(--font-ui); font-weight: 500;
  font-size: 9px; letter-spacing: 0.30em; text-transform: uppercase;
  color: var(--brass);
  margin: 28px 0 12px;
  opacity: 0.95;
}
.graph-section-title::before {
  content: ""; display: inline-block;
  width: 14px; height: 1px;
  background: var(--brass);
  opacity: 0.7;
}

.graph-works-list { display: flex; flex-direction: column; gap: 0; }
.graph-work-row {
  display: grid;
  grid-template-columns: 26px 1fr auto;
  align-items: center; gap: 14px;
  padding: 3px 12px; margin: 0 -12px;
  border-radius: 2px;
  transition: background-color 160ms;
}
.graph-work-row:hover { background: rgba(213,160,122,0.05); }
.graph-work-spotify {
  width: 22px; height: 22px; min-height: 0;
  display: inline-flex; align-items: center; justify-content: center;
  color: #1db954;
  background: transparent;
  border: 0;
  padding: 0;
  cursor: pointer;
  text-decoration: none;
  transition: color 220ms, transform 220ms;
}
.graph-work-spotify:hover {
  color: #1ed760;
  transform: scale(1.12);
}
.graph-work-title {
  font-family: "Bodoni Moda", serif; font-style: italic;
  font-size: 15px; line-height: 1.2;
  color: var(--text-main);
  text-decoration: none;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  transition: color 180ms;
}
.graph-work-title:hover { color: var(--brass-2); }
.graph-work-roles {
  font-family: var(--font-ui);
  font-size: 8.5px; letter-spacing: 0.20em; text-transform: uppercase;
  color: var(--text-muted);
  flex-shrink: 0;
}

.graph-neighbor-list { display: flex; flex-direction: column; gap: 1px; }
.graph-neighbor {
  display: flex; align-items: center; gap: 11px;
  padding: 8px 12px; margin: 0 -12px;
  cursor: pointer;
  border-radius: 2px;
  transition: background-color 160ms;
}
.graph-neighbor:hover { background: rgba(213,160,122,0.05); }
.graph-neighbor-dot {
  width: 8px; height: 8px; border-radius: 50%;
  flex-shrink: 0;
}
.graph-neighbor-name {
  font-family: "Bodoni Moda", serif; font-style: italic;
  font-size: 15px; color: var(--text-main);
}

.graph-panel-cta {
  display: inline-flex; align-items: center; gap: 10px;
  margin-top: 26px;
  padding: 11px 22px;
  background: transparent;
  border: 1px solid var(--brass);
  border-radius: 999px;
  color: var(--brass-2);
  text-decoration: none;
  font-family: var(--font-ui); font-size: 10.5px;
  font-weight: 500;
  letter-spacing: 0.22em; text-transform: uppercase;
  transition: background-color 240ms, color 240ms;
}
.graph-panel-cta:hover {
  background: var(--brass);
  color: var(--cordovan);
}

.graph-panel-meta {
  font-family: var(--font-ui);
  font-size: 9.5px; color: var(--text-muted);
  margin: 16px 0 0;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  opacity: 0.7;
}

/* ── Edge relation labels (focused state) ─────────────────────────── */

/*
 * Galaxy name captions (one per palette community, at its centroid): the
 * initial-view wayfinding — the map reads as named constellations before any
 * interaction. Serif italic like the node names; quiet, clickable.
 */
.graph-galaxy-label {
  font-family: "Bodoni Moda", serif;
  font-style: italic;
  font-size: 15px;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: rgba(231, 223, 213, 0.62);
  text-shadow: 0 1px 10px rgba(7, 5, 10, 0.9);
  cursor: pointer;
  user-select: none;
  transition: color 160ms ease-out, opacity 400ms ease;
}
.graph-galaxy-label:hover { color: var(--brass-2, #d5a07a); }
/* Zoomed past the wayfinding range: captions would sit on the avatars and
   (being the only interactive CSS2D elements) swallow wheel-zoom — fade out
   and stop catching the pointer. Toggled per-frame from graph.js. */
.graph-galaxy-label.faded { opacity: 0; pointer-events: none !important; }

.graph-edge-label {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-family: var(--font-ui);
  font-size: 8px;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: rgba(213, 160, 122, 0.75);
  background: rgba(7, 5, 10, 0.72);
  padding: 2px 6px;
  border-radius: 2px;
  pointer-events: none;
  white-space: nowrap;
  opacity: 0;
  transition: opacity 140ms cubic-bezier(0.16, 1, 0.3, 1);
}
.graph-edge-label::before {
  content: "";
  width: 9px;
  height: 1px;
  flex: 0 0 auto;
  background: currentColor;
  opacity: 0.68;
}
.graph-edge-label.is-visible { opacity: 1; }

/* ── Focus hint ───────────────────────────────────────────────────── */

.graph-focus-hint {
  position: absolute; bottom: 30px; left: 50%; transform: translateX(-50%);
  z-index: 4;
  display: inline-flex; align-items: center; gap: 10px;
  font-family: var(--font-ui);
  font-size: 9.5px; font-weight: 500;
  letter-spacing: 0.26em; text-transform: uppercase;
  color: var(--brass-2);
  background: rgba(10,6,8,0.85);
  border: 1px solid rgba(213,160,122,0.20);
  border-radius: 999px;
  padding: 9px 18px;
  box-shadow: 0 14px 32px rgba(0,0,0,0.42);
  opacity: 0; pointer-events: none;
  transition: opacity 280ms ease;
}
.graph-focus-hint.visible { opacity: 1; }
.graph-focus-hint .hint-dot {
  width: 6px; height: 6px; border-radius: 50%;
  background: var(--brass);
}

/* ── Onboarding pill (first-visit hint, QW5) ──────────────────────── */

.graph-onboard-pill {
  position: absolute; bottom: 72px; left: 50%;
  transform: translateX(-50%) translateY(8px);
  z-index: 5;
  display: inline-flex; align-items: center; gap: 10px;
  font-family: var(--font-ui);
  font-size: 10.5px; font-weight: 500;
  letter-spacing: 0.18em; text-transform: uppercase;
  color: var(--brass-2);
  background: rgba(10,6,8,0.9);
  border: 1px solid rgba(213,160,122,0.30);
  border-radius: 999px;
  padding: 10px 20px;
  box-shadow: 0 16px 36px rgba(0,0,0,0.48);
  opacity: 0; pointer-events: none;
  transition: opacity 320ms ease, transform 320ms ease;
}
.graph-onboard-pill.visible {
  opacity: 1;
  transform: translateX(-50%) translateY(0);
}
.graph-onboard-pill .onboard-dot {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--brass);
  box-shadow: 0 0 0 0 rgba(213,160,122,0.55);
  animation: graph-onboard-ping 1.8s ease-out infinite;
}
@keyframes graph-onboard-ping {
  0%   { box-shadow: 0 0 0 0 rgba(213,160,122,0.55); }
  70%  { box-shadow: 0 0 0 8px rgba(213,160,122,0); }
  100% { box-shadow: 0 0 0 0 rgba(213,160,122,0); }
}

/* ── Loading splash ───────────────────────────────────────────────── */

.graph-loading {
  position: absolute; inset: 0; z-index: 9;
  display: flex; align-items: center; justify-content: center;
  background:
    radial-gradient(ellipse at 50% 50%, var(--oxblood) 0%, var(--cordovan) 50%, var(--night) 100%);
  transition: opacity 600ms ease;
}
.graph-loading.fading { opacity: 0; pointer-events: none; }
.graph-loading-inner {
  display: flex; flex-direction: column; align-items: center;
  gap: 16px;
  text-align: center;
}
.graph-loading-glyph {
  font-family: "Bodoni Moda", serif;
  font-size: 26px;
  color: var(--brass);
  opacity: 0.7;
}
.graph-loading-pulse {
  font-family: "Bodoni Moda", "Times New Roman", serif;
  font-style: italic;
  font-weight: 300;
  font-size: 30px;
  color: var(--text-main);
  letter-spacing: 0.02em;
  line-height: 1;
  animation: graph-pulse 1.8s ease-in-out infinite;
}
@keyframes graph-pulse {
  0%, 100% { opacity: 0.55; }
  50%      { opacity: 1.0; }
}
.graph-loading-sub {
  font-family: var(--font-ui); font-weight: 500;
  font-size: 9px; letter-spacing: 0.34em; text-transform: uppercase;
  color: var(--brass-2);
  opacity: 0.6;
}

/* ── Mobile fallback ──────────────────────────────────────────────── */

.graph-mobile-fallback { display: none; }

@media (max-width: 720px) {
  .graph-scene > :not(.graph-mobile-fallback) { display: none; }
  .graph-mobile-fallback {
    display: flex; flex-direction: column; align-items: center;
    justify-content: center; gap: 18px;
    padding: 80px 32px;
    height: 100%;
    text-align: center;
  }
  .graph-mobile-fallback h2 {
    font-family: "Bodoni Moda", serif; font-style: italic;
    font-size: 28px; color: var(--text-main); margin: 0;
  }
  .graph-mobile-fallback p {
    font-family: var(--font-reading); font-size: 15px;
    color: var(--text-soft); max-width: 36ch; margin: 0;
  }
  .graph-mobile-fallback a {
    display: inline-flex; align-items: center; gap: 8px;
    padding: 12px 22px;
    border: 1px solid var(--brass); border-radius: 999px;
    color: var(--brass-2); text-decoration: none;
    font-family: var(--font-ui); font-size: 11px;
    letter-spacing: 0.22em; text-transform: uppercase;
  }
}

/* ── Reduced motion ───────────────────────────────────────────────── */

@media (prefers-reduced-motion: reduce) {
  .graph-edge-label { transition: none; }
  .graph-loading-pulse { animation: none !important; }
  .graph-onboard-pill {
    transform: translateX(-50%);
    transition: opacity 320ms ease;
  }
  .graph-onboard-pill.visible { transform: translateX(-50%); }
  .graph-onboard-pill .onboard-dot { animation: none !important; }
}
