/* ============================================================
   Connections replica (`cgr`)
   /capabilities/connections
   crew phossil-capability-showcase, 2026-07-26

   Loads AFTER capability.css, which owns the `.cap-replica`
   shell (dark primary panel, title bar, sample note) and the
   token base from marketing-template.css. Tokens only here,
   zero raw hex.

   Why a hand-rolled SVG rather than the real graph: the product
   draws this with D3 (public/vendor/d3@7.9.0, 276K self-hosted)
   and a live force simulation. Neither belongs on a marketing
   page, so the replica keeps the MECHANISM (radius by photo
   count, stroke by shared photos, click to light a person's
   ties, a weight filter that drops thin links and then the
   people left with none) and drops the physics: the positions
   are pre-computed and the layout never settles because it was
   never unsettled.

   The vocabulary it renders is pinned to public/connections.html
   and public/js/ui/connections-graph.js by
   tests/frontend/capability-replicas.test.js.
   ============================================================ */

/* --- Stage ------------------------------------------------- */

.cgr {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-md);
}

/* Above 900px the panel sits beside the plot the way the real
   sidebar does. Below it, the panel stacks under the plot so the
   graph keeps the full measure on a phone. */
.cgr__stage {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-md);
  align-items: start;
}
@media (min-width: 900px) {
  .cgr__stage {
    grid-template-columns: minmax(0, 1fr) 280px;
  }
}

.cgr__plot {
  position: relative;
  width: 100%;
  min-width: 0; /* a grid child will not shrink below its SVG without this */
}
.cgr__svg {
  display: block;
  width: 100%;
  height: auto;
  overflow: visible;
}

/* --- Links ------------------------------------------------- */
/* Drawn first so the node group paints on top and wins taps.
   `pointer-events: stroke` keeps the native title tooltip
   reachable on a thick line without giving the line a click
   affordance it cannot honor here. */

.cgr__link {
  stroke: var(--color-accent);
  stroke-opacity: 0.32;
  stroke-linecap: round;
  fill: none;
  pointer-events: stroke;
  transition: stroke-opacity var(--transition-normal);
}
.cgr__link.is-highlighted { stroke-opacity: 0.95; }
.cgr__link.is-dimmed { stroke-opacity: 0.07; }

/* --- Nodes ------------------------------------------------- */

.cgr__node { cursor: pointer; }
/* Opaque on purpose. Links terminate at the node center, so a
   translucent disc shows the line running under it as a streak
   across the person's circle. */
.cgr__node circle.cgr__disc {
  fill: var(--color-accent);
  fill-opacity: 1;
  stroke: var(--color-primary);
  stroke-width: 2;
  transition: fill-opacity var(--transition-normal), stroke var(--transition-normal);
}
/* The tap target, not the drawing. Sized in the JS to clear 44px
   on the narrow coordinate space as well as the wide one. */
.cgr__hit {
  fill: transparent;
  stroke: none;
}
.cgr__node text {
  font-family: var(--font-sans);
  font-size: 13px;
  fill: var(--color-text-light);
  text-anchor: middle;
  pointer-events: none;
  transition: fill var(--transition-normal), fill-opacity var(--transition-normal);
}
.cgr__node.is-highlighted circle.cgr__disc {
  fill-opacity: 1;
  stroke: var(--color-text-light);
}
.cgr__node.is-highlighted text { fill: var(--color-accent-hover); }
.cgr__node.is-dimmed circle.cgr__disc { fill-opacity: 0.2; }
.cgr__node.is-dimmed text { fill-opacity: 0.3; }
.cgr__node:focus { outline: none; }
.cgr__node:focus-visible circle.cgr__disc {
  stroke: var(--color-focus-ring);
  stroke-width: 3;
}

/* SVG text scales with the viewBox. Below 720px the script swaps
   to a 460-unit coordinate space, so the nominal size has to grow
   to land on the same on-screen pixels. Without this the names
   render at roughly seven pixels. */
@media (max-width: 719px) {
  .cgr__node text { font-size: 18px; }
}

/* --- Controls ---------------------------------------------- */

.cgr__controls {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-sm);
}
.cgr__control {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
  flex: 1 1 240px;
  max-width: 400px; /* the track is a 20-step control, not a scrubber; a full-width one reads as a progress bar */
  min-width: 0;
}
.cgr__control label {
  font-family: var(--font-sans);
  font-size: 0.85rem;
  color: var(--color-text-light);
  white-space: nowrap;
}
.cgr__slider {
  flex: 1;
  min-width: 100px;
  min-height: 44px;
  accent-color: var(--color-accent);
  cursor: pointer;
}
.cgr__slider:focus-visible {
  outline: 2px solid var(--color-focus-ring);
  outline-offset: 2px;
}
.cgr__slider-value {
  font-family: var(--font-sans);
  font-size: 0.95rem;
  color: var(--color-accent);
  font-variant-numeric: tabular-nums;
  min-width: 2ch;
  text-align: right;
}
.cgr__stats {
  font-family: var(--font-sans);
  font-size: 0.9rem;
  color: var(--color-text-muted);
  font-variant-numeric: tabular-nums;
  flex: 0 1 auto;
}

/* --- Person panel (mirrors the real sidebar) --------------- */

.cgr__panel {
  background: rgba(243, 240, 230, 0.06);
  border: 1px solid rgba(243, 240, 230, 0.12);
  border-radius: var(--radius-md);
  padding: var(--space-md);
}
.cgr__panel-head {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
}
.cgr__avatar {
  flex: 0 0 auto;
  width: 44px;
  height: 44px;
  border-radius: var(--radius-full);
  background: var(--color-accent);
  color: var(--color-text-on-accent);
  font-family: var(--font-serif);
  font-size: 1.05rem;
  display: flex;
  align-items: center;
  justify-content: center;
}
.cgr__name {
  font-family: var(--font-serif);
  font-size: 1.15rem;
  line-height: 1.25;
  color: var(--color-text-light);
  margin: 0;
}
.cgr__rel {
  display: block;
  font-family: var(--font-sans);
  font-size: 0.78rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-accent);
}

.cgr__figures {
  display: flex;
  gap: var(--space-md);
  margin-top: var(--space-md);
  padding-top: var(--space-sm);
  border-top: 1px solid rgba(243, 240, 230, 0.12);
}
.cgr__figure-value {
  display: block;
  font-family: var(--font-serif);
  font-size: 1.5rem;
  line-height: 1.1;
  color: var(--color-accent);
  font-variant-numeric: tabular-nums;
}
.cgr__figure-label {
  display: block;
  font-family: var(--font-sans);
  font-size: 0.74rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--color-text-muted);
}

/* Shown only for someone on the edge of the network. Reserved
   height would leave a hole under everyone else, so the block is
   removed rather than hidden and the panel simply gets shorter. */
.cgr__nudge {
  font-family: var(--font-sans);
  font-size: 0.85rem;
  line-height: 1.6;
  color: var(--color-text-muted);
  margin: var(--space-sm) 0 0;
}

.cgr__list-title {
  font-family: var(--font-sans);
  font-size: 0.78rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--color-text-muted);
  margin: var(--space-md) 0 var(--space-xs);
}
.cgr__list {
  list-style: none;
  margin: 0;
  padding: 0;
}
.cgr__row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-sm);
  padding: var(--space-xs) 0;
  border-bottom: 1px solid rgba(243, 240, 230, 0.08);
  font-family: var(--font-sans);
  font-size: 0.92rem;
}
.cgr__row:last-child { border-bottom: none; }
.cgr__row-name { color: var(--color-text-light); }
.cgr__row-weight {
  color: var(--color-accent);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* --- Legend ------------------------------------------------ */

.cgr__legend {
  border-top: 1px solid rgba(243, 240, 230, 0.12);
  padding-top: var(--space-sm);
}
.cgr__legend h4 {
  font-family: var(--font-sans);
  font-size: 0.74rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--color-text-muted);
  margin: 0 0 var(--space-xs);
}
.cgr__legend-item {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
  font-family: var(--font-sans);
  font-size: 0.9rem;
  color: var(--color-text-light);
}
.cgr__legend-dot {
  width: 12px;
  height: 12px;
  border-radius: var(--radius-full);
  background: var(--color-accent);
}
.cgr__legend-note {
  font-family: var(--font-sans);
  font-size: 0.85rem;
  line-height: 1.6;
  color: var(--color-text-muted);
  margin: var(--space-xs) 0 0;
}

/* --- Reduced motion ---------------------------------------- */
/* Nothing here animates on its own; the transitions only fire on
   a tap the reader chose to make. Anyone who asked for less
   motion gets the same graph with the fade removed. */

@media (prefers-reduced-motion: reduce) {
  .cgr__link,
  .cgr__node circle.cgr__disc,
  .cgr__node text {
    transition: none;
  }
}
