/* ============================================================================
   GARPI 2026 | Semantic visual concepts – presentation layer
   Geometry is shared (assets/visuals.js); art direction happens through the
   [data-treatment] hooks at the foot of this file, so every direction reads
   as the same GARPI system rendered in its own voice.
   ========================================================================== */

.v-figure {
  margin: 0;
  display: grid;
  gap: var(--space-4);
  justify-items: center;

  /* Treatment variables – remapped per direction. */
  --v-line: var(--line-strong);
  --v-grid: var(--line);
  --v-accent: var(--accent);
  --v-ink: var(--fg-strong);
  --v-muted: var(--fg-subtle);
  --v-fill: var(--accent-wash);
  --v-stroke-w: 1.25;
  --v-label-size: 8.5px;
  --v-glow: none;
}

.v-svg {
  width: 100%;
  max-width: 380px;
  height: auto;
  overflow: visible;
}

.v-caption {
  max-width: 34ch;
  font-size: var(--type-caption);
  line-height: 1.5;
  color: var(--v-muted);
  text-align: center;
  text-wrap: pretty;
}

/* -- Shared primitives ---------------------------------------------------- */

.v-grid line,
.v-grid circle {
  fill: none;
  stroke: var(--v-grid);
  stroke-width: 1;
}

.v-tag,
.v-label {
  font-family: var(--font-body);
  font-size: var(--v-label-size);
  font-weight: 700;
  letter-spacing: var(--tracking-eyebrow);
  fill: var(--v-muted);
  text-transform: uppercase;
}

.v-label { text-transform: none; letter-spacing: 0.02em; font-weight: 400; }

/* ============================================================================
   assemble – evidence assembles into a profile that is never valued here
   ========================================================================== */

.v-axis {
  stroke: var(--v-line);
  stroke-width: var(--v-stroke-w);
  stroke-linecap: round;
}

.v-cap { fill: var(--v-accent); }

.v-pending {
  fill: none;
  stroke: var(--v-accent);
  stroke-width: 1;
  opacity: 0.5;
}

.v-core circle {
  fill: var(--bg-raised);
  stroke: var(--v-ink);
  stroke-width: 1.25;
  filter: var(--v-glow);
}

.v-core-value {
  font-family: var(--font-num);
  font-variant-numeric: tabular-nums;
  font-size: 26px;
  fill: var(--v-ink);
}

.v-core-unit {
  font-family: var(--font-body);
  font-size: 8px;
  font-weight: 700;
  letter-spacing: var(--tracking-eyebrow);
  fill: var(--v-muted);
}

/* ============================================================================
   cohort – the peer group resolves out of the field
   ========================================================================== */

.v-dot {
  fill: var(--v-muted);
  opacity: 0.32;
  transition: transform calc(var(--dur-scene) * var(--tempo)) var(--ease-scene),
              opacity calc(var(--dur-scene) * var(--tempo)) var(--ease-scene),
              fill calc(var(--dur-slow) * var(--tempo)) var(--ease-standard);
  animation: m-signal-stabilise calc(var(--dur-scene) * var(--tempo)) var(--ease-scene) backwards;
  animation-delay: calc(var(--stagger) * var(--i, 0));
}

[data-stage="formed"] .v-dot[data-member="true"],
[data-stage="closed"] .v-dot[data-member="true"] {
  transform: translate(var(--tx), var(--ty));
  fill: var(--v-accent);
  opacity: 1;
}

[data-stage="closed"] .v-dot[data-member="false"] { opacity: 0.16; }

.v-ring {
  fill: none;
  stroke: var(--v-accent);
  stroke-width: 1.25;
  stroke-dashoffset: 465;
  opacity: 0;
  transition: stroke-dashoffset calc(var(--dur-scene) * var(--tempo)) var(--ease-signal),
              opacity calc(var(--dur-base) * var(--tempo)) var(--ease-standard);
}
[data-stage="closed"] .v-ring { stroke-dashoffset: 0; opacity: 0.85; }

.v-you-halo {
  fill: var(--v-fill);
  opacity: 0;
  transition: opacity calc(var(--dur-slow) * var(--tempo)) var(--ease-standard);
}
.v-you-dot {
  fill: var(--v-ink);
  opacity: 0;
  transform-origin: 160px 128px;
  transition: opacity calc(var(--dur-slow) * var(--tempo)) var(--ease-standard);
}
[data-stage="formed"] .v-you-halo,
[data-stage="closed"] .v-you-halo { opacity: 1; }
[data-stage="formed"] .v-you-dot,
[data-stage="closed"] .v-you-dot { opacity: 1; animation: m-node-settle calc(var(--dur-base) * var(--tempo)) var(--ease-spring) backwards; }

.v-figure[data-concept="cohort"] .v-tag {
  opacity: 0;
  transition: opacity calc(var(--dur-slow) * var(--tempo)) var(--ease-standard);
}
[data-stage="formed"] .v-tag,
[data-stage="closed"] .v-tag { opacity: 1; }

/* ============================================================================
   availability – uptime bands rise and illuminate
   Every band is drawn identically. Only the chosen band is marked, and no
   band is styled as better or worse than another.
   ========================================================================== */

.v-band-ghost {
  fill: var(--v-grid);
  opacity: 0.35;
}

.v-band-fill {
  fill: var(--v-line);
  opacity: 0.45;
  transition: fill calc(var(--dur-base) * var(--tempo)) var(--ease-standard),
              opacity calc(var(--dur-base) * var(--tempo)) var(--ease-standard);
}

.v-band-cap {
  fill: var(--v-line);
  opacity: 0;
  transition: opacity calc(var(--dur-base) * var(--tempo)) var(--ease-standard),
              fill calc(var(--dur-base) * var(--tempo)) var(--ease-standard);
}

.v-band[data-chosen="true"] .v-band-fill {
  fill: var(--v-accent);
  opacity: 1;
}
.v-band[data-chosen="true"] .v-band-cap {
  fill: var(--v-ink);
  opacity: 1;
}
.v-band[data-chosen="true"] .v-band-label {
  fill: var(--v-ink);
  font-weight: 700;
}

.v-band-label {
  font-family: var(--font-body);
  font-size: var(--v-label-size);
  fill: var(--v-muted);
  letter-spacing: 0.02em;
  transition: fill calc(var(--dur-base) * var(--tempo)) var(--ease-standard);
}

.v-baseline {
  stroke: var(--v-ink);
  stroke-width: 1.5;
}

/* ============================================================================
   governance – nodes connect into a controlled decision structure
   ========================================================================== */

.v-link {
  stroke: var(--v-line);
  stroke-width: var(--v-stroke-w);
  stroke-linecap: round;
}

.v-gnode-halo {
  fill: var(--v-fill);
  opacity: 0;
  transition: opacity calc(var(--dur-slow) * var(--tempo)) var(--ease-standard);
}
.v-gnode-core {
  fill: var(--bg-raised);
  stroke: var(--v-ink);
  stroke-width: 1.5;
}
.v-gnode[data-tier="board"] .v-gnode-core { fill: var(--v-accent); stroke: var(--v-accent); }
.v-gnode[data-tier="function"] .v-gnode-core { fill: var(--bg-raised); stroke: var(--v-accent); }

/* Acknowledge the answer with one settle; the structure never changes. */
.v-figure[data-concept="governance"][data-answered="true"] .v-gnode-halo { opacity: 1; }
.v-figure[data-concept="governance"][data-answered="true"] .v-nodes {
  animation: m-absorb-return calc(var(--dur-scene) * var(--tempo) * 1.4) var(--ease-standard) 1;
}

/* ============================================================================
   outlook – pathways converge on the selected priority
   ========================================================================== */

.v-path {
  stroke: var(--v-line);
  stroke-width: 1;
  opacity: 0.45;
  transition: stroke calc(var(--dur-base) * var(--tempo)) var(--ease-standard),
              stroke-width calc(var(--dur-base) * var(--tempo)) var(--ease-standard),
              opacity calc(var(--dur-base) * var(--tempo)) var(--ease-standard);
}

.v-origin {
  fill: var(--v-muted);
  opacity: 0.5;
  transition: fill calc(var(--dur-base) * var(--tempo)) var(--ease-standard),
              opacity calc(var(--dur-base) * var(--tempo)) var(--ease-standard);
}

.v-figure[data-answered="true"] .v-path { opacity: 0.14; }
.v-figure[data-answered="true"] .v-origin { opacity: 0.2; }

.v-path[data-chosen="true"] {
  stroke: var(--v-accent);
  stroke-width: 2.25;
  opacity: 1;
}
.v-origin[data-chosen="true"] {
  fill: var(--v-accent);
  opacity: 1;
}

.v-target-halo {
  fill: var(--v-fill);
  opacity: 0;
  transition: opacity calc(var(--dur-slow) * var(--tempo)) var(--ease-standard);
}
.v-target-ring {
  fill: none;
  stroke: var(--v-line);
  stroke-width: 1;
  transition: stroke calc(var(--dur-base) * var(--tempo)) var(--ease-standard);
}
.v-target-core {
  fill: var(--v-ink);
  transition: fill calc(var(--dur-base) * var(--tempo)) var(--ease-standard);
}
.v-figure[data-answered="true"] .v-target-halo { opacity: 1; }
.v-figure[data-answered="true"] .v-target-ring { stroke: var(--v-accent); }
.v-figure[data-answered="true"] .v-target-core { fill: var(--v-accent); }
.v-figure[data-concept="outlook"] .v-tag {
  opacity: 0;
  transition: opacity calc(var(--dur-slow) * var(--tempo)) var(--ease-standard);
}
.v-figure[data-concept="outlook"][data-answered="true"] .v-tag { opacity: 1; }

/* Production semantic plates ------------------------------------------------
   Each motion is a single, subject-specific entrance: orbit, interlock,
   information hand-off, lifecycle rotation, supply connection or containment. */

.v-figure--semantic .v-orbit ellipse,
.v-system-grid rect,
.v-system-grid line,
.v-road,
.v-gear,
.v-cycle circle,
.v-cycle-arrow,
.v-supply-line,
.v-radar circle,
.v-radar path,
.v-shield,
.v-barrier-paths path,
.v-open-path {
  fill: none;
  stroke: var(--v-line);
  stroke-width: var(--v-stroke-w);
  vector-effect: non-scaling-stroke;
}

.v-sem-node,
.v-supply-nodes rect,
.v-packets circle {
  fill: var(--v-fill);
  stroke: var(--v-line);
  stroke-width: var(--v-stroke-w);
  transform-box: fill-box;
  transform-origin: center;
  animation: m-node-settle calc(var(--dur-slow) * var(--tempo)) var(--ease-out) both;
  animation-delay: calc(var(--i, 0) * var(--stagger));
}

.v-sem-core {
  fill: var(--v-ink);
  opacity: .9;
  transform-box: fill-box;
  transform-origin: center;
  animation: m-assemble calc(var(--dur-slow) * var(--tempo)) var(--ease-out) both;
}

.v-variant-line,
.v-variant-horizon,
.v-variant-signals path,
.v-variant-beam,
.v-variant-bowl,
.v-variant-check,
.v-variant-branches path {
  fill: none;
  stroke: var(--v-line);
  stroke-width: var(--v-stroke-w);
  vector-effect: non-scaling-stroke;
}

.v-variant-signals path,
.v-variant-check {
  stroke: var(--v-accent);
  stroke-width: calc(var(--v-stroke-w) * 1.7);
  stroke-linecap: round;
}

.v-variant-horizon {
  opacity: .38;
  stroke-dasharray: 3 4;
}

.v-variant-box,
.v-variant-cell,
.v-variant-weight {
  fill: var(--v-fill);
  stroke: var(--v-line);
  stroke-width: var(--v-stroke-w);
  vector-effect: non-scaling-stroke;
  transform-box: fill-box;
  transform-origin: center;
}

.v-variant-box--active,
.v-variant-cell--active,
.v-variant-weight--active {
  fill: var(--v-ink);
  stroke: var(--v-ink);
}

.v-variant-fulcrum {
  fill: var(--v-fill);
  stroke: var(--v-line);
  stroke-width: var(--v-stroke-w);
}

.v-variant-packets circle {
  fill: var(--v-accent);
  stroke: none;
  transform-box: fill-box;
  transform-origin: center;
  animation: v-packet-arrive calc(var(--dur-slow) * var(--tempo)) var(--ease-out) both;
  animation-delay: calc(var(--i, 0) * var(--stagger));
}

.v-orbit {
  transform-origin: 160px 126px;
  animation: v-orbit-settle calc(1.2s * var(--tempo)) var(--ease-editorial) both;
}

.v-columns rect { fill: var(--v-fill); stroke: var(--v-line); stroke-width: var(--v-stroke-w); }
.v-columns rect:nth-child(4) { fill: var(--v-ink); }

.v-links path { stroke: var(--v-line); stroke-width: var(--v-stroke-w); fill: none; }

.v-system-grid { opacity: .62; }
.v-packets circle { fill: var(--v-ink); animation-name: v-packet-arrive; }

.v-road { stroke-width: calc(var(--v-stroke-w) * 1.8); }
.v-milestones circle:last-child { fill: var(--v-ink); }

.v-gears { transform-origin: 160px 130px; }
.v-gear { stroke-width: 8; transform-box: fill-box; transform-origin: center; }
.v-gear--a { animation: v-gear-a calc(1s * var(--tempo)) var(--ease-editorial) both; }
.v-gear--b { animation: v-gear-b calc(1s * var(--tempo)) var(--ease-editorial) both; }

.v-cycle {
  transform-origin: 160px 126px;
  transform-box: view-box;
  animation: v-cycle-settle calc(1.1s * var(--tempo)) var(--ease-editorial) both;
}

.v-cycle circle:first-child { stroke: var(--v-ink); }
.v-cycle-arrow { stroke: var(--v-accent); stroke-width: calc(var(--v-stroke-w) * 2); }

.v-supply-line,
.v-open-path {
  stroke: var(--v-accent);
  stroke-width: calc(var(--v-stroke-w) * 1.7);
  stroke-linecap: round;
}

.v-shield {
  fill: var(--v-fill);
  stroke: var(--v-ink);
  stroke-width: calc(var(--v-stroke-w) * 1.6);
  transform-box: fill-box;
  transform-origin: center;
  animation: v-shield-form calc(1s * var(--tempo)) var(--ease-editorial) both;
}

.v-radar {
  transform-origin: 160px 128px;
  transform-box: view-box;
  animation: v-radar-settle calc(1.15s * var(--tempo)) var(--ease-editorial) both;
}
.v-radar circle { opacity: .62; }
.v-radar path { stroke: var(--v-accent); stroke-width: calc(var(--v-stroke-w) * 1.8); }

.v-barrier-paths path {
  stroke-linecap: round;
  stroke-dasharray: 106;
  animation: v-barrier-arrive calc(.9s * var(--tempo)) var(--ease-signal) both;
  animation-delay: calc(var(--stagger) * var(--i, 0));
}

.v-wall {
  fill: var(--v-fill);
  stroke: var(--v-ink);
  stroke-width: var(--v-stroke-w);
  transform-box: fill-box;
  transform-origin: center;
  animation: v-wall-form calc(.9s * var(--tempo)) var(--ease-editorial) both;
}

@keyframes v-orbit-settle {
  from { transform: rotate(-16deg) scale(.92); opacity: .2; }
  to   { transform: rotate(0) scale(1); opacity: 1; }
}

@keyframes v-packet-arrive {
  from { transform: translateX(-18px) scale(.7); opacity: 0; }
  to   { transform: translateX(0) scale(1); opacity: 1; }
}

@keyframes v-gear-a {
  from { transform: rotate(-42deg); opacity: .2; }
  to   { transform: rotate(0); opacity: 1; }
}

@keyframes v-gear-b {
  from { transform: rotate(42deg); opacity: .2; }
  to   { transform: rotate(0); opacity: 1; }
}

@keyframes v-cycle-settle {
  from { transform: rotate(-28deg) scale(.94); opacity: .25; }
  to   { transform: rotate(0) scale(1); opacity: 1; }
}

@keyframes v-shield-form {
  from { transform: scale(.86); opacity: .18; }
  to   { transform: scale(1); opacity: 1; }
}

@keyframes v-radar-settle {
  from { transform: rotate(-22deg); opacity: 0; }
  to   { transform: rotate(0); opacity: 1; }
}

@keyframes v-barrier-arrive {
  from { stroke-dashoffset: 106; opacity: .2; }
  to   { stroke-dashoffset: 0; opacity: 1; }
}

@keyframes v-wall-form {
  from { transform: scaleY(.12); opacity: .25; }
  to   { transform: scaleY(1); opacity: 1; }
}

/* GARPI benchmark architecture --------------------------------------------
   The decision chain and the eight-dimension coverage map are neutral,
   interactive orientation diagrams. They communicate scope and relationships,
   never score, tier or comparative standing. */

.v-figure--architecture .v-svg { overflow: visible; }

.v-arch-box,
.v-arch-support,
.v-dimension-box {
  fill: var(--bg-raised);
  stroke: var(--v-line);
  stroke-width: var(--v-stroke-w);
  vector-effect: non-scaling-stroke;
}

.v-arch-box--active,
.v-dimension-box--active {
  fill: var(--v-ink);
  stroke: var(--v-ink);
  filter: drop-shadow(0 4px 6px rgba(0, 47, 101, .16));
}

.v-arch-text,
.v-dimension-text {
  fill: var(--v-ink);
  font-family: var(--font-body);
  font-size: 6.4px;
  font-weight: 700;
  letter-spacing: .04em;
}

.v-arch-text--active,
.v-dimension-text--active { fill: var(--brand-white); }

.v-arch-flow,
.v-arch-soft,
.v-arch-feedback,
.v-dimension-link,
.v-arch-ring {
  fill: none;
  stroke: var(--v-line);
  stroke-width: var(--v-stroke-w);
  vector-effect: non-scaling-stroke;
}

.v-arch-flow,
.v-dimension-link { stroke: var(--v-accent); }
.v-arch-soft { opacity: .55; }
.v-arch-feedback { stroke: var(--v-accent); stroke-dasharray: 5 5; animation: v-feedback-arrive calc(1.1s * var(--tempo)) var(--ease-editorial) both; }
.v-arch-support { fill: var(--bg-sunken); }
.v-arch-spine { fill: var(--v-ink); }
.v-arch-spine-text { fill: var(--brand-white); font-family: var(--font-body); font-size: 6.5px; font-weight: 700; letter-spacing: .055em; }
.v-arch-marker { fill: var(--v-accent); }
.v-arch-ring { opacity: .55; }

.v-dimension-box--complete { fill: var(--v-fill); stroke: var(--v-accent); }
.v-dimension-core { fill: var(--v-ink); stroke: var(--v-ink); stroke-width: var(--v-stroke-w); }
.v-dimension-core-text { fill: var(--brand-white); font-family: var(--font-body); font-size: 8px; font-weight: 700; letter-spacing: .08em; }
.v-dimension-check { fill: var(--v-accent); }
.v-check { fill: none; stroke: var(--brand-white); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }

@keyframes v-feedback-arrive {
  from { stroke-dashoffset: 90; opacity: .1; }
  to { stroke-dashoffset: 0; opacity: 1; }
}

/* ============================================================================
   Direction treatments
   ========================================================================== */

/* 01 | OnePulse Precision - crisp, buoyant, high-clarity analytics. */
[data-treatment="precision"] .v-figure {
  --v-stroke-w: 1.5;
  --v-line: #B9C4D2;
  --v-grid: #E7EAEF;
  --v-label-size: 8.5px;
}

/* 02 | Industrial Signal - telemetry drawn on an instrument. */
[data-treatment="industrial"] .v-figure {
  --v-stroke-w: 1;
  --v-line: rgba(157, 182, 204, 0.5);
  --v-grid: rgba(0, 168, 203, 0.16);
  --v-glow: drop-shadow(0 0 6px rgba(0, 168, 203, 0.45));
  --v-label-size: 8px;
}
[data-treatment="industrial"] .v-cap,
[data-treatment="industrial"] .v-band[data-chosen="true"] .v-band-fill,
[data-treatment="industrial"] .v-path[data-chosen="true"] {
  filter: drop-shadow(0 0 5px rgba(0, 168, 203, 0.55));
}
[data-treatment="industrial"] .v-tag { letter-spacing: 0.18em; }
[data-treatment="industrial"] .v-core-value { font-size: 23px; }

/* 03 | Executive Benchmark - an engraved diagram in a printed report. */
[data-treatment="executive"] .v-figure {
  --v-stroke-w: 0.9;
  --v-line: var(--brand-navy);
  --v-grid: var(--brand-rule);
  --v-accent: var(--brand-navy);
  --v-fill: var(--brand-rule-light);
  --v-label-size: 8px;
}
[data-treatment="executive"] .v-label {
  font-family: var(--font-display);
  font-size: 9px;
}
[data-treatment="executive"] .v-caption {
  font-size: var(--type-small);
}
[data-treatment="executive"] .v-pending { opacity: 0.7; }
[data-treatment="executive"] .v-cap { fill: var(--brand-navy); }

/* 04 | Guided Diagnostic - an explanatory diagram, generously labelled. */
[data-treatment="guided"] .v-figure {
  --v-stroke-w: 1.75;
  --v-line: #A9BCC9;
  --v-grid: #E3EDF2;
  --v-label-size: 9px;
}
[data-treatment="guided"] .v-caption {
  max-width: 40ch;
  font-size: var(--type-small);
  color: var(--fg-muted);
}
[data-treatment="guided"] .v-svg { max-width: 320px; }

@media (prefers-reduced-motion: reduce) {
  .v-orbit,
  .v-packets circle,
  .v-gear--a,
  .v-gear--b,
  .v-cycle,
  .v-shield,
  .v-radar,
  .v-barrier-paths path,
  .v-variant-packets circle,
  .v-wall,
  .v-arch-feedback {
    animation: none !important;
  }
}
