/* =========================================================
   ZAR AI v2 — FLOATING ORB (STATE A)

   2026-09 finalization: the launcher button IS the single
   circular halo/container. The logo sits directly inside it —
   no second wrapper, no nested halo, no nested background circle
   around the image itself (see components/icon.css for the bare
   logo rule that applies everywhere else). The logo is sized to
   ~80% of the button's diameter and centered by the button's own
   flex layout.

   Interaction states, deliberately kept to one each:
   - idle: a restrained breathing halo (::before) — a resting-
     state "alive" cue, not a hover/focus treatment.
   - hover/focus-hover: a single lift (translateY). Keyboard
     focus additionally gets the shared, independent
     :focus-visible ring from base/typography.css — never
     replaced or duplicated by this file.
   - open (.is-active): a single accent border change, so the
     launcher visibly reflects that its panel is open without
     adding another glow layer.
========================================================= */

.zar-v2-orb {
  position: fixed;
  right: 24px;
  bottom: 24px;
  z-index: var(--zar-v2-z-orb);

  width: 56px;
  height: 56px;
  border-radius: var(--zar-v2-radius-circle);

  display: flex;
  align-items: center;
  justify-content: center;

  background: var(--zar-v2-bg-surface-raised);
  border: 1px solid var(--zar-v2-border-strong);
  box-shadow: var(--zar-v2-shadow-orb);

  /* Draggable launcher (2026-09): the orb's default position stays
     the existing `right`/`bottom` fixed offset — dragging LAYERS a
     translate on top via these two custom properties, which
     Scripts/shared/ai/zar-v2/zar-v2-launcher-drag.js (a thin
     wrapper around the same shared Scripts/shared/ui/
     zar_draggable_panel.js the help-bulb lightbulb already uses)
     writes to during a drag and restores from localStorage on
     mount. Never 0-specificity-reset by base/reset.css's `:where()`
     button rule, since this is this component's own class. */
  --zar-v2-drag-x: 0px;
  --zar-v2-drag-y: 0px;
  transform: translate(var(--zar-v2-drag-x), var(--zar-v2-drag-y));

  transition: transform var(--zar-v2-duration-base) var(--zar-v2-ease-emphasized),
              border-color var(--zar-v2-duration-fast) var(--zar-v2-ease-standard);
}

/* Hover/active lifts must COMPOSE with the drag offset, not replace
   it — otherwise hovering a dragged orb would visually snap it back
   to its un-dragged corner until the pointer left. */
.zar-v2-orb:hover {
  transform: translate(var(--zar-v2-drag-x), calc(var(--zar-v2-drag-y) - 2px));
}
.zar-v2-orb:active {
  transform: translate(var(--zar-v2-drag-x), var(--zar-v2-drag-y));
}

/* No transform transition while a drag is actively in progress —
   the position must track the pointer 1:1, not ease toward it.
   `.is-dragging` is the shared drag-helper's own default class
   (see zar_draggable_panel.js); scoped here rather than added to
   index.php's generic `.is-dragging` rule, which only lists
   cursor, not transition, for the un-scoped case. */
.zar-v2-orb.is-dragging {
  transition: none;
}

.zar-v2-orb.is-active {
  border-color: var(--zar-v2-orb-active-border);
}

/* Idle breathing halo — sits behind the button (negative z-index),
   never wraps the logo itself. */
.zar-v2-orb::before {
  content: "";
  position: absolute;
  inset: -14px;
  border-radius: var(--zar-v2-radius-circle);
  background: var(--zar-v2-orb-halo);
  animation: zar-v2-orb-breathe var(--zar-v2-duration-pulse) var(--zar-v2-ease-standard) infinite;
  pointer-events: none;
  z-index: -1;
}

.zar-v2-orb::after {
  content:""; position:absolute; inset:-6px; border-radius:50%; pointer-events:none; opacity:0;
  border:2px solid transparent; border-top-color:var(--zar-v2-accent); border-right-color:var(--zar-v2-border-focus);
}
.zar-v2[data-zar-v2-bootstrap="loading"] .zar-v2-orb { pointer-events:none; cursor:wait; }
.zar-v2[data-zar-v2-bootstrap="loading"] .zar-v2-orb::before { animation:none; opacity:.35; }
.zar-v2[data-zar-v2-bootstrap="loading"] .zar-v2-orb::after { opacity:1; animation:zar-v2-orb-loading .9s linear infinite; }
.zar-v2-orb.is-ready-heartbeat::after { border-color:var(--zar-v2-accent); animation:zar-v2-orb-ready-heartbeat .9s var(--zar-v2-ease-emphasized) 1; }

.zar-v2-orb__logo {
  display: block;
  width: 80%;
  height: 80%;
  max-width: none;
  object-fit: contain;
}

.zar-v2-orb__tooltip {
  position: absolute;
  right: calc(100% + var(--zar-v2-space-3));
  top: 50%;
  transform: translateY(-50%) translateX(4px);

  padding: var(--zar-v2-space-2) var(--zar-v2-space-3);
  border-radius: var(--zar-v2-radius-sm);
  border: 1px solid var(--zar-v2-border-subtle);
  background: var(--zar-v2-bg-surface-raised);
  color: var(--zar-v2-text-primary);
  font-size: var(--zar-v2-font-size-xs);
  font-weight: var(--zar-v2-font-weight-semibold);
  white-space: nowrap;
  box-shadow: var(--zar-v2-shadow-2);

  opacity: 0;
  pointer-events: none;
  transition: opacity var(--zar-v2-duration-fast) var(--zar-v2-ease-standard),
              transform var(--zar-v2-duration-fast) var(--zar-v2-ease-standard);
}

.zar-v2-orb:hover .zar-v2-orb__tooltip,
.zar-v2-orb:focus-visible .zar-v2-orb__tooltip {
  opacity: 1;
  transform: translateY(-50%) translateX(0);
}

.zar-v2-orb[hidden] { display: none; }

@keyframes zar-v2-orb-breathe {
  0%, 100% { opacity: 0.55; transform: scale(1); }
  50%      { opacity: 0.85; transform: scale(1.06); }
}
@keyframes zar-v2-orb-loading { to { transform:rotate(360deg); } }
@keyframes zar-v2-orb-ready-heartbeat {
  0% { opacity:0; transform:scale(.92); }
  35% { opacity:.8; }
  100% { opacity:0; transform:scale(1.28); }
}

@media (prefers-reduced-motion: reduce) {
  .zar-v2-orb::before, .zar-v2-orb::after { animation: none !important; }
}

@media (max-width: 560px) {
  .zar-v2-orb {
    right: var(--zar-v2-space-4);
    bottom: var(--zar-v2-space-4);
    width: 52px;
    height: 52px;
  }
}
