/*
 * piweb — Discord-flavoured dark UI, phone first.
 *
 * Layout rules that matter on iOS Safari:
 *  - 100dvh (not 100vh) so the URL bar collapsing doesn't hide the composer
 *  - env(safe-area-inset-*) padding for the notch and home indicator
 *  - 16px input font, otherwise iOS zooms the page on focus
 */

:root {
  --bg: #313338;
  --bg-alt: #2b2d31;
  --bg-dark: #1e1f22;
  --bg-input: #383a40;
  --border: #3f4147;
  --text: #dbdee1;
  --text-dim: #949ba4;
  --text-bright: #f2f3f5;
  --accent: #5865f2;
  --accent-hover: #4752c4;
  --danger: #da373c;
  --thinking: #a78bfa;
  --tool: #3ba55d;
  --radius: 8px;
  --topbar-h: 48px;
}

* {
  box-sizing: border-box;
}

/*
 * The UA rule for [hidden] is `display: none`, but ANY author rule that sets
 * display (.login{display:grid}, .app{display:flex}, .typing, .autocomplete, …)
 * beats it — author styles win over the UA sheet regardless of specificity.
 * Without this the login overlay renders on top of the app forever even though
 * `hidden` is set. Keep this above every display rule.
 */
[hidden] {
  display: none !important;
}

html,
body {
  margin: 0;
  padding: 0;
  height: 100%;
  overscroll-behavior: none;
}

body {
  background: var(--bg);
  color: var(--text);
  font-family:
    'gg sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', sans-serif;
  font-size: 15px;
  line-height: 1.45;
  -webkit-font-smoothing: antialiased;
}

button {
  font: inherit;
  color: inherit;
  cursor: pointer;
}

svg {
  width: 20px;
  height: 20px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* ── login ───────────────────────────────────────────────────────────── */

.login {
  display: grid;
  place-items: center;
  height: 100dvh;
  padding: 24px;
  background: var(--bg-dark);
}

.login-card {
  width: 100%;
  max-width: 360px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 28px 24px;
  background: var(--bg-alt);
  border-radius: 12px;
  box-shadow: 0 8px 24px rgb(0 0 0 / 0.4);
  text-align: center;
}

.login-logo {
  width: 56px;
  height: 56px;
  margin: 0 auto;
  display: grid;
  place-items: center;
  font-size: 30px;
  border-radius: 50%;
  background: var(--accent);
  color: #fff;
}

.login-card h1 {
  margin: 4px 0 0;
  font-size: 22px;
  color: var(--text-bright);
}

.login-sub {
  margin: 0 0 8px;
  color: var(--text-dim);
  font-size: 14px;
}

.login-card input,
.composer textarea {
  width: 100%;
  padding: 12px 14px;
  background: var(--bg-input);
  border: 1px solid transparent;
  border-radius: var(--radius);
  color: var(--text-bright);
  font-size: 16px; /* < 16px makes iOS zoom on focus */
  outline: none;
}

.login-card input:focus {
  border-color: var(--accent);
}

.btn-primary {
  padding: 12px 14px;
  background: var(--accent);
  border: 0;
  border-radius: var(--radius);
  color: #fff;
  font-size: 15px;
  font-weight: 600;
}

.btn-primary:active {
  background: var(--accent-hover);
}

.login-error {
  margin: 0;
  color: #f87171;
  font-size: 14px;
}

/* ── shell ───────────────────────────────────────────────────────────── */

.app {
  height: 100dvh;
  display: flex;
  overflow: hidden;
}

.main {
  position: relative; /* containing block for .jump-live */
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  height: 100dvh;
}

.topbar {
  display: flex;
  align-items: center;
  gap: 8px;
  height: calc(var(--topbar-h) + env(safe-area-inset-top));
  padding: env(safe-area-inset-top) 8px 0;
  background: var(--bg);
  border-bottom: 1px solid var(--bg-dark);
  flex: none;
}

.topbar-title {
  flex: 1;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 4px;
  font-weight: 600;
  color: var(--text-bright);
}

#session-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  padding: 2px 6px;
  margin-left: -6px;
  border-radius: 6px;
  cursor: text;
}

#session-name:hover,
#session-name:focus-visible {
  background: var(--bg-input);
  outline: none;
}

/* Inline rename: an in-place field rather than a native prompt(), which on iOS
   is a jarring system sheet that hides the thing being renamed. */
.name-edit {
  flex: 1;
  min-width: 0;
  padding: 3px 6px;
  background: var(--bg-input);
  border: 1px solid var(--accent);
  border-radius: 6px;
  color: var(--text-bright);
  font: inherit;
  font-size: 16px; /* keep iOS from zooming */
  outline: none;
}

.hash {
  color: var(--text-dim);
  font-size: 20px;
}

.icon-btn {
  display: grid;
  place-items: center;
  width: 38px;
  height: 38px;
  flex: none;
  background: transparent;
  border: 0;
  border-radius: var(--radius);
  color: var(--text-dim);
}

.icon-btn:active {
  background: var(--bg-input);
  color: var(--text-bright);
}

.icon-btn.send {
  color: var(--accent);
}

/* ── drawer ──────────────────────────────────────────────────────────── */

.drawer {
  position: fixed;
  z-index: 20;
  top: 0;
  left: 0;
  width: 78%;
  max-width: 300px;
  height: 100dvh;
  display: flex;
  flex-direction: column;
  background: var(--bg-alt);
  transform: translateX(-100%);
  transition: transform 0.18s ease;
  padding-top: env(safe-area-inset-top);
}

.drawer.open {
  transform: translateX(0);
}

.scrim {
  position: fixed;
  inset: 0;
  z-index: 15;
  background: rgb(0 0 0 / 0.5);
  /* Fades with the drawer; during an edge swipe JS drives opacity directly. */
  transition: opacity 0.18s ease;
}

.drawer-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: var(--topbar-h);
  padding: 0 8px 0 16px;
  border-bottom: 1px solid var(--bg-dark);
  flex: none;
}

.drawer-title {
  font-weight: 700;
  color: var(--text-bright);
}

.session-list {
  flex: 1;
  overflow-y: auto;
  padding: 8px;
  -webkit-overflow-scrolling: touch;
}

.session-item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 9px 10px;
  border-radius: 6px;
  color: var(--text-dim);
  font-weight: 500;
}

.session-item.active {
  background: var(--bg-input);
  color: var(--text-bright);
}

.session-item .name {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.session-item .hash {
  font-size: 18px;
}

.session-item .unread-dot {
  width: 9px;
  height: 9px;
  flex: none;
  border-radius: 50%;
  background: var(--tool);
  box-shadow: 0 0 0 2px rgb(59 165 93 / 0.25);
}

/* Spinner = working now. Distinct shape from the unread dot on purpose: the
   two states must be tellable apart at a glance, not only by motion. */
.session-item .work-spinner {
  width: 13px;
  height: 13px;
  flex: none;
  border-radius: 50%;
  border: 2px solid rgb(255 255 255 / 0.18);
  border-top-color: var(--accent);
  animation: spin 0.7s linear infinite;
}

@keyframes spin {
  to {
    transform: rotate(360deg);
  }
}

@media (prefers-reduced-motion: reduce) {
  .session-item .work-spinner {
    animation-duration: 2.4s;
  }
}

.session-item .del {
  width: 28px;
  height: 28px;
  color: var(--text-dim);
}

.drawer-foot {
  padding: 10px 16px calc(10px + env(safe-area-inset-bottom));
  border-top: 1px solid var(--bg-dark);
  flex: none;
}

.text-btn {
  background: none;
  border: 0;
  padding: 0;
  color: var(--text-dim);
  font-size: 14px;
}

.empty-note {
  padding: 24px 16px;
  color: var(--text-dim);
  font-size: 14px;
  text-align: center;
}

/* ── messages ────────────────────────────────────────────────────────── */

.messages {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  padding: 12px 0 4px;
}

.msg {
  display: flex;
  gap: 10px;
  padding: 5px 14px;
}

.msg:hover {
  background: rgb(0 0 0 / 0.08);
}

.avatar {
  width: 32px;
  height: 32px;
  flex: none;
  border-radius: 50%;
  display: grid;
  place-items: center;
  font-size: 14px;
  font-weight: 700;
  color: #fff;
  background: var(--accent);
}

.avatar.pi {
  background: #43b581;
}

.msg-body {
  flex: 1;
  min-width: 0;
}

.msg-head {
  display: flex;
  align-items: baseline;
  gap: 8px;
}

.msg-author {
  font-weight: 600;
  color: var(--text-bright);
  font-size: 14px;
}

.msg-time {
  color: var(--text-dim);
  font-size: 11px;
}

.msg-text {
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.msg-text code {
  background: var(--bg-dark);
  padding: 1px 4px;
  border-radius: 4px;
  font-family: ui-monospace, 'SF Mono', Menlo, Consolas, monospace;
  font-size: 13px;
}

.msg-text pre {
  margin: 6px 0;
  padding: 10px 12px;
  background: var(--bg-dark);
  border: 1px solid var(--border);
  border-radius: 6px;
  /* Long tool output must scroll inside its own box; the page itself never
     scrolls sideways on a phone. */
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

.msg-text pre code {
  background: none;
  padding: 0;
  font-size: 12.5px;
  line-height: 1.5;
}

.msg-files {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 6px;
}

.msg-files img,
.msg-files video {
  max-width: min(100%, 320px);
  max-height: 320px;
  border-radius: 8px;
  display: block;
}

.file-link {
  display: inline-block;
  padding: 8px 12px;
  background: var(--bg-alt);
  border: 1px solid var(--border);
  border-radius: 6px;
  color: #00a8fc;
  text-decoration: none;
  font-size: 14px;
}

/* ── streamed events (thinking / tools) ──────────────────────────────── */

.event {
  margin: 3px 14px;
  border-radius: 6px;
  background: var(--bg-alt);
  border-left: 3px solid var(--border);
  overflow: hidden;
}

.event.thinking {
  border-left-color: var(--thinking);
}

.event.tool,
.event.tool_result {
  border-left-color: var(--tool);
}

.event.system {
  border-left-color: var(--accent);
}

.event.error {
  border-left-color: var(--danger);
}

.event summary {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 7px 10px;
  cursor: pointer;
  color: var(--text-dim);
  font-size: 13px;
  list-style: none;
}

.event summary::-webkit-details-marker {
  display: none;
}

.event summary .label {
  font-weight: 600;
}

.event summary .peek {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-family: ui-monospace, 'SF Mono', Menlo, Consolas, monospace;
  font-size: 12px;
  opacity: 0.8;
}

.event .event-body {
  padding: 0 10px 9px;
  font-size: 13px;
  color: var(--text);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  max-height: 320px;
  overflow-y: auto;
}

/* System/command output is short and worth reading without a tap. */
.event.system .event-body,
.event.error .event-body {
  padding-top: 2px;
}

/* ── typing indicator ────────────────────────────────────────────────── */

.typing {
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 2px 16px 6px;
  color: var(--text-dim);
  font-size: 13px;
  flex: none;
}

.typing .dot {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--text-dim);
  animation: blink 1.2s infinite ease-in-out;
}

.typing .dot:nth-child(2) {
  animation-delay: 0.2s;
}

.typing .dot:nth-child(3) {
  animation-delay: 0.4s;
}

.typing-label {
  margin-left: 6px;
}

@keyframes blink {
  0%,
  80%,
  100% {
    opacity: 0.3;
  }
  40% {
    opacity: 1;
  }
}

@media (prefers-reduced-motion: reduce) {
  .typing .dot {
    animation: none;
    opacity: 0.7;
  }
  .drawer {
    transition: none;
  }
}

/* ── composer ────────────────────────────────────────────────────────── */

.composer-wrap {
  position: relative;
  flex: none;
  display: flex;
  flex-direction: column;
  min-height: 0;
  padding: 0 10px calc(10px + env(safe-area-inset-bottom));
  background: var(--bg);
}

.composer {
  display: flex;
  align-items: flex-end;
  gap: 4px;
  padding: 4px;
  background: var(--bg-input);
  border-radius: 10px;
}

.composer textarea {
  flex: 1;
  min-width: 0;
  background: none;
  border: 0;
  padding: 9px 4px;
  max-height: 40vh;
  resize: none;
  line-height: 1.4;
}

.attachments {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  padding: 8px 4px;
}

.chip {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 5px 8px;
  background: var(--bg-alt);
  border: 1px solid var(--border);
  border-radius: 6px;
  font-size: 13px;
  color: var(--text);
  max-width: 100%;
}

.chip .chip-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 160px;
}

.chip button {
  background: none;
  border: 0;
  padding: 0;
  color: var(--text-dim);
  line-height: 1;
  font-size: 16px;
}

/* ── slash autocomplete ──────────────────────────────────────────────── */

.autocomplete {
  /*
   * In normal flow, NOT absolutely positioned. Absolute + `max-height: 46vh`
   * overflowed off-screen with the keyboard open: `vh` tracks the layout
   * viewport, which iOS does not shrink for the keyboard, so the box became
   * taller than the visible area above the composer and got clipped at both
   * ends with nothing to scroll. As a flex item it is bounded by the column and
   * always scrolls internally instead.
   *
   * --ac-max is kept in sync with visualViewport by app.js (the keyboard only
   * changes the VISUAL viewport, which no CSS unit exposes).
   */
  flex: 0 1 auto;
  min-height: 0;
  max-height: var(--ac-max, 40dvh);
  margin-bottom: 6px;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  /* Don't chain the scroll to the page when the list hits its end. */
  overscroll-behavior: contain;
  /* Let the browser own vertical panning; taps are detected in JS. */
  touch-action: pan-y;
  background: var(--bg-alt);
  border: 1px solid var(--bg-dark);
  border-radius: 8px;
  box-shadow: 0 8px 24px rgb(0 0 0 / 0.45);
  z-index: 10;
}

.ac-head {
  /* Sticky so you can still see what the list is while scrolling it. */
  position: sticky;
  top: 0;
  background: var(--bg-alt);
  padding: 8px 12px;
  font-size: 12px;
  font-weight: 700;
  color: var(--text-dim);
  text-transform: uppercase;
  letter-spacing: 0.02em;
  border-bottom: 1px solid var(--bg-dark);
}

.ac-item {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 9px 12px;
}

.ac-item.sel {
  background: var(--bg-input);
}

.ac-name {
  color: var(--text-bright);
  font-weight: 600;
  font-size: 14px;
}

.ac-name .arg {
  color: var(--text-dim);
  font-weight: 400;
}

.ac-desc {
  color: var(--text-dim);
  font-size: 12.5px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ── wider screens ───────────────────────────────────────────────────── */

@media (min-width: 768px) {
  .drawer {
    position: relative;
    transform: none;
    width: 260px;
    max-width: none;
    border-right: 1px solid var(--bg-dark);
  }

  #btn-menu,
  .scrim {
    display: none;
  }

  .messages {
    padding-inline: 8px;
  }
}

/* ── infinite scroll sentinel ─────────────────────────────────────────── */

.top-sentinel {
  padding: 12px 14px;
  text-align: center;
  color: var(--text-dim);
  font-size: 13px;
  cursor: pointer;
}

.top-sentinel.start {
  cursor: default;
  opacity: 0.6;
  font-size: 12px;
}

/* ── search ──────────────────────────────────────────────────────────── */

.search-panel {
  display: flex;
  flex-direction: column;
  min-height: 0;
  /* Sits between the topbar and the transcript, taking at most half the
     screen so the conversation behind it stays visible for context. */
  max-height: 55dvh;
  background: var(--bg-alt);
  border-bottom: 1px solid var(--bg-dark);
  flex: none;
}

.search-bar {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 8px 8px 8px 12px;
  flex: none;
}

.search-bar input {
  flex: 1;
  min-width: 0;
  padding: 10px 12px;
  background: var(--bg-input);
  border: 1px solid transparent;
  border-radius: var(--radius);
  color: var(--text-bright);
  font-size: 16px; /* keep iOS from zooming */
  outline: none;
}

.search-bar input:focus {
  border-color: var(--accent);
}

.search-results {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
  touch-action: pan-y;
  padding-bottom: 6px;
}

.search-hit {
  padding: 9px 14px;
  border-top: 1px solid var(--bg-dark);
}

.search-hit .hit-meta {
  display: flex;
  gap: 8px;
  align-items: baseline;
  color: var(--text-dim);
  font-size: 12px;
  margin-bottom: 2px;
}

.search-hit .hit-who {
  font-weight: 600;
  color: var(--text);
}

.search-hit .hit-text {
  font-size: 13.5px;
  color: var(--text);
  overflow-wrap: anywhere;
}

.search-hit mark {
  background: #b58900;
  color: #1e1f22;
  border-radius: 2px;
  padding: 0 1px;
}

.search-empty {
  padding: 16px;
  text-align: center;
  color: var(--text-dim);
  font-size: 13px;
}

/* Flash the message you jumped to, so it is obvious where you landed. */
.msg.jump-target,
.event.jump-target {
  animation: jump-flash 2s ease-out;
}

@keyframes jump-flash {
  0%,
  40% {
    background: rgb(88 101 242 / 0.28);
  }
  100% {
    background: transparent;
  }
}

@media (prefers-reduced-motion: reduce) {
  .msg.jump-target,
  .event.jump-target {
    animation: none;
    outline: 2px solid var(--accent);
  }
}

.jump-live {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  bottom: 96px;
  z-index: 5;
  padding: 8px 14px;
  background: var(--accent);
  color: #fff;
  border: 0;
  border-radius: 999px;
  font-size: 13px;
  font-weight: 600;
  box-shadow: 0 4px 12px rgb(0 0 0 / 0.4);
}

/* ── rendered markdown ───────────────────────────────────────────────── */

.msg-text h1,
.msg-text h2,
.msg-text h3,
.msg-text h4,
.msg-text h5,
.msg-text h6 {
  margin: 12px 0 6px;
  line-height: 1.3;
  color: var(--text-bright);
  font-weight: 700;
}

.msg-text h1 { font-size: 1.35em; }
.msg-text h2 { font-size: 1.22em; }
.msg-text h3 { font-size: 1.1em; }
.msg-text h4,
.msg-text h5,
.msg-text h6 { font-size: 1em; }

.msg-text > *:first-child { margin-top: 0; }
.msg-text > *:last-child { margin-bottom: 0; }

.msg-text p {
  margin: 0 0 8px;
}

.msg-text ul,
.msg-text ol {
  margin: 4px 0 8px;
  padding-left: 22px;
}

.msg-text li {
  margin: 2px 0;
}

.msg-text blockquote {
  margin: 6px 0;
  padding: 2px 0 2px 10px;
  border-left: 3px solid var(--border);
  color: var(--text-dim);
}

.msg-text hr {
  margin: 12px 0;
  border: 0;
  border-top: 1px solid var(--border);
}

.msg-text a {
  color: #00a8fc;
  text-decoration: none;
  overflow-wrap: anywhere;
}

.msg-text a:hover {
  text-decoration: underline;
}

.msg-text strong { color: var(--text-bright); }

/* Tables scroll inside their own box — the page must never scroll sideways. */
.table-wrap {
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  margin: 8px 0;
}

.msg-text table {
  border-collapse: collapse;
  font-size: 13.5px;
}

.msg-text th,
.msg-text td {
  border: 1px solid var(--border);
  padding: 5px 9px;
  text-align: left;
  white-space: nowrap;
}

.msg-text th {
  background: var(--bg-alt);
  color: var(--text-bright);
}

/* ── math ────────────────────────────────────────────────────────────── */

.math-display {
  margin: 10px 0;
  /* A long equation scrolls in place rather than widening the page. */
  overflow-x: auto;
  overflow-y: hidden;
  -webkit-overflow-scrolling: touch;
  padding-bottom: 2px;
}

.katex {
  font-size: 1.05em;
}

/* KaTeX ships light-theme colours; inherit the app's instead. */
.katex,
.katex .mord,
.katex .mbin,
.katex .mrel,
.katex .mopen,
.katex .mclose,
.katex .mpunct {
  color: inherit;
}

/* ── recently deleted ────────────────────────────────────────────────── */

.trash-entry {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 6px 0;
  margin-bottom: 6px;
}

.trash-entry svg {
  width: 16px;
  height: 16px;
}

.trash-count {
  margin-left: auto;
  min-width: 20px;
  padding: 1px 6px;
  border-radius: 999px;
  background: var(--bg-input);
  color: var(--text);
  font-size: 12px;
  text-align: center;
}

/* Bottom sheet: reachable one-handed on a phone, unlike a centred modal. */
.sheet {
  position: fixed;
  inset: 0;
  z-index: 40;
  display: flex;
  align-items: flex-end;
  background: rgb(0 0 0 / 0.55);
}

.sheet-panel {
  width: 100%;
  /* --sheet-max is synced to visualViewport by app.js: with the keyboard open
     dvh still reports the full screen, so a dvh-only cap runs off-screen. */
  max-height: var(--sheet-max, 82dvh);
  display: flex;
  flex-direction: column;
  min-height: 0;
  background: var(--bg-alt);
  border-radius: 14px 14px 0 0;
  padding-bottom: env(safe-area-inset-bottom);
}

.sheet-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 12px 8px 12px 16px;
  border-bottom: 1px solid var(--bg-dark);
  flex: none;
}

.sheet-title {
  font-weight: 700;
  color: var(--text-bright);
}

.sheet-note {
  margin: 0;
  padding: 10px 16px 0;
  color: var(--text-dim);
  font-size: 12.5px;
  flex: none;
}

.trash-list {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
  padding: 8px 0 12px;
}

.trash-item {
  padding: 10px 16px;
  border-top: 1px solid var(--bg-dark);
}

.trash-item .t-name {
  color: var(--text-bright);
  font-weight: 600;
}

.trash-item .t-meta {
  color: var(--text-dim);
  font-size: 12px;
  margin-top: 2px;
}

.trash-actions {
  display: flex;
  gap: 8px;
  margin-top: 8px;
  flex-wrap: wrap;
}

.trash-actions button {
  padding: 7px 12px;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--bg-input);
  color: var(--text);
  font-size: 13px;
}

.trash-actions .primary {
  background: var(--accent);
  border-color: var(--accent);
  color: #fff;
  font-weight: 600;
}

.trash-actions .danger {
  color: #f87171;
  border-color: #5c2b2b;
}

.deleted-banner {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 14px;
  background: #4a3b12;
  color: #f5e3b3;
  font-size: 13px;
  flex: none;
}

.deleted-banner button {
  margin-left: auto;
  padding: 5px 10px;
  border: 0;
  border-radius: 6px;
  background: var(--accent);
  color: #fff;
  font-size: 13px;
  font-weight: 600;
}

/* ── image lightbox ──────────────────────────────────────────────────── */

.lightbox {
  position: fixed;
  inset: 0;
  z-index: 60;
  display: grid;
  grid-template-rows: auto 1fr auto;
  background: #0b0b0d;
  /* The surface owns its gestures: sideways pages, down dismisses. */
  touch-action: none;
  user-select: none;
  animation: lb-in 0.16s ease-out;
}

@keyframes lb-in {
  from { opacity: 0; }
  to { opacity: 1; }
}

.lb-bar {
  grid-row: 1;
  z-index: 2;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: calc(10px + env(safe-area-inset-top)) 10px 10px 12px;
  color: #fff;
}

.lb-count {
  padding: 4px 11px;
  border-radius: 999px;
  background: rgb(255 255 255 / 0.12);
  font-size: 13px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.lb-open {
  margin-left: auto;
  padding: 6px 12px;
  border-radius: 999px;
  background: rgb(255 255 255 / 0.12);
  color: #fff;
  font-size: 13px;
  text-decoration: none;
}

.lb-bar .icon-btn {
  color: #fff;
}

.lb-bar .icon-btn:active {
  background: rgb(255 255 255 / 0.16);
}

.lb-stage {
  grid-row: 2;
  min-height: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 8px 12px;
  overflow: hidden;
}

/*
 * Small images are scaled UP to a comfortable size rather than left as a stamp
 * in a black void — an icon shown at its native 180px on a phone reads as a
 * mistake. `contain` keeps the aspect ratio, and the frame gives a transparent
 * or light-backgrounded image something to sit on.
 */
#lb-img {
  max-width: 100%;
  max-height: 100%;
  width: auto;
  height: auto;
  object-fit: contain;
  border-radius: 14px;
  box-shadow: 0 18px 50px rgb(0 0 0 / 0.6);
  background: rgb(255 255 255 / 0.03);
  will-change: transform, opacity;
}

/* Square-ish small images (icons) get a sensible target size. */
#lb-img.fit-up {
  width: min(88vw, 62vh, 560px);
}

.lb-nav {
  position: absolute;
  z-index: 2;
  top: 50%;
  transform: translateY(-50%);
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border: 0;
  border-radius: 50%;
  background: rgb(255 255 255 / 0.12);
  color: #fff;
  backdrop-filter: blur(6px);
}

.lb-nav[disabled] {
  opacity: 0.2;
}

.lb-prev { left: 10px; }
.lb-next { right: 10px; }

/* ── filmstrip ── */

.lb-strip {
  grid-row: 3;
  display: flex;
  gap: 8px;
  align-items: center;
  padding: 10px 12px calc(12px + env(safe-area-inset-bottom));
  overflow-x: auto;
  overscroll-behavior: contain;
  touch-action: pan-x;
  scrollbar-width: none;
}

.lb-strip::-webkit-scrollbar {
  display: none;
}

.lb-thumb {
  flex: none;
  width: 52px;
  height: 52px;
  padding: 0;
  border: 2px solid transparent;
  border-radius: 10px;
  background: rgb(255 255 255 / 0.06);
  overflow: hidden;
  opacity: 0.55;
  transition: opacity 0.15s ease, border-color 0.15s ease;
}

.lb-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.lb-thumb.active {
  opacity: 1;
  border-color: var(--accent);
}

/* One image: the strip and the arrows are just clutter. */
.lightbox.single .lb-strip,
.lightbox.single .lb-nav {
  display: none;
}

@media (max-width: 767px) {
  .lb-nav {
    display: none;
  }
}

.msg-files img {
  cursor: zoom-in;
}

/* ── header command shortcuts ────────────────────────────────────────── */

.icon-btn.danger {
  color: #f87171;
}

/* Five controls plus the session name is tight on a 390px phone; shaving the
   hit target to 34px keeps the name readable while staying above the ~32px
   comfortable-touch floor. */
@media (max-width: 420px) {
  .topbar .icon-btn {
    width: 34px;
    height: 34px;
  }

  .topbar {
    gap: 2px;
  }
}

.model-list {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  overscroll-behavior: contain;
  padding: 6px 0 12px;
}

.model-item {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 11px 16px;
  border: 0;
  border-top: 1px solid var(--bg-dark);
  background: none;
  color: var(--text);
  text-align: left;
  font-size: 14px;
}

.model-item .m-ref {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.model-item .m-tag {
  flex: none;
  padding: 2px 7px;
  border-radius: 999px;
  background: var(--bg-input);
  color: var(--text-dim);
  font-size: 11px;
}

.model-item.current {
  color: var(--text-bright);
  font-weight: 600;
}

.model-item.current::before {
  content: '✓';
  color: var(--accent);
}

.model-item:not(.current)::before {
  content: '';
  width: 1ch;
}

/* ── provider badge ──────────────────────────────────────────────────── */

.provider-badge {
  flex: none;
  padding: 1px 6px;
  border-radius: 5px;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.04em;
  line-height: 1.6;
  border: 1px solid transparent;
  white-space: nowrap;
}

/* Colour-coded by where the compute happens: green = this machine,
   NVIDIA green = NIM, and so on. Text label carries the meaning; colour is
   only a shortcut, so it still reads without colour vision. */
.provider-badge.local {
  background: rgb(59 165 93 / 0.18);
  border-color: rgb(59 165 93 / 0.5);
  color: #7ee2a8;
}

.provider-badge.nv {
  background: rgb(118 185 0 / 0.18);
  border-color: rgb(118 185 0 / 0.5);
  color: #a6e34d;
}

.provider-badge.gpt {
  background: rgb(16 163 127 / 0.18);
  border-color: rgb(16 163 127 / 0.5);
  color: #5fd3b8;
}

.provider-badge.gem {
  background: rgb(66 133 244 / 0.18);
  border-color: rgb(66 133 244 / 0.5);
  color: #8ab4f8;
}

.provider-badge.xai {
  background: rgb(255 255 255 / 0.1);
  border-color: rgb(255 255 255 / 0.28);
  color: #e6e6e6;
}

.provider-badge.or {
  background: rgb(139 92 246 / 0.18);
  border-color: rgb(139 92 246 / 0.5);
  color: #c4b5fd;
}

.provider-badge.sak,
.provider-badge.other {
  background: var(--bg-input);
  border-color: var(--border);
  color: var(--text-dim);
}

#header-badge {
  margin-left: 2px;
}

/* ── sheet search ────────────────────────────────────────────────────── */

.sheet-search {
  flex: none;
  padding: 10px 16px 4px;
}

.sheet-search input {
  width: 100%;
  padding: 10px 12px;
  background: var(--bg-input);
  border: 1px solid transparent;
  border-radius: var(--radius);
  color: var(--text-bright);
  font-size: 16px; /* keep iOS from zooming on focus */
  outline: none;
}

.sheet-search input:focus {
  border-color: var(--accent);
}

.model-item .provider-badge {
  margin-left: 2px;
}

.model-item mark {
  background: rgb(88 101 242 / 0.35);
  color: inherit;
  border-radius: 2px;
}

/* ── notification toggle ─────────────────────────────────────────────── */

.notif-toggle {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 6px 0;
  margin-bottom: 6px;
  text-align: left;
}

.notif-toggle svg {
  width: 16px;
  height: 16px;
  flex: none;
}

.notif-state {
  margin-left: auto;
  padding: 1px 7px;
  border-radius: 999px;
  background: var(--bg-input);
  color: var(--text-dim);
  font-size: 11px;
}

.notif-state.on {
  background: rgb(59 165 93 / 0.2);
  color: #7ee2a8;
}

.notif-state.blocked {
  background: rgb(218 55 60 / 0.18);
  color: #f4a3a5;
}

/* ── toast ───────────────────────────────────────────────────────────── */

.toast {
  position: fixed;
  left: 50%;
  transform: translateX(-50%);
  bottom: calc(84px + env(safe-area-inset-bottom));
  z-index: 70;
  display: flex;
  align-items: center;
  gap: 12px;
  max-width: calc(100vw - 32px);
  padding: 10px 14px;
  border-radius: 10px;
  background: #101114;
  border: 1px solid var(--border);
  box-shadow: 0 8px 24px rgb(0 0 0 / 0.5);
  color: var(--text-bright);
  font-size: 13.5px;
  animation: toast-in 0.14s ease-out;
}

@keyframes toast-in {
  from {
    opacity: 0;
    transform: translate(-50%, 8px);
  }
  to {
    opacity: 1;
    transform: translate(-50%, 0);
  }
}

.toast span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.toast button {
  flex: none;
  padding: 5px 11px;
  border: 0;
  border-radius: 6px;
  background: var(--accent);
  color: #fff;
  font-size: 13px;
  font-weight: 600;
}

/* A tapped link copies rather than navigating, so it should not look like a
   plain hyperlink invitation to leave the page. */
.msg-text a {
  text-decoration-style: dotted;
  text-decoration-line: underline;
  text-underline-offset: 2px;
}
