/* ── Shared MOX launcher artwork sizing (single source of truth) ──────────────
   The MOX artwork (mox/mox-welcome.png) is PORTRAIT (1024×1536, ~2:3). All three
   surfaces (2D reference, public site, 3D) derive the visible artwork WIDTH from
   these variables and let height be auto, so they share one perceived size and
   can never drift back into a squashed square. The 2D studio is the reference:
   72px wide → 108px tall. */
:root {
  --mox-launcher-art-w: 72px;         /* desktop artwork width — 2D reference */
  --mox-launcher-art-w-mobile: 56px;  /* mobile proportional (container floors the ≥44px target) */
}

/* ── LML Assistant scrollbar */
#lml-assistant-body::-webkit-scrollbar { width:4px; }
#lml-assistant-body::-webkit-scrollbar-thumb { background:#374151; border-radius:2px; }

/* ── Message bubbles */
#lml-assistant-body .lml-msg {
  max-width:82%;
  margin-bottom:8px;
  padding:9px 13px;
  border-radius:12px;
  font-size:12.5px;
  line-height:1.65;
  word-wrap:break-word;
  display:block;
}
#lml-assistant-body .lml-msg-user {
  margin-left:auto;
  background:linear-gradient(135deg,#3b82f6,#6366f1);
  color:#fff;
  border-bottom-right-radius:3px;
}
#lml-assistant-body .lml-msg-assistant {
  margin-right:auto;
  background:#1f2937;
  color:#e5e7eb;
  border:1px solid #374151;
  border-bottom-left-radius:3px;
}

/* ────────────────────────────────────────────────
   MOX SHELL — fixed anchor for avatar + panel
   Positioned inside canvas area, left of right panel (288px desktop).
   ──────────────────────────────────────────────── */
#lml-assistant-shell {
  display: none;
  position: fixed;
  right: calc(288px + 20px); /* clear right panel (288px) + gap */
  bottom: 84px;
  width: 360px;
  max-width: calc(100vw - 24px);
  z-index: 9998;
  /* overflow:visible so the avatar can stick out above */
}

/* ── MOX character — floats above the panel ── */
#mox-character {
  position: absolute;
  left: 50%;
  /* PNG is 200px wide → 300px tall (2:3 ratio).
     Character body occupies roughly the top 75% (~225px); bottom ~75px is transparent.
     top: -185px → body bottom lands at -185+225 = +40px → ~12px visual overlap over panel border. */
  top: -185px;
  transform: translateX(-50%);
  z-index: 2;
  pointer-events: none;
  text-align: center;
}

/* Glow aura behind PNG */
#mox-character::before {
  content: '';
  position: absolute;
  inset: 20% 15%;
  border-radius: 50%;
  background: radial-gradient(ellipse at center,
    rgba(99,102,241,0.45) 0%,
    rgba(59,130,246,0.18) 55%,
    transparent 80%);
  filter: blur(14px);
  pointer-events: none;
  z-index: 0;
}

#mox-avatar-img {
  position: relative;
  z-index: 1;
  width: 200px;
  height: auto;
  display: block;
  object-fit: contain;
  pointer-events: none;
  /* mood swap transition */
  transition: opacity 0.18s ease, transform 0.18s ease;
  /* subtle drop shadow */
  filter: drop-shadow(0 8px 20px rgba(0,0,0,0.55));
}

/* Mood swap — JS adds this class, removes after src swap */
#mox-avatar-img.mox-mood-swap {
  opacity: 0;
  transform: scale(0.94) translateY(6px);
}

/* ── Panel — speech box ── */
#lml-assistant-panel {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  max-height: 72vh;
  /* Opaque, and deliberately unfiltered. A backdrop-filter here bought almost
     nothing at 96% opacity, rasterised the panel's own text softly, and made
     this element a containing block — so a fixed-position descendant anchored
     to the panel instead of the viewport. */
  background: rgba(17,24,39,0.98);
  border: 1px solid #374151;
  border-radius: 16px;
  box-shadow: 0 20px 60px rgba(0,0,0,0.6);
  overflow: hidden;
  /* open/close animation driven by JS via opacity+transform */
  opacity: 0;
  transform: translateY(12px);
  transition: opacity .2s, transform .2s;
}

/* ── Typing indicator */
#lml-typing-indicator {
  display:none;
  align-items:center;
  gap:4px;
  padding:9px 13px;
  background:#1f2937;
  border:1px solid #374151;
  border-radius:12px;
  border-bottom-left-radius:3px;
  width:fit-content;
  margin-bottom:8px;
}
#lml-typing-indicator span {
  width:5px; height:5px; border-radius:50%;
  background:#6b7280; display:inline-block;
  animation:lml-bounce .9s infinite ease-in-out;
}
#lml-typing-indicator span:nth-child(2) { animation-delay:.18s; }
#lml-typing-indicator span:nth-child(3) { animation-delay:.36s; }
@keyframes lml-bounce {
  0%,60%,100% { transform:translateY(0); }
  30%          { transform:translateY(-5px); background:#9ca3af; }
}

/* ── Quick-suggestion chips */
#lml-chips {
  display:flex;
  flex-wrap:wrap;
  gap:6px;
  margin-top:10px;
  margin-bottom:4px;
}
.lml-chip {
  background:rgba(59,130,246,0.1);
  border:1px solid rgba(59,130,246,0.35);
  color:#93c5fd;
  font-size:11px;
  font-weight:600;
  padding:4px 10px;
  border-radius:20px;
  cursor:pointer;
  white-space:nowrap;
  transition:background .15s, border-color .15s, color .15s;
  font-family:inherit;
}
.lml-chip:hover {
  background:rgba(59,130,246,0.25);
  border-color:#3b82f6;
  color:#eff6ff;
}

/* ── Tablet: right panel narrows to 240px */
@media (max-width: 1024px) {
  #lml-assistant-shell {
    right: calc(240px + 16px); /* clear 240px right panel + gap */
  }
  #mox-launcher {
    right: calc(240px + 16px); /* clear 240px right panel + gap */
  }
}

/* ── Mobile */
@media (max-width: 768px) {

  /* Shell: right panel slides off-screen as drawer; return MOX to right edge
     but raise above 56px mobile toolbar + buffer */
  #lml-assistant-shell {
    right: 12px !important;
    left: 12px !important;
    width: auto !important;
    bottom: 150px !important; /* well above 56px toolbar */
  }

  /* Panel: constrained height so MOX (120px) + shell bottom (150px) + buffer fits in viewport */
  #lml-assistant-panel {
    max-height: calc(100vh - 290px) !important;
    display: flex !important;
    flex-direction: column !important;
    overflow: hidden !important;
  }

  /* Message body: takes remaining flex space and scrolls internally */
  #lml-assistant-body {
    flex: 1 1 auto !important;
    overflow-y: auto !important;
    min-height: 0 !important;          /* critical: allows flex child to shrink below content size */
    -webkit-overflow-scrolling: touch !important;
  }

  /* Avatar: smaller image, closer to panel top */
  #mox-character {
    top: -120px !important;
  }
  #mox-avatar-img {
    width: 115px !important;
  }

  #lml-assistant-footer { padding-bottom: max(10px, env(safe-area-inset-bottom)) !important; }
  #lml-chips { gap: 5px; }
  .lml-chip { font-size: 10.5px; padding: 4px 8px; }
}

/* ────────────────────────────────────────────────
   MOX FLOATING LAUNCHER
   ──────────────────────────────────────────────── */
#mox-launcher {
  position: fixed;
  bottom: 20px;
  right: calc(288px + 20px); /* clear right panel (288px) + gap */
  z-index: 9999;
  width: 72px;
  cursor: pointer;
  /* stacking context for bubble + image */
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
  /* entry animation */
  animation: mox-launcher-rise 0.45s cubic-bezier(0.34,1.56,0.64,1) both;
}

@keyframes mox-launcher-rise {
  from { opacity: 0; transform: translateY(20px) scale(0.85); }
  to   { opacity: 1; transform: translateY(0)   scale(1);    }
}

/* ── Launcher image ── */
#mox-launcher-img {
  width: var(--mox-launcher-art-w);
  height: auto;
  object-fit: contain;
  aspect-ratio: auto;
  display: block;
  filter: drop-shadow(0 6px 18px rgba(99,102,241,0.55));
  transition: transform 0.18s cubic-bezier(0.34,1.56,0.64,1),
              filter 0.18s ease;
}
#mox-launcher:hover #mox-launcher-img,
#mox-launcher:focus-visible #mox-launcher-img {
  transform: scale(1.08) translateY(-3px);
  filter: drop-shadow(0 10px 24px rgba(99,102,241,0.75));
}
#mox-launcher:active #mox-launcher-img {
  transform: scale(0.96);
}

/* ── Speech bubble — desktop only ── */
#mox-bubble {
  position: absolute;
  bottom: calc(100% - 6px);
  right: 0;
  background: rgba(17,24,39,0.98);
  border: 1px solid rgba(99,102,241,0.35);
  border-radius: 12px 12px 4px 12px;
  padding: 8px 13px;
  font-size: 12px;
  font-weight: 500;
  color: #e5e7eb;
  white-space: nowrap;
  box-shadow: 0 4px 16px rgba(0,0,0,0.45);
  pointer-events: none;
  /* show/hide animation */
  opacity: 0;
  transform: translateY(6px) scale(0.95);
  transform-origin: bottom right;
  transition: opacity 0.25s ease, transform 0.25s ease;
}
#mox-bubble.mox-bubble-visible {
  opacity: 1;
  transform: translateY(0) scale(1);
}
/* Tail triangle */
#mox-bubble::after {
  content: '';
  position: absolute;
  bottom: -7px;
  right: 18px;
  width: 0; height: 0;
  border-left: 7px solid transparent;
  border-right: 0px solid transparent;
  border-top: 7px solid rgba(17,24,39,0.96);
  filter: drop-shadow(0 2px 2px rgba(0,0,0,0.2));
}

/* Accessibility: keyboard focus ring */
#mox-launcher:focus-visible {
  outline: 2px solid #6366f1;
  outline-offset: 4px;
  border-radius: 50%;
}

/* ── Mobile: no bubble, smaller image ── */
@media (max-width: 768px) {
  #mox-launcher {
    bottom: calc(56px + 12px); /* clear 56px mobile toolbar + gap */
    right: 14px; /* right panel is off-screen drawer on mobile */
    width: 54px;
  }
  #mox-launcher-img {
    width: 54px;
  }
  #mox-bubble {
    display: none !important;
  }
}

/* ── Panel layout: keep transcript and composer usable ────────────────────────
   The draft used to be a SIBLING between the transcript and the composer, with
   no flex bound, so once the consent paragraph and eleven optional fields were
   present it could not shrink below its content and ate the column. Bounding it
   kept the panel usable, but the shape was still wrong: a photo is part of the
   message being written, not a second form sitting on top of the conversation.

   It now lives INSIDE the composer as a compact tray, so the transcript keeps
   its own region and the attachment travels with the message box. */

#lml-assistant-panel > div:first-child {           /* header */
  flex: 0 0 auto;
}

#lml-assistant-body {
  /* min-height:0 is the part that was missing: without it a flex item refuses
     to shrink below its content, which is what let the draft win the column. */
  flex: 1 1 auto;
  min-height: 0;
}

/* The composer owns the attachment now, so it becomes the positioning context
   for the tray and for the two panels that open above it. */
#lml-assistant-footer {
  position: relative;
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
}

#mox-vis-tray {
  /* Spans the whole composer row above +, input and Send. Deliberately small:
     a thumbnail, a name, two actions and a checkbox. Anything longer opens in a
     panel above rather than growing this strip. */
  grid-column: 1 / -1;
  min-height: 0;
  max-height: 110px;
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-width: thin;
  scrollbar-color: #374151 transparent;
  margin-bottom: 6px;
}

#mox-vis-tray[hidden] { display: none; }

/* Long copy and the optional fields open OVER the composer instead of pushing
   it: no layer over the page, no dimming, no blur — just a bounded, scrollable
   panel anchored to the control that opened it. */
#mox-vis-consent-detail,
#mox-vis-fields {
  position: absolute;
  left: 12px;
  right: 12px;
  bottom: calc(100% - 4px);
  z-index: 3;
  max-height: 45vh;
  overflow-y: auto;
  overscroll-behavior: contain;
  background: #111827;
  border: 1px solid #374151;
  border-radius: 10px;
  padding: 9px 11px;
  box-shadow: 0 -8px 24px rgba(0,0,0,0.45);
}

#mox-vis-plus:focus-visible,
#mox-vis-replace:focus-visible,
#mox-vis-remove:focus-visible {
  outline: 2px solid #93c5fd;
  outline-offset: 2px;
}

#mox-vis-plus[disabled],
#mox-vis-replace[disabled],
#mox-vis-remove[disabled] {
  opacity: 0.5;
  cursor: default;
}

#mox-vis-details,
#mox-vis-consent-more {
  /* Collapsed by default. Opening one must not move the composer, which is why
     the content is positioned above rather than inserted into the flow. */
  position: static;
}

#mox-quota-indicator,
#lml-assistant-footer {
  flex: 0 0 auto;
}

/* A hard floor for the transcript, but only where there is room to honour it:
   on a short viewport the composer matters more than a tall transcript. */
@media (min-height: 560px) {
  #lml-assistant-body { min-height: 96px; }
}

/* ── Expanded (maximised) state ───────────────────────────────────────────────
   A CSS state, not the Fullscreen API: no permission prompt, no escape from the
   page, and the surrounding application stays visible and SHARP behind it.

   There is deliberately no backdrop element and no blur. Maximise is not a
   modal: it does not take a decision away from the reader, so it has no
   business dimming or blurring the page they are working on. The dimmed,
   blurred overlay this used to draw sat at z-index 2147482000 and made both
   the application and — through the panel's own backdrop-filter — the panel
   itself unreadable. */


#lml-assistant-shell.mox-expanded {
  position: fixed;
  z-index: 2147483000;
  top: max(16px, env(safe-area-inset-top));
  right: max(16px, env(safe-area-inset-right));
  bottom: max(16px, env(safe-area-inset-bottom));
  left: max(16px, env(safe-area-inset-left));
  width: auto;
  max-width: none;
  height: auto;
  display: flex;
  flex-direction: column;
  align-items: stretch;
}

/* The avatar is decoration; the panel needs the height when expanded. */
#lml-assistant-shell.mox-expanded #mox-character {
  display: none;
}

#lml-assistant-shell.mox-expanded #lml-assistant-panel {
  flex: 1 1 auto;
  width: 100%;
  max-width: 880px;                     /* readable measure on wide screens */
  margin: 0 auto;
  max-height: none;
  height: 100%;
}

/* Phone: use the whole viewport, safe-area aware, no horizontal overflow. */
@media (max-width: 640px) {
  #lml-assistant-shell.mox-expanded {
    top: env(safe-area-inset-top, 0px);
    right: env(safe-area-inset-right, 0px);
    bottom: env(safe-area-inset-bottom, 0px);
    left: env(safe-area-inset-left, 0px);
  }
  #lml-assistant-shell.mox-expanded #lml-assistant-panel {
    border-radius: 0;
    max-width: none;
  }
  /* Expanded gives the draft more room than the cramped compact panel. */
  #lml-assistant-shell.mox-expanded #mox-vis-tray { max-height: 140px; }
}

/* Dynamic viewport where supported: 100dvh excludes mobile browser chrome, so
   the composer is not hidden behind it. The inset rules above are the fallback. */
@supports (height: 100dvh) {
  #lml-assistant-shell.mox-expanded { max-height: 100dvh; }
}

#mox-expand-btn:focus-visible,
#mox-clear-btn:focus-visible,
#lml-assistant-shell button:focus-visible {
  outline: 2px solid #93c5fd;
  outline-offset: 2px;
  border-radius: 6px;
}

@media (prefers-reduced-motion: reduce) {
  #lml-assistant-panel {
    transition: none !important;
    animation: none !important;
  }
}

/* ── On-screen keyboard (added 2026-08-18) ───────────────────────────────────
   mox-keyboard.js publishes the keyboard's overlap as --mox-kb-inset and marks
   <html> with .mox-kb-open. Both are inert until a keyboard is actually open,
   so every rule above behaves exactly as before on desktop and on a phone with
   the composer unfocused. Without this the composer — the only control the
   panel exists for — sat behind the keyboard on iOS and Android. */
.mox-kb-open #lml-assistant-shell {
  bottom: calc(12px + var(--mox-kb-inset, 0px)) !important;
}
.mox-kb-open #lml-assistant-panel {
  max-height: calc(100vh - var(--mox-kb-inset, 0px) - 36px) !important;
}
@supports (height: 100dvh) {
  .mox-kb-open #lml-assistant-panel {
    max-height: calc(100dvh - var(--mox-kb-inset, 0px) - 36px) !important;
  }
}
/* The transcript owns its own scroll; without containment, reaching its end
   scrolled the page (or the editor) behind the panel on touch devices. */
#lml-assistant-body { overscroll-behavior: contain; }
