.tree-container {
  position: absolute;
  inset: 0;
  overflow: hidden;
  background-color: var(--color-bg);
  /* Tree-canvas background is a layered system:
     1. `--tree-bg-image` — defaults to `none`, becomes `url(../assets/tree-bg.webp)`
        (or whatever the user supplies) for the optional heartwarming backdrop
        described in CLAUDE.md (#26). We keep the dot pattern beneath it so
        even when the backdrop is set, the dotted "graph paper" feel survives.
     2. The brass-tinted dot pattern — the default we shipped previously.
     This avoids "background just changed without my say-so" surprises and
     lets the user drop a generated image in by adding a single CSS rule. */
  --tree-bg-image: none;
  background-image:
    var(--tree-bg-image),
    radial-gradient(circle at 1px 1px, rgba(13, 94, 74, 0.07) 1px, transparent 0);
  background-size: cover, 26px 26px;
  background-position: center, top left;
  background-repeat: no-repeat, repeat;
  /* Cursor lives on the container so it stays visible across SVG paint
     gaps, zoom transitions, and re-renders. The SVG inherits unless a
     specific element overrides (nodes get `pointer`). */
  cursor: grab;
}

.tree-container:active {
  cursor: grabbing;
}

.tree-svg {
  width: 100%;
  height: 100%;
  cursor: inherit;
  display: block;
}

.tree-viewport,
.tree-link {
  cursor: inherit;
}

.tree-controls {
  position: absolute;
  bottom: var(--space-md);
  right: var(--space-md);
  display: flex;
  flex-direction: column;
  gap: var(--space-xxs);
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-xxs);
  box-shadow: var(--shadow-md);
  z-index: var(--z-base);
}

.tree-controls__btn {
  width: 36px;
  height: 36px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-sm);
  font-size: var(--font-size-md);
  color: var(--color-text);
  transition: background-color var(--transition-fast);
}

.tree-controls__btn:hover {
  background-color: var(--color-surface-alt);
}

.tree-node {
  cursor: pointer;
}

.tree-node__rect {
  fill: var(--color-node-fill);
  stroke: var(--color-node-stroke);
  stroke-width: 1.5;
  rx: 10;
  ry: 10;
  transition: stroke var(--transition-fast), filter var(--transition-fast);
  filter: drop-shadow(0 1px 3px rgba(0, 0, 0, 0.08));
}

/* Family-distinct colour: --node-hue is set per-node by tree.js#render when
   there are 2+ disconnected family components. A subtle outline tint + a
   barely-there fill wash keeps the canvas readable while making "these two
   are not in the same family" instantly visible. */
.tree-node[style*="--node-hue"] .tree-node__rect {
  stroke: hsl(var(--node-hue), 48%, 34%);
  fill: hsl(var(--node-hue), 36%, 97%);
}

.tree-node[style*="--node-hue"] .tree-node__photo {
  fill: hsl(var(--node-hue), 36%, 92%);
}

.tree-node[style*="--node-hue"] .tree-node__photo-fallback {
  fill: hsl(var(--node-hue), 42%, 28%);
}

.tree-node:hover .tree-node__rect {
  filter: drop-shadow(0 4px 8px rgba(0, 0, 0, 0.16));
}

.tree-node--selected .tree-node__rect {
  stroke-width: 2.5;
}

.tree-node--deceased .tree-node__rect {
  fill: var(--color-node-deceased);
}

.tree-node--pending .tree-node__rect {
  stroke: var(--color-node-stroke-pending);
  stroke-dasharray: 4 3;
}

.tree-node--placeholder .tree-node__rect {
  fill: var(--color-surface-alt);
  stroke: var(--color-border-strong);
  stroke-dasharray: 3 3;
}

.tree-node__photo {
  fill: var(--color-accent-soft);
}

.tree-node__photo-fallback {
  font-family: var(--font-serif);
  font-size: 14px;
  fill: var(--color-accent);
  text-anchor: middle;
  dominant-baseline: middle;
  pointer-events: none;
}

.tree-node__name {
  font-family: var(--font-sans);
  font-size: 13px;
  font-weight: var(--font-weight-medium);
  fill: var(--color-text);
  text-anchor: start;
  pointer-events: none;
}

.tree-node__dates {
  font-family: var(--font-sans);
  font-size: 11px;
  fill: var(--color-text-muted);
  text-anchor: start;
  pointer-events: none;
}

.tree-link {
  fill: none;
  stroke: var(--color-link);
  stroke-width: 1.5;
}

/* Lineage-coloured parent-child link: when `--link-hue` is set on the path
   element by `tree.js#render` we tint the line with the parent's lineage
   hue so the canvas reads as two coloured lines converging into the
   (blended-tone) child node. Saturation / lightness kept moderate so the
   lines don't dominate the nodes — the hue is informational, not loud. */
.tree-link[style*="--link-hue"] {
  stroke: hsl(var(--link-hue), 32%, 48%);
}

/* Pets badge — top-right corner of a person node when they own one or
   more pets. Brass tint to match the pet brand colour; the label is a
   paw emoji + count (just "🐾" when only one pet). Clicking opens the
   pet's panel directly (single pet) or a popover (multi-pet). */
.tree-node__pets-badge {
  pointer-events: all;
}

.tree-node__pets-badge:hover .tree-node__pets-badge-bg {
  filter: brightness(0.95);
}

.tree-node__pets-badge-bg {
  fill: var(--color-highlight-soft);
  stroke: var(--color-highlight);
  stroke-width: 1.25;
  transition: filter var(--transition-fast);
}

.tree-node__pets-badge-label {
  font-family: var(--font-sans);
  font-size: 10px;
  font-weight: var(--font-weight-medium);
  fill: var(--color-highlight);
  pointer-events: none;
}

.tree-node__collapse-badge-bg {
  fill: var(--color-accent);
  stroke: var(--color-surface);
  stroke-width: 1.5;
}

.tree-node__collapse-badge-label {
  font-family: var(--font-sans);
  font-size: 10px;
  font-weight: var(--font-weight-bold);
  fill: var(--color-surface);
  pointer-events: none;
}

.tree-node[style*="--node-hue"] .tree-node__collapse-badge-bg {
  fill: hsl(var(--node-hue), 48%, 34%);
}

.tree-link-icon {
  pointer-events: none;
}

.tree-link-icon__badge {
  fill: var(--color-bg);
  stroke: var(--color-border-strong);
  stroke-width: 1;
}

.tree-link-icon--partnership .tree-link-icon__glyph {
  color: var(--color-accent);
}

.tree-link-icon--partnership-divorced .tree-link-icon__glyph,
.tree-link-icon--partnership-separated .tree-link-icon__glyph {
  color: var(--color-highlight);
}

.tree-link-icon--parent-child .tree-link-icon__glyph {
  color: var(--color-text-muted);
}

.tree-link-icon--ownership .tree-link-icon__glyph {
  color: var(--color-highlight);
}

.tree-link--partnership {
  stroke: var(--color-accent);
  stroke-width: 2;
}

.tree-link--divorced {
  stroke: var(--color-link-divorced);
  stroke-dasharray: 6 4;
}

.tree-link--step {
  stroke: var(--color-link-step);
  stroke-dasharray: 3 3;
}

.tree-context-menu {
  position: absolute;
  background-color: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-xxs);
  box-shadow: var(--shadow-lg);
  min-width: 180px;
  z-index: var(--z-modal);
}

.tree-context-menu__item {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
  padding: var(--space-xs) var(--space-sm);
  font-size: var(--font-size-sm);
  border-radius: var(--radius-sm);
  width: 100%;
  text-align: left;
}

.tree-context-menu__item:hover {
  background-color: var(--color-surface-alt);
}

.tree-context-menu__item--danger {
  color: var(--color-error);
}

.tree-context-menu__separator {
  height: 1px;
  background-color: var(--color-border);
  margin: var(--space-xxs) 0;
}

/* Pets popover — variant of the context menu used when an owner has more
   than one pet and we need to disambiguate before opening a panel. The
   small header makes "you're picking a pet" obvious. */
.tree-context-menu--pets {
  min-width: 220px;
}

.tree-context-menu__header {
  padding: var(--space-xxs) var(--space-sm);
  font-size: var(--font-size-xs);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--color-highlight);
  font-weight: var(--font-weight-medium);
}
