/* T12: the tree page itself spans the full available width so the canvas
   can break out to a real pannable/zoomable size; the heading and toolbar
   keep the readable measure that .tree-page used to apply to everything. */
.tree-page {
  width: 100%;
  padding: clamp(1rem, 3vw, 1.75rem) clamp(1.5rem, 6vw, 4rem);
  box-sizing: border-box;
}

.tree-page > h1 {
  width: min(100%, 60rem);
  margin: 0 auto var(--space-2);
}

.tree-illustration {
  display: block;
  width: min(100%, 32rem);
  height: auto;
  margin-top: 2rem;
}

/* Toolbar (T12): search + zoom/fit/reset controls, kept at the same
   readable measure as the heading. Plain/outline styling — never the
   burgundy .button-primary fill, which is reserved for mutating actions. */
.tree-toolbar {
  display: flex;
  flex-wrap: wrap;
  /* .tree-search stacks a <label> above its <input>, while the action
     buttons have no label above them -- aligning to the end (not the
     start) puts the input and the buttons on the same visual baseline
     instead of the buttons floating above the input. */
  align-items: flex-end;
  gap: var(--space-4);
  width: min(100%, 60rem);
  margin-inline: auto;
  margin-top: var(--space-4);
}

.tree-toolbar-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2);
}

.tree-toolbar button,
.tree-boundary-control button {
  min-width: 44px;
  min-height: 44px;
  background: var(--color-ivory);
  color: var(--color-ink);
  border: 1px solid var(--color-wood-mid);
}

.tree-toolbar button:hover,
.tree-boundary-control button:hover {
  background: var(--color-parchment);
}

.tree-toolbar-focus-label {
  margin: 0;
  font-weight: 700;
  color: var(--color-wood-mid);
}

.tree-toolbar-pending {
  margin: 0;
  color: var(--color-wood-mid);
  font-size: 0.9rem;
}

/* Search control (T12) — mirrors .relationship-picker's tokens. */
.tree-search {
  display: grid;
  gap: 0.4rem;
  max-width: 24rem;
}

.tree-search input {
  min-height: 44px;
  width: 100%;
  padding: 0.7rem;
  border: 1px solid var(--color-wood-mid);
  border-radius: var(--radius-sm);
  background: white;
  color: inherit;
  font: inherit;
}

.tree-search-status {
  font-size: 0.85rem;
  color: var(--color-wood-mid);
}

/* Always in the DOM (aria-live region), but empty until a search runs --
   collapse its grid row then so the search box's own bottom edge lines up
   with the toolbar buttons (.tree-toolbar aligns everything to flex-end). */
.tree-search-status:empty {
  display: none;
}

.tree-search-results {
  display: grid;
  gap: var(--space-1);
  margin: 0;
  padding: 0;
  list-style: none;
  max-height: 12rem;
  overflow-y: auto;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
}

.tree-search-results button {
  width: 100%;
  text-align: left;
  padding: 0.5rem 0.7rem;
  border: 0;
  background: white;
  color: inherit;
  font-weight: 400;
}

.tree-search-results button:hover {
  background: var(--color-parchment);
}

/* Boundary loading affordances (T12) — user-triggered, localized status. */
.tree-boundary-control {
  width: min(100%, 60rem);
  margin: var(--space-2) auto;
  text-align: center;
}

/* Matches .genealogy-tree-scroll's own margin-top: var(--space-4) above it,
   so the gap reads consistently on both sides of the canvas instead of the
   tighter var(--space-2) squeezing this control against the scroll edge. */
.tree-boundary-control--descendants {
  margin-top: var(--space-4);
}

@media (max-width: 40rem) {
  /* Mirrors --breakpoint-tablet (640px): the toolbar stacks but every
     control stays visible — never collapsed behind a menu. Stacked, the
     end-alignment used for the row layout would right-align each block
     instead of the intended left edge, so it's reset here. */
  .tree-toolbar {
    flex-direction: column;
    align-items: flex-start;
  }
}

/* Renderer (T11B) — SVG tree, scrolls horizontally instead of shrinking.
   T12: also the pannable/zoomable canvas region, so it breaks out to fill
   the available viewport width instead of the narrow reading column.
   Sized to leave room for the header/title/toolbar above it within a
   typical viewport (~50-60vh gives content above room for ~40vh before the
   whole page needs to scroll) -- content beyond what fits pans/zooms inside
   the canvas itself rather than growing the outer page. */
.genealogy-tree-scroll {
  position: relative;
  width: 100%;
  height: clamp(22rem, 56vh, 38rem);
  overflow: hidden;
  margin-top: var(--space-4);
  box-sizing: border-box;
}

/* "More content below" cue: the tree canvas is a fixed-height pannable
   viewport (panning is the intended model, not an auto-growing container —
   see docs/06-ui-ux.md), so a fade at the bottom edge signals there may be
   more of the tree to reach by panning/zooming instead of implying the
   view already shows everything. Pointer-events: none so it never
   intercepts pan gestures or clicks on the SVG beneath it. */
.genealogy-tree-scroll::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 2.5rem;
  pointer-events: none;
  border-bottom-left-radius: var(--radius-md);
  border-bottom-right-radius: var(--radius-md);
  background: linear-gradient(to bottom, transparent, var(--color-ivory));
}

.genealogy-tree-svg {
  display: block;
  width: 100%;
  height: 100%;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-ivory);
  box-sizing: border-box;
  transition: border-color 120ms ease;
  /* Pan gestures are handled by d3-zoom on this element only; scoping
     touch-action here (not on the page) keeps normal page scroll working
     everywhere outside the visibly bounded canvas. */
  touch-action: none;
}

.genealogy-tree-svg:hover {
  border-color: var(--color-wood-mid);
}

.genealogy-tree-scroll:focus-visible .genealogy-tree-svg {
  outline: var(--focus-ring);
  outline-offset: 2px;
}

.tree-connector-line,
.tree-connector-path,
.tree-connector-line-outline,
.tree-connector-path-outline {
  fill: none;
  stroke-linecap: round;
}

/* Two independent color axes, kept deliberately non-overlapping:
   -- relationship TYPE: .tree-connector-line (a marriage/partnership bond)
      is always --color-marriage-gold, no matter whose lineage it's in --
      so a marriage never gets confused for a parent-child link by color.
   -- relationship ROLE (.tree-connector-path only, parent-child links):
      Italian flag colors for context/parent/descendant relative to the
      focused person -- white/context, red/ancestors (parent), green/
      children (descendant).
   Each colored line sits on top of a wider dark "outline" copy of the same
   line (rendered first in ConnectorLayer.jsx) so it reads as a bordered
   ribbon against the ivory canvas instead of blending into it -- white in
   particular would be invisible without that border. */
/* Neon-style glow on every colored connector (not the black outline copies)
   -- each role/type glows its own color, so the whole tree reads as lit up
   rather than just the marriage line standing alone. */
.tree-connector-line,
.tree-connector-path {
  filter:
    drop-shadow(0 0 1px currentcolor)
    drop-shadow(0 0 2.5px currentcolor);
}

.tree-connector-line {
  stroke: var(--color-marriage-gold);
  color: var(--color-marriage-gold);
  stroke-width: 2.5px;
}

.tree-connector-line-outline {
  stroke: var(--color-line-outline);
  stroke-width: 4.5px;
}

.tree-connector-path {
  stroke: var(--color-italy-white);
  color: var(--color-italy-white);
  stroke-width: 1.5px;
}

.tree-connector-path-outline {
  stroke: var(--color-line-outline);
  stroke-width: 3.5px;
}

/* Barber-pole stripes (see the <pattern> in ConnectorLayer.jsx) on every
   parent-child connector, ascendant or descendant -- keeps the Italian
   flag motif consistent in both directions instead of only on children.
   Less glow than gold/marriage since the stripes already carry visual
   interest on their own; the tinted drop-shadow still leans red "up" /
   green "down" so direction stays readable at a glance. */
.tree-connector-path.tree-connector--parent {
  stroke: url(#tree-connector-italy-stripes);
  color: var(--color-italy-red);
  stroke-width: 2.5px;
  filter: drop-shadow(0 0 1.5px var(--color-italy-red));
}

.tree-connector-path-outline.tree-connector--parent {
  stroke-width: 4.5px;
}

.tree-connector-path.tree-connector--descendant {
  stroke: url(#tree-connector-italy-stripes);
  color: var(--color-italy-green);
  stroke-width: 3px;
  filter: drop-shadow(0 0 1.5px var(--color-italy-green));
}

.tree-connector-path-outline.tree-connector--descendant {
  stroke-width: 5px;
}

.tree-connector-stripe--green { fill: var(--color-italy-green); }
.tree-connector-stripe--white { fill: var(--color-italy-white); }
.tree-connector-stripe--red { fill: var(--color-italy-red); }

/* Small filled joints at each partnership/branch point -- what turns a
   network of thin strokes into a tree that reads as branches rather than a
   wiring diagram. */
.tree-connector-joint {
  fill: var(--color-italy-white);
  stroke: var(--color-line-outline);
  stroke-width: 1px;
}

.tree-connector-joint.tree-connector--parent {
  fill: var(--color-italy-green);
}

.tree-connector-joint.tree-connector--descendant {
  fill: var(--color-italy-red);
}

/* Interlocking rings at the bond's midpoint -- reads as "married" on sight
   (unlike a plain marker, which only means that once you already know the
   color convention). Hollow/outlined like an actual ring, always gold to
   match .tree-connector-line -- a marriage stays a marriage regardless of
   lineage role. */
.tree-connector-partner-mark circle {
  fill: none;
  stroke: var(--color-marriage-gold);
  stroke-width: 1.75px;
}

.tree-connector-partner-mark {
  filter:
    drop-shadow(0 0 0.75px var(--color-line-outline))
    drop-shadow(0 0 1px var(--color-marriage-gold))
    drop-shadow(0 0 2.5px var(--color-marriage-gold));
}

/* NODE_WIDTH/NODE_HEIGHT (computeLayout.js) size the SVG foreignObject that
   hosts this card, but a two-line name can need more than NODE_HEIGHT of
   room. Blink/WebKit clip foreignObject content to its box by default, which
   silently cut off wrapped names -- .tree-node-foreign opts back into
   visible overflow so the card grows into the ROW_HEIGHT - NODE_HEIGHT
   (240 - 190 = 50px) gap already reserved between generations instead of
   truncating. */
.tree-node-foreign {
  overflow: visible;
}

/* Node card (precedent: .person-card in people.css) */
.tree-node-inner {
  position: relative;
  display: grid;
  gap: var(--space-1);
  width: 100%;
  min-height: 100%;
  padding: var(--space-3);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-ivory);
  text-align: center;
  box-sizing: border-box;
}

.tree-node--focus .tree-node-inner {
  border: 2px solid var(--color-burgundy);
  background: var(--color-ivory);
}

.tree-node--parent .tree-node-inner {
  border-color: var(--color-border);
  background: var(--color-parchment);
}

.tree-node--parent .tree-node-name,
.tree-node--parent .tree-node-years {
  color: var(--color-wood-mid);
}

.tree-node--parent .tree-node-photo {
  filter: saturate(0.7) contrast(0.9);
}

.tree-node--parent .tree-node-inner:hover,
.tree-node--parent .tree-node-inner:focus-within {
  border-color: var(--color-wood-mid);
  background: var(--color-ivory);
}

.tree-node--parent .tree-node-inner:hover .tree-node-name,
.tree-node--parent .tree-node-inner:focus-within .tree-node-name {
  color: var(--color-burgundy);
}

.tree-node--parent .tree-node-inner:hover .tree-node-photo,
.tree-node--parent .tree-node-inner:focus-within .tree-node-photo {
  filter: none;
}

.tree-node--descendant .tree-node-inner {
  border-color: var(--color-wood-mid);
}

/* Spouse-of-a-child (not blood Albiero lineage): gold border + faint gold
   wash, matching the marriage-gold used on the connector lines/rings, so
   the same "married in" identity reads on the card itself, not just the
   line connecting it. */
.tree-node--descendant-partner .tree-node-inner {
  border-color: var(--color-marriage-gold);
  background: linear-gradient(135deg, rgb(255 195 0 / 14%), transparent 65%), var(--color-ivory);
}

.tree-node-partner-badge {
  position: absolute;
  top: 0.3rem;
  right: 0.3rem;
  width: 1.1rem;
  height: 1.1rem;
}

.tree-node-partner-badge circle {
  fill: none;
  stroke: var(--color-marriage-gold);
  stroke-width: 1.6;
  filter: drop-shadow(0 0 0.5px var(--color-line-outline));
}

.tree-node-partner-label {
  display: block;
  font-size: 0.7rem;
  font-weight: 700;
  color: var(--color-marriage-gold);
  /* Subtle outline (not a heavy blurred glow) so the small text stays crisp
     while retaining contrast against the gold-tinted card background. */
  -webkit-text-stroke: 0.35px var(--color-line-outline);
  text-shadow:
    0 0 0.75px var(--color-line-outline),
    0 0 0.5px var(--color-line-outline);
}

/* Quick-add-relationship corner control (viewer-authorized nodes only).
   Top-left corner, mirroring .tree-node-partner-badge's top-right position
   so the two never collide (partner badge only shows on descendant-partner
   nodes; this shows on every node the viewer can manage). The visible
   circle is compact (~1.75rem) but the button itself is a full 44px hit
   area via transparent padding/hit-slop, same convention as every other
   interactive control in this app (see .tree-node-name/.tree-node-focus-trigger
   above) -- it just doesn't crowd the 152px-wide card visually. */
.tree-node-quick-add {
  all: unset;
  position: absolute;
  top: 0;
  left: 0;
  width: 44px;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  box-sizing: border-box;
}

.tree-node-quick-add-icon {
  width: 1.75rem;
  height: 1.75rem;
  pointer-events: none;
}

.tree-node-quick-add-icon circle {
  fill: var(--color-burgundy);
  stroke: var(--color-line-outline);
  stroke-width: 0.5;
}

.tree-node-quick-add-icon line {
  stroke: white;
  stroke-width: 2;
  stroke-linecap: round;
}

.tree-node-quick-add:focus-visible {
  outline: var(--focus-ring);
  outline-offset: 1px;
  border-radius: 50%;
}

/* Hover-capable devices: near-invisible until the card itself is hovered or
   has focus-within, same fade-in pattern .tree-node--parent already uses on
   hover/focus-within above. Keyboard focus on the control itself must still
   reveal it even before hover, since it can otherwise be tabbed to while
   invisible. */
@media (hover: hover) {
  .tree-node-quick-add {
    opacity: 0.02;
    transition: opacity 120ms ease;
  }

  .tree-node-inner:hover .tree-node-quick-add,
  .tree-node-inner:focus-within .tree-node-quick-add,
  .tree-node-quick-add:focus-visible {
    opacity: 1;
  }
}

/* Touch/coarse-pointer devices have no hover state to reveal it on, so it
   stays visible (slightly less than full opacity, per spec) instead of
   being permanently unreachable. */
@media (hover: none) {
  .tree-node-quick-add {
    opacity: 0.85;
  }
}

.tree-node-photo {
  width: 72px;
  height: 72px;
  object-fit: cover;
  border-radius: var(--radius-sm);
  display: block;
  margin-inline: auto;
}

.tree-node-name {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  min-width: 44px;
  min-height: 44px;
  color: var(--color-burgundy);
  font-weight: 700;
  line-height: 1.15;
  text-decoration: none;
  overflow-wrap: anywhere;
}
.tree-node-name:hover { text-decoration: underline; }

.tree-node-years {
  display: block;
  color: var(--color-wood-mid);
  /* Keep the birth/death years and age together inside the wider card. */
  max-width: 100%;
  font-size: 0.8rem;
  line-height: 1.15;
  white-space: nowrap;
  overflow: visible;
}

/* Focus-here control (T12) — wraps the non-name parts of the card body; the
   name stays its own separately reachable Link (.tree-node-name below). */
.tree-node-focus-trigger {
  all: unset;
  display: grid;
  align-content: center;
  gap: var(--space-1);
  width: 100%;
  min-width: 44px;
  min-height: 44px;
  cursor: pointer;
}
.tree-node-focus-trigger:focus-visible {
  outline: var(--focus-ring);
  outline-offset: 2px;
}

/* Visually-hidden linear fallback — stays in the accessibility tree (not
   display:none) while being removed from the visual flow. */
.genealogy-tree-fallback {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* Defense-in-depth: useTreeViewport.js already skips d3 .transition() calls
   when prefers-reduced-motion is set; this guards any CSS-only transition
   on the canvas for the same preference. */
@media (prefers-reduced-motion: reduce) {
  .genealogy-tree-svg,
  .genealogy-tree-svg * {
    transition: none !important;
  }
}

@media (max-width: 40rem) {
  .genealogy-tree-scroll {
    height: 28rem;
  }
}

/* Quick-add-relationship dialog (native <dialog>, precedent: .relationship-editor
   in people.css for the reused RelationshipEditor's own chrome). */
.quick-add-relationship-dialog {
  width: min(90vw, 28rem);
  padding: var(--space-4);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-ivory);
  color: var(--color-ink);
}

.quick-add-relationship-dialog::backdrop {
  background: rgb(43 27 18 / 55%);
}

.quick-add-relationship-dialog h2 {
  margin-top: 0;
  font-family: var(--font-serif);
}

.quick-add-relationship-kind-picker {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-3);
  margin-bottom: var(--space-3);
}

.quick-add-relationship-kind-picker label {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  min-height: 44px;
}
