/* =============================================================================
   ASSISTANT SUMMON FAB
   Bottom-right summoning element. Just the assistant portrait sitting on the
   squared-paper canvas — no card, no ring, no shadow. Tap fans out three
   small satellites: + capture / mic / chat.
   ============================================================================= */

.assistant-summon {
  position: fixed;
  right: var(--space-5);
  bottom: var(--space-5);
  z-index: var(--z-fab, 90);
  display: flex;
  align-items: flex-end;
  justify-content: flex-end;
  pointer-events: none;
}

.assistant-summon > * {
  pointer-events: auto;
}

/* -----------------------------------------------------------------------------
   Portrait — the click target. Chrome-less; the SVG's own ink is the edge.
   ----------------------------------------------------------------------------- */

.assistant-summon__portrait {
  position: relative;
  z-index: 2;
  width: 64px;
  height: 64px;
  padding: 0;
  border: none;
  background: transparent;
  cursor: pointer;
  display: block;
  transition: transform var(--transition-fast);
}

.assistant-summon__portrait:hover {
  transform: scale(1.04);
}

.assistant-summon__portrait:active {
  transform: scale(0.96);
}

.assistant-summon__portrait:focus-visible {
  outline: 2px solid var(--color-text-main);
  outline-offset: 4px;
  border-radius: var(--radius-full);
}

.assistant-summon__portrait-mount {
  display: block;
  width: 100%;
  height: 100%;
}

.assistant-summon__portrait-img,
.assistant-summon__portrait-svg {
  display: block;
  width: 100%;
  height: 100%;
}

.assistant-summon__portrait-img {
  object-fit: contain;
}

/* The breathe oscillation can push the head a fraction above the SVG viewport;
   `overflow: visible` keeps it from clipping. */
.assistant-summon__portrait-svg {
  overflow: visible;
}

/* When open, slight lift on portrait so the satellites read as flowing from it */
.assistant-summon[data-open="true"] .assistant-summon__portrait {
  transform: scale(0.92);
}

/* -----------------------------------------------------------------------------
   Movement — idle breathe, blink, hover head-tilt, one-shot nod.
   The portrait SVGs ship with three nested groups: <g class="a-body"> wraps
   everything, <g class="a-head"> wraps just head/face content, <g class="a-eyes">
   wraps the eye whites/pupils/highlights. Per-character cadence comes from
   data-assistant overriding the duration/delay custom properties.
   ----------------------------------------------------------------------------- */

.assistant-summon .a-body,
.assistant-summon .a-head,
.assistant-summon .a-eyes {
  transform-box: fill-box;
}

.assistant-summon .a-body {
  animation: a-breathe var(--portrait-breathe-dur, 4.4s) ease-in-out infinite;
}

.assistant-summon .a-eyes {
  transform-origin: 50% 50%;
  animation: a-blink var(--portrait-blink-period, 5s) linear infinite;
  animation-delay: var(--portrait-blink-delay, 0s);
}

.assistant-summon .a-head {
  /* Pivot at the bottom edge of the head's bounding box (≈ the neck) */
  transform-origin: 50% 100%;
  transition: transform 0.4s ease-out;
}

/* Per-character timings: Saga slowest (calm), Iris fastest (energetic).
   Blink delays are staggered so multiple portraits in view never sync. */
.assistant-summon[data-assistant="saga"] {
  --portrait-breathe-dur: 5.4s;
  --portrait-blink-period: 5.6s;
  --portrait-blink-delay: 0s;
}
.assistant-summon[data-assistant="felix"] {
  --portrait-breathe-dur: 4.4s;
  --portrait-blink-period: 5.0s;
  --portrait-blink-delay: 1.3s;
}
.assistant-summon[data-assistant="arvid"] {
  --portrait-breathe-dur: 4.0s;
  --portrait-blink-period: 5.3s;
  --portrait-blink-delay: 2.7s;
}
.assistant-summon[data-assistant="iris"] {
  --portrait-breathe-dur: 3.4s;
  --portrait-blink-period: 4.6s;
  --portrait-blink-delay: 0.8s;
}

@keyframes a-breathe {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-1.6px); }
}

@keyframes a-blink {
  0%, 92%, 100% { transform: scaleY(1); }
  96%           { transform: scaleY(0.08); }
}

@keyframes a-nod {
  0%   { transform: rotate(0deg); }
  22%  { transform: rotate(-3.2deg); }
  58%  { transform: rotate(2deg); }
  100% { transform: rotate(0deg); }
}

.assistant-summon.is-nodding .a-head {
  animation: a-nod 0.72s ease-in-out;
}

/* Hover wakes the head with a subtle tilt — composes with the breathe on body */
.assistant-summon__portrait:hover .a-head {
  transform: rotate(-1.6deg);
}

/* --- Onboarding variant -----------------------------------------------------
   Larger portrait (96px) at the same bottom-right anchor, no satellites,
   no click. Reuses every animation rule above so breathe + blink + nod
   work without duplication. */

.assistant-summon--xl .assistant-summon__portrait {
  width: 96px;
  height: 96px;
}

.assistant-summon--inert .assistant-summon__portrait {
  cursor: default;
  pointer-events: none;
}

.assistant-summon--inert .assistant-summon__portrait:hover {
  transform: none;
}

.assistant-summon--inert .assistant-summon__portrait:hover .a-head {
  transform: none;
}

/* Inline variant — drops the fixed positioning so the element flows in normal
   layout. Used by the logged-in landing hero (above the greeting). */
.assistant-summon--inline {
  position: static;
  right: auto;
  bottom: auto;
  display: block;
  pointer-events: auto;
}

/* Landing hero — sized to carry the page on its own. The split layout pairs
   it with the greeting on desktop, so it scales up substantially there. The
   wrapper has no inherent margins; the hero shell handles spacing. */
.assistant-summon--landing {
  margin: 0;
}

.assistant-summon--landing .assistant-summon__portrait {
  width: 160px;
  height: 160px;
}

@media (min-width: 900px) {
  .assistant-summon--landing .assistant-summon__portrait {
    width: 280px;
    height: 280px;
  }
}

@media (min-width: 1200px) {
  .assistant-summon--landing .assistant-summon__portrait {
    width: 320px;
    height: 320px;
  }
}

/* -----------------------------------------------------------------------------
   Desktop — larger touch target on hover-driven viewports.
   Mobile stays at 56px (thumb reach); desktop scales up proportionally.
   ----------------------------------------------------------------------------- */

@media (min-width: 1024px) {
  .assistant-summon {
    right: var(--space-6);
    bottom: var(--space-6);
  }

  .assistant-summon__portrait,
  .assistant-summon__satellites {
    width: 76px;
    height: 76px;
  }

  .assistant-summon__satellite {
    width: 48px;
    height: 48px;
    right: 14px;
    bottom: 14px;
  }

  .assistant-summon[data-open="true"] .assistant-summon__satellite--add {
    transform: translate(-110px, 0) scale(1);
  }
  .assistant-summon[data-open="true"] .assistant-summon__satellite--mic {
    transform: translate(-80px, -80px) scale(1);
  }
  .assistant-summon[data-open="true"] .assistant-summon__satellite--text {
    transform: translate(0, -110px) scale(1);
  }
}

/* -----------------------------------------------------------------------------
   Satellites — small chrome-less buttons fanning to the upper-left arc
   ----------------------------------------------------------------------------- */

.assistant-summon__satellites {
  position: absolute;
  right: 0;
  bottom: 0;
  width: 64px;
  height: 64px;
  pointer-events: none;
}

.assistant-summon__satellite {
  position: absolute;
  right: 10px;
  bottom: 10px;
  width: 44px;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1.5px solid var(--color-text-main);
  border-radius: var(--radius-full);
  background: var(--paper-bg, #f3e8d3);
  color: var(--color-text-main);
  cursor: pointer;
  opacity: 0;
  transform: translate(0, 0) scale(0.4);
  transition:
    transform 0.32s cubic-bezier(0.34, 1.56, 0.64, 1),
    opacity 0.18s ease-out;
  pointer-events: none;
}

.assistant-summon__satellite .material-symbols-rounded {
  font-size: var(--icon-lg);
}

.assistant-summon__satellite:hover {
  background: var(--color-bg-elevated, #fdf6e3);
}

.assistant-summon__satellite:active {
  transform: scale(0.94);
}

.assistant-summon__satellite:focus-visible {
  outline: 2px solid var(--color-text-main);
  outline-offset: 2px;
}

/* Open state — fan out on an upper-left arc with staggered spring */
.assistant-summon[data-open="true"] .assistant-summon__satellite {
  opacity: 1;
  pointer-events: auto;
}

/* +Add at 225° — straight left */
.assistant-summon[data-open="true"] .assistant-summon__satellite--add {
  transform: translate(-96px, 0) scale(1);
  transition-delay: 0s, 0s;
}

/* Mic at 180° — diagonal up-left */
.assistant-summon[data-open="true"] .assistant-summon__satellite--mic {
  transform: translate(-70px, -70px) scale(1);
  transition-delay: 0.04s, 0.04s;
}

/* Chat at 135° — straight up */
.assistant-summon[data-open="true"] .assistant-summon__satellite--text {
  transform: translate(0, -96px) scale(1);
  transition-delay: 0.08s, 0.08s;
}

/* -----------------------------------------------------------------------------
   Reduced motion — skip the spring, instant reveal
   ----------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  .assistant-summon__satellite {
    transition: opacity 0.1s linear;
  }
  .assistant-summon__portrait {
    transition: none;
  }
  .assistant-summon .a-body,
  .assistant-summon .a-eyes,
  .assistant-summon.is-nodding .a-head {
    animation: none;
  }
  .assistant-summon .a-head {
    transition: none;
  }
  .assistant-summon__portrait:hover .a-head {
    transform: none;
  }
}
