/* Globe app: the tree. Portraits at any size (.av-s), couple portraits, the canvas on the stage with its floating
   controls, the panel beside it, and the branch pager on phones. Rings and the lines inside a branch wear the branch
   hue; the bracket from Opa & Oma stays neutral. */
:root { --line: #c3c9d1; }
:root[data-theme="dark"] { --line: #3f4650; }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) { --line: #3f4650; } }

/* ---------- portraits ---------- */
.av.av-s { width: var(--s); height: var(--s); font-size: calc(var(--s) * 0.36); letter-spacing: 0.01em; position: relative; }
.av .mono { line-height: 1; }
.av.has-ring { box-shadow: 0 0 0 calc(var(--s) * 0.028 + 1px) var(--ring-gap, var(--cell)), 0 0 0 calc(var(--s) * 0.028 + 2.5px) var(--c); }
.face { display: inline-flex; align-items: center; justify-content: center; border-radius: 50%; color: inherit; text-decoration: none; -webkit-touch-callout: none; }
.face:focus-visible { outline-offset: 3px; border-radius: 50%; }
.face .av { transition: transform 200ms var(--ease), box-shadow 240ms var(--ease); }
.face:active .av { transform: scale(0.96); }
@media (hover: hover) { .face:hover .av { transform: scale(1.04); } }
.face.is-sel .av { box-shadow: 0 0 0 3px var(--ring-gap, var(--cell)), 0 0 0 6px var(--accent); }
/* night: the branch ring is drawn at full chroma and, on the stage and the branch cards, glows softly in its own hue,
   like the family's places on the night globe; the inner ring of the monogram steps aside for it */
:root[data-scheme="dark"] .av.has-ring { --av-rw: 0px; box-shadow: 0 0 0 calc(var(--s) * 0.028 + 1px) var(--ring-gap, var(--cell)),
  0 0 0 calc(var(--s) * 0.028 + 3px) var(--c), 0 0 14px 1px color-mix(in srgb, var(--c) var(--glow, 0%), transparent); }
:root[data-scheme="dark"] .tn-faces .av:not(.has-ring) { box-shadow: 0 0 0 2px var(--ground, transparent), 0 0 12px color-mix(in srgb, var(--c) var(--glow, 0%), transparent); }
:root[data-scheme="dark"] .face.is-sel .av { box-shadow: 0 0 0 3px var(--ring-gap, var(--cell)), 0 0 0 6px var(--accent); }
.face.is-found .av { animation: found 1100ms var(--ease) 1; }
@keyframes found { 0%, 100% { transform: none; } 30% { transform: scale(1.12); } 60% { transform: scale(0.98); } }
.duo { --ground: var(--cell); position: relative; display: block; flex: none; }
.duo > .av, .duo > .face { position: absolute; }
.duo > .face { display: grid; place-items: center; }
.duo .duo-a { z-index: 1; }
.duo .duo-b { z-index: 2; }
.duo .av.duo-b, .duo .duo-b .av { box-shadow: 0 0 0 2px var(--ground); }
.duo.has-partner .duo-a .mono { transform: translate(calc(var(--S) * -0.07), calc(var(--S) * -0.06)); }
.duo-join { position: absolute; height: 0; border-top: 1.5px dashed var(--line); z-index: 0; }

/* ---------- the canvas on the stage ---------- */
.stage .tree-vp { position: absolute; inset: 0; overflow: hidden; touch-action: none; cursor: grab; user-select: none; -webkit-user-select: none; --ring-gap: var(--stage); --glow: 35%; }
.tree-vp.is-dragging { cursor: grabbing; }
.tree-vp:focus-visible { outline: none; box-shadow: inset 0 0 0 3px var(--accent-ring); }
.tree-canvas { position: absolute; left: 0; top: 0; transform-origin: 0 0; will-change: transform; }
.tree-links { position: absolute; left: 0; top: 0; overflow: visible; pointer-events: none; }
.tree-links path { fill: none; stroke: var(--line); stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
.tree-links path[class*="hue-"] { stroke: var(--c); stroke-width: 1.75; opacity: 0.62; }
.tree-links.in { animation: tree-in 420ms var(--ease) both; }
@keyframes tree-in { from { opacity: 0; } }
.tn { position: absolute; display: flex; flex-direction: column; align-items: center; transition: transform 420ms var(--ease), opacity 320ms var(--ease); }
.tn-faces { position: relative; flex: none; align-self: flex-start; }
.tn-faces.tn-pair { align-self: center; display: flex; align-items: center; }
.tn-pair-join { width: 20px; height: 1.5px; background: var(--line); }
.tn .duo { --ground: var(--stage); }
.tn-label { display: flex; flex-direction: column; align-items: center; margin-top: 8px; text-align: center; max-width: 100%; transition: opacity 200ms var(--ease); }
.tn-n1 { font-size: 18px; line-height: 23px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; }
.tn.is-root .tn-n1 { font-size: 20px; letter-spacing: -0.01em; }
.tn-n2 { font-size: 16px; line-height: 21px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; }
.tn-meta { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; max-width: 100%;
  font-size: 15px; line-height: 19px; color: var(--label-2); font-variant-numeric: tabular-nums; text-wrap: balance; }
.tn .dagger, .pp-n .dagger, .ol-n .dagger { font-size: 0.8em; font-weight: 500; color: var(--label-2); }
/* semantic zoom: further away, the tree keeps its faces and first names and lets the small print go */
.is-far .tn-n2, .is-far .tn-meta { opacity: 0; }
.is-tiny .tn-label, .is-tiny .ttoggle { opacity: 0; pointer-events: none; }
.ttoggle { display: grid; place-items: center; min-width: 56px; height: 52px; border-radius: 22px; color: var(--label); text-decoration: none; transition: opacity 200ms; }
.tt-pill { display: inline-flex; align-items: center; gap: 6px; height: 40px; padding: 0 12px 0 5px; border-radius: 999px;
  background: var(--cell); color: var(--label); font-size: 15px; font-weight: 600; box-shadow: 0 0 0 0.5px var(--sep), var(--shadow-1);
  transition: transform 160ms var(--ease), background-color 160ms; }
.tt-pill .num { min-width: 1ch; }
.tt-pill .ph { font-size: 15px; color: var(--label-2); }
.tt-faces { display: inline-flex; align-items: center; }
/* the grandchildren in a pill: up to three 32px faces (two in a narrow column), each a photo or two 13px initials on
   the branch tint, overlapping only by their knockout ring so no letter is cut (never under 27px and 11px on screen,
   since the stage never opens below 0.85). Zoomed further out the faces step aside and the count remains: a disc is
   never shown without the person in it. */
.tt-faces .av { --av-rw: 1.5px; box-shadow: 0 0 0 2px var(--cell); }
.tt-faces .av.av-s { font-size: 13px; font-weight: 600; letter-spacing: -0.01em; }
.tt-faces .av + .av { margin-left: -3px; }
.tree-canvas.is-far .tt-faces { display: none; }
.tree-canvas.is-far .tt-pill { padding-left: 12px; }
.ttoggle.is-open .tt-pill { padding-left: 12px; background: var(--fill); box-shadow: none; }
.tbranch .tt-pill { box-shadow: inset 0 0 0 1.5px color-mix(in srgb, var(--c) 55%, transparent), var(--shadow-1); }
:root[data-scheme="dark"] .tbranch .tt-pill { box-shadow: inset 0 0 0 1.5px color-mix(in srgb, var(--c) 80%, transparent), var(--shadow-1); }
.tbranch .tt-pill .ph { color: var(--c-ink); }
.ttoggle:active .tt-pill { transform: scale(0.95); }
.ttoggle:focus-visible { outline: none; }
.ttoggle:focus-visible .tt-pill { outline: 3px solid var(--accent-ring); outline-offset: 2px; }
@media (hover: hover) { .ttoggle:hover .tt-pill { background: var(--cell-hover); } }
.tree-ctl { position: absolute; z-index: 3; top: calc(var(--safe-t) + 12px); right: 16px; width: 48px; display: flex; flex-direction: column; border-radius: 14px; overflow: hidden; }
.tree-ctl .ctl:disabled { opacity: 0.35; }

/* ---------- the panel beside the stage ---------- */
.tree-depth { margin: 20px var(--gutter) 0; }
.tree-depth .setting-label { margin: 0 4px 8px; }
.tree-help { margin-top: 12px; }
.br-row { --inset: 84px; min-height: 68px; }
.br-row .duo-wrap { display: grid; place-items: start; width: 58px; flex: none; }
.br-row .duo { --ground: var(--cell); }
.br-row .row-title { font-weight: 600; }
.br-row.is-current { background: var(--cell-press); }
.br-row > .ph { flex: none; font-size: 17px; color: var(--chev); }
.br-row.is-current > .ph { color: var(--accent); font-size: 20px; }

/* ---------- the pager (phones and short landscape) ---------- */
.pager { padding: 8px var(--gutter) 0; }
.pg-bar { display: grid; gap: 10px; margin-bottom: 8px; }
.pg-row { display: flex; align-items: center; justify-content: space-between; gap: 8px; max-width: 560px; width: 100%; margin: 0 auto; }
.pg-pick { flex: 1; min-width: 0; display: inline-flex; align-items: center; justify-content: center; gap: 8px; min-height: 44px; padding: 0 14px;
  border-radius: var(--rad-cell); background: var(--cell); color: var(--label); font-size: var(--s-body); font-weight: 600; transition: transform 160ms var(--ease); }
.pg-pick .pg-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pg-pick .ph { font-size: 18px; color: var(--label-2); }
.pg-pick:active { transform: scale(0.98); }
.pg-arrow { background: var(--cell); }
.pg-dots { display: flex; justify-content: center; gap: 7px; }
.pg-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--c, var(--label-2)); opacity: 0.4; transition: opacity 200ms, transform 200ms var(--ease); }
.pg-dot.is-on { opacity: 1; transform: scale(1.3); }
.pg-page { touch-action: pan-y; transition: transform 380ms var(--ease), opacity 280ms var(--ease); }
.pp-head { --ring-gap: var(--cell); display: grid; justify-items: center; gap: 4px; margin: 12px 0 8px; padding: 24px 16px 20px; text-align: center;
  border-radius: var(--rad-cell); background: linear-gradient(180deg, color-mix(in srgb, var(--c) 10%, var(--cell)), var(--cell) 70%); }
/* night: the card's hue is light falling from the top, not a dark tint of it */
:root[data-scheme="dark"] .pp-head { --glow: 35%; background: radial-gradient(ellipse 72% 150px at 50% 0, color-mix(in oklab, var(--c) 16%, transparent), transparent 100%) no-repeat, var(--cell); }
/* Opa & Oma's card is the plain cool cell; their gold is only in the rings and ink of their portraits */
.pp-head.hue-f, :root[data-scheme="dark"] .pp-head.hue-f { background: var(--cell); }
.pp-title { margin-bottom: 14px; font-size: var(--s-t2); line-height: var(--l-t2); font-weight: 700; }
.pp-couple { display: flex; align-items: center; justify-content: center; }
.pp-join { width: 20px; height: 1px; background: var(--line); }
.pp-join.is-ended { height: 0; border-top: 1.5px dashed var(--line); background: none; }
.pp-names { display: flex; justify-content: center; gap: 8px; margin-top: 10px; width: 100%; }
.pp-name { display: grid; align-content: start; gap: 1px; flex: 1 1 0; min-height: 44px; max-width: 200px; padding: 4px; border-radius: var(--rad-thumb); text-align: center; color: var(--label); text-decoration: none; }
.pp-name:active { background: var(--cell-press); }
@media (hover: hover) { .pp-name:hover { background: var(--cell-hover); } }
.pp-n { font-size: var(--s-body); line-height: var(--l-body); font-weight: 600; text-wrap: balance; }
.pp-s { font-size: var(--s-sub); line-height: var(--l-sub); color: var(--label-2); }
.pp-married { margin-top: 8px; font-size: var(--s-body); line-height: 24px; color: var(--label-2); text-wrap: balance; }
.pp-married:empty { display: none; }
.pp-count { font-size: var(--s-sub); color: var(--label-2); }
.br-list { margin: 24px 0 0; }
.pager .br-list .group-title { margin-left: 4px; }
/* outline: a hairline in the branch hue for each family, a soft elbow into every child */
.ol { display: grid; gap: 4px; margin: 8px 0 0; padding: 0; list-style: none; }
.ol-item > .ol-sub { margin: 4px 0 0 36px; }
.ol-sub .ol-item > .ol-sub { margin-left: 32px; }
.ol-item { position: relative; padding-left: 22px; --ol-line: color-mix(in srgb, var(--c) 55%, var(--line)); }
.ol-item::before { content: ""; position: absolute; left: 0; top: -4px; bottom: 0; border-left: 1.5px solid var(--ol-line); }
.ol-item:last-child::before { bottom: auto; height: 38px; border-bottom: 1.5px solid var(--ol-line); border-bottom-left-radius: 12px; width: 18px; }
.ol-item:not(:last-child)::after { content: ""; position: absolute; left: 0; top: 33px; width: 18px; border-top: 1.5px solid var(--ol-line); }
.ol > .ol-item:first-child::before { top: -8px; }
.ol-unit { --ring-gap: var(--cell); display: flex; align-items: center; gap: 10px; min-height: 68px; padding: 8px 10px; border-radius: var(--rad-cell); background: var(--cell); }
.ol-unit .duo { --ground: var(--cell); }
.ol-sub .ol-unit { min-height: 60px; }
.ol-faces { display: flex; align-items: center; flex: none; }
.ol-text { display: grid; gap: 1px; flex: 1; min-width: 0; min-height: 44px; padding: 2px 4px; border-radius: var(--rad-thumb); text-align: left; color: var(--label); text-decoration: none; }
.ol-text:active { background: var(--cell-press); }
@media (hover: hover) { .ol-text:hover { background: var(--cell-hover); } }
.ol-n { font-size: var(--s-body); line-height: var(--l-body); font-weight: 600; overflow-wrap: anywhere; }
.ol-s { font-size: var(--s-sub); line-height: var(--l-sub); }
.ol-m { font-size: var(--s-sub); line-height: var(--l-sub); color: var(--label-2); }
.ol-unit.is-found { animation: found-row 1400ms var(--ease) 1; }
@keyframes found-row { 0% { box-shadow: 0 0 0 0 var(--accent-soft); } 25% { box-shadow: 0 0 0 4px var(--accent); } 100% { box-shadow: 0 0 0 0 transparent; } }
/* short screens: a wide sheet reads each family head sideways, so the tree starts at once; in the narrow panel of a
   phone on its side the head stays stacked, only smaller */
@media (max-height: 500px) {
  :root[data-layout="panel"] .pp-head { padding: 16px 12px 14px; }
  :root[data-layout="panel"] .pp-head .pp-couple .av { --s: 64px !important; }
  :root[data-layout="panel"] .pp-title { margin-bottom: 8px; }
}
@media (max-height: 500px) {
  :root[data-layout="sheet"] .pp-head { grid-template-columns: auto minmax(0, 1fr); column-gap: 20px; row-gap: 2px; justify-items: start; align-items: center; margin-top: 4px; padding: 16px 20px; text-align: left; }
  :root[data-layout="sheet"] .pp-head > * { grid-column: 2; }
  :root[data-layout="sheet"] .pp-head > .pp-couple { grid-column: 1; grid-row: 1 / span 5; }
  :root[data-layout="sheet"] .pp-head .pp-couple .av { --s: 64px !important; }
  :root[data-layout="sheet"] .pp-title { margin-bottom: 2px; }
  :root[data-layout="sheet"] .pp-names { justify-content: flex-start; gap: 16px; margin-top: 0; }
  :root[data-layout="sheet"] .pp-name { flex: 0 1 auto; max-width: none; padding: 2px 0; text-align: left; }
  :root[data-layout="sheet"] .pp-married { margin-top: 2px; }
}
