/* ============================================================================
   House of the Dragon: Who's Who
   Dark, warm, Valyrian. Deliberately no webfonts: this ships as a static folder
   and must render identically offline and in Safari.
   ========================================================================== */

:root {
  --bg:        #0e0d0c;
  --bg-2:      #171513;
  --bg-3:      #201d1a;
  --line:      #2f2a25;
  --ink:       #ece6da;
  --ink-2:     #a79f92;
  --ink-3:     #6f675c;
  --gold:      #c9a227;
  --blood:     #a02c22;
  --radius:    10px;
  --serif:     "Iowan Old Style", "Palatino Linotype", Palatino, Georgia, "Times New Roman", serif;
  --sans:      ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
}

* { box-sizing: border-box; }

html, body {
  margin: 0; height: 100%;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--sans);
  -webkit-font-smoothing: antialiased;
}

body {
  display: flex; flex-direction: column;
  overflow: hidden;
}

button, select { font: inherit; color: inherit; }

/* ─────────────────────────── episode gate ─────────────────────────── */

.gate {
  position: fixed; inset: 0; z-index: 100;
  background:
    radial-gradient(ellipse at 50% -10%, rgba(160,44,34,.22), transparent 60%),
    var(--bg);
  display: flex; align-items: center; justify-content: center;
  overflow-y: auto; padding: 40px 20px;
}
.gate[hidden] { display: none; }

.gate-inner { max-width: 620px; width: 100%; text-align: center; }

.gate-mark { color: var(--blood); font-size: 26px; letter-spacing: 8px; margin-bottom: 14px; }

.gate h1 {
  font-family: var(--serif); font-weight: 400;
  font-size: clamp(30px, 6vw, 46px); margin: 0 0 6px;
  letter-spacing: .04em;
}
.gate-sub { color: var(--ink-2); margin: 0 0 40px; font-size: 15px; }

.gate-q {
  font-family: var(--serif); font-weight: 400; font-size: 19px;
  color: var(--ink); margin: 0 0 18px;
}

.gate-seasons { display: flex; gap: 10px; justify-content: center; flex-wrap: wrap; }

.season-btn {
  background: var(--bg-2); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 12px 24px;
  cursor: pointer; transition: .15s;
}
.season-btn:hover { border-color: var(--ink-3); background: var(--bg-3); }
.season-btn.on { border-color: var(--gold); color: var(--gold); background: rgba(201,162,39,.08); }

.gate-eps {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
  gap: 8px; margin-top: 16px; text-align: left;
}
.gate-eps[hidden] { display: none; }

.ep-btn {
  display: flex; align-items: baseline; gap: 10px;
  background: var(--bg-2); border: 1px solid var(--line);
  border-radius: 8px; padding: 10px 12px; cursor: pointer; transition: .15s;
}
.ep-btn:hover { border-color: var(--gold); background: var(--bg-3); }
.ep-btn b { color: var(--gold); font-size: 15px; min-width: 16px; }
.ep-btn span { color: var(--ink-2); font-size: 12.5px; line-height: 1.3; }

.gate-or {
  position: relative; margin: 30px 0 16px; color: var(--ink-3); font-size: 12px;
}
.gate-or::before {
  content: ""; position: absolute; left: 0; right: 0; top: 50%;
  border-top: 1px solid var(--line);
}
.gate-or span { position: relative; background: var(--bg); padding: 0 14px; }

.gate-all {
  background: transparent; border: 1px solid var(--line); color: var(--ink-2);
  border-radius: var(--radius); padding: 11px 26px; cursor: pointer; transition: .15s;
}
.gate-all:hover { border-color: var(--ink-3); color: var(--ink); }

.gate-note {
  color: var(--ink-3); font-size: 12.5px; line-height: 1.65;
  margin: 34px auto 0; max-width: 460px;
}

/* ─────────────────────────── topbar ─────────────────────────── */

.topbar {
  flex: none; display: flex; align-items: center; justify-content: space-between;
  gap: 16px; padding: 0 16px; height: 54px;
  background: var(--bg-2); border-bottom: 1px solid var(--line);
}

.brand { display: flex; align-items: center; gap: 10px; min-width: 0; }
.brand-mark { color: var(--blood); }
.brand-text {
  font-family: var(--serif); font-size: 15px; letter-spacing: .03em;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.brand-text em { color: var(--ink-3); font-style: normal; }

.ep-control { display: flex; align-items: center; gap: 8px; }
.ep-label { color: var(--ink-3); font-size: 12px; }
.ep-badge {
  color: var(--gold); font-weight: 600; font-size: 13px;
  border: 1px solid rgba(201,162,39,.35); border-radius: 6px;
  padding: 3px 8px; background: rgba(201,162,39,.08);
}
#ep-select {
  background: var(--bg-3); border: 1px solid var(--line);
  border-radius: 6px; padding: 5px 8px; font-size: 12.5px; max-width: 230px;
}
.ghost {
  background: transparent; border: 1px solid var(--line); color: var(--ink-2);
  border-radius: 6px; padding: 5px 12px; cursor: pointer; font-size: 12.5px;
}
.ghost:hover { border-color: var(--ink-3); color: var(--ink); }

.notice {
  flex: none; padding: 9px 16px; font-size: 12.5px; line-height: 1.5;
  background: rgba(201,162,39,.07); border-bottom: 1px solid rgba(201,162,39,.22);
  color: #d8c48a;
}
.notice[hidden] { display: none; }

/* ─────────────────────────── split view ─────────────────────────── */

.split { flex: 1; display: flex; min-height: 0; }

.tree-pane { flex: 1; position: relative; min-width: 0; }

.tree-canvas {
  position: absolute; inset: 0;
  background:
    radial-gradient(ellipse at 50% 0%, rgba(160,44,34,.10), transparent 55%),
    var(--bg);
}
.tree-svg { width: 100%; height: 100%; display: block; cursor: grab; }
.tree-svg.grabbing { cursor: grabbing; }

.tree-controls {
  position: absolute; right: 14px; top: 14px; display: flex; gap: 4px; z-index: 5;
}
.tree-controls button {
  background: rgba(23,21,19,.9); border: 1px solid var(--line); color: var(--ink-2);
  border-radius: 6px; min-width: 30px; height: 30px; padding: 0 9px;
  cursor: pointer; font-size: 13px;
}
.tree-controls button:hover { border-color: var(--ink-3); color: var(--ink); }

/* Find a face. Ninety-odd portraits is past the point where scanning works,
   and the tree is the one view that had no way to ask for someone by name. */
.tree-find { position: absolute; left: 14px; top: 14px; z-index: 6; width: 236px; }
.tree-find input {
  width: 100%; background: rgba(23,21,19,.94); border: 1px solid var(--line);
  color: var(--ink); border-radius: 6px; height: 30px; padding: 0 10px;
  font: inherit; font-size: 13px; outline: none;
}
.tree-find input:focus { border-color: var(--ink-3); }
.tree-find input::placeholder { color: var(--ink-3); }

.tree-results {
  margin: 4px 0 0; padding: 4px; list-style: none; max-height: 300px; overflow-y: auto;
  background: rgba(23,21,19,.97); border: 1px solid var(--line); border-radius: 6px;
}
.tree-results[hidden] { display: none; }
.tree-results li {
  display: flex; align-items: baseline; gap: 8px;
  padding: 5px 8px; border-radius: 4px; cursor: pointer; font-size: 13px;
}
.tree-results li[aria-selected="true"], .tree-results li:hover { background: var(--bg-3); }
.tree-results .r-name { color: var(--ink); }
.tree-results .r-sub  { color: var(--ink-3); font-size: 11px; margin-left: auto; }
.tree-results .r-none { color: var(--ink-3); cursor: default; }
.tree-results .r-none:hover { background: none; }

/* While a search is active everything that does not match steps back, so the
   answer is the only bright thing on the canvas. */
.tree-canvas.searching .node { opacity: .13; }
.tree-canvas.searching .node.match { opacity: 1; }
.tree-canvas.searching .edges { opacity: .16; }

/* ─────────────────────────── tree nodes ─────────────────────────── */

.node { cursor: pointer; outline: none; }
.node-plate { fill: var(--bg-3); }
.node-ring  { fill: none; stroke-width: 2.5; }
.node-img   { }
.node-initials {
  fill: var(--ink-3); font-family: var(--serif); font-size: 20px;
  letter-spacing: .06em; pointer-events: none;
}
.node-name {
  fill: var(--ink); font-size: 12.5px; font-weight: 600;
  pointer-events: none; paint-order: stroke;
  stroke: var(--bg); stroke-width: 3px; stroke-linejoin: round;
}
.node-sub {
  fill: var(--ink-3); font-size: 10px; pointer-events: none; paint-order: stroke;
  stroke: var(--bg); stroke-width: 3px; stroke-linejoin: round;
}
.faction-badge { stroke-width: 2; }
.dead-slash { stroke: rgba(236,230,218,.62); stroke-width: 3; stroke-linecap: round; }
.dead-slash.sm { stroke-width: 2.2; }
.dead-badge { fill: var(--bg); stroke: rgba(236,230,218,.35); stroke-width: 1.5; }
.node.is-dead .node-plate,
.node.is-dead .node-img { opacity: .78; }
.node.is-dead .node-ring { stroke-dasharray: 4 4; }
.node.is-dead.is-unseen .node-plate { opacity: 1; }
.node.is-dragon .node-initials { font-size: 16px; }

/* referenced in dialogue, never on screen, so there is no face to learn */
.node.is-unseen .node-plate { fill: #14120f; }
.node.is-unseen .node-ring  { stroke-dasharray: 2 4; opacity: .65; }
.node-initials.is-unseen-mark { fill: #574f45; font-size: 30px; }
.node.is-unseen .node-name { fill: var(--ink-2); font-style: italic; }

.band-label {
  fill: var(--ink-3); font-size: 11px; letter-spacing: .22em;
  text-transform: uppercase; font-family: var(--sans);
}

/* structural edges */
.edge { fill: none; stroke: #4a423a; stroke-width: 1.6; }
.edge-spouse { stroke: rgba(224,198,106,.55); stroke-width: 2.4; }
.edge-sibling { stroke: #453d35; stroke-dasharray: 1 0; }
.edge-half-sibling { stroke: #453d35; stroke-dasharray: 6 5; }
.edge-assumed { stroke-dasharray: 2 5; }

/* hover web, the thing the whole layout is for */
.web {
  fill: none; stroke-width: 2.4; opacity: .95;
  stroke-linecap: round;
  filter: drop-shadow(0 0 5px rgba(0,0,0,.9));
}
.web-assumed { stroke-dasharray: 3 6; }
.web-label {
  font-size: 10px; letter-spacing: .08em; text-transform: uppercase;
  paint-order: stroke; stroke: var(--bg); stroke-width: 4px; stroke-linejoin: round;
  pointer-events: none;
}

/* dim everything that isn't part of the hovered character's web */
.tree-canvas.dimming .node       { opacity: .13; transition: opacity .16s; }
.tree-canvas.dimming .node.lit   { opacity: 1; }
.tree-canvas.dimming .node.focus .node-ring { stroke-width: 4; }
.tree-canvas.dimming .edge       { opacity: .12; transition: opacity .16s; }
.tree-canvas.dimming .edge.lit   { opacity: 1; stroke: var(--ink-2); }
.tree-canvas.dimming .edge.lit.edge-spouse { stroke: var(--gold); }
.tree-canvas.dimming .band-label { opacity: .25; }

/* ─────────────────────────── detail panel ─────────────────────────── */

.panel {
  flex: none; width: 380px; border-left: 1px solid var(--line);
  background: var(--bg-2); display: flex; flex-direction: column; min-height: 0;
  --house: var(--blood);
}
.panel-scroll { overflow-y: auto; padding: 20px; }

.panel.is-empty { align-items: center; justify-content: center; }
.panel-empty { text-align: center; padding: 30px; color: var(--ink-3); }
.panel-empty-mark { color: var(--line); font-size: 30px; margin-bottom: 14px; }
.panel-empty h2 { font-family: var(--serif); font-weight: 400; font-size: 20px; color: var(--ink-2); margin: 0 0 12px; }
.panel-empty p { font-size: 13px; line-height: 1.7; margin: 0 0 10px; }
.panel-empty-note { color: var(--ink-3); font-size: 12px; }
.panel-empty-note strong { color: var(--gold); }

.panel-hero { display: flex; gap: 14px; align-items: flex-start; }

.panel-portrait {
  position: relative; flex: none; width: 116px; height: 116px;
  border-radius: 50%; overflow: hidden;
  background: var(--bg-3); border: 2.5px solid var(--house);
  display: flex; align-items: center; justify-content: center;
}
.panel-portrait.is-dragon { border-radius: 12px; }
.panel-portrait.is-dead { opacity: .72; border-style: dashed; }
.panel-initials {
  font-family: var(--serif); font-size: 34px; color: var(--ink-3); letter-spacing: .05em;
}
.panel-portrait img {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; opacity: 0; transition: opacity .2s;
}
.panel-portrait img.ok { opacity: 1; }

.panel-heading { min-width: 0; padding-top: 2px; }
.panel-heading h2 {
  font-family: var(--serif); font-weight: 400; font-size: 21px;
  margin: 0 0 6px; line-height: 1.2;
}
.panel-house { font-size: 12px; color: var(--ink-2); display: flex; align-items: center; gap: 7px; flex-wrap: wrap; }
.swatch { width: 9px; height: 9px; border-radius: 2px; display: inline-block; flex: none; }
.swatch.sm { width: 7px; height: 7px; }

.faction-chip { font-size: 10px; padding: 2px 7px; border-radius: 20px; letter-spacing: .05em; }
.faction-black { background: #141414; color: #e8e8e8; border: 1px solid #444; }
.faction-green { background: #5d9e6e; color: #10180f; }

.panel-titles { list-style: none; margin: 9px 0 0; padding: 0; }
.panel-titles li {
  font-size: 11.5px; color: var(--ink-3); font-family: var(--serif); font-style: italic;
  line-height: 1.55;
}

.panel-portrait.is-unseen {
  border-style: dashed; opacity: .8; background: #14120f;
}
.panel-portrait.is-unseen .panel-initials { font-size: 34px; color: #574f45; }

.panel-unseen {
  margin: 18px 0 0; padding: 11px 12px; display: flex; gap: 11px; align-items: flex-start;
  background: var(--bg-3); border: 1px dashed var(--line); border-radius: 8px;
}
.panel-unseen-mark {
  flex: none; width: 26px; height: 26px; border-radius: 50%;
  border: 1px dashed var(--ink-3); color: var(--ink-3);
  display: flex; align-items: center; justify-content: center;
  font-family: var(--serif); font-size: 15px;
}
.panel-unseen strong { display: block; font-size: 12.5px; color: var(--ink); margin-bottom: 3px; }
.panel-unseen span { font-size: 11.5px; color: var(--ink-3); line-height: 1.6; }

.panel-actor {
  margin: 18px 0 0; padding: 10px 12px;
  background: var(--bg-3); border-radius: 8px; border: 1px solid var(--line);
  font-size: 12.5px;
}
.panel-actor .k { color: var(--ink-3); margin-right: 8px; }
.panel-actor .v { color: var(--ink); font-weight: 600; }
.panel-recast {
  margin-top: 7px; padding-top: 7px; border-top: 1px solid var(--line);
  color: var(--gold); font-size: 11.5px; line-height: 1.5;
}

.panel-status {
  margin-top: 12px; font-size: 12.5px; color: var(--ink-2);
  display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap;
}
.panel-status .dot { width: 7px; height: 7px; border-radius: 50%; background: #6aa96a; flex: none; }
.panel-status.status-dead .dot { background: var(--blood); }
.panel-status .cause {
  flex-basis: 100%; color: var(--ink-3); font-size: 11.5px;
  line-height: 1.6; margin-top: 3px; padding-left: 15px;
}

.panel-bio {
  margin: 16px 0 0; font-size: 13.5px; line-height: 1.75;
  color: var(--ink); font-family: var(--serif);
}

/* relationships */
.panel-ties { margin-top: 24px; }
.panel-ties h3 {
  font-size: 11px; letter-spacing: .2em; text-transform: uppercase;
  color: var(--ink-3); margin: 0 0 12px; display: flex; align-items: center; gap: 8px;
  border-top: 1px solid var(--line); padding-top: 16px;
}
.panel-ties h3 .count {
  background: var(--bg-3); border-radius: 20px; padding: 1px 8px;
  font-size: 10px; letter-spacing: 0; color: var(--ink-2);
}
.panel-ties .none { color: var(--ink-3); font-size: 12.5px; }

.tie-group { margin-bottom: 16px; }
.tie-group h4 {
  font-size: 10px; letter-spacing: .16em; text-transform: uppercase;
  margin: 0 0 6px; color: var(--ink-3); font-weight: 600;
}
.tie-group h4.cat-hostile  { color: #b3564a; }
.tie-group h4.cat-dragon   { color: #c99a3a; }
.tie-group h4.cat-intimate { color: #b4738f; }
.tie-group h4.cat-legal    { color: #b09640; }

.tie-group ul { list-style: none; margin: 0; padding: 0; }

.tie {
  display: grid; grid-template-columns: 96px 1fr auto; gap: 4px 8px;
  align-items: baseline; padding: 7px 8px; border-radius: 6px;
  cursor: pointer; transition: background .12s;
}
.tie:hover { background: var(--bg-3); }
.tie-label { font-size: 11px; color: var(--ink-3); }
.tie-who { font-size: 13px; display: flex; align-items: center; gap: 6px; }
.tie-ep { font-size: 10.5px; color: var(--gold); opacity: .8; }
.tie-flag {
  grid-column: 2 / -1; font-size: 9.5px; letter-spacing: .1em; text-transform: uppercase;
  color: #b4738f; border: 1px solid rgba(180,115,143,.35); border-radius: 20px;
  padding: 1px 7px; justify-self: start;
}
.tie-note {
  grid-column: 2 / -1; font-size: 11.5px; color: var(--ink-3);
  line-height: 1.6; margin-top: 2px;
}

.panel-foot {
  margin-top: 26px; padding-top: 14px; border-top: 1px solid var(--line);
  font-size: 11px; color: var(--ink-3); line-height: 1.6;
}
.panel-foot strong { color: var(--ink-2); }
.panel-foot.is-revealed { color: #c39a5a; }
.panel-foot.is-revealed strong { color: #e0b96e; }

.reveal-btn {
  display: block; width: 100%; margin-top: 10px; padding: 8px 10px;
  background: transparent; border: 1px dashed var(--line); border-radius: 6px;
  color: var(--ink-2); font-size: 11.5px; cursor: pointer;
  transition: border-color .15s, color .15s, background .15s; text-align: center;
}
.reveal-btn:hover { border-color: var(--blood); color: #d98a7e; background: rgba(160,44,34,.07); }
.reveal-btn.is-on {
  border-style: solid; border-color: rgba(201,162,39,.4);
  color: var(--gold); background: rgba(201,162,39,.08);
}
.reveal-btn.is-on:hover { border-color: var(--gold); background: rgba(201,162,39,.16); color: var(--gold); }

.reveal-flag {
  font-size: 10px; letter-spacing: .08em; text-transform: uppercase;
  color: var(--blood); border: 1px solid rgba(160,44,34,.45);
  background: rgba(160,44,34,.12); border-radius: 20px; padding: 2px 8px;
}
.reveal-flag[hidden] { display: none; }

/* the empty state also carries the reveal control, so it needs to lay out
   as a normal scrolling column rather than a centred block */
.panel.is-empty { align-items: stretch; justify-content: flex-start; }
.panel-empty-wrap { display: flex; flex-direction: column; height: 100%; }
.panel-empty-wrap .panel-empty { margin: auto 0; }
.panel-empty-wrap .panel-foot { margin-top: auto; }

.panel-look {
  display: block; margin-top: 4px; font-size: 11px;
  color: var(--gold); font-style: italic;
}

/* ─────────────────────────── legend ─────────────────────────── */

.legend {
  position: absolute; left: 0; right: 0; bottom: 0; z-index: 4;
  background: linear-gradient(to top, rgba(14,13,12,.98) 72%, rgba(14,13,12,.75) 88%, transparent);
  padding: 20px 16px 11px; pointer-events: none;
}
.legend-row { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.legend-title {
  font-size: 10px; letter-spacing: .18em; text-transform: uppercase; color: var(--ink-3);
}
.legend-items { display: flex; gap: 12px; flex-wrap: wrap; }
.legend-item { display: flex; align-items: center; gap: 5px; font-size: 11.5px; color: var(--ink-2); }
.legend-row + .legend-row { margin-top: 6px; }
.key-mark {
  width: 14px; height: 14px; border-radius: 50%; flex: none;
  border: 1px dashed var(--ink-3); color: var(--ink-3);
  display: inline-flex; align-items: center; justify-content: center;
  font-size: 9px; font-family: var(--serif);
}
.key-mark svg { width: 9px; height: 9px; fill: currentColor; }
.key-mark.key-dead { border-style: solid; border-color: rgba(236,230,218,.4); color: rgba(236,230,218,.55); }
.legend-meta { margin-top: 7px; font-size: 11px; color: var(--ink-3); gap: 16px; }
.legend-meta b { color: var(--ink-2); }
.legend-hint { margin-left: auto; }

/* ─────────────────────────── responsive ─────────────────────────── */

@media (max-width: 860px) {
  .split { flex-direction: column; }
  .panel { width: auto; max-height: 46%; border-left: none; border-top: 1px solid var(--line); }
  .tree-pane { flex: 1; min-height: 240px; }
  .legend-hint { display: none; }
  .brand-text em { display: none; }
  #ep-select { max-width: 130px; }

  /* The header ran 30px past the right edge and gave the whole page a sideways
     scroll. "Watching" and the badge both restate what the dropdown already
     says, so on a narrow screen they go and the dropdown carries it alone. */
  .ep-label, #ep-badge { display: none; }
  .topbar { gap: 10px; padding: 0 12px; }

  /* The house list wrapped to three rows and 153px, laid over a 300px tree, so
     half the tree was legend. One row that scrolls sideways keeps every house
     reachable and gives the height back. */
  .legend { padding: 14px 12px 8px; }
  .legend-row { flex-wrap: nowrap; overflow-x: auto; gap: 10px;
                scrollbar-width: none; -ms-overflow-style: none; }
  .legend-row::-webkit-scrollbar { display: none; }
  .legend-items { flex-wrap: nowrap; }
  .legend-item { flex: none; }
  .legend-title { flex: none; }
  /* Only the rows take pointer events, so they can be swiped. The padding and
     the gradient around them stay transparent to touch, or the legend would
     swallow drags meant for the tree behind it. */
  .legend-row { pointer-events: auto; }
  .legend-row + .legend-row { margin-top: 4px; }

  /* The find box and the zoom buttons were on the same line and colliding. */
  .tree-find { width: calc(100% - 130px); max-width: 236px; }

  /* With nobody selected, the panel was holding 245px of a 665px screen to say
     "hover someone", which on a phone is both wrong and expensive. Empty, it
     shrinks to a prompt. The moment a character is picked it takes its room
     back. */
  .panel.is-empty { max-height: none; flex: 0 0 auto; }
  .panel.is-empty .panel-empty-mark,
  .panel.is-empty .panel-empty-note,
  .panel.is-empty .panel-foot { display: none; }
  .panel.is-empty .panel-empty { padding: 10px 16px; }
  .panel.is-empty .panel-empty h2 { font-size: 15px; margin: 0 0 2px; }
  .panel.is-empty .panel-empty p { font-size: 12px; margin: 0; }
}

/* ============================================================================
   VIEW SWITCHER  ·  GRID  ·  PATH FINDER                            (Phase 5)
   ========================================================================== */

.views {
  display: flex; gap: 2px; margin-left: 26px;
  background: var(--bg-3); border: 1px solid var(--line);
  border-radius: 999px; padding: 3px;
}
.view-btn {
  appearance: none; cursor: pointer;
  background: transparent; border: 0; color: var(--ink-2);
  font: inherit; font-size: 12.5px; letter-spacing: .02em;
  padding: 5px 15px; border-radius: 999px;
  transition: color .15s, background .15s;
}
.view-btn:hover { color: var(--ink); }
.view-btn.on { background: var(--bg); color: var(--gold); }
.view-btn:focus-visible { outline: 1px solid var(--gold); outline-offset: 2px; }

/* ------------------------------------------------------------------ grid -- */

.grid-pane, .path-pane {
  flex: 1; min-width: 0; display: flex; flex-direction: column;
  background: var(--bg);
}
.grid-pane[hidden], .path-pane[hidden] { display: none; }

.grid-bar {
  display: flex; align-items: center; gap: 10px;
  padding: 14px 20px; border-bottom: 1px solid var(--line);
  background: var(--bg-2);
}
.grid-search {
  flex: 1; min-width: 0;
  background: var(--bg); border: 1px solid var(--line); color: var(--ink);
  font: inherit; font-size: 13.5px; padding: 8px 12px; border-radius: var(--radius);
}
.grid-search:focus { outline: none; border-color: var(--gold); }
.grid-search::placeholder { color: var(--ink-3); }
.grid-house {
  background: var(--bg); border: 1px solid var(--line); color: var(--ink-2);
  font: inherit; font-size: 12.5px; padding: 8px 10px; border-radius: var(--radius);
}
.grid-count { color: var(--ink-3); font-size: 12px; white-space: nowrap; }

.grid-scroll { flex: 1; overflow-y: auto; padding: 20px 20px 40px; }

.grid-section + .grid-section { margin-top: 30px; }
.grid-section-title {
  margin: 0 0 12px; font: 500 11px/1 var(--sans);
  letter-spacing: .18em; text-transform: uppercase; color: var(--ink-3);
}
.grid-section-title span {
  margin-left: 8px; color: var(--ink-3); opacity: .7;
  letter-spacing: 0; font-size: 11px;
}
.grid-cards {
  display: grid; gap: 14px;
  grid-template-columns: repeat(auto-fill, minmax(132px, 1fr));
}

/* A wall of faces, not a list with avatars. This view exists to answer "who
   was that person in the green", so the picture is the card and the text is
   the caption, rather than the other way round. */
.gcard {
  position: relative; display: flex; flex-direction: column; align-items: center;
  gap: 9px; text-align: center; cursor: pointer;
  padding: 12px 8px 13px; border-radius: var(--radius);
  background: var(--bg-2); border: 1px solid var(--line);
  color: inherit; font: inherit;
  transition: border-color .15s, background .15s, transform .15s;
}
.gcard:hover { background: var(--bg-3); border-color: var(--house); transform: translateY(-2px); }
.gcard:focus-visible { outline: 1px solid var(--gold); outline-offset: 2px; }

.gcard-face {
  position: relative; width: 100%; aspect-ratio: 1 / 1;
  border-radius: 50%; overflow: hidden;
  background: var(--bg-3); border: 2px solid var(--house);
  display: grid; place-items: center;
}
.gcard-face img {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; opacity: 0; transition: opacity .25s;
}
.gcard-face img.ok { opacity: 1; }
.gcard-initials {
  font-family: var(--serif); font-size: 26px; color: var(--ink-3); letter-spacing: .04em;
}
/* a corner badge, for the same reason as on the tree: a cross drawn over the
   picture hides the face it is annotating */
.gcard-dead {
  position: absolute; left: 6%; bottom: 6%;
  width: 22px; height: 22px; border-radius: 50%;
  background: var(--bg); border: 1px solid rgba(236,230,218,.32);
  display: grid; place-items: center;
  font-size: 15px; line-height: 1; color: rgba(236,230,218,.72);
}
.gcard.is-dead .gcard-face { border-style: dashed; }
.gcard.is-dead .gcard-face img { opacity: .78; }
.gcard.is-unseen .gcard-face { border-style: dotted; opacity: .6; }
.gcard.is-unseen .gcard-name { font-style: italic; color: var(--ink-2); }

.gcard-body { width: 100%; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.gcard-name {
  font-family: var(--serif); font-size: 14px; color: var(--ink); line-height: 1.25;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.gcard-sub {
  font-size: 11px; color: var(--ink-3); line-height: 1.3;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.gcard-fac {
  position: absolute; top: 14px; right: 12px;
  width: 9px; height: 9px; border-radius: 50%;
  border: 1.5px solid var(--bg-2);
}
.gcard-fac.faction-black { background: #e8e8e8; }
.gcard-fac.faction-green { background: #5d9e6e; }

.grid-empty { padding: 60px 20px; text-align: center; color: var(--ink-2); }
.grid-empty-note { color: var(--ink-3); font-size: 12.5px; max-width: 420px; margin: 8px auto 0; }

/* ------------------------------------------------------------------ path -- */

.path-bar {
  display: flex; align-items: flex-end; gap: 10px;
  padding: 14px 20px; border-bottom: 1px solid var(--line);
  background: var(--bg-2); flex-wrap: wrap;
}
.path-pick { display: flex; flex-direction: column; gap: 5px; flex: 1; min-width: 160px; max-width: 300px; }
.path-pick span {
  font-size: 10.5px; letter-spacing: .16em; text-transform: uppercase; color: var(--ink-3);
}
.path-pick select {
  background: var(--bg); border: 1px solid var(--line); color: var(--ink);
  font: inherit; font-size: 13px; padding: 8px 10px; border-radius: var(--radius);
  max-width: 100%;
}
.path-pick select:focus { outline: none; border-color: var(--gold); }
.path-arrow { color: var(--ink-3); padding-bottom: 9px; }
#path-swap { padding: 8px 12px; }

.path-scroll { flex: 1; overflow-y: auto; padding: 26px 20px 40px; }

.path-intro { max-width: 460px; margin: 40px auto; text-align: center; color: var(--ink-2); }
.path-intro-mark { font-size: 30px; color: var(--gold); opacity: .6; margin-bottom: 10px; }
.path-intro h3 { font-family: var(--serif); font-size: 21px; color: var(--ink); margin: 0 0 12px; font-weight: 400; }
.path-intro p { font-size: 13.5px; line-height: 1.6; margin: 0 0 10px; }
.path-intro-note { color: var(--ink-3); font-size: 12.5px; }

.path-result { max-width: 560px; margin: 0 auto; }
.path-summary { text-align: center; color: var(--ink-2); font-size: 13.5px; margin: 0 0 22px; }
.path-summary strong { color: var(--gold); font-weight: 500; }

.path-chain { list-style: none; margin: 0; padding: 0; }
.path-node {
  display: flex; align-items: center; gap: 10px; cursor: pointer;
  padding: 11px 14px; border-radius: var(--radius);
  background: var(--bg-2); border: 1px solid var(--line);
  transition: border-color .15s, background .15s;
}
.path-node:hover { background: var(--bg-3); border-color: var(--ink-3); }
.path-node:focus-visible { outline: 1px solid var(--gold); outline-offset: 2px; }
.path-node.is-dead { opacity: .68; }
.path-node-name { font-family: var(--serif); font-size: 15px; }
.path-node-house { margin-left: auto; font-size: 11.5px; color: var(--ink-3); }

.path-rel { display: flex; align-items: center; gap: 10px; padding: 4px 0 4px 24px; }
.path-rel-line { width: 1px; height: 26px; background: var(--line); flex: 0 0 auto; }
.path-rel-label { font-size: 12px; color: var(--ink-2); letter-spacing: .02em; }
.path-rel-label em { font-style: normal; color: var(--ink-3); font-size: 10.5px; margin-left: 5px; }
.path-rel-ep { color: var(--ink-3); font-size: 10.5px; margin-left: 8px; }
.path-note {
  margin: 22px 0 0; text-align: center;
  color: var(--ink-3); font-size: 12px; line-height: 1.6;
}

@media (max-width: 900px) {
  .views { margin-left: 12px; }
  .view-btn { padding: 5px 11px; }
  .grid-cards { grid-template-columns: repeat(auto-fill, minmax(112px, 1fr)); }
}

/* ------------------------------------------------------------- footer ---- */
/* Sits under the split view rather than inside it, so it never competes with
   the tree for space and is always reachable at the bottom of the page. */
.site-foot {
  border-top: 1px solid var(--line);
  background: var(--bg-2);
  padding: 16px 24px 20px;
  color: var(--ink-3);
  font-size: 11.5px;
  line-height: 1.65;
}
.site-foot p { margin: 0; max-width: 88ch; }
.site-foot em { font-style: italic; color: var(--ink-2); }
.site-foot-sub { margin-top: 5px; opacity: .8; }

/* The ask sits under the disclaimer rather than beside it, and is worded for
   time spent rather than access bought, because access is free and the images
   are not mine to sell. */
.site-foot-links { margin-top: 8px; color: var(--ink-2); }
.site-foot-links a {
  color: var(--ink); text-decoration: none;
  border-bottom: 1px solid var(--ink-3); padding-bottom: 1px;
}
.site-foot-links a:hover { border-bottom-color: var(--ink); }
.foot-sep { display: none; }   /* only earns its place on a narrow screen */

/* On a phone the disclaimer was 151px of a 665px screen, permanently, and it
   is the least interesting thing on the page. It collapses behind a tap there
   and stays open on desktop, where the room exists. app.js drives the `open`
   attribute off a media query. */
.foot-legal > summary {
  cursor: pointer; color: var(--ink-3); font-size: 11px;
  letter-spacing: .1em; text-transform: uppercase; list-style: none;
  padding: 2px 0; width: max-content;
}
.foot-legal > summary::-webkit-details-marker { display: none; }
.foot-legal > summary::after { content: ' +'; }
.foot-legal[open] > summary::after { content: ' \2212'; }
.foot-legal[open] > summary { margin-bottom: 6px; }
.site-foot code {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 11px; color: var(--ink-2);
}

/* the split view sizes itself off the viewport, so give the footer its own
   room instead of letting it be pushed off the bottom */
body { display: flex; flex-direction: column; }
.split { flex: 1 1 auto; }
.site-foot { flex: 0 0 auto; }

/* ───────────────────── footer on a narrow screen ─────────────────────
   This block sits at the end of the file on purpose. The footer's base rules
   are declared below the main responsive block, so overrides placed up there
   lose on source order and silently do nothing. */
@media (max-width: 860px) {
  /* One line: the credit, with the Legal toggle pushed to the end of it. Two
     stacked lines cost 78px of a screen that has none to spare. Opening Legal
     gives it a full row of its own. */
  .site-foot {
    padding: 10px 14px 12px;
    display: flex; flex-wrap: wrap; align-items: baseline;
    gap: 4px 12px;
  }
  .site-foot-links { order: 1; flex: 1 1 auto; margin-top: 0; }
  .foot-legal { order: 2; flex: 0 0 auto; }
  .foot-legal[open] { flex: 1 1 100%; order: 3; }

  /* The sentence around the links is what pushed Legal onto a second row. Drop
     the connective and the two links sit either side of a separator. The
     separator is its own element rather than a ::before on the link, because
     inside the anchor it picked up the link's underline. */
  .foot-mid { display: none; }
  .foot-sep { display: inline; color: var(--ink-3); }
}
