:root {
  --bg-1: #1a1033;
  --bg-2: #2d1b4e;
  --bg-3: #4a1e4a;
  --panel: rgba(255, 255, 255, 0.06);
  --panel-solid: #241a3d;
  --text: #f3eefc;
  --muted: #b3a2d6;
  --accent: #ffb84d;
  --accent-2: #ff6fb0;
  --accent-3: #9d7bff;
  --user-bubble: linear-gradient(135deg, #7b4fff, #ff6fb0);
  --ai-bubble: rgba(255, 255, 255, 0.08);
  --border: rgba(255, 255, 255, 0.12);
  --shadow: rgba(20, 8, 40, 0.4);
  --danger: #ff6b6b;
}

* { box-sizing: border-box; }

html, body {
  height: 100%;
  height: 100dvh;
  margin: 0;
  color: var(--text);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  background:
    radial-gradient(circle at 15% 20%, rgba(255, 184, 77, 0.18), transparent 35%),
    radial-gradient(circle at 85% 15%, rgba(255, 111, 176, 0.18), transparent 40%),
    radial-gradient(circle at 50% 90%, rgba(157, 123, 255, 0.2), transparent 45%),
    linear-gradient(160deg, var(--bg-1), var(--bg-2) 55%, var(--bg-3));
  overflow: hidden;
}

.splash {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: center;
  background: linear-gradient(160deg, var(--bg-1), var(--bg-2) 55%, var(--bg-3));
  opacity: 1;
  transition: opacity 0.5s ease;
  cursor: pointer;
}
.splash.hide { opacity: 0; pointer-events: none; }
.splash video { width: 100%; height: 100%; object-fit: contain; }

#app {
  display: flex;
  flex-direction: column;
  /* 100vh on a phone is the LARGE viewport height — it includes the space behind the browser URL
     bar, so the bottom of this column (the composer) sits off-screen and the app looks like it has
     no text box at all. dvh tracks the actually-visible height. vh first as the fallback for any
     browser without dvh. The desktop Electron build never hit this: no dynamic browser chrome. */
  height: 100vh;
  height: 100dvh;
}

header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.9rem 1.1rem;
  border-bottom: 1px solid var(--border);
  -webkit-app-region: drag;
}

header h1 {
  margin: 0;
  font-size: 1.1rem;
  font-family: 'Fraunces', Georgia, serif;
  background: linear-gradient(90deg, var(--accent), var(--accent-2), var(--accent-3));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.header-actions { display: flex; gap: 0.5rem; -webkit-app-region: no-drag; }

.header-actions button {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 10px;
  color: var(--text);
  padding: 0.4rem 0.7rem;
  font-size: 0.85rem;
  cursor: pointer;
}
.header-actions button:hover { background: var(--panel-solid); }

#messages {
  flex: 1;
  /* Without this a flex item refuses to shrink below its content size, so a long conversation
     grows the column instead of scrolling inside it — which pushes the composer off-screen again
     for a completely different reason. */
  min-height: 0;
  overflow-y: auto;
  padding: 1rem;
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}

.bubble {
  max-width: 82%;
  padding: 0.6rem 0.85rem;
  border-radius: 16px;
  font-size: 0.92rem;
  line-height: 1.4;
  white-space: pre-wrap;
  word-wrap: break-word;
}

.bubble.user {
  align-self: flex-end;
  background: var(--user-bubble);
  color: #fff;
  border-bottom-right-radius: 4px;
}

.bubble.assistant {
  align-self: flex-start;
  background: var(--ai-bubble);
  border: 1px solid var(--border);
  border-bottom-left-radius: 4px;
}

.bubble.system {
  align-self: center;
  background: transparent;
  color: var(--muted);
  font-size: 0.8rem;
  font-style: italic;
}

.bubble.pending .bubble-text { opacity: 0.6; }

.memory-note {
  align-self: center;
  color: var(--accent-3);
  font-size: 0.72rem;
  opacity: 0.85;
}

#composer {
  border-top: 1px solid var(--border);
  padding: 0.7rem;
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
}

.composer-tools { display: flex; gap: 0.4rem; }

.composer-tools button {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 10px;
  color: var(--text);
  padding: 0.35rem 0.55rem;
  font-size: 0.95rem;
  cursor: pointer;
}
.composer-tools button.recording { background: var(--danger); color: #fff; }
.composer-tools button.active { background: var(--accent-3); color: #fff; }
.composer-tools button.muted { opacity: 0.5; }
.composer-tools button:disabled { opacity: 0.35; cursor: not-allowed; }

.composer-input-row { display: flex; gap: 0.5rem; }

#input {
  flex: 1;
  resize: none;
  max-height: 140px;
  background: var(--panel-solid);
  border: 1px solid var(--border);
  border-radius: 14px;
  color: var(--text);
  padding: 0.6rem 0.8rem;
  font-family: inherit;
  font-size: 0.92rem;
}
#input:focus { outline: 2px solid var(--accent-3); }

#send-btn {
  background: linear-gradient(135deg, var(--accent), var(--accent-2));
  border: none;
  border-radius: 14px;
  color: #241a3d;
  font-weight: 700;
  padding: 0 1.1rem;
  cursor: pointer;
}
#send-btn:disabled { opacity: 0.5; cursor: not-allowed; }

.voice-mode-banner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  background: var(--panel-solid);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 0.5rem 0.8rem;
  font-size: 0.85rem;
}
.voice-mode-banner button {
  background: transparent;
  border: none;
  color: var(--muted);
  cursor: pointer;
}

.empty-state {
  align-self: center;
  margin: auto;
  text-align: center;
  color: var(--muted);
  max-width: 300px;
  font-size: 0.9rem;
}

/* --- Settings window --- */
.settings-body { padding: 1.25rem; overflow-y: auto; height: 100vh; }
.settings-body h1 { font-family: 'Fraunces', Georgia, serif; font-size: 1.2rem; margin: 0 0 1rem; }
.field { margin-bottom: 1.1rem; }
.field label { display: block; font-size: 0.82rem; color: var(--muted); margin-bottom: 0.35rem; }
.field input[type="password"],
.field input[type="text"],
.field select,
.field textarea {
  width: 100%;
  background: var(--panel-solid);
  border: 1px solid var(--border);
  border-radius: 10px;
  color: var(--text);
  padding: 0.55rem 0.7rem;
  font-family: inherit;
  font-size: 0.88rem;
}
.field textarea { resize: vertical; min-height: 70px; }
.field .hint { font-size: 0.75rem; color: var(--muted); margin-top: 0.3rem; }
.row { display: flex; gap: 0.6rem; align-items: center; }
.row button {
  background: linear-gradient(135deg, var(--accent), var(--accent-2));
  border: none;
  border-radius: 10px;
  color: #241a3d;
  font-weight: 700;
  padding: 0.5rem 1rem;
  cursor: pointer;
}
.row .secondary { background: var(--panel); color: var(--text); }
.status-msg { font-size: 0.8rem; margin-top: 0.5rem; min-height: 1em; }
.status-msg.ok { color: #7de3a0; }
.status-msg.err { color: var(--danger); }

.directive-slot { margin-bottom: 0.5rem; }
.directive-slot input {
  width: 100%;
  background: var(--panel-solid);
  border: 1px solid var(--border);
  border-radius: 10px;
  color: var(--text);
  padding: 0.5rem 0.65rem;
  font-family: inherit;
  font-size: 0.86rem;
}


/* ─────────────────────────────────────────────────────────────────────────
   Hosted-web additions. Everything above is carried over from the desktop
   build unchanged; these cover the pieces that only exist in this version —
   the in-page Settings dialog (there's no second BrowserWindow to open),
   the offline state (this app genuinely needs the server), and the pending
   bubble shown while a turn is in flight.
   ───────────────────────────────────────────────────────────────────────── */

.bubble.pending { opacity: 0.55; font-style: italic; }
.bubble.error {
  align-self: center;
  background: rgba(255, 107, 107, 0.12);
  border: 1px solid var(--danger);
  color: #ffd4d4;
  font-size: 0.82rem;
  font-style: normal;
}
.bubble.notice { align-self: center; color: var(--muted); font-size: 0.8rem; font-style: italic; }

.offline-badge {
  font-size: 0.7rem;
  padding: 2px 8px;
  border-radius: 999px;
  background: rgba(255, 107, 107, 0.15);
  border: 1px solid var(--danger);
  color: #ffd4d4;
  align-self: center;
}

#settings-dialog {
  width: min(560px, 94vw);
  /* dvh, not vh — on a phone vh includes the space behind the browser chrome, so the dialog is
     taller than the screen and its bottom (where the action buttons live) is unreachable. Same
     bug that hid the composer. */
  max-height: 88dvh;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: 16px;
  background: var(--panel-solid);
  color: var(--text);
  box-shadow: 0 24px 64px var(--shadow);
}
#settings-dialog::backdrop { background: rgba(10, 5, 20, 0.66); }
/* ONE scroll container, not two. The dialog and this element both had a max-height and both
   scrolled, and nested scroll containers on touch are genuinely unreliable — a drag often moves
   the outer box while the inner content stays put, so anything below the fold reads as missing
   rather than merely unscrolled. */
#settings-body { padding: 20px 22px 22px; overflow-y: auto; max-height: inherit; -webkit-overflow-scrolling: touch; overscroll-behavior: contain; }

.settings-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; }
.settings-head h2 { margin: 0 0 6px; font-size: 1.15rem; }
.settings-user { font-size: 0.75rem; color: var(--muted); }

.settings-field { margin-top: 16px; display: flex; flex-direction: column; gap: 6px; }
.settings-field label { font-size: 0.82rem; font-weight: 600; }
.settings-hint { font-size: 0.72rem; color: var(--muted); line-height: 1.35; }
.settings-field input,
.settings-field select,
.settings-field textarea {
  width: 100%;
  padding: 9px 11px;
  border-radius: 8px;
  border: 1px solid var(--border);
  background: rgba(0, 0, 0, 0.22);
  color: var(--text);
  font: inherit;
  font-size: 0.86rem;
}
.settings-field textarea { resize: vertical; line-height: 1.4; }

.settings-status { margin-top: 12px; font-size: 0.78rem; color: var(--muted); min-height: 1.1em; }
.settings-status.bad { color: #ffb0b0; }

.settings-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 22px; }
.settings-actions button {
  padding: 9px 15px;
  border-radius: 8px;
  border: 1px solid transparent;
  background: var(--accent-3);
  color: #fff;
  font: inherit;
  font-size: 0.84rem;
  cursor: pointer;
}
.settings-actions button.settings-secondary { background: transparent; border-color: var(--border); color: var(--text); }
.settings-actions button.settings-danger { background: transparent; border-color: var(--danger); color: #ffb0b0; margin-left: auto; }
.settings-actions button:disabled { opacity: 0.55; cursor: default; }
.settings-secondary { margin-top: 6px; align-self: flex-start; padding: 7px 12px; border-radius: 8px;
  border: 1px solid var(--border); background: transparent; color: var(--text); font: inherit;
  font-size: 0.78rem; cursor: pointer; }

/* ChromeOS/Android installed-PWA safe areas — the app runs in its own window with no browser
   chrome, so bottom insets are ours to handle. */
@supports (padding: max(0px)) {
  #composer { padding-bottom: max(0.6rem, env(safe-area-inset-bottom)); }
}

/* --- Add-ons section in Settings ------------------------------------------------------------ */
.settings-addons { margin-top: 26px; border-top: 1px solid var(--border); padding-top: 18px; }
.settings-addons h3 { margin: 0 0 12px; font-size: 0.95rem; }

.addon-card {
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 12px 14px;
  margin-bottom: 12px;
  background: rgba(0, 0, 0, 0.16);
}
.addon-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.addon-toggle { display: flex; align-items: center; gap: 9px; cursor: pointer; font-size: 0.9rem; }
.addon-toggle input { width: 18px; height: 18px; accent-color: var(--accent-3); cursor: pointer; }
.addon-name { font-weight: 600; }
.addon-status { font-size: 0.72rem; color: var(--muted); text-align: right; }
.addon-desc { font-size: 0.76rem; color: var(--muted); margin-top: 6px; line-height: 1.4; }
.addon-fields { margin-top: 10px; border-top: 1px solid var(--border); padding-top: 6px; }

/* On a phone, give Settings the whole screen. A centred 94vw box with rounded corners wastes the
   space a long form needs most, and the shorter the scroll, the less there is to get lost in. */
@media (max-width: 640px) {
  #settings-dialog {
    width: 100vw;
    max-width: 100vw;
    height: 100dvh;
    max-height: 100dvh;
    margin: 0;
    border: none;
    border-radius: 0;
  }
  #settings-body {
    max-height: 100dvh;
    padding-bottom: max(28px, env(safe-area-inset-bottom));
  }
  .settings-actions { position: sticky; bottom: 0; background: var(--panel-solid); padding: 12px 0 4px; margin-top: 18px; }
  .settings-actions button { flex: 1 1 44%; }
  .settings-actions button.settings-danger { margin-left: 0; flex-basis: 100%; }
}
