/* =======================================================================
   AI PORTUGUESE TEACHER — floating chat launcher + panel
   Site-wide (unlike the level-specific Dictionary widget), so placed
   on the opposite (left) corner to avoid crowding the existing
   back-to-top stack on the right.
   ======================================================================= */

.ai-teacher-toggle {
  position: fixed;
  left: var(--space-md);
  bottom: calc(var(--space-md) + env(safe-area-inset-bottom, 0px));
  z-index: 900;
  display: inline-flex;
  align-items: center;
  gap: 0.5em;
  padding: 0.75em 1.1em;
  border-radius: 999px;
  border: none;
  background: var(--color-accent);
  color: var(--parchment-100);
  font-weight: 700;
  font-size: var(--step--1);
  cursor: pointer;
  box-shadow: var(--shadow-lg);
  transition: transform var(--duration-fast) var(--ease-standard),
              opacity var(--duration-slow) var(--ease-standard);
}
.ai-teacher-toggle:hover { transform: translateY(-2px); }
.ai-teacher-toggle svg { width: 20px; height: 20px; flex-shrink: 0; }
.ai-teacher-toggle__label { white-space: nowrap; }
@media (max-width: 560px) {
  .ai-teacher-toggle { padding: 0.7em; }
  .ai-teacher-toggle__label { display: none; }
}

/* ---------------------------------------------------------------------
   Sunrise medallion intro (assets/js/ai-teacher.js)
   Once per browser tab session (sessionStorage key "aiTeacherIntroShown",
   see ai-teacher.js), the AI Teacher button starts hidden
   (.ai-teacher-toggle--pending) while a small round medallion — a
   green seal with a gold sunrise over a thin terracotta horizon line —
   rises into place for ~2.2s (INTRO_WAVE_MS in ai-teacher.js — keep
   the two in sync). Deliberately not a flag or any national emblem:
   tokens.css documents this site's palette as "uma paisagem, não um
   cartaz" (a landscape, not a poster) and explicitly rules out flag
   imagery, so the medallion uses a plain sunrise-over-horizon motif
   from that same landscape palette instead, and "rises" rather than
   "waves" since a circular badge has no natural hinge edge to flutter
   from the way a rectangular banner does. Comes with a golden sparkle
   burst on the medallion itself (reuses .xp-burst/.xp-burst__spark
   from the gamification toasts, see components.css) partway through
   the rise, PLUS several more of the same bursts scattered at random
   points around the medallion/button corner (.ai-teacher-fireworks /
   .ai-teacher-fireworks__spot below — see buildScatteredFireworks()
   in ai-teacher.js), so the moment reads as fireworks around that
   whole area rather than one fixed sparkle. Then the medallion is
   removed and the real button fades/scales in. Skipped entirely
   under prefers-reduced-motion or once the session flag is set, in
   which case the button just renders normally with no extra markup
   or delay.
   --------------------------------------------------------------------- */
.ai-teacher-toggle--pending {
  opacity: 0;
  /* transform: scale(), not the bare `scale` property — broader
     mobile-browser support (the individual transform properties are a
     newer addition WebKit only shipped from iOS 14.5) for what's
     otherwise an identical effect. */
  transform: scale(0.85);
  pointer-events: none;
}
.ai-teacher-intro {
  position: fixed;
  left: var(--space-md);
  bottom: calc(var(--space-md) + env(safe-area-inset-bottom, 0px));
  z-index: 900;
  display: inline-flex;
  align-items: center;
  height: 44px;
  pointer-events: none;
}
.ai-teacher-intro__medallion {
  width: 52px;
  height: 52px;
  transform-origin: 50% 50%;
  filter: drop-shadow(0 6px 14px rgba(0, 0, 0, 0.35));
  animation: ai-medallion-rise 2.2s ease-in-out 1 both;
}
@keyframes ai-medallion-rise {
  0%   { transform: translateY(10px) scale(0.5) rotate(-8deg); opacity: 0; }
  10%  { opacity: 1; }
  40%  { transform: translateY(-3px) scale(1.08) rotate(4deg); }
  60%  { transform: translateY(1px) scale(0.98) rotate(-2deg); }
  80%  { transform: translateY(-1px) scale(1.02) rotate(1deg); }
  100% { transform: translateY(0) scale(1) rotate(0deg); opacity: 1; }
}
@media (max-width: 480px) {
  .ai-teacher-intro { left: var(--space-sm); bottom: calc(var(--space-sm) + env(safe-area-inset-bottom, 0px)); }
}

/* Scattered fireworks zone — a fixed, invisible box hugging the same
   corner as .ai-teacher-intro/.ai-teacher-toggle (deliberately bigger
   than the medallion itself, since "the general AI Teacher area" includes
   the button it un-hides into). buildScatteredFireworks() drops a
   handful of .ai-teacher-fireworks__spot points at random positions
   inside it, each hosting its own small .xp-burst — see the JS for
   why. The zone itself is never visible or interactive. */
.ai-teacher-fireworks {
  position: fixed;
  left: var(--space-md);
  bottom: calc(var(--space-md) + env(safe-area-inset-bottom, 0px));
  width: 170px;
  height: 130px;
  z-index: 899;
  pointer-events: none;
}
@media (max-width: 480px) {
  .ai-teacher-fireworks { left: var(--space-sm); bottom: calc(var(--space-sm) + env(safe-area-inset-bottom, 0px)); }
}
.ai-teacher-fireworks__spot {
  position: absolute;
  /* left/top set inline, per spot, to a random % within the zone. */
}

/* Panel geometry — kept fully on-screen at any viewport size via two
   shared custom properties rather than hard-coded numbers baked into
   both `bottom` and `max-height` separately:
   --ai-panel-bottom-gap: distance reserved below the panel (clears the
     launcher button); --ai-panel-top-gap: matching margin reserved
     above it. max-height is *derived* from those two gaps plus the
     viewport height, so the panel can never compute a height that
     pushes its top off-screen — it always leaves --ai-panel-top-gap of
     breathing room, on any phone, not just the ~375-414px range this
     was eyeballed against. env(safe-area-inset-*) keeps both gaps
     clear of notches/home-indicators on devices that report them.
   --ai-kb-offset defaults to 0px and is written by ai-teacher.js (via
   the VisualViewport API) once the on-screen keyboard opens — iOS
   Safari doesn't shrink 100vh/100dvh for the keyboard the way it does
   for browser-chrome changes, so a fixed-position panel needs that JS
   nudge to stay above the keyboard instead of being covered by it.
   --ai-panel-top-gap includes --header-height, not just breathing
   room: .site-header is sticky with a higher z-index (1000 vs. this
   panel's 901), so on short viewports letting the panel's max-height
   grow into that band would tuck the panel's own bar — brand label
   *and* its close button — behind the site header, leaving no visible
   way to close it. */
.ai-teacher-panel {
  --ai-panel-bottom-gap: calc(var(--space-md) + 64px);
  --ai-panel-top-gap: calc(var(--header-height) + var(--space-sm));
  position: fixed;
  left: var(--space-md);
  bottom: calc(var(--ai-panel-bottom-gap) + env(safe-area-inset-bottom, 0px) + var(--ai-kb-offset, 0px));
  z-index: 901;
  width: min(380px, calc(100vw - 2 * var(--space-md)));
  max-width: calc(100vw - 2 * var(--space-md));
  /* vh fallback first for browsers without dvh support (invalid dvh
     value leaves this earlier declaration in place); dvh afterwards
     tracks the browser's dynamic toolbar so the cap doesn't leave a
     stale gap once the address bar collapses on scroll. */
  max-height: min(560px, calc(100vh - var(--ai-panel-bottom-gap) - var(--ai-panel-top-gap) - env(safe-area-inset-bottom, 0px) - env(safe-area-inset-top, 0px) - var(--ai-kb-offset, 0px)));
  max-height: min(560px, calc(100dvh - var(--ai-panel-bottom-gap) - var(--ai-panel-top-gap) - env(safe-area-inset-bottom, 0px) - env(safe-area-inset-top, 0px) - var(--ai-kb-offset, 0px)));
  display: flex;
  flex-direction: column;
  background: var(--color-surface-raised);
  border: 2px solid var(--color-accent);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg);
  overflow: hidden;
  /* Stops a scroll gesture inside the panel (e.g. flung past the top/
     bottom of the messages list) from "chaining" into the page behind
     it — on iOS Safari that scroll-chaining is what makes the whole
     page rubber-band/shift after the panel opens, one of the ways the
     page can appear to "lose proportions" once you start scrolling a
     chat reply. */
  overscroll-behavior: contain;
}
.ai-teacher-panel[hidden] { display: none; }

.ai-teacher-panel__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-sm);
  padding: 0.8em 0.9em;
  background: var(--color-primary-strong);
  color: var(--color-text-on-dark);
  flex-shrink: 0;
}
.ai-teacher-panel__brand { display: flex; align-items: center; gap: 0.6em; min-width: 0; }
.ai-teacher-panel__brand-icon { width: 24px; height: 24px; flex-shrink: 0; color: var(--gold-300); }
.ai-teacher-panel__brand strong { display: block; font-size: var(--step--1); }
.ai-teacher-panel__brand span { display: block; font-size: 0.72rem; color: var(--color-text-on-dark-muted); }
.ai-teacher-panel__close {
  flex-shrink: 0;
  width: 28px; height: 28px;
  border-radius: 50%;
  border: 1px solid rgba(255,255,255,0.3);
  background: transparent;
  color: inherit;
  display: inline-flex; align-items: center; justify-content: center;
  cursor: pointer;
}
.ai-teacher-panel__close svg { width: 14px; height: 14px; }

.ai-teacher-panel__messages {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: var(--space-sm) var(--space-md);
  display: flex;
  flex-direction: column;
  gap: 0.6em;
}
.ai-teacher-msg p {
  margin: 0;
  padding: 0.6em 0.85em;
  border-radius: var(--radius-md);
  font-size: var(--step--1);
  line-height: 1.5;
  max-width: 88%;
}
.ai-teacher-msg--bot p { background: var(--color-surface); color: var(--color-text); border-bottom-left-radius: 2px; }
.ai-teacher-msg--user { display: flex; justify-content: flex-end; }
.ai-teacher-msg--user p { background: var(--color-accent); color: #fff; border-bottom-right-radius: 2px; }

.ai-teacher-msg--typing p {
  display: inline-flex;
  gap: 4px;
  align-items: center;
  padding: 0.8em 0.9em;
}
.ai-teacher-msg--typing span {
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--color-text-muted);
  animation: ai-typing-bounce 1.1s infinite ease-in-out;
}
.ai-teacher-msg--typing span:nth-child(2) { animation-delay: 0.15s; }
.ai-teacher-msg--typing span:nth-child(3) { animation-delay: 0.3s; }
@keyframes ai-typing-bounce {
  0%, 60%, 100% { transform: translateY(0); opacity: 0.5; }
  30% { transform: translateY(-4px); opacity: 1; }
}

.ai-teacher-panel__form {
  display: flex;
  align-items: flex-end;
  gap: 0.5em;
  padding: 0.7em 0.8em;
  border-top: var(--border-hairline);
  flex-shrink: 0;
}
.ai-teacher-panel__form textarea {
  flex: 1;
  resize: none;
  max-height: 120px;
  border: var(--border-hairline);
  border-radius: var(--radius-md);
  padding: 0.55em 0.8em;
  font: inherit;
  /* Fixed at 16px rather than var(--step--1) (~13-14px): iOS Safari
     auto-zooms the whole page in on focus for any text input under
     16px, and toggleOpen() in ai-teacher.js focuses this the instant
     the panel opens. Below 16px that zoom fires immediately on tap and
     doesn't always settle back to 100% on its own — exactly the
     "loses proportions after opening" bug. 16px is the documented iOS
     threshold that suppresses the zoom entirely. */
  font-size: 16px;
  background: var(--color-surface);
  color: var(--color-text);
  line-height: 1.4;
}
.ai-teacher-panel__form textarea:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 1px;
}
.ai-teacher-panel__send {
  flex-shrink: 0;
  width: 38px; height: 38px;
  border-radius: 50%;
  border: none;
  background: var(--color-accent);
  color: #fff;
  display: inline-flex; align-items: center; justify-content: center;
  cursor: pointer;
}
.ai-teacher-panel__send svg { width: 16px; height: 16px; }
.ai-teacher-panel__send:disabled,
.ai-teacher-panel__form textarea:disabled { opacity: 0.6; cursor: not-allowed; }

.ai-teacher-panel__hint {
  padding: 0 0.9em 0.7em;
  font-size: 0.72rem;
  color: var(--color-text-muted);
  flex-shrink: 0;
}

@media (max-width: 480px) {
  .ai-teacher-panel {
    left: var(--space-sm);
    right: var(--space-sm);
    width: auto;
    max-width: none;
    /* Redeclaring the two gap variables is enough — `bottom` and both
       `max-height` rules above read from them, so the on-screen
       geometry stays consistent without repeating the calc() here. */
    --ai-panel-bottom-gap: calc(var(--space-sm) + 60px);
    --ai-panel-top-gap: calc(var(--header-height) + var(--space-2xs));
  }
  .ai-teacher-toggle { left: var(--space-sm); bottom: calc(var(--space-sm) + env(safe-area-inset-bottom, 0px)); }
}
