/* Agents: the robot mascot (all states), the intro stage (robots, spokes, cross-links, packets, labels)
   and the robot look in the dock and the report. */

/* ---------- Robot ---------- */

.robot { display: block; overflow: visible; }
.robot .robot-tint { fill: var(--agent); }
.robot .robot-tint-stroke { stroke: var(--agent); }
.robot .robot-emblem { color: var(--agent); }
.robot .robot-ok { fill: var(--ok, #7fd48b); }

/* Transforms are expressed in viewBox units (64 × 72). */
.robot :is(.robot-float, .robot-rig, .robot-glow, .robot-arm-l, .robot-arm-r, .robot-eyes) { transform-box: view-box; }
.robot .robot-rig { transform-origin: 32px 61px; transition: transform .45s var(--ease-spring, ease); }
.robot .robot-glow { transform-origin: 32px 67.4px; }
.robot .robot-arm-l { transform-origin: 16.4px 46px; transition: transform .4s var(--ease-spring, ease); }
.robot .robot-arm-r { transform-origin: 47.6px 46px; transition: transform .4s var(--ease-spring, ease); }
.robot :is(.robot-eye, .robot-antenna-halo, .robot-check, .robot-jet, .robot-mouth) { transform-box: fill-box; transform-origin: 50% 50%; }
.robot .robot-jet { transform-origin: 50% 0; }
.robot .robot-mouth { transform-origin: 50% 0; }
.robot .robot-eyes { transition: opacity .18s ease; }
.robot .robot-eyes-happy { opacity: 0; transition: opacity .18s ease; }
.robot .robot-antenna-halo { opacity: 0; }
.robot .robot-check { opacity: 0; transform: scale(.2); transition: opacity .18s ease, transform .5s var(--ease-spring, ease); }

/* Idle: gentle hover, slow blinks. */
.robot.is-idle .robot-float { animation: robot-bob 2.8s ease-in-out var(--robot-phase, 0s) infinite; }
.robot.is-idle .robot-glow { animation: robot-glow 2.8s ease-in-out var(--robot-phase, 0s) infinite; }
.robot.is-idle .robot-eye { animation: robot-blink 4.4s linear var(--robot-blink, 0s) infinite; }
.robot:is(.is-idle, .is-working, .is-talking) .robot-jet { animation: robot-jet .28s ease-in-out infinite alternate; }

/* Working: busier hover, eyes scanning, antenna blinking fast, arms typing. */
.robot.is-working .robot-float { animation: robot-bob 1.8s ease-in-out var(--robot-phase, 0s) infinite; }
.robot.is-working .robot-glow { animation: robot-glow 1.8s ease-in-out var(--robot-phase, 0s) infinite; }
.robot.is-working .robot-eyes { animation: robot-scan 1.5s ease-in-out var(--robot-phase, 0s) infinite; }
.robot.is-working .robot-antenna-tip { animation: robot-tip .5s ease-in-out infinite; }
.robot.is-working .robot-arm-l { animation: robot-type-l .36s ease-in-out infinite alternate; }
.robot.is-working .robot-arm-r { animation: robot-type-r .36s ease-in-out infinite alternate-reverse; }

/* Talking: leans towards its partner, waves, antenna pulses, mouth moves. */
.robot.is-talking .robot-float { animation: robot-bob 1.8s ease-in-out var(--robot-phase, 0s) infinite; }
.robot.is-talking .robot-rig { transform: rotate(var(--lean, -6deg)); }
.robot.is-talking .robot-arm-l { transform: rotate(var(--arm-l, 0deg)); }
.robot.is-talking .robot-arm-r { transform: rotate(var(--arm-r, 0deg)); }
.robot.is-talking .robot-antenna-halo { animation: robot-halo .75s ease-out infinite; }
.robot.is-talking .robot-mouth { animation: robot-talk .16s ease-in-out infinite alternate; }

/* Done: happy eyes, a check badge and one little hop. */
.robot.is-done .robot-eyes { opacity: 0; }
.robot.is-done .robot-eyes-happy { opacity: 1; }
.robot.is-done .robot-check { opacity: 1; transform: none; }
.robot.is-done .robot-rig { animation: robot-hop .72s var(--ease-out, ease-out) 1; }

@keyframes robot-bob { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-2.4px); } }
@keyframes robot-glow { 0%, 100% { transform: scale(1); opacity: 1; } 50% { transform: scale(.82); opacity: .7; } }
@keyframes robot-blink { 0%, 92%, 100% { transform: scaleY(1); } 95% { transform: scaleY(.12); } }
@keyframes robot-scan { 0%, 100% { transform: translateX(-2.2px); } 50% { transform: translateX(2.2px); } }
@keyframes robot-tip { 0%, 100% { opacity: 1; } 50% { opacity: .22; } }
@keyframes robot-halo { from { transform: scale(1); opacity: .7; } to { transform: scale(2.7); opacity: 0; } }
@keyframes robot-type-l { from { transform: rotate(8deg); } to { transform: rotate(-10deg); } }
@keyframes robot-type-r { from { transform: rotate(-8deg); } to { transform: rotate(10deg); } }
@keyframes robot-talk { from { transform: scaleY(1); } to { transform: scaleY(2.1); } }
@keyframes robot-jet { from { transform: scaleY(1); } to { transform: scaleY(.7); } }
@keyframes robot-hop {
  0% { transform: none; }
  16% { transform: translateY(.6px) scale(1.07, .92); }
  44% { transform: translateY(-7px) scale(.96, 1.05); }
  68% { transform: translateY(0) scale(1.05, .95); }
  84% { transform: translateY(0) scale(.99, 1.01); }
  100% { transform: none; }
}

/* ---------- Stage (inside #intro, under the Claude window) ---------- */

.agents-stage {
  position: absolute;
  inset: 0;
  z-index: 1;
  overflow: hidden;
  pointer-events: none;
}

.agents-links {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
  transition: opacity .45s ease;
}

/* The window "lights up" during the synthesis: a halo drawn behind it. */
.agents-hub-glow {
  position: absolute;
  left: 0;
  top: 0;
  border-radius: 16px;
  transition: opacity .4s ease;
}
.agents-hub-glow::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  box-shadow:
    0 0 0 1.5px rgba(217,119,87,.85),
    0 0 26px 4px rgba(217,119,87,.42),
    0 0 90px 22px rgba(217,119,87,.16);
  opacity: 0;
  will-change: opacity;
}
.agents-hub-glow.is-on::before { animation: agents-hub-glow 1.8s var(--ease-out, ease-out) forwards; }
@keyframes agents-hub-glow { 0% { opacity: 0; } 22% { opacity: 1; } 100% { opacity: .4; } }

/* Spokes: robot → window. */
.agent-spoke {
  fill: none;
  stroke: var(--agent);
  stroke-width: 1.5;
  stroke-linecap: round;
  opacity: 0;
  transition: opacity .35s ease;
}
.agent-spoke.is-on { opacity: .34; }
.agent-spoke.is-done { opacity: .5; }
.agents-links.is-synth .agent-spoke { animation: agents-spoke-pulse .5s ease-in-out 2; }
@keyframes agents-spoke-pulse { 50% { opacity: .95; stroke-width: 2.6; } }

/* Cross-links: a bright trail is drawn behind the packet, then cools down into a dashed link. */
.agent-xlink {
  fill: none;
  stroke-width: 1.4;
  stroke-linecap: round;
  stroke-dasharray: 1.5 5.5;
  opacity: 0;
  transition: opacity .8s ease;
}
.agent-xlink.is-linked { opacity: .6; }
.agent-xlink-trail { fill: none; stroke-width: 2.2; stroke-linecap: round; opacity: 0; }
.agent-xlink-trail.is-drawing { opacity: .95; }
.agent-xlink-trail.is-fading { opacity: 0; transition: opacity 1.1s ease .15s; }

/* Packets: small glowing dots in the agent colour. */
.agent-packet-halo { fill: var(--agent); opacity: .24; }
.agent-packet-core { fill: var(--agent); }
.agent-packet-hot { fill: #fff; opacity: .92; }

/* One robot: figure + name + status, the text on the side away from the window. */
.agent-bot {
  position: absolute;
  left: 0;
  top: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  row-gap: 3px;
  text-align: center;
  z-index: 1;
  will-change: transform;
}
.agent-bot.is-above { flex-direction: column-reverse; }
.agent-bot.is-pending { visibility: hidden; }
/* Own layer: the robot's idle animations repaint the figure only, not the haloed text next to it. */
.agent-figure { position: relative; flex: none; transform-origin: 50% 100%; will-change: transform; }
.agent-figure > .robot { display: block; }

/* Touchdown ripple when a robot lands, a green one when it reports back. */
.agent-figure::after {
  content: '';
  position: absolute;
  left: 15%;
  bottom: 2%;
  width: 70%;
  height: 14%;
  border: 1.5px solid var(--agent);
  border-radius: 50%;
  opacity: 0;
  pointer-events: none;
}
.agent-bot.is-landed .agent-figure::after { animation: agent-ripple .75s var(--ease-out, ease-out); }
.agent-bot.is-landed.is-finished .agent-figure::after { border-color: var(--ok, #7fd48b); animation: agent-ripple-ok .9s var(--ease-out, ease-out); }
@keyframes agent-ripple { from { opacity: .85; transform: scale(.45); } to { opacity: 0; transform: scale(1.7); } }
@keyframes agent-ripple-ok { from { opacity: .9; transform: scale(.45); } to { opacity: 0; transform: scale(1.9); } }

.agent-name {
  display: inline-flex;
  align-items: center;
  gap: .5em;
  max-width: 100%;
  color: var(--text, #f4f3ee);
  font: 650 .64rem/1.3 var(--font-mono, monospace);
  letter-spacing: .1em;
  text-transform: uppercase;
  white-space: nowrap;
}
.agent-name::before {
  content: '';
  flex: none;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--agent);
  box-shadow: 0 0 8px var(--agent);
}
.agent-status {
  min-height: 1.4em;
  max-width: 100%;
  color: var(--muted, #9aa3b2);
  font: 450 .68rem/1.4 var(--font-mono, monospace);
  white-space: nowrap;
}
/* A plate in the backdrop colour masks any line passing behind the text; the halo softens its edges. */
.agent-name, .agent-status {
  padding: .1rem .35rem;
  border-radius: 6px;
  background: color-mix(in srgb, var(--bg, #1b1f27) 88%, transparent);
  text-shadow: 0 0 2px rgba(27,31,39,.95), 0 0 7px rgba(27,31,39,.9);
  opacity: 0;
  transform: translateY(3px);
  transition: opacity .3s ease, transform .45s var(--ease-out, ease-out);
}
.agent-bot.is-above :is(.agent-name, .agent-status) { transform: translateY(-3px); }
.agent-bot.is-landed :is(.agent-name, .agent-status) { opacity: 1; transform: none; }
.agent-bot.is-landed .agent-status { transition-delay: .08s; }
.agent-status:empty { background: none; }
.agent-status-line { display: inline-block; animation: agent-status-in .4s var(--ease-out, ease-out) both; }
.agent-status-line.is-done { color: var(--text-dim, #d3d7de); }
.agent-ok { color: var(--ok, #7fd48b); font-weight: 700; }
@keyframes agent-status-in { from { opacity: 0; transform: translateY(3px); } }

/* Grid (phones, narrow screens): statuses wrap inside their column; the scene sizes rows for it. */
.agents-stage.is-grid .agent-status,
.agents-measure .agent-status.is-wrapped {
  white-space: normal;
  overflow-wrap: anywhere;
  text-wrap: balance;
}
.agents-stage.is-grid .agent-status-line { display: inline; }
/* A one-word tool argument stays whole; if it is wider than the column, it overflows evenly on both sides. */
.agent-status-arg { white-space: nowrap; }
.agents-stage.is-grid .agent-status { min-width: min-content; }
/* Columns (short screens): one line per status, cut with an ellipsis at the column width. */
.agents-stage.is-columns .agent-status { overflow: hidden; text-overflow: ellipsis; }
.agents-stage.is-columns .agent-status-line { display: inline; }
@media (max-width: 599.98px) {
  .agent-bot { row-gap: 2px; }
  .agent-name { gap: .35em; font-size: .56rem; letter-spacing: .04em; }
  .agent-name, .agent-status { padding: .08rem .25rem; }
  .agent-name::before { width: 4px; height: 4px; }
  .agent-status { font-size: .58rem; line-height: 1.32; }
}
@media (max-width: 359.98px) {
  .agent-name { letter-spacing: .02em; }
  .agent-name::before { display: none; }
  /* 74px columns: a long tool argument such as trainmymat.com) breaks rather than spilling into its neighbour. */
  .agent-name, .agent-status { padding-inline: .15rem; }
  .agent-status { font-size: .56rem; }
  .agents-stage.is-grid .agent-status,
  .agents-measure .agent-status.is-wrapped { overflow-wrap: break-word; }
  .agents-stage.is-grid .agent-status-arg,
  .agents-measure .is-wrapped .agent-status-arg { white-space: normal; overflow-wrap: anywhere; }
}

/* Cross-link label: a small dark pill with the two agents' colours. */
.agent-link-label {
  position: absolute;
  left: 0;
  top: 0;
  z-index: 2;
  display: flex;
  align-items: center;
  gap: .5rem;
  max-width: min(20rem, calc(100vw - 24px));
  padding: .3rem .75rem .32rem .55rem;
  border: 1px solid color-mix(in srgb, var(--from) 55%, transparent);
  border-radius: 999px;
  background: rgba(16,19,25,.92);
  box-shadow: 0 10px 24px -12px rgba(0,0,0,.9), inset 0 1px 0 rgba(255,255,255,.05);
  color: var(--term-text, #e9e7e1);
  font: 500 .68rem/1.3 var(--font-mono, monospace);
  letter-spacing: .01em;
  white-space: nowrap;
  opacity: 0;
  transform: translateY(5px) scale(.95);
  transition: opacity .22s ease, transform .4s var(--ease-out, ease-out);
}
.agent-link-label.is-visible { opacity: 1; transform: none; }
.agent-link-label.is-visible.is-delayed { transition-delay: .16s; }
.agent-link-dots { display: inline-flex; flex: none; gap: 3px; }
.agent-link-dots > i { width: 6px; height: 6px; border-radius: 50%; background: var(--from); box-shadow: 0 0 8px var(--from); }
.agent-link-dots > i + i { background: var(--to); box-shadow: 0 0 8px var(--to); }
.agent-link-arrow { color: var(--to); }
.agent-link-target { color: var(--text-dim, #d3d7de); }
/* Compact variant for tight spots: the label wraps on two lines. */
.agent-link-label.is-compact {
  align-items: flex-start;
  max-width: 10rem;
  border-radius: 10px;
  white-space: normal;
}
.agent-link-label.is-compact .agent-link-dots { margin-top: .32em; }
@media (max-width: 599.98px) {
  .agent-link-label { white-space: normal; border-radius: 10px; font-size: .62rem; text-wrap: balance; }
  .agent-link-label.is-compact { max-width: 9.5rem; }
}

/* Docking: the network fades while the robots fly into the topbar. */
.agents-stage.is-docking .agents-links,
.agents-stage.is-docking .agents-hub-glow { opacity: 0; transition: opacity .4s ease; }
.agent-bot.is-leaving :is(.agent-name, .agent-status) { opacity: 0; transition: opacity .2s ease; }

/* Off-screen text probe used to size the robots' footprints. */
.agents-measure { position: absolute; left: 0; top: 0; visibility: hidden; pointer-events: none; }
.agents-measure .agent-bot { position: static; width: max-content; }
.agents-measure :is(.agent-name, .agent-status) { opacity: 1; transform: none; transition: none; }
.agents-measure .agent-status { display: block; white-space: nowrap; }
.agents-measure .agent-status-line { display: block; width: max-content; animation: none; }

/* The idle hover keeps going after the hop while the robots wait on stage. */
.agents-stage .robot.is-done .robot-float { animation: robot-bob 3s ease-in-out var(--robot-phase, 0s) infinite; }
.agents-stage .robot.is-done .robot-glow { animation: robot-glow 3s ease-in-out var(--robot-phase, 0s) infinite; }
.agents-stage .robot.is-done .robot-jet { animation: robot-jet .3s ease-in-out infinite alternate; }

/* ---------- Robots outside the stage: dock, report bylines, hero card ---------- */

.dock .robot .robot-check { display: none; }
.dock-item.is-active .robot .robot-antenna-tip { animation: robot-tip 1.6s ease-in-out infinite; }
.dock.is-awaiting .dock-robot { opacity: 0; transition: none; }
.dock-robot.is-landing > .robot { animation: dock-land .6s var(--ease-out, ease-out) 1; transform-origin: 50% 100%; }
@keyframes dock-land {
  0% { transform: translateY(-2px); }
  35% { transform: translateY(0) scale(1.1, .88); }
  65% { transform: scale(.96, 1.05); }
  100% { transform: none; }
}
@media (hover: hover) {
  .dock-item:hover .robot .robot-rig { animation: robot-hop .7s var(--ease-out, ease-out) 1; }
  .dock-item:hover .robot .robot-arm-r { transform: rotate(-60deg); }
}

.agent-avatar .robot .robot-glow { opacity: .85; }
@media (hover: hover) {
  .agent-avatar:hover .robot .robot-rig { animation: robot-hop .7s var(--ease-out, ease-out) 1; }
}

/* Reduced motion: final states, no movement (base.css also collapses durations). */
html.motion-reduced .robot *,
html.motion-reduced .agent-bot *,
html.motion-reduced .agent-figure::after,
html.motion-reduced .agent-link-label,
html.motion-reduced .dock-robot > .robot { animation: none !important; transition: none !important; }
