/* altpunk v3, /families: the family tree (lineage graph), the lineage list, the family cards and the bridge lists.
   Markup: html/families/index.html. Behaviour: assets/js/v3/families.js. */

/* ---------- graph ---------- */
.tree-sec { padding-bottom: var(--space-6); }
.tree__bar { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--space-3) var(--space-5); margin-bottom: var(--space-4); }
.tree__bar .count { margin: 0; }
.tree__kin-toggle { display: inline-flex; align-items: center; gap: var(--space-2); min-height: var(--tap); font: 500 var(--step--2)/1 var(--font-mono); letter-spacing: var(--track-label); text-transform: uppercase; color: var(--ink-dim); cursor: pointer; }
.tree__kin-toggle input { width: 18px; height: 18px; accent-color: var(--accent); margin: 0; }
.tree__kin-key { width: 28px; border-top: 2px dotted var(--ink-dim); }

.tree__scroll { overflow-x: auto; overscroll-behavior-x: contain; scrollbar-width: thin; border-block: 1px solid var(--line-soft); }
.tree__scroll:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.tree {
  --tree-ink: var(--head); --tree-dim: var(--ink-dim); --tree-bg: var(--bg);   /* resolved here, so light skins keep legible labels */
  position: relative;
  aspect-ratio: 1100 / 620;
  min-width: 720px;
  container: tree / inline-size;
  background:
    radial-gradient(ellipse 50% 60% at 50% 35%, color-mix(in srgb, var(--accent) 7%, transparent), transparent 70%),
    radial-gradient(1px 1px at 14% 18%, #fff6 50%, transparent 51%),
    radial-gradient(1px 1px at 41% 63%, #fff4 50%, transparent 51%),
    radial-gradient(1.5px 1.5px at 77% 9%, #fff5 50%, transparent 51%),
    radial-gradient(1px 1px at 88% 52%, #fff4 50%, transparent 51%),
    radial-gradient(1px 1px at 27% 88%, #fff3 50%, transparent 51%);
}
.tree__svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.tree__grid line { stroke: var(--line-soft); stroke-dasharray: 2 6; }
.tree__grid text { font: 500 13px var(--font-mono); letter-spacing: .14em; text-transform: uppercase; fill: var(--tree-dim); text-anchor: middle; }
.tree__grid .tree__axis { text-anchor: start; }
.tree__grid line.tree__now { stroke: var(--accent); stroke-dasharray: none; opacity: .6; }
.tree__grid text.tree__now { fill: var(--accent); text-anchor: end; }
.tree stop { stop-color: var(--accent-lift, var(--accent)); }

.tree__path {
  fill: none; stroke-width: var(--sw); stroke-linecap: round;
  stroke-dasharray: 1; stroke-dashoffset: 1;
  animation: tree-draw 1.4s var(--ease-out) forwards; animation-delay: calc(.3s + var(--i) * 60ms);
  transition: opacity var(--dur-2), stroke-width var(--dur-2);
}
@keyframes tree-draw { to { stroke-dashoffset: 0; } }
.tree__kin path { fill: none; stroke: var(--tree-dim); stroke-width: 1.5; stroke-dasharray: 1 7; stroke-linecap: round; opacity: 0; transition: opacity var(--dur-3); }
.tree-sec:has(#tree-kin:checked) .tree__kin path { opacity: .8; }
.tree[data-focus] .tree__path { opacity: .1; }
.tree[data-focus] .tree__path.is-lit { opacity: 1; stroke-width: calc(var(--sw) + 1.5); }
.tree[data-focus] .tree__kin path { opacity: 0; }
.tree[data-focus] .tree__kin path.is-lit { opacity: .9; }

.tree__nodes, .tree__badges { list-style: none; margin: 0; padding: 0; }
.tnode { position: absolute; left: var(--x); top: var(--y); width: 0; height: 0; z-index: 2; animation: tree-pop .7s var(--ease-spring) both; animation-delay: calc(var(--i) * 50ms); transition: opacity var(--dur-2), filter var(--dur-2); }
@keyframes tree-pop { from { scale: 0; opacity: 0; } }
.tnode__a {
  position: absolute; left: 0; top: 0; translate: -50% -11px;
  display: grid; justify-items: center; gap: 3px;
  min-width: var(--tap); padding: 2px 4px 4px;
  text-decoration: none; text-align: center; white-space: nowrap;
  outline: none;
}
.tnode__dot {
  --c: var(--accent-lift, var(--accent));
  width: 14px; height: 14px; margin: 4px;
  border-radius: var(--marker-r); rotate: var(--marker-rot);
  background: var(--c);
  box-shadow: 0 0 0 4px color-mix(in srgb, var(--c) 22%, transparent), 0 0 20px var(--c);
  transition: transform var(--dur-3) var(--ease-spring);
}
.tnode__name {
  font-family: var(--font-display); font-weight: var(--h-weight); text-transform: var(--h-case); letter-spacing: var(--h-track);
  font-size: clamp(12px, 1.6cqi, 19px); line-height: 1;
  color: var(--tree-ink);
  text-shadow: 0 0 6px var(--tree-bg), 0 0 12px var(--tree-bg);
}
.tnode__since { font: 500 clamp(9px, .95cqi, 11px)/1.2 var(--font-mono); letter-spacing: .08em; color: var(--tree-dim); text-shadow: 0 0 6px var(--tree-bg); }
.tnode--up .tnode__a { translate: -50% calc(-100% + 11px); }
.tnode--up .tnode__dot { order: 3; }
.tnode--up .tnode__since { order: -1; }
.tnode:is(:hover, :focus-within) { z-index: 5; }
.tnode__a:is(:hover, :focus-visible) .tnode__dot, .tnode.is-self .tnode__dot { transform: scale(1.6); }
.tnode__a:is(:hover, :focus-visible) .tnode__name { text-decoration: underline 2px var(--accent-lift, var(--accent)); text-underline-offset: 5px; }
.tnode__a:focus-visible .tnode__dot { outline: 2px solid var(--tree-ink); outline-offset: 6px; }
.tree[data-focus] .tnode:not(.is-lit) { opacity: .28; filter: saturate(.2); }
.tnode.is-anc .tnode__since::before { content: "ancestor · "; color: var(--accent-lift, var(--accent)); }
.tnode.is-desc .tnode__since::before { content: "descendant · "; color: var(--accent-lift, var(--accent)); }

.tedge {
  position: absolute; left: var(--x); top: var(--y); translate: -50% -50%; z-index: 3;
  display: grid; place-items: center;
  min-width: 28px; height: 28px; padding: 0 6px;
  border: 1px solid var(--line); border-radius: 999px;
  background: var(--tree-bg);
  font: 600 12px/1 var(--font-mono); font-variant-numeric: tabular-nums;
  color: var(--tree-ink); text-decoration: none;
  transition: background var(--dur-2), color var(--dur-2), opacity var(--dur-2), scale var(--dur-2) var(--ease-spring);
}
.tedge::before { content: ""; position: absolute; inset: -8px; }   /* 44px target */
/* direction: a small arrowhead on the rim of the badge, along the thread (parent -> child) */
.tedge::after { content: ""; position: absolute; left: 50%; top: 50%; width: 0; height: 0; margin: -5px 0 0 -4px; border-block: 5px solid transparent; border-left: 8px solid var(--line); transform-origin: 4px 5px; transform: rotate(atan2(var(--dy), var(--dx))) translateX(20px); pointer-events: none; }
.tedge:is(:hover, :focus-visible)::after, .tedge.is-on::after, .tree[data-focus] .tedge.is-lit::after { border-left-color: var(--accent); }
.tedge[data-n="0"] { color: var(--tree-dim); border-style: dashed; }
.tedge:is(:hover, :focus-visible), .tedge.is-on { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); scale: 1.15; outline: none; }
.tedge:focus-visible { box-shadow: 0 0 0 3px var(--tree-bg), 0 0 0 5px var(--tree-ink); }
.tree[data-focus] .tedge:not(.is-lit) { opacity: .2; }

.tree__hint { margin: var(--space-3) 0 0; }
@media (max-width: 760px) {
  .tree { min-width: 680px; }
  .tree__hint::after { content: " Swipe the tree sideways, or read the list below."; }
}

/* bridge panel (JS) */
.tree__panel { margin-top: var(--space-5); padding: var(--space-5); border: 1px solid var(--line); border-radius: var(--r); clip-path: var(--shape); background: var(--panel); }
.tree__panel[hidden] { display: none; }
@media (prefers-reduced-motion: no-preference) { .tree__panel:not([hidden]) { animation: tree-in var(--dur-3) var(--ease-out); } }
@keyframes tree-in { from { opacity: 0; transform: translateY(12px); } }
.tree__panel-head { display: flex; justify-content: space-between; align-items: start; gap: var(--space-4); margin-bottom: var(--space-5); }
.tree__panel-head .eyebrow { margin-bottom: var(--space-2); }
.tree__panel-head .h { font-size: var(--step-2); margin: 0; }
.tree__panel-head .h a { color: var(--accent-lift, var(--accent)); text-decoration: none; }
.tree__panel-head .h a:hover { text-decoration: underline; }
.tree__panel-sub { margin: var(--space-2) 0 0; color: var(--ink-dim); max-width: 60ch; }

.tree__pair { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-3); margin-top: var(--space-5); }
.tree__pair .eyebrow { margin: 0 var(--space-2) 0 0; flex-basis: 100%; }
.tree__pair .select { width: auto; min-width: 13ch; flex: 1 1 10rem; max-width: 16rem; }
.tree__pair-and { font: 600 var(--step-1)/1 var(--font-mono); color: var(--ink-dim); }

/* ---------- lineage list ---------- */
.lineage { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-4); grid-template-columns: repeat(auto-fill, minmax(min(100%, 320px), 1fr)); }
.lin { display: grid; gap: var(--space-4); align-content: start; padding: var(--space-5); border: var(--frame-border); border-radius: var(--r); clip-path: var(--shape); background: var(--panel); color: var(--ink); scroll-margin-top: calc(var(--header-h) + var(--space-4)); }
.lin__head { display: grid; gap: var(--space-1); }
.lin__year { font: 600 var(--step--2)/1 var(--font-mono); letter-spacing: .2em; color: var(--accent); }
.lin__name { font-size: var(--step-2); margin: 0; }
.lin__name a { color: var(--head); text-decoration: none; }
.lin__name a:hover { text-decoration: underline 2px var(--accent); text-underline-offset: 5px; }
.lin__origin { font-size: var(--step--1); color: var(--ink-dim); }
.lin__rel { margin: 0; display: grid; gap: var(--space-3); }
.lin__rel > div { display: grid; grid-template-columns: 7.5em 1fr; gap: var(--space-3); align-items: baseline; }
.lin__rel dt { font: 500 var(--step--2)/1.2 var(--font-mono); letter-spacing: var(--track-label); text-transform: uppercase; color: var(--ink-dim); }
.lin__rel dd { margin: 0; align-items: center; justify-content: start; }
.lin__rel dd b { color: var(--head); }
.lin__n { display: inline-grid; place-items: center; min-width: 24px; height: 24px; padding: 0 5px; margin-left: calc(-1 * var(--space-1)); border-radius: 999px; border: 1px solid var(--line); font: 600 11px/1 var(--font-mono); color: var(--ink); text-decoration: none; position: relative; }
.lin__n::before { content: ""; position: absolute; inset: -10px -6px; }
.lin__n:hover, .lin__n:focus-visible { background: var(--accent); color: var(--accent-ink); }
.lin__none { color: var(--ink-dim); font-size: var(--step--1); }

/* ---------- family cards ---------- */
.famgrid { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-4); grid-template-columns: repeat(auto-fill, minmax(min(100%, 230px), 1fr)); }
@media (max-width: 520px) { .famgrid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-3); } .famgrid__tag { display: none; } }
.famgrid .fcard { height: 100%; }
.famgrid__tag { margin-top: var(--space-2); font-size: var(--step--1); line-height: 1.45; color: var(--ink); display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }

/* ---------- bridges ---------- */
.bridges { display: grid; gap: var(--space-4); grid-template-columns: repeat(auto-fill, minmax(min(100%, 340px), 1fr)); align-items: start; }
.bridge { padding: var(--space-5); border: 1px solid var(--line-soft); border-radius: var(--r); clip-path: var(--shape); background: var(--bg-2); scroll-margin-top: calc(var(--header-h) + var(--space-4)); }
.bridge:target { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); }
@media (prefers-reduced-motion: no-preference) { .bridge:target { animation: tree-flash 1.6s var(--ease-out); } }
@keyframes tree-flash { from { background: color-mix(in srgb, var(--accent) 22%, var(--bg-2)); } }
.bridge__h { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); margin: 0 0 var(--space-4); font: 600 var(--step-0)/1.2 var(--font-body); }
.bridge__h svg { width: 1em; height: 1em; color: var(--ink-dim); }
.bridge__h a { color: var(--accent-lift, var(--accent)); text-decoration: none; }
.bridge__h a:hover { text-decoration: underline; }
.bridge__n { margin-left: auto; font: 600 var(--step--1)/1 var(--font-mono); color: var(--ink-dim); font-variant-numeric: tabular-nums; }
.bridge__list { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-2); }
.bridge__list li { display: grid; gap: 2px; padding-left: var(--space-3); border-left: 2px solid var(--line-soft); }
.bridge__list a { color: var(--head); text-decoration: none; font-weight: 600; }
.bridge__list a:hover { text-decoration: underline var(--accent); }
.bridge__list span { font-size: var(--step--1); color: var(--ink-dim); }
.bridge__none { margin: 0; color: var(--ink-dim); font-size: var(--step--1); }

@media (prefers-reduced-motion: reduce) {
  .tree__path { animation: none; stroke-dashoffset: 0; }
  .tnode { animation: none; }
}
