/*! Tess Presence 0.6.0 | generated by build.mjs from src/tess-presence.css */
/* Tess Presence. Every selector starts with .tess- and every keyframe name with
   tess-, so nothing here can collide with the host site's styles.
   Colours come from custom properties set on the element by the theme. */

/* ---------- root and box ---------------------------------------------------
   --tess-size is the diameter of the glass BODY. The box reserves exactly that
   square, so there is no layout shift. The outer layers of light and the ring are
   drawn beyond the box: the canvas is 42% of the size on each side (0.5.0, was 21%),
   for the waves and the wave tendrils; the ring (22%) is inside it. That overflow is
   paint only: `contain: layout` keeps it out of the page's scrollable area, and it never
   takes pointer events. Leave that much clear space around her, or mount with
   reserveSpace to have the element pad itself. */
.tess-root {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  position: relative;
  box-sizing: content-box;
  width: var(--tess-size, var(--tess-size-default, 120px));
  max-width: 100%;
  vertical-align: middle;
  line-height: 1;
  -webkit-tap-highlight-color: transparent;
}
.tess-variant-hero { --tess-size-default: clamp(170px, 27vw, 380px); }
.tess-variant-assistant { --tess-size-default: 96px; }
.tess-variant-avatar { --tess-size-default: 48px; }
.tess-variant-icon { --tess-size-default: 24px; }
/* reserveSpace: the element is 184% of the size and the body sits in its middle, so nothing overflows it */
.tess-reserve { width: calc(var(--tess-size, var(--tess-size-default, 120px)) * 1.84); }
.tess-reserve > .tess-box,
.tess-reserve > .tess-button { width: 54.3478%; margin: 22.8261%; }

.tess-box {
  position: relative;
  display: block;
  width: 100%;
  aspect-ratio: 1 / 1;
  border-radius: 50%;
  contain: layout;
}
/* the outer layers and the tendrils need room around the body: the canvas is 184% of the box */
.tess-canvas {
  position: absolute;
  inset: -42%;
  width: 184%;
  height: 184%;
  display: block;
  pointer-events: none;
}
.tess-still,
.tess-still > .tess-svg,
.tess-ring,
.tess-face {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  overflow: visible;
  pointer-events: none;
}
/* WebGL is drawing: the still steps aside. Without it (below 40 px, no WebGL, a lost context) the still is the body. */
.tess-gl-on > .tess-still,
.tess-no-gl > .tess-canvas { visibility: hidden; }

.tess-button {
  -webkit-appearance: none;
  appearance: none;
  display: block;
  width: 100%;
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: none;
  color: inherit;
  font: inherit;
  cursor: pointer;
}
.tess-button:focus { outline: none; }
.tess-button:focus-visible {
  outline: 3px solid var(--tess-focus, #2B50FF);
  outline-offset: 3px;
}

.tess-sr {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

.tess-caption {
  display: block;
  margin-top: 0.6em;
  min-height: 1.3em;
  font-family: inherit;
  font-weight: 500;
  font-size: 13px;
  line-height: 1.3;
  color: var(--tess-text-muted, inherit);
  text-align: center;
}
/* with a ring the caption sits below it */
.tess-variant-hero > .tess-caption,
.tess-variant-assistant > .tess-caption { margin-top: calc(var(--tess-size, var(--tess-size-default, 120px)) * 0.22 + 0.6em); }
.tess-reserve > .tess-caption { margin-top: 0.6em; }

.tess-demo-tag {
  position: absolute;
  top: 0;
  left: 0;
  z-index: 2;
  padding: 2px 5px;
  border-radius: 3px;
  background: #FFC73B;
  color: #0B1026;
  font-family: inherit;
  font-weight: 700;
  font-size: 9px;
  line-height: 1.2;
  letter-spacing: 0.08em;
  pointer-events: none;
}
.tess-variant-avatar > .tess-demo-tag,
.tess-variant-icon > .tess-demo-tag {
  top: -9px;
  left: 50%;
  transform: translateX(-50%);
  padding: 1px 3px;
  font-size: 7px;
}

/* ---------- eyes and symbols: everything fades, nothing swaps ----------------- */
/* the eyes' fill is an attribute set from the theme (eyeFill in theme.js): a rule here would override it */
.tess-face-symbol { color: var(--tess-eye, #fff); }
.tess-face-eyes,
.tess-face-symbol {
  transition: opacity 420ms cubic-bezier(0.23, 1, 0.32, 1), transform 520ms cubic-bezier(0.23, 1, 0.32, 1);
  transform-origin: 50% 50%;
  transform-box: view-box;
}
/* the eyes zoom out as a symbol zooms in, and back: both fade as they scale */
.tess-box[data-tess-show="symbol"] .tess-face-eyes,
.tess-box[data-tess-show="none"] .tess-face-eyes { opacity: 0; transform: scale(0.6); }
.tess-box[data-tess-show="face"] .tess-face-symbol,
.tess-box[data-tess-show="none"] .tess-face-symbol { opacity: 0; transform: scale(0.35); }
.tess-face-mover { transition: opacity 0.6s ease; }
.tess-state-offline .tess-face-mover { opacity: 0.6; }
.tess-state-sleeping .tess-face-mover { opacity: 0.8; }

/* motion inside a symbol: a working indicator, like a spinner. It reports no event. */
.tess-sym-pulse { opacity: 1; }
.tess-sym-spin { transform-origin: 100px 100px; }
.tess-animated .tess-sym-pulse { animation: tess-sym-pulse 1.2s ease-in-out infinite; }
.tess-animated .tess-sym-d2 { animation-delay: 0.2s; }
.tess-animated .tess-sym-d3 { animation-delay: 0.4s; }
.tess-animated .tess-sym-spin { animation: tess-spin 1.6s linear infinite; }
@keyframes tess-sym-pulse {
  0%, 100% { opacity: 0.35; }
  50% { opacity: 1; }
}

/* ---------- the ring ---------------------------------------------------------- */
.tess-ring {
  color: var(--tess-orb-ring, #8FEFFF);
  transition: opacity 0.6s ease;
}
.tess-ring-spin { transform-origin: 50% 50%; }
.tess-ring-a { animation: tess-spin 16s linear infinite; }
.tess-ring-b { animation: tess-spin 48s linear infinite reverse; }
.tess-root:not(.tess-animated) .tess-ring-spin { animation-play-state: paused; }
.tess-box[data-tess-ring="stopped"] > .tess-ring { opacity: 0.3; }
.tess-box[data-tess-ring="stopped"] > .tess-ring-spin { animation-play-state: paused; }
/* ---------- the still body (no WebGL): offline drains its colour -------------- */
.tess-still { transition: filter 0.6s ease; }
.tess-state-offline .tess-still { filter: grayscale(0.9) brightness(0.8); }
.tess-state-sleeping .tess-still { filter: grayscale(0.35) brightness(0.9); }

/* ---------- agent orb: a small Tess Core (0.4.0) ------------------------------
   Tess Core's still body and ring with a white task symbol in place of her eyes and
   a state badge on the rim. The box holds the whole drawing. Colour by state (V2):
   cyan / blue active, purple working, green success, amber warning, red failure,
   muted grey offline. Every state also has its own badge symbol and its own words. */
.tess-agent {
  --tess-agent-tone: var(--tess-orb-ring, #8FEFFF);
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  vertical-align: middle;
  line-height: 1.2;
  -webkit-tap-highlight-color: transparent;
}
.tess-agent-box {
  position: relative;
  display: block;
  width: var(--tess-size, 44px);
  aspect-ratio: 1 / 1;
}
.tess-agent-button { width: auto; }
.tess-agent-svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  overflow: visible;
  color: var(--tess-agent-tone);
  transition: filter 0.6s ease, opacity 0.6s ease;
}
.tess-agent-halo { opacity: 0; transition: opacity 0.6s ease; }
.tess-agent-ring { color: var(--tess-agent-tone); transition: opacity 0.6s ease; }
.tess-agent-ring-a,
.tess-agent-ring-b { transform-origin: 100px 100px; transform-box: view-box; }
.tess-agent-glyph { stroke: var(--tess-eye, #fff); transition: opacity 0.6s ease; }
.tess-agent-badge-bg { fill: var(--tess-badge-bg); stroke: var(--tess-agent-tone); }
.tess-agent-badge-icon { stroke: var(--tess-badge-fg); }
/* the badge's symbol fades as Tess Core's symbols do: 420 ms, the same curve, an empty beat between */
.tess-agent-badge .tess-agent-badge-icon { transition: opacity 420ms cubic-bezier(0.23, 1, 0.32, 1); }
.tess-agent-badge[data-tess-show="none"] .tess-agent-badge-icon { opacity: 0; }
.tess-agent-label {
  font-family: inherit;
  font-weight: 600;
  font-size: 12px;
  line-height: 1.2;
  color: var(--tess-text, inherit);
  text-align: center;
}
.tess-agent-status {
  font-family: inherit;
  font-weight: 500;
  font-size: 11px;
  line-height: 1.2;
  color: var(--tess-text-muted, inherit);
  text-align: center;
}

/* Colour of each state. A host may set these four custom properties to its own colours. */
.tess-agent-state-working { --tess-agent-tone: var(--tess-agent-working, #A68CFF); }
.tess-agent-light.tess-agent-state-working { --tess-agent-tone: var(--tess-agent-working, #6A48E8); }
.tess-agent-state-completed { --tess-agent-tone: var(--tess-success, #2BB673); }
.tess-agent-state-warning,
.tess-agent-state-awaiting-approval { --tess-agent-tone: var(--tess-warning, #F5A524); }
.tess-agent-state-failed,
.tess-agent-state-blocked { --tess-agent-tone: var(--tess-error, #F08A7B); }
.tess-agent-state-unavailable,
.tess-agent-state-unknown { --tess-agent-tone: var(--tess-agent-offline, #8A93B0); }
.tess-agent-light.tess-agent-state-unavailable,
.tess-agent-light.tess-agent-state-unknown { --tess-agent-tone: var(--tess-agent-offline, #7A8199); }

/* What else tells the states apart, besides the badge and the words */
.tess-agent-state-dormant .tess-agent-glyph { opacity: 0.72; }
.tess-agent-state-working .tess-agent-halo { opacity: 0.55; }
.tess-agent-state-warning .tess-agent-halo,
.tess-agent-state-awaiting-approval .tess-agent-halo,
.tess-agent-state-blocked .tess-agent-halo,
.tess-agent-state-failed .tess-agent-halo { opacity: 0.4; }
.tess-agent-state-completed .tess-agent-halo { opacity: 0.25; }
.tess-agent-state-blocked .tess-agent-ring { opacity: 0.6; }
/* unavailable: drained and resting, as Tess Core is when offline */
.tess-agent-state-unavailable .tess-agent-svg { filter: grayscale(0.9) brightness(0.8); }
.tess-agent-state-unavailable .tess-agent-ring { opacity: 0.3; }
.tess-agent-state-unavailable .tess-agent-glyph { opacity: 0.6; }
/* unknown: the state went stale, was never reported, or was not a state the library knows.
   Neutral on purpose: no colour, no glow, a question mark in the badge, and nothing that moves.
   It must never read as idle or as working. */
.tess-agent-state-unknown .tess-agent-svg { filter: grayscale(1); }
.tess-agent-state-unknown .tess-agent-svg { opacity: 0.7; }
.tess-agent-state-unknown .tess-agent-ring { opacity: 0.3; }
.tess-agent-state-unknown .tess-agent-glyph { opacity: 0.55; }
.tess-agent-state-unknown .tess-agent-halo { opacity: 0; animation: none; }
.tess-agent-state-unknown .tess-agent-ring-a,
.tess-agent-state-unknown .tess-agent-ring-b { animation: none; }

/* Motion. The script adds .tess-agent-animated only to a live orb (not example, not still, not under
   reduced motion) that is on screen and in a state whose ring turns. Nothing animates without it.
   The ring turns at Tess Core's speeds; working makes it turn faster (by playbackRate, from the script)
   and the glow pulse. Working motion is never attached to an example orb. */
.tess-agent-animated .tess-agent-ring-a { animation: tess-spin 16s linear infinite; }
.tess-agent-animated .tess-agent-ring-b { animation: tess-spin 48s linear infinite reverse; }
.tess-agent-animated.tess-agent-state-working:not(.tess-agent-example):not(.tess-rm):not(.tess-agent-still) .tess-agent-halo { animation: tess-agent-pulse 2.4s ease-in-out infinite; }
@keyframes tess-agent-pulse {
  0%, 100% { opacity: 0.3; }
  50% { opacity: 0.85; }
}

/* example data: a hook, not words. The orb carries .tess-agent-example and
   data-tess-example="true"; the mark is an empty element the host styles and labels
   (the exampleLabel option, or its own stylesheet). By default the orb gets a dashed outline,
   so an example is visibly not live even where the host adds nothing. */
.tess-agent-example .tess-agent-box {
  outline: 1px dashed var(--tess-example, var(--tess-text-muted, currentColor));
  outline-offset: 3px;
  border-radius: 50%;
}
.tess-agent-example-mark { display: none; }
.tess-agent-example .tess-agent-example-mark:not(:empty) {
  display: block;
  position: absolute;
  left: 50%;
  bottom: 100%;
  transform: translate(-50%, -5px);
  padding: 1px 5px;
  border: 1px dashed var(--tess-example, var(--tess-text-muted, currentColor));
  border-radius: 3px;
  background: var(--tess-chip-bg, transparent);
  color: var(--tess-text, inherit);
  font-family: inherit;
  font-weight: 600;
  font-size: 9px;
  line-height: 1.3;
  white-space: nowrap;
  pointer-events: none;
}
.tess-chip-example { border-style: dashed; }
@keyframes tess-spin {
  to { transform: rotate(360deg); }
}

/* ---------- delegation arc --------------------------------------------------- */
.tess-arc-layer {
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  z-index: var(--tess-arc-z, 40);
  pointer-events: none;
  overflow: visible;
}
.tess-arc-hidden { display: none; }
.tess-arc-path,
.tess-arc-glow,
.tess-arc-flow,
.tess-arc-head {
  fill: none;
  stroke: var(--tess-ring-bright, #7FE9FF);
  stroke-linecap: round;
  stroke-linejoin: round;
  opacity: 0;
  transition: opacity 0.35s ease;
}
.tess-arc-path { stroke-width: 1.5; }
.tess-arc-glow { stroke-width: 8; }
.tess-arc-flow { stroke-width: 2.5; stroke-dasharray: 10 22; }
.tess-arc-head { stroke-width: 2; }
.tess-arc-active .tess-arc-path { opacity: 0.75; }
.tess-arc-active .tess-arc-glow { opacity: 0.16; }
.tess-arc-active .tess-arc-head { opacity: 0.95; }
.tess-arc-active .tess-arc-flow { opacity: 0.95; animation: tess-arc-flow 1.1s linear infinite; }
.tess-arc-active.tess-arc-steady .tess-arc-flow { opacity: 0; animation: none; }
.tess-arc-active.tess-arc-steady .tess-arc-path { opacity: 0.5; }
.tess-arc-layer.tess-rm .tess-arc-flow { animation: none; opacity: 0; }
@keyframes tess-arc-flow {
  to { stroke-dashoffset: -32; }
}

/* ---------- status chip (board panels 3 and 5) ------------------------------- */
.tess-chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  box-sizing: border-box;
  min-height: 32px;
  padding: 6px 14px 6px 10px;
  border: 1px solid var(--tess-chip-border, #26357A);
  border-radius: 999px;
  background: var(--tess-chip-bg, #111C4A);
  color: var(--tess-text, #EEF3FF);
  font-family: inherit;
  font-weight: 500;
  font-size: 14px;
  line-height: 1.2;
  white-space: nowrap;
}
.tess-chip-icon {
  flex: none;
  width: 18px;
  height: 18px;
  fill: none;
  stroke: var(--tess-ring-bright, #7FE9FF);
  stroke-width: 0.2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.tess-chip-state-success .tess-chip-icon,
.tess-chip-state-completed .tess-chip-icon { stroke: var(--tess-success, #2BB673); }
.tess-chip-state-warning .tess-chip-icon,
.tess-chip-state-blocked .tess-chip-icon,
.tess-chip-state-awaiting-approval .tess-chip-icon,
.tess-chip-state-waiting-approval .tess-chip-icon { stroke: var(--tess-warning, #F5A524); }
.tess-chip-state-error .tess-chip-icon,
.tess-chip-state-failed .tess-chip-icon { stroke: var(--tess-error, #F08A7B); }
.tess-chip-state-offline,
.tess-chip-state-unavailable,
.tess-chip-state-unknown,
.tess-chip-state-dormant { opacity: 0.75; }

/* ---------- reduced motion: the orb is still, her eyes are still, the ring does not turn.
   States still change, by a short fade of opacity only. ------------------------- */
.tess-rm,
.tess-rm * {
  animation: none !important;
  transition: none !important;
}
.tess-rm .tess-box .tess-face-eyes,
.tess-rm .tess-box .tess-face-symbol {
  transition: opacity 200ms ease !important;
  transform: none !important;
}
.tess-agent.tess-rm .tess-agent-badge-icon { transition: opacity 200ms ease !important; }
@media (prefers-reduced-motion: reduce) {
  .tess-root:not(.tess-motion-forced) *,
  .tess-agent:not(.tess-motion-forced) *,
  .tess-arc-layer * {
    animation: none !important;
    transition: none !important;
  }
  .tess-root:not(.tess-motion-forced) .tess-box .tess-face-eyes,
  .tess-root:not(.tess-motion-forced) .tess-box .tess-face-symbol {
    transition: opacity 200ms ease !important;
    transform: none !important;
  }
  .tess-agent:not(.tess-motion-forced) .tess-agent-badge-icon { transition: opacity 200ms ease !important; }
}

/* ---------- still: one fixed frame per state, for visual checks ------------------
   The `still` option of mount / mountAgent. Nothing animates and nothing fades: a state is
   swapped in at once, the ring does not turn, a symbol does not pulse. These rules come last
   and beat the reduced-motion fades above. (Under `still` the script side runs no animation
   loop either: see docs/TESS_LIVING_IDENTITY.md, section 7.) */
.tess-still-mode,
.tess-still-mode *,
.tess-agent-still,
.tess-agent-still * {
  animation: none !important;
  transition: none !important;
}
.tess-root.tess-still-mode .tess-box .tess-face-eyes,
.tess-root.tess-still-mode .tess-box .tess-face-symbol {
  transition: none !important;
  transform: none !important;
}
