/* DecodingUs custom styles (vendored bootstrap handles the rest). Mirrors the
   Scala app's main.css for a consistent site feel: fixed top + bottom navbars,
   smooth scroll, and a gray code style. */
html { scroll-behavior: smooth; }
body { padding-top: 56px; padding-bottom: 56px; }

/* Override Bootstrap's default pink/cyan code styling to use gray (Scala parity). */
code { color: #495057; background-color: #f8f9fa; }

.logo-placeholder {
  max-width: 900px;
  display: block;
  margin: 0 auto;
  padding: 20px 0;
}

.detail-empty { color: var(--bs-secondary-color); }

/* References list: clamp the abstract preview to two lines. */
.ref-abstract {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* ── Phylogenetic tree (SVG cladogram) ─────────────────────────────────────── */
.tree-scroll-container {
  overflow: auto;
  max-height: 78vh;
  border: 1px solid var(--bs-border-color);
  border-radius: .375rem;
  background:
    linear-gradient(90deg, rgba(0,0,0,.02) 1px, transparent 1px) 0 0 / 24px 24px,
    linear-gradient(rgba(0,0,0,.02) 1px, transparent 1px) 0 0 / 24px 24px;
}
.phylo-tree { display: block; }

.tree-link { fill: none; stroke: var(--bs-border-color, #ccc); stroke-width: 1.5; }

/* "More below" affordance on depth-clipped nodes: a stub + chevron growing out of
   the box so it's obvious the node re-roots into a deeper view. Cue only — the box
   itself is the click target, so the stub never steals pointer events. */
.tree-more-stub {
  fill: none;
  stroke: var(--bs-secondary-color, #6c757d);
  stroke-width: 1.75;
  stroke-linecap: round;
  stroke-linejoin: round;
  pointer-events: none;
}

.tree-node-rect {
  stroke: #888;
  stroke-width: 1;
  cursor: pointer;
  transition: filter .12s ease;
}
.tree-node-rect:hover,
.tree-node-rect:focus {
  filter: drop-shadow(0 2px 3px rgba(0,0,0,.25));
  stroke-width: 1.5;
  outline: none;
}
.tree-node-rect.node-backbone { fill: #d4edda; stroke: #2e7d32; }
.tree-node-rect.node-recent   { fill: #ffeeba; stroke: #e65100; stroke-dasharray: 4 2; }
.tree-node-rect.node-default  { fill: #f8f9fa; stroke: #6c757d; }

.tree-node-name {
  text-anchor: middle;
  font-weight: 600;
  font-size: 13px;
  fill: #212529;
  pointer-events: none;
}
.tree-variant-link {
  text-anchor: middle;
  font-size: 11px;
  fill: #0d6efd;
  cursor: pointer;
}
.tree-variant-link:hover { text-decoration: underline; }
.tree-node-age {
  text-anchor: middle;
  font-size: 10px;
  fill: var(--bs-secondary-color, #6c757d);
  pointer-events: none;
}
/* TMRCA is the headline age estimate — give it a touch more weight/contrast so it
   reads at a glance instead of being lost among the other lines. */
.tree-node-tmrca {
  font-weight: 600;
  fill: #1b5e20;
}

/* Legend swatches mirror the node fills. */
.legend-swatch {
  display: inline-block;
  width: .9rem; height: .9rem;
  vertical-align: -2px;
  border-radius: 2px;
  border: 1px solid #888;
}
.legend-swatch.node-backbone { background: #d4edda; border-color: #2e7d32; }
.legend-swatch.node-recent   { background: #ffeeba; border-color: #e65100; }
.legend-swatch.node-default  { background: #f8f9fa; border-color: #6c757d; }

/* ── Clade "Geography & Time" panel (in the SNP off-canvas) ──────────────────── */
/* Give the off-canvas enough room for a usable map + full-width time axis. */
#snpOffcanvas { --bs-offcanvas-width: min(94vw, 480px); }

.clade-map {
  height: 240px;
  border-radius: .375rem;
  border: 1px solid var(--bs-border-color);
  background: var(--bs-tertiary-bg, #f8f9fa);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--bs-secondary-color, #6c757d);
  font-size: .8rem;
}

.clade-time-axis { display: block; width: 100%; height: auto; }
.cta-grid   { stroke: rgba(0,0,0,.08); stroke-width: 1; }
.cta-tick   { font-size: 9px; fill: var(--bs-secondary-color, #6c757d); }
.cta-axis-label { font-size: 9px; fill: var(--bs-secondary-color, #6c757d); }
.cta-branch { stroke: #6c757d; stroke-width: 2; stroke-linecap: round; }
.cta-ci     { fill: rgba(27,94,32,.18); stroke: #1b5e20; stroke-width: .75; }
.cta-tmrca  { fill: #1b5e20; stroke: #fff; stroke-width: 1; }
.cta-formed { stroke: #6c757d; stroke-width: 1.5; stroke-linecap: round; }
.cta-whisker { stroke: #8a4b12; stroke-width: 1; }
.cta-anchor  { fill: #e08a3c; stroke: #8a4b12; stroke-width: 1; }

/* Clade-map legend dots. */
.clade-geo-legend { display: flex; flex-wrap: wrap; align-items: center; }
.cg-dot, .cg-diamond {
  display: inline-block;
  width: .75rem; height: .75rem;
  vertical-align: -1px;
  margin-right: .2rem;
}
.cg-dot { border-radius: 50%; border: 1px solid; }
.cg-modern  { background: #0d6efd; border-color: #0d6efd; }
.cg-ancient { background: #e08a3c; border-color: #8a4b12; }
.cg-tmrca   { background: rgba(27,94,32,.35); border-color: #1b5e20; border-radius: 2px; }
.cg-diamond { transform: rotate(45deg); }
.cg-anchor  { background: #e08a3c; border: 1px solid #8a4b12; }

/* ── Mobile layout ──────────────────────────────────────────────────────────
   The footer is a `fixed-bottom` navbar. Below `lg` its links don't collapse, so
   they wrap into a tall bar that overlaps `main` while `body`'s padding only
   reserves one row's height — content gets hidden and you "can't scroll far
   enough". On small screens let the footer flow after the content (static) and
   drop the reserved padding, so nothing is ever trapped under it. Keep the links
   as a compact centered wrap instead of a tall stacked column. */
@media (max-width: 991.98px) {
  body { padding-bottom: 0; }
  footer .navbar.fixed-bottom {
    position: static;
  }
  footer .navbar.fixed-bottom .navbar-nav {
    flex-direction: row;
    flex-wrap: wrap;
    justify-content: center;
  }
  footer .navbar.fixed-bottom .nav-link {
    padding-left: .5rem;
    padding-right: .5rem;
  }
  /* The nested tree canvas no longer competes with a fixed footer for the last
     slice of viewport — give it more room and let the page scroll carry the rest. */
  .tree-scroll-container { max-height: 88vh; }
}

/* ── Ancestral-origin icicle (proposals/ancestral-origin-icicle.md §5) ───────── */
/* Colour roles live here so the chart is written against roles rather than raw hex.
   The palette is the validated 8-slot categorical set — fixed order, never cycled.
   Slot 0 is the reserved neutral carrying both "Other" and "no locality recorded":
   an absence is not an identity, so it must not wear a categorical hue.

   THEME FOLLOWS THE PAGE, NOT THE OS. An earlier cut keyed the dark values off
   `prefers-color-scheme`, but the site itself is light-only — so on a dark-mode
   desktop the SVG surface went dark while the Bootstrap-derived block fills stayed
   light, and every block label became dark text with a dark halo on a light block.
   The dark values now hang off `[data-bs-theme="dark"]` alone, which is what the
   app would set if it ever gains a dark theme. */
.origins-icicle {
  --surface-1: var(--bs-body-bg, #ffffff);
  --o-0: #adb5bd;                 /* reserved neutral: Other / no locality */
  --o-1: #2a78d6; --o-2: #eb6834; --o-3: #1baf7a; --o-4: #eda100;
  --o-5: #e87ba4; --o-6: #008300; --o-7: #4a3aa7; --o-8: #e34948;
  display: block;
  background: var(--surface-1);
}
[data-bs-theme="dark"] .origins-icicle {
  --o-0: #6c757d;
  --o-1: #3987e5; --o-2: #d95926; --o-3: #199e70; --o-4: #c98500;
  --o-5: #d55181; --o-6: #008300; --o-7: #9085e9; --o-8: #e66767;
}

.origins-scroll { overflow-x: auto; max-height: 80vh; }

/* The band behind the composition — visible where a branch has no men at all. */
.origins-band-bg { fill: var(--bs-tertiary-bg, #f8f9fa); stroke: var(--bs-border-color, #dee2e6); stroke-width: 1; }
.origins-band a { cursor: pointer; }
.origins-band:hover .origins-band-bg { stroke: var(--bs-primary, #0d6efd); stroke-width: 1.5; }
/* Text wears text tokens, never the series colour. */
.origins-band-label { fill: var(--bs-body-color, #212529); font-weight: 600; paint-order: stroke; stroke: var(--bs-tertiary-bg, #f8f9fa); stroke-width: 3px; }
.origins-tip-label  { fill: var(--bs-body-color, #212529); paint-order: stroke; stroke: var(--surface-1); stroke-width: 3px; }

/* Stacked segments are separated by surface, not by a stroke (mark spec). */
.origins-seg { stroke: none; }
.origins-seg.s0 { fill: var(--o-0); }
.origins-seg.s1 { fill: var(--o-1); }
.origins-seg.s2 { fill: var(--o-2); }
.origins-seg.s3 { fill: var(--o-3); }
.origins-seg.s4 { fill: var(--o-4); }
.origins-seg.s5 { fill: var(--o-5); }
.origins-seg.s6 { fill: var(--o-6); }
.origins-seg.s7 { fill: var(--o-7); }
.origins-seg.s8 { fill: var(--o-8); }

/* Recessive ruler. */
.origins-tick line { stroke: var(--bs-border-color, #dee2e6); stroke-width: 1; }
.origins-tick text { fill: var(--bs-secondary-color, #6c757d); }

.origins-legend { display: flex; flex-wrap: wrap; gap: .25rem .9rem; }
.origins-legend-item { display: inline-flex; align-items: center; gap: .3rem; }
.origins-swatch {
  display: inline-block; width: .8rem; height: .8rem;
  border-radius: 2px; border: 1px solid rgba(0,0,0,.15);
  --o-0: #adb5bd;
  --o-1: #2a78d6; --o-2: #eb6834; --o-3: #1baf7a; --o-4: #eda100;
  --o-5: #e87ba4; --o-6: #008300; --o-7: #4a3aa7; --o-8: #e34948;
}
.origins-swatch.s0 { background: var(--o-0); }
.origins-swatch.s1 { background: var(--o-1); }
.origins-swatch.s2 { background: var(--o-2); }
.origins-swatch.s3 { background: var(--o-3); }
.origins-swatch.s4 { background: var(--o-4); }
.origins-swatch.s5 { background: var(--o-5); }
.origins-swatch.s6 { background: var(--o-6); }
.origins-swatch.s7 { background: var(--o-7); }
.origins-swatch.s8 { background: var(--o-8); }
.origins-more { fill: var(--bs-secondary-color, #6c757d); font-weight: 700; }
/* Block contents: the branch's equivalent SNPs. Recessive against the block, and never coloured
   by anything — a mutation has no locality. */
.origins-snp { fill: var(--bs-body-color, #212529); opacity: .8; font-family: var(--bs-font-monospace, monospace); }
.origins-snp-more { fill: var(--bs-secondary-color, #6c757d); font-style: italic; }
.origins-tick-unit { fill: var(--bs-secondary-color, #6c757d); font-style: italic; }
