/* ==========================================================================
   Harness Lab · Wrapped Core (b36): the logo, the mark's motion and the agent's avatar.
   A port of the brand kit's brand-motion.css (research/design/brand-kit/) to plain CSS: no @layer, and no colour here at all.
   Every colour below is a semantic token from tokens.css, so light and dark both work and tokens.css stays the only file
   with colour literals. brand.js draws the markup (window.Brand). Every animation stops under "Reduce motion" (the end).
   ========================================================================== */

:root {
  --bm-body: var(--primary);          /* the brackets: the harness */
  --bm-agent: var(--ai);              /* the core: the model, the brain */
  --bm-done: var(--success);          /* the core when a task is done */
  --bm-disc: var(--surface-2);        /* the avatar's disc */
  --bm-disc-edge: var(--border-strong);
  --bm-ring-from: var(--ai);          /* the ring gradient is the kit's aura */
  --bm-ring-to: var(--primary);
  --bm-wordmark: var(--foreground);
  --bm-hover-time: var(--dur-fast);
  --bm-ease-hover: var(--ease-out-quart);
  --bm-ease-out: var(--ease-out-expo);
  --bm-ease-pop: cubic-bezier(.34, 1.56, .64, 1);   /* the logo only: the small bounce when the core lands */
}

/* ---------- the mark ---------- */
.bm { display: inline-block; flex-shrink: 0; overflow: visible; vertical-align: middle; }
.bm .bm-agent { fill: var(--bm-agent); }
.bm .bm-halo { fill: var(--bm-agent); opacity: 0; pointer-events: none; }
.bm .bm-burst { fill: none; stroke: var(--bm-done); stroke-width: 1; opacity: 0; pointer-events: none; }
.bm .bm-agent, .bm .bm-halo, .bm .bm-burst { transform-box: fill-box; transform-origin: center; }
.bm .bm-body, .bm .bm-agent { transition: transform var(--bm-hover-time) var(--bm-ease-hover); }

.bm-harness .bm-left, .bm-harness .bm-right { fill: none; stroke: var(--bm-body); stroke-width: 3.8; stroke-linecap: round; stroke-linejoin: round; }
.bm-harness[data-mono] .bm-left, .bm-harness[data-mono] .bm-right { stroke: currentColor; }
.bm-harness[data-mono] .bm-agent { fill: currentColor; }
.bm-harness[data-compact] .bm-left, .bm-harness[data-compact] .bm-right { stroke-width: 4.4; }   /* the small-size drawing, under 20 px */
.bm-harness[data-core="done"] .bm-agent { fill: var(--bm-done); }   /* a finished line: the green core, still */

/* Reveal: once per visit per place. The brackets close in, then the core pops. */
.bm-harness[data-state="reveal"] .bm-left  { animation: bm-in-left .5s var(--bm-ease-out) both; }
.bm-harness[data-state="reveal"] .bm-right { animation: bm-in-right .5s var(--bm-ease-out) both; }
.bm-harness[data-state="reveal"] .bm-agent { animation: bm-pop .45s var(--bm-ease-pop) .25s both; }

/* Idle: not used inside the app (the motion rule: only the AI moves, and only while it works); kept for slides and videos. */
.bm-harness[data-state="idle"] .bm-halo { animation: bm-halo 3s ease-out infinite; }

/* Thinking (the brain works): the brackets breathe and the core dims. On AI buttons it replaces the spinner. */
.bm-harness[data-state="thinking"] .bm-left  { animation: bm-breathe-left 1.2s ease-in-out infinite; }
.bm-harness[data-state="thinking"] .bm-right { animation: bm-breathe-right 1.2s ease-in-out infinite; }
.bm-harness[data-state="thinking"] .bm-agent { animation: bm-dim 1.2s ease-in-out infinite; }

/* Speaking: the core beats with the voice level that the ring writes into --bm-level. */
.bm-harness[data-state="speaking"] .bm-agent { transform: scale(calc(1 + var(--bm-level, .4) * .2)); transition: transform 80ms linear; }

/* Done (answer ready): the core turns green with a small burst, once. */
.bm-harness[data-state="done"] .bm-agent { animation: bm-done .6s ease-out both; }
.bm-harness[data-state="done"] .bm-burst { animation: bm-burst .6s ease-out both; }

/* Hover: put .bm-hover on the button or link that holds the mark. */
.bm-hover:hover .bm-harness .bm-left,  .bm-hover:focus-visible .bm-harness .bm-left  { transform: translateX(-2px); }
.bm-hover:hover .bm-harness .bm-right, .bm-hover:focus-visible .bm-harness .bm-right { transform: translateX(2px); }
.bm-hover:hover .bm-harness .bm-agent, .bm-hover:focus-visible .bm-harness .bm-agent { transform: scale(1.2); }

/* ---------- the avatar and its speaking ring ---------- */
.bm-ring { position: relative; display: inline-grid; place-items: center; flex-shrink: 0; vertical-align: middle; }
.bm-ring-svg { position: absolute; inset: 0; overflow: visible; }
.bm-ring-disc { fill: var(--bm-disc); stroke: var(--bm-disc-edge); stroke-width: 1; }
.bm-ring-stop-from { stop-color: var(--bm-ring-from); }
.bm-ring-stop-to { stop-color: var(--bm-ring-to); }
.bm-ring-front { opacity: 1; }   /* always lit, like the kit's ring-light */
.bm-ring-back { opacity: .45; transition: opacity var(--dur-base) ease; }
.bm-ring:not([data-speaking="true"]) .bm-ring-back { opacity: 0; }   /* the second wave shows only while speaking */
.bm-ring-content { position: relative; display: grid; place-items: center; }

/* ---------- the logo lockup: the name is 0.8x the mark's height and the gap 0.32x (brand.js sets other heights itself) ---------- */
.bm-logo { display: inline-flex; align-items: center; line-height: 1; }
.bm-wordmark {
  font-family: var(--font-sans);
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--bm-wordmark);
  white-space: nowrap;
}
.bm-logo-28 { gap: 9px; }
.bm-logo-28 .bm-wordmark { font-size: 22px; }
.bm-logo-40 { gap: 13px; }
.bm-logo-40 .bm-wordmark { font-size: 32px; }

/* ---------- keyframes ---------- */
@keyframes bm-pop   { 0% { transform: scale(0); } 70% { transform: scale(1.1); } 100% { transform: scale(1); } }
@keyframes bm-halo  { 0% { transform: scale(1); opacity: .55; } 100% { transform: scale(2.4); opacity: 0; } }
@keyframes bm-done  { 0% { fill: var(--bm-agent); transform: scale(1); } 40% { fill: var(--bm-done); transform: scale(1.28); } 100% { fill: var(--bm-done); transform: scale(1); } }
@keyframes bm-burst { 0% { transform: scale(1); opacity: .85; } 100% { transform: scale(2.6); opacity: 0; } }
@keyframes bm-in-left  { from { transform: translateX(-7px); opacity: 0; } to { transform: translateX(0); opacity: 1; } }
@keyframes bm-in-right { from { transform: translateX(7px); opacity: 0; } to { transform: translateX(0); opacity: 1; } }
@keyframes bm-breathe-left  { 0%, 100% { transform: translateX(0); } 50% { transform: translateX(-2.5px); } }
@keyframes bm-breathe-right { 0%, 100% { transform: translateX(0); } 50% { transform: translateX(2.5px); } }
@keyframes bm-dim   { 0%, 100% { opacity: 1; } 50% { opacity: .55; } }

/* ---------- Reduce motion: everything still, the end states shown ---------- */
@media (prefers-reduced-motion: reduce) {
  .bm *, .bm-ring * { animation: none !important; transition: none !important; }
  .bm[data-state="speaking"] .bm-agent { transform: none; }
  .bm[data-state="done"] .bm-agent { fill: var(--bm-done); }
}
