:root,
[data-theme="light"] {
  --cream-0: #faf9f6;
  --cream-1: #f4f3ee;
  --cream-2: #ece9e1;
  --surface: #ffffff;
  --border: #e3e0d8;
  --text: #3d3d3a;
  --text-muted: #87867f;
  --accent: #d97757;
  --accent-dark: #c05e3f;
  --accent-tint: #f2e5de;
  --danger: #b3543f;
  --danger-tint: #fbeae6;
  --code-bg: #282c34;
  --shadow: rgba(0, 0, 0, 0.05);
}

[data-theme="dark"] {
  --cream-0: #1f1e1c;
  --cream-1: #2a2926;
  --cream-2: #383734;
  --surface: #262524;
  --border: #3d3b37;
  --text: #ece9e1;
  --text-muted: #9a978d;
  --accent: #e08b68;
  --accent-dark: #eb9e7d;
  --accent-tint: #3a2c25;
  --danger: #e08872;
  --danger-tint: #3a2622;
  --code-bg: #17171a;
  --shadow: rgba(0, 0, 0, 0.35);
}

* { box-sizing: border-box; }
html, body { height: 100%; overflow-x: hidden; }

body {
  margin: 0;
  font-family: var(--sans, -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif);
  background: var(--cream-0);
  color: var(--text);
  font-size: 15px;
  transition: background 0.15s ease, color 0.15s ease;
}

button { font-family: inherit; }
a { color: inherit; }

:root {
  --serif: Georgia, "Iowan Old Style", "Palatino Linotype", serif;
}


/* ==================== brand logo ====================
   A single white PNG, painted through a CSS mask so it takes whatever colour
   we set as `background`. That means one asset tints itself to the accent in
   both themes, instead of shipping a light and a dark file and swapping them.
   Falls back to the accent-coloured box if masks aren't supported, which
   still reads as a mark rather than a broken image. */
.brand-logo {
  display: inline-block;
  width: 1.15em;
  height: 1.15em;
  flex: 0 0 auto;
  background-color: var(--accent);
  -webkit-mask: url("logo.png") center / contain no-repeat;
  mask: url("logo.png") center / contain no-repeat;
  vertical-align: -0.2em;
}

.brand-logo-lg {
  width: 52px;
  height: 52px;
  background-color: var(--accent);
}

/* ==================== home page ====================
   The hero is a working composer rather than a button, so the page's one
   bold element is the thing the product actually does. Everything around it
   stays quiet: no cards, no gradients, one accent.

   Palette and serif are inherited from the app on purpose — the visitor is
   one click from the chat, and a home page in a different visual language
   would read as a different product. */

.home {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  background: var(--cream-0);
}

/* ---------- nav ---------- */
.home-nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 18px clamp(16px, 5vw, 44px);
  flex-wrap: wrap;
}

.home-brand {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-weight: 600;
  font-size: 17px;
  color: var(--text);
  text-decoration: none;
  letter-spacing: -0.01em;
}

.home-brand .brand-logo { width: 20px; height: 20px; }

.home-nav-right { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; }

.home-login, .home-login-lg {
  color: var(--text);
  text-decoration: none;
  font-size: 14px;
  font-weight: 500;
}

.home-login:hover, .home-login-lg:hover { color: var(--accent-dark); }

.home-signup {
  background: var(--accent);
  color: #fff;
  border-radius: 8px;
  padding: 8px 16px;
  text-decoration: none;
  font-weight: 600;
  font-size: 14px;
}

.home-signup:hover { background: var(--accent-dark); }

/* ---------- hero ---------- */
.home-hero {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 230px;
  gap: clamp(28px, 6vw, 72px);
  align-items: start;
  max-width: 1040px;
  width: 100%;
  margin: clamp(28px, 7vh, 76px) auto clamp(40px, 8vh, 88px);
  padding: 0 clamp(16px, 5vw, 44px);
}

.home-hero h1 {
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(34px, 6.2vw, 56px);
  line-height: 1.04;
  letter-spacing: -0.02em;
  margin: 0 0 14px;
  max-width: 19ch;
}

.home-sub {
  color: var(--text-muted);
  font-size: clamp(15px, 1.8vw, 17px);
  line-height: 1.65;
  max-width: 52ch;
  margin: 0 0 26px;
}

/* The composer. Sized and shaped like the one in the chat, so the jump
   between the two pages doesn't feel like a jump. */
.home-composer {
  display: flex;
  align-items: flex-end;
  gap: 8px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 10px 10px 10px 16px;
  max-width: 620px;
  box-shadow: 0 1px 3px var(--shadow);
  transition: border-color 0.15s ease;
}

.home-composer:focus-within { border-color: var(--accent); }

.home-composer textarea {
  flex: 1;
  border: none;
  background: none;
  resize: none;
  color: var(--text);
  font-family: inherit;
  font-size: 16px;
  line-height: 1.5;
  padding: 7px 0;
  max-height: 160px;
  outline: none;
}

.home-composer textarea::placeholder { color: var(--text-muted); }

.home-composer button {
  flex: 0 0 auto;
  width: 38px;
  height: 38px;
  border: none;
  border-radius: 10px;
  background: var(--accent);
  color: #fff;
  cursor: pointer;
  display: grid;
  place-items: center;
}

.home-composer button:hover { background: var(--accent-dark); }

.home-note {
  margin: 12px 0 0;
  font-size: 13.5px;
  color: var(--text-muted);
}

.home-actions { display: flex; gap: 12px; flex-wrap: wrap; align-items: center; }

.home-signup-lg { padding: 12px 22px; font-size: 15px; }
.home-login-lg {
  padding: 12px 20px;
  border: 1px solid var(--border);
  border-radius: 8px;
  font-weight: 600;
}

/* ---------- facts column ---------- */
.home-facts {
  display: flex;
  flex-direction: column;
  gap: 22px;
  padding-top: 10px;
  border-left: 1px solid var(--border);
  padding-left: 24px;
}

.home-fact { display: flex; flex-direction: column; gap: 3px; }

.home-fact-n {
  font-family: var(--serif);
  font-size: 30px;
  line-height: 1;
  color: var(--text);
}

.home-fact-sym { color: var(--accent); }

.home-fact-t {
  font-size: 12.5px;
  line-height: 1.45;
  color: var(--text-muted);
  max-width: 22ch;
}

/* ---------- model wall ----------
   Live rows from the catalog: enabling a model in the admin panel puts it
   on the home page. The dark band is the page's second register — without
   it the whole thing is one flat sheet of cream. */
.home-wall {
  background: #242320;
  color: #ece9e1;
  padding: clamp(34px, 6vw, 56px) clamp(16px, 5vw, 44px);
}

.home-wall h2 {
  max-width: 1040px;
  margin: 0 auto 22px;
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(19px, 2.6vw, 25px);
  color: #f4f1ea;
}

.home-wall-list {
  max-width: 1040px;
  margin: 0 auto;
  padding: 0;
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.home-wall-list li {
  font-size: 13px;
  padding: 5px 12px;
  border-radius: 999px;
  border: 1px solid #3d3b37;
  color: #b8b4aa;
  white-space: nowrap;
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Provider is the one distinction worth colouring here — it tells you
   whose model you're looking at without a legend. */
.home-wall-list li.wall-anthropic { color: #e8a98c; border-color: #6b4436; }
.home-wall-list li.wall-openai { color: #9fd4b1; border-color: #35543f; }
.home-wall-list li.wall-more { color: #78756d; border-style: dashed; }

/* ---------- steps ---------- */
.home-steps {
  max-width: 1040px;
  width: 100%;
  margin: clamp(40px, 8vh, 84px) auto;
  padding: 0 clamp(16px, 5vw, 44px);
}

.home-steps h2 {
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(21px, 3vw, 28px);
  margin: 0 0 26px;
}

.home-steps ol {
  margin: 0;
  padding: 0;
  list-style: none;
  counter-reset: step;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: clamp(20px, 4vw, 40px);
}

/* Numbered because this genuinely is a sequence: you type, then you switch,
   then you decide whether to keep it. */
.home-steps li { counter-increment: step; }

.home-steps li::before {
  content: counter(step);
  display: block;
  font-family: var(--serif);
  font-size: 15px;
  color: var(--accent);
  margin-bottom: 8px;
  padding-bottom: 8px;
  border-bottom: 1px solid var(--border);
}

.home-steps h3 { margin: 0 0 6px; font-size: 15.5px; font-weight: 600; }

.home-steps p {
  margin: 0;
  color: var(--text-muted);
  font-size: 14px;
  line-height: 1.6;
  max-width: 42ch;
}

/* ---------- footer ---------- */
.home-footer {
  border-top: 1px solid var(--border);
  padding: clamp(28px, 5vw, 48px) clamp(16px, 5vw, 44px);
  color: var(--text-muted);
  font-size: 13px;
  line-height: 1.65;
}

.footer-top {
  max-width: 1040px;
  margin: 0 auto 24px;
  display: grid;
  grid-template-columns: 1.4fr 1fr 1fr;
  gap: clamp(24px, 5vw, 56px);
}

.footer-brand { display: flex; flex-direction: column; gap: 6px; }
.footer-brand .home-brand { font-size: 16px; color: var(--text); }
.footer-tagline { color: var(--text-muted); font-size: 13px; }

.footer-col { display: flex; flex-direction: column; gap: 8px; }
.footer-col h4 {
  margin: 0;
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--text);
}

.footer-col a {
  color: var(--text-muted);
  text-decoration: none;
  font-size: 13.5px;
}

.footer-col a:hover { color: var(--accent-dark); }

.footer-bottom {
  max-width: 1040px;
  margin: 0 auto;
  padding-top: 18px;
  border-top: 1px solid var(--border);
  display: flex;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 8px;
  font-size: 12.5px;
}

.footer-bottom a {
  color: var(--text-muted);
  text-decoration: none;
}

.footer-bottom a:hover { color: var(--accent-dark); }

@media (max-width: 600px) {
  .footer-top { grid-template-columns: 1fr; gap: 22px; }
}

/* ==================== legal pages ==================== */
.legal-page {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  background: var(--cream-0);
}

.legal-nav {
  padding: 18px clamp(16px, 5vw, 44px);
}

.legal-body {
  max-width: 680px;
  width: 100%;
  margin: 0 auto;
  padding: clamp(24px, 5vw, 48px) clamp(16px, 5vw, 44px);
  flex: 1;
}

.legal-body h1 {
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(26px, 4vw, 36px);
  margin: 0 0 6px;
}

.legal-updated {
  color: var(--text-muted);
  font-size: 13px;
  margin: 0 0 30px;
}

.legal-body h2 {
  font-size: 16px;
  font-weight: 600;
  margin: 28px 0 8px;
}

.legal-body p {
  color: var(--text-muted);
  font-size: 14.5px;
  line-height: 1.7;
  margin: 0 0 16px;
}

.legal-footer {
  padding: 22px clamp(16px, 5vw, 44px);
  text-align: center;
  font-size: 13.5px;
}

.legal-footer a {
  color: var(--text-muted);
  text-decoration: none;
}

.legal-footer a:hover { color: var(--accent-dark); }

@media (max-width: 800px) {
  .home-hero { grid-template-columns: 1fr; }

  /* The facts stop being a sidebar and become a row under the composer —
     still legible, and it keeps the composer above the fold on a phone. */
  .home-facts {
    flex-direction: row;
    flex-wrap: wrap;
    gap: 20px 28px;
    border-left: none;
    border-top: 1px solid var(--border);
    padding: 20px 0 0;
  }

  .home-fact-n { font-size: 24px; }
}

@media (max-width: 460px) {
  .home-nav { gap: 10px; }
  .home-nav-right { width: 100%; justify-content: space-between; }
}

[dir="rtl"] .home-facts {
  border-left: none;
  border-right: 1px solid var(--border);
  padding-left: 0;
  padding-right: 24px;
}

@media (max-width: 800px) {
  [dir="rtl"] .home-facts { border-right: none; border-top: 1px solid var(--border); padding-right: 0; }
}

/* Model names are latin identifiers; they read left-to-right in any UI. */
[dir="rtl"] .home-wall-list li { direction: ltr; }

/* ==================== chat layout ==================== */
.app {
  display: flex;
  height: 100vh;
  height: 100dvh; /* accounts for mobile browser chrome (address bar) so the composer isn't pushed off-screen */
  overflow: hidden;
}

.sidebar {
  width: 260px;
  min-width: 260px;
  background: var(--cream-1);
  border-right: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  padding: 14px 10px;
  transition: margin-left 0.18s ease;
}

.sidebar.collapsed { margin-left: -260px; }

.sidebar-top {
  padding: 0 4px 10px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.brand-mini { padding: 2px 4px; }
.brand-mini .brand-logo { width: 18px; height: 18px; }

.new-chat-btn {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  background: var(--surface);
  border: 1px solid var(--border);
  color: var(--text);
  border-radius: 10px;
  padding: 9px 12px;
  font-size: 13.5px;
  font-weight: 500;
  cursor: pointer;
}

.new-chat-btn:hover { border-color: var(--accent); color: var(--accent-dark); }

.sidebar-section-label {
  font-size: 11.5px;
  color: var(--text-muted);
  padding: 14px 10px 6px;
}

.conversation-list {
  list-style: none;
  margin: 0;
  padding: 0;
  overflow-y: auto;
  flex: 1;
}

.conversation-item {
  display: flex;
  align-items: center;
  gap: 6px;
  border-radius: 8px;
  padding: 8px 10px;
  cursor: pointer;
  font-size: 13.5px;
  margin-bottom: 2px;
}

.conversation-item:hover { background: var(--cream-2); }

.conversation-item.active {
  background: var(--accent-tint);
  color: var(--accent-dark);
}

.conversation-title {
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.conversation-delete {
  opacity: 0;
  background: none;
  border: none;
  color: var(--text-muted);
  cursor: pointer;
  padding: 2px 4px;
  border-radius: 4px;
  font-size: 13px;
}

.conversation-item:hover .conversation-delete { opacity: 1; }
.conversation-delete:hover { color: var(--danger); background: var(--danger-tint); }

.sidebar-bottom {
  border-top: 1px solid var(--border);
  padding: 10px 8px 2px;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.theme-toggle-btn {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 7px 10px;
  cursor: pointer;
  font-size: 13px;
  color: var(--text);
  display: flex;
  justify-content: space-between;
}

.theme-icon-dark { display: none; }
[data-theme="dark"] .theme-icon-light { display: none; }
[data-theme="dark"] .theme-icon-dark { display: inline; }

.sidebar-user {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 12.5px;
  color: var(--text-muted);
  padding: 2px 2px;
}

.sidebar-email {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 150px;
}

.sidebar-user a { text-decoration: none; }
.sidebar-user a:hover { color: var(--accent-dark); }

.admin-link {
  font-size: 12px;
  color: var(--text-muted);
  text-decoration: none;
  padding: 2px;
}

.admin-link:hover { color: var(--accent-dark); }

/* ---------------- main column ---------------- */
.main {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-width: 0;
  background: var(--cream-0);
}

.topbar {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 10px 18px;
}

.topbar-row {
  display: flex;
  align-items: center;
  gap: 10px;
}

.category-tabs {
  display: flex;
  align-items: center;
  gap: 4px;
  overflow-x: auto;
  scrollbar-width: none;
}

.category-tabs::-webkit-scrollbar { display: none; }

.category-tab {
  flex: 0 0 auto;
  background: none;
  border: 1px solid transparent;
  color: var(--text-muted);
  border-radius: 8px;
  padding: 6px 11px;
  font-size: 13px;
  white-space: nowrap;
  cursor: pointer;
}

.category-tab:hover { background: var(--cream-2); color: var(--text); }

.category-tab.active {
  background: var(--accent-tint);
  color: var(--accent-dark);
  border-color: var(--accent);
  font-weight: 500;
}

.category-tab.is-empty { opacity: 0.55; }

.icon-btn {
  background: none;
  border: none;
  color: var(--text-muted);
  cursor: pointer;
  padding: 6px;
  border-radius: 6px;
  display: flex;
}

.icon-btn:hover { background: var(--cream-2); color: var(--text); }

.video-mode-btn {
  font-size: 13px;
  padding: 6px 12px;
  border: 1px solid var(--border);
  border-radius: 8px;
}

.video-mode-btn.active {
  background: var(--accent-tint);
  color: var(--accent-dark);
  border-color: var(--accent);
}

/* ---------------- searchable model picker ---------------- */
.model-picker {
  position: relative;
  flex: 1;
  min-width: 0;
  max-width: 420px;
}

.model-picker-btn {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  background: var(--cream-1);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 7px 10px;
  font-size: 13px;
  cursor: pointer;
  text-align: left;
}

.model-picker-btn:hover { background: var(--cream-2); }
.model-picker-btn:disabled { opacity: 0.6; cursor: not-allowed; }

.model-picker-label {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.model-picker-caret { flex-shrink: 0; opacity: 0.7; }
.model-picker-btn[aria-expanded="true"] .model-picker-caret { transform: rotate(180deg); }

.model-picker-panel {
  position: absolute;
  z-index: 60;
  top: calc(100% + 6px);
  left: 0;
  width: min(460px, 92vw);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  box-shadow: 0 12px 32px var(--shadow);
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.model-picker-panel[hidden] { display: none; }

.model-picker-search {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 12px;
  border-bottom: 1px solid var(--border);
  color: var(--text-muted);
}

.model-picker-search input {
  flex: 1;
  border: none;
  outline: none;
  background: transparent;
  color: var(--text);
  /* 16px so iOS Safari doesn't zoom the whole page when this gets focus. */
  font-size: 16px;
  font-family: inherit;
}

.model-provider-chips {
  display: flex;
  gap: 6px;
  padding: 8px 10px;
  overflow-x: auto;
  border-bottom: 1px solid var(--border);
  scrollbar-width: none;
}
.model-provider-chips::-webkit-scrollbar { display: none; }

.model-chip {
  flex-shrink: 0;
  border: 1px solid var(--border);
  background: var(--cream-1);
  color: var(--text-muted);
  border-radius: 999px;
  padding: 4px 10px;
  font-size: 12px;
  cursor: pointer;
  white-space: nowrap;
}
.model-chip:hover { background: var(--cream-2); color: var(--text); }
.model-chip.active {
  background: var(--accent-tint);
  border-color: var(--accent);
  color: var(--accent-dark);
}

.model-list {
  max-height: min(380px, 52vh);
  overflow-y: auto;
  padding: 4px 0;
}

.model-section {
  padding: 8px 12px 4px;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-muted);
}

.model-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 7px 12px;
  cursor: pointer;
}
.model-row:hover, .model-row.highlight { background: var(--cream-1); }
.model-row.selected { background: var(--accent-tint); }

.model-row-main { flex: 1; min-width: 0; }

.model-row-name {
  font-size: 13.5px;
  display: flex;
  align-items: center;
  gap: 6px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.model-row-badge {
  font-size: 10px;
  color: var(--accent-dark);
  background: var(--accent-tint);
  border-radius: 4px;
  padding: 1px 5px;
}

.model-row-sub {
  font-size: 11.5px;
  color: var(--text-muted);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.model-star {
  border: none;
  background: transparent;
  color: var(--border);
  cursor: pointer;
  padding: 4px;
  line-height: 0;
  border-radius: 6px;
}
.model-star:hover { color: var(--text-muted); background: var(--cream-2); }
.model-star.on { color: var(--accent); }

.model-empty, .model-picker-foot {
  padding: 12px;
  font-size: 12px;
  color: var(--text-muted);
}
.model-picker-foot {
  padding: 8px 12px;
  border-top: 1px solid var(--border);
}

/* A soft blinking caret at the end of a reply that's still streaming in. */
.msg-row.streaming .markdown-body > *:last-child::after {
  content: "";
  display: inline-block;
  width: 7px;
  height: 1em;
  margin-left: 2px;
  vertical-align: text-bottom;
  background: var(--accent);
  opacity: 0.7;
  animation: stream-blink 1s steps(2, start) infinite;
}

@keyframes stream-blink {
  0%, 50% { opacity: 0.7; }
  50.01%, 100% { opacity: 0; }
}

/* ---------------- message area ---------------- */
.messages {
  flex: 1;
  min-width: 0;
  overflow-y: auto;
  overflow-x: hidden;
  padding: 10px 20px 30px;
}

/* A single very long line (a code block, a URL, a wide table) used to
   stretch the message column and take the whole page sideways with it.
   Every link in that chain gets min-width:0 so the overflow stays inside
   the element that owns it. */
.msg-row, .msg-bubble, .markdown-body { min-width: 0; max-width: 100%; }
.markdown-body p, .markdown-body li, .markdown-body a { overflow-wrap: break-word; }
.markdown-body table { display: block; width: 100%; overflow-x: auto; }

.empty-state {
  max-width: 680px;
  margin: 8vh auto 0;
  text-align: center;
}

.empty-mark { margin-bottom: 12px; }

.empty-state h2 {
  font-family: var(--serif);
  font-weight: 400;
  font-size: 30px;
  margin: 0;
}

.msg-row {
  max-width: 720px;
  margin: 0 auto 22px;
  display: flex;
  flex-direction: column;
}

.msg-row.user { align-items: flex-end; }
.msg-row.assistant { align-items: flex-start; }

.msg-bubble { position: relative; line-height: 1.6; }

.msg-row.user .msg-bubble {
  background: var(--cream-1);
  border: 1px solid var(--border);
  border-radius: 16px;
  padding: 10px 16px;
  max-width: 80%;
  white-space: pre-wrap;
}

.msg-row.assistant .msg-bubble { width: 100%; padding: 4px 2px; }

.msg-attachments {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: 6px;
}

.msg-attachment-chip {
  font-size: 12px;
  background: var(--cream-2);
  border-radius: 6px;
  padding: 4px 8px;
  color: var(--text-muted);
}

a.msg-attachment-chip {
  text-decoration: none;
  cursor: pointer;
}

a.msg-attachment-chip:hover {
  background: var(--accent-tint);
  color: var(--accent-dark);
}

/* Buttons for downloading a model-generated file (an updated project .zip,
   or a message exported to PDF/Word) — unlike .media-download-btn (which
   floats over an image/video and only appears on hover), these need to be
   visible and tappable on their own, so they get their own static layout. */
.generated-files {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 10px;
}

.generated-files .media-download-btn {
  position: static;
  opacity: 1;
  background: var(--accent-tint);
  color: var(--accent-dark);
  border: 1px solid var(--accent);
}

.generated-files .media-download-btn:hover {
  background: var(--accent);
  color: #fff;
}

.msg-actions {
  display: flex;
  gap: 4px;
  margin-top: 6px;
  opacity: 0;
  transition: opacity 0.12s ease;
}

.msg-row:hover .msg-actions { opacity: 1; }

.msg-copy-btn {
  background: none;
  border: none;
  color: var(--text-muted);
  cursor: pointer;
  font-size: 12px;
  padding: 3px 6px;
  border-radius: 6px;
}

.msg-copy-btn:hover { background: var(--cream-2); color: var(--text); }

.msg-row.error .msg-bubble {
  background: var(--danger-tint);
  border: 1px solid var(--danger);
  color: var(--danger);
  border-radius: 12px;
  padding: 10px 16px;
}

.msg-row.pending .msg-bubble { color: var(--text-muted); }

.typing-dots span {
  display: inline-block;
  width: 5px;
  height: 5px;
  margin-right: 3px;
  border-radius: 50%;
  background: var(--text-muted);
  animation: blink 1.2s infinite;
}
.typing-dots span:nth-child(2) { animation-delay: 0.2s; }
.typing-dots span:nth-child(3) { animation-delay: 0.4s; }

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

.video-result, .image-result {
  position: relative;
}

.video-result video {
  max-width: 100%;
  border-radius: 12px;
  border: 1px solid var(--border);
  display: block;
}

.image-result img {
  max-width: 100%;
  border-radius: 12px;
  border: 1px solid var(--border);
  display: block;
}

.image-result + .markdown-body {
  margin-top: 8px;
}

.media-download-btn {
  position: absolute;
  top: 10px;
  right: 10px;
  display: flex;
  align-items: center;
  gap: 5px;
  background: rgba(0, 0, 0, 0.55);
  color: #fff;
  border: none;
  border-radius: 8px;
  padding: 6px 10px;
  font-size: 12.5px;
  cursor: pointer;
  text-decoration: none;
  opacity: 0;
  transition: opacity 0.12s ease, background 0.12s ease;
}

.media-download-btn svg { display: block; }

.video-result:hover .media-download-btn,
.image-result:hover .media-download-btn,
.media-download-btn:focus-visible {
  opacity: 1;
}

.media-download-btn:hover { background: rgba(0, 0, 0, 0.75); }

@media (hover: none) {
  /* touch devices have no hover — keep the download action visible */
  .media-download-btn { opacity: 1; }
}

.video-pending {
  display: flex;
  align-items: center;
  gap: 8px;
  color: var(--text-muted);
  font-size: 13.5px;
}

/* markdown content inside assistant messages */
.markdown-body p { margin: 0 0 12px; }
.markdown-body p:last-child { margin-bottom: 0; }
.markdown-body ul, .markdown-body ol { margin: 0 0 12px; padding-left: 22px; }
.markdown-body li { margin-bottom: 4px; }
.markdown-body h1, .markdown-body h2, .markdown-body h3 {
  font-family: var(--serif);
  font-weight: 400;
  margin: 18px 0 8px;
}
.markdown-body h1 { font-size: 22px; }
.markdown-body h2 { font-size: 19px; }
.markdown-body h3 { font-size: 16px; }
.markdown-body blockquote {
  border-left: 3px solid var(--accent);
  margin: 0 0 12px;
  padding: 2px 14px;
  color: var(--text-muted);
}
.markdown-body a { color: var(--accent-dark); }
.markdown-body code:not(pre code) {
  background: var(--cream-2);
  padding: 1px 5px;
  border-radius: 4px;
  font-size: 0.88em;
  font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, monospace;
}
.markdown-body table { border-collapse: collapse; margin-bottom: 12px; font-size: 13.5px; }
.markdown-body th, .markdown-body td { border: 1px solid var(--border); padding: 6px 10px; }

/* code block wrapper with copy button */
.code-block {
  max-width: 100%;
  min-width: 0;
  background: var(--code-bg);
  border-radius: 10px;
  overflow: hidden;
  margin: 0 0 14px;
  font-size: 13px;
}

.code-block-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 7px 12px;
  background: rgba(0,0,0,0.2);
  color: #b5b3ab;
  font-family: "SFMono-Regular", Consolas, monospace;
  font-size: 12px;
}

.code-copy-btn {
  background: none;
  border: none;
  color: #b5b3ab;
  cursor: pointer;
  font-size: 12px;
  padding: 2px 6px;
  border-radius: 5px;
}

.code-copy-btn:hover { background: rgba(255,255,255,0.08); color: #fff; }

.code-block pre { margin: 0; padding: 14px; overflow-x: auto; }
.code-block code {
  font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, monospace;
  font-size: 13px;
  line-height: 1.5;
}

/* ---------------- composer ---------------- */
.composer-wrap { padding: 4px 20px 18px; }

.attachment-tray {
  max-width: 720px;
  margin: 0 auto 8px;
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.attachment-tray:empty { display: none; }

.attachment-pill {
  display: flex;
  align-items: center;
  gap: 6px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 6px 10px;
  font-size: 12.5px;
  max-width: 100%;
}

.attachment-pill span { overflow-wrap: anywhere; }

.attachment-pill button {
  background: none;
  border: none;
  color: var(--text-muted);
  cursor: pointer;
  font-size: 13px;
  padding: 0;
}

.attachment-pill button:hover { color: var(--danger); }

.composer {
  max-width: 720px;
  margin: 0 auto;
  display: flex;
  align-items: flex-end;
  gap: 8px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 18px;
  padding: 8px 10px 8px 10px;
  box-shadow: 0 1px 3px var(--shadow);
}

.attach-btn {
  background: none;
  border: none;
  color: var(--text-muted);
  cursor: pointer;
  padding: 8px;
  border-radius: 50%;
  display: flex;
  flex-shrink: 0;
}

.attach-btn:hover { background: var(--cream-2); color: var(--text); }

.composer textarea {
  flex: 1;
  resize: none;
  border: none;
  outline: none;
  background: transparent;
  color: var(--text);
  font-size: 15px;
  font-family: inherit;
  max-height: 200px;
  line-height: 1.5;
  padding: 6px 0;
}

.send-btn {
  background: var(--accent);
  border: none;
  color: #fff;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  flex-shrink: 0;
}

.send-btn:hover { background: var(--accent-dark); }
.send-btn:disabled { opacity: 0.4; cursor: default; }

.composer-hint {
  max-width: 720px;
  margin: 6px auto 0;
  font-size: 12px;
  color: var(--text-muted);
  text-align: center;
  min-height: 14px;
}

/* ==================== auth pages ==================== */
.login-wrap {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 12px;
  min-height: 100vh;
  background: var(--cream-0);
  padding: 20px;
}

.login-box {
  background: var(--surface);
  border: 1px solid var(--border);
  padding: 32px;
  border-radius: 14px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  width: 320px;
  box-shadow: 0 4px 20px var(--shadow);
}

.login-box h2 { font-family: var(--serif); font-weight: 400; margin: 0 0 4px; }

.login-box input {
  padding: 9px 10px;
  border-radius: 8px;
  border: 1px solid var(--border);
  background: var(--cream-0);
  color: var(--text);
  font-size: 14px;
}

.login-box button {
  background: var(--accent);
  border: none;
  border-radius: 8px;
  padding: 9px;
  color: #fff;
  font-weight: 600;
  cursor: pointer;
}

.login-box button:hover { background: var(--accent-dark); }

.login-box a { color: var(--text-muted); font-size: 13px; text-align: center; text-decoration: none; }
.login-box a:hover { color: var(--accent-dark); }

.error { color: var(--danger); font-size: 13px; margin: 0; }
.muted-text { color: var(--text-muted); font-size: 13.5px; line-height: 1.5; margin: 0; }
.dev-link { font-size: 12.5px; word-break: break-all; background: var(--cream-1); padding: 8px; border-radius: 6px; }

/* The code is the one thing on the page worth looking at, so it gets the
   weight: tabular digits, wide tracking, big enough to check against the
   email at a glance. 20px also keeps iOS from zooming the page on focus. */
.otp-input {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 20px;
  letter-spacing: 0.4em;
  text-align: center;
  text-indent: 0.4em; /* re-centres the text despite trailing letter-spacing */
  padding: 12px 10px;
}

/* The resend action is a second form (it posts elsewhere), but it shouldn't
   read as a second decision of equal weight. */
.login-box-secondary {
  padding: 16px 32px 20px;
  gap: 10px;
}
.login-box-secondary button {
  background: none;
  border: 1px solid var(--border);
  color: var(--text-muted);
  font-weight: 500;
}
.login-box-secondary button:hover {
  background: var(--cream-1);
  color: var(--accent-dark);
}

/* ==================== admin pages ==================== */
.admin-wrap {
  max-width: 1100px;
  margin: 0 auto;
  padding: 26px 20px;
  background: var(--cream-0);
  min-height: 100vh;
}

.admin-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 22px; flex-wrap: wrap; gap: 10px; }
.admin-header h1 { font-family: var(--serif); font-weight: 400; margin: 0; }
.admin-header a { color: var(--text); margin-left: 14px; text-decoration: none; font-size: 13.5px; }
.admin-header a:hover { color: var(--accent-dark); }

.add-keys, .keys-list, .models-info {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 18px;
  margin-bottom: 20px;
}

.add-keys h2, .keys-list h2, .models-info h2 { font-size: 15px; font-weight: 600; margin: 0 0 12px; }

.add-keys form { display: flex; flex-direction: column; gap: 10px; align-items: flex-start; }

.field-label { font-size: 12.5px; color: var(--text-muted); margin-bottom: -4px; }

.add-keys input, .add-keys textarea, .add-keys select {
  background: var(--cream-0);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 9px 10px;
  font-family: "SFMono-Regular", Consolas, monospace;
  font-size: 13px;
  width: 100%;
}

.add-keys select { font-family: inherit; }

.checkbox-label {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  font-family: inherit;
  color: var(--text-muted);
}

.add-keys button, .actions button {
  background: var(--accent);
  border: none;
  border-radius: 8px;
  padding: 8px 14px;
  color: #fff;
  font-weight: 600;
  cursor: pointer;
  width: fit-content;
}

.add-keys button:hover, .actions button:hover { background: var(--accent-dark); }

table { width: 100%; border-collapse: collapse; font-size: 13px; }
th, td { text-align: left; padding: 9px 8px; border-bottom: 1px solid var(--border); }
th { color: var(--text-muted); font-weight: 600; font-size: 12px; }
.disabled-row { opacity: 0.5; }
.actions { display: flex; gap: 6px; }
.actions form { display: inline; }
.actions .danger { background: var(--danger); }

.error-cell {
  max-width: 220px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--text-muted);
}

.provider-pill {
  font-size: 11px;
  padding: 2px 8px;
  border-radius: 20px;
  background: var(--cream-2);
  text-transform: capitalize;
}
.provider-anthropic { background: var(--accent-tint); color: var(--accent-dark); }
.provider-openai { background: #dcebe0; color: #2f6b45; }
[data-theme="dark"] .provider-openai { background: #234230; color: #8fd3a5; }
.provider-openrouter { background: #dde3f2; color: #33518c; }
[data-theme="dark"] .provider-openrouter { background: #232c42; color: #93a9e6; }

/* ==================== responsive ==================== */
.sidebar-backdrop { display: none; }

/* Only shown inside the drawer on phones — see the media query below. */
.sidebar-close {
  display: none;
  background: none;
  border: none;
  color: var(--text-muted);
  cursor: pointer;
  padding: 8px;
  border-radius: 8px;
  margin-left: auto;
}
.sidebar-close:hover { background: var(--cream-2); color: var(--text); }

@media (max-width: 760px) {
  .app { position: relative; max-width: 100vw; }

  .sidebar {
    position: fixed;
    top: 0;
    left: 0;
    z-index: 30;
    height: 100vh;
    height: 100dvh;
    width: 82vw;
    max-width: 320px;
    min-width: 0;
    /* Slide with transform rather than margin-left: it doesn't trigger
       layout on every frame, and it can't leave a negative-margin gap in
       the flex row if a rule below ever changes the sidebar's width. */
    margin-left: 0;
    transform: translateX(-100%);
    transition: transform 0.22s ease, visibility 0.22s;
    box-shadow: 2px 0 12px var(--shadow);
    padding-top: calc(14px + env(safe-area-inset-top));
    padding-bottom: calc(14px + env(safe-area-inset-bottom));
    overscroll-behavior: contain;
  }

  /* A translated-but-still-rendered drawer keeps its links focusable and
     tappable off-screen, which is how you end up "logging out" by tapping
     empty space near the left edge. visibility takes it out of play. */
  /* `.sidebar.collapsed { margin-left: -260px }` from the desktop rules is
     more specific than `.sidebar` above, so it still applies here unless
     it's cancelled — otherwise the drawer gets pushed by transform AND by
     margin, and the margin half snaps instead of animating. */
  .sidebar.collapsed { margin-left: 0; visibility: hidden; }
  .sidebar:not(.collapsed) { transform: translateX(0); visibility: visible; }

  .sidebar-top { flex-direction: column; }
  .brand-mini { display: flex; align-items: center; gap: 8px; }
  .sidebar-close { display: flex; }

  /* Keeps the recents list, not the whole drawer, as the scrolling area. */
  .conversation-list { min-height: 0; overscroll-behavior: contain; }

  .sidebar-backdrop {
    display: block;
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.35);
    z-index: 25;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.22s ease;
  }
  .sidebar-backdrop.visible { opacity: 1; pointer-events: auto; }

  /* While the drawer is open, the page behind it must not scroll — on iOS
     the touch otherwise passes through and scrolls the message list. */
  body.sidebar-open { overflow: hidden; }

  /* The toggle used to live inline in the topbar, which buried it under
     the open drawer. It's pinned above everything instead — and hidden
     while the drawer is open, since the drawer has its own close button
     and the backdrop closes it too. Sitting a floating button on top of
     the drawer's own header was the thing that looked broken. */
  #sidebar-toggle {
    position: fixed;
    top: calc(10px + env(safe-area-inset-top));
    left: 10px;
    z-index: 40;
    background: var(--surface);
    border: 1px solid var(--border);
    border-radius: 8px;
    box-shadow: 0 1px 6px var(--shadow);
    transition: opacity 0.15s ease;
  }
  body.sidebar-open #sidebar-toggle { opacity: 0; pointer-events: none; }

  /* The toggle no longer takes up space inline (it's fixed now), so
     reserve room for it at the start of the top bar instead of letting
     the category tabs slide underneath it. */
  .topbar-row-1 { padding-left: 46px; }

  .topbar {
    padding: 8px 10px;
    padding-top: calc(8px + env(safe-area-inset-top));
    gap: 6px;
  }

  .topbar-row { gap: 6px; }

  .category-tab {
    padding: 8px 10px;
    font-size: 12.5px;
  }

  .model-picker { max-width: none; }
  .model-picker-btn { padding: 7px 8px; font-size: 13px; }
  /* The panel is anchored to the left edge of a full-width control here, so
     it can use the whole viewport instead of being clipped by it. */
  .model-picker-panel { width: 100%; }
  .model-list { max-height: 46vh; }

  .video-mode-btn .btn-label { display: none; }
  .video-mode-btn { padding: 8px; }

  .messages { padding: 8px 12px 20px; -webkit-overflow-scrolling: touch; }

  .msg-row { max-width: 100%; }
  .msg-row.user .msg-bubble { max-width: 92%; }

  .composer-wrap {
    padding: 4px 10px 14px;
    padding-bottom: calc(14px + env(safe-area-inset-bottom));
  }
  .attachment-tray { max-width: 100%; }

  /* Same 16px rule as the select above — this is the input people type in
     most, so it matters most that it never triggers zoom. */
  .composer textarea { font-size: 16px; }

  /* Comfortable tap targets (Apple/Google guidance: ~44px minimum) */
  .attach-btn, .send-btn, #sidebar-toggle, .theme-toggle-btn, #settings-btn {
    min-width: 40px;
    min-height: 40px;
  }

  .empty-state { margin-top: 6vh; padding: 0 12px; }
  .empty-state h2 { font-size: 24px; }

  .msg-actions { opacity: 1; }

  .media-download-btn { top: 8px; right: 8px; padding: 5px 8px; }

  .generated-files { flex-wrap: wrap; }

  /* horizontally scrollable mode tabs instead of squeezing/wrapping */
  .category-tabs {
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    flex-wrap: nowrap;
  }
  .category-tabs::-webkit-scrollbar { display: none; }
  .category-tab { flex-shrink: 0; }
}

@media (max-width: 400px) {
  .sidebar-email { max-width: 90px; }
  .model-picker-btn { font-size: 12.5px; }
}
/* ==================== settings modal ==================== */
.modal-backdrop {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.35);
  z-index: 50;
  align-items: center;
  justify-content: center;
}

.modal-backdrop.visible { display: flex; }

.modal {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  width: 92%;
  max-width: 420px;
  max-height: 86vh;
  overflow-y: auto;
  box-shadow: 0 12px 32px var(--shadow);
}

.modal-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 14px 16px;
  border-bottom: 1px solid var(--border);
}

.modal-header h3 { margin: 0; font-family: var(--serif); font-weight: 400; font-size: 17px; color: var(--text); }

.modal-close {
  background: none;
  border: none;
  color: var(--text-muted);
  cursor: pointer;
  padding: 4px;
  border-radius: 6px;
}

.modal-close:hover { background: var(--cream-2); color: var(--text); }

.modal-body { padding: 16px; display: flex; flex-direction: column; gap: 22px; }

.settings-form { display: flex; flex-direction: column; gap: 8px; }

.settings-form h4 { margin: 0 0 2px; font-size: 13px; font-weight: 600; color: var(--text); }

.settings-form input {
  background: var(--cream-1);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 8px 10px;
  font-size: 13.5px;
  color: var(--text);
  font-family: inherit;
}

.settings-form button {
  align-self: flex-start;
  background: var(--accent);
  color: #fff;
  border: none;
  border-radius: 8px;
  padding: 7px 14px;
  font-size: 13px;
  cursor: pointer;
  margin-top: 2px;
}

.settings-form button:hover { background: var(--accent-dark); }

.form-msg { font-size: 12.5px; margin: 0; min-height: 15px; color: var(--text-muted); }
.form-msg.success-msg { color: #4a8a5c; }
.form-msg.error-msg { color: var(--danger); }

/* ==================== build-steps panel ==================== */
.steps-panel {
  border: 1px solid var(--border);
  background: var(--cream-1);
  border-radius: 10px;
  padding: 10px 12px;
  margin-bottom: 10px;
  font-size: 13px;
}

.steps-panel-title {
  font-weight: 600;
  color: var(--text);
  margin-bottom: 6px;
  font-size: 12.5px;
}

.steps-panel-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 5px; }

.step-item { display: flex; align-items: center; gap: 8px; color: var(--text-muted); }

.step-item.step-done { color: var(--text); }
.step-item.step-done .step-check { color: var(--accent); flex: 0 0 auto; display: flex; }

.step-item.step-active .step-label { color: var(--text); }

.step-spinner {
  width: 11px;
  height: 11px;
  border-radius: 50%;
  border: 2px solid var(--border);
  border-top-color: var(--accent);
  animation: step-spin 0.8s linear infinite;
  flex: 0 0 auto;
}

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

.msg-row.system { display: flex; justify-content: center; margin: 6px 0; }
.msg-row.system .steps-panel { max-width: 520px; width: 100%; }

/* ==================== admin: users ==================== */
.actions form.inline-reset-form { display: inline-flex; }
.inline-reset-form { display: flex; gap: 4px; align-items: center; }
.inline-reset-form input {
  background: var(--cream-1);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 5px 7px;
  font-size: 12px;
  width: 120px;
  font-family: inherit;
}

/* ---------------- admin toolbar ---------------- */
.admin-toolbar {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  align-items: center;
  margin-bottom: 12px;
}

.admin-toolbar input[type="text"] {
  flex: 1;
  min-width: 220px;
  padding: 7px 10px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--surface);
  color: var(--text);
  font-family: inherit;
  font-size: 13px;
}

/* ==================== guest mode (no account) ==================== */
/* Every account-only control still exists in the DOM — chat.js looks a lot
   of them up by id at load — so it's hidden here off the guest flag rather
   than removed from the template. */
[data-guest="1"] .guest-hide { display: none !important; }

.sidebar-note {
  margin: 0 12px 10px;
  font-size: 12px;
  line-height: 1.5;
  color: var(--text-muted);
}

.sidebar-signup {
  display: block;
  margin: 8px 12px 4px;
  padding: 8px 10px;
  text-align: center;
  font-size: 13px;
  font-weight: 600;
  border-radius: 8px;
  background: var(--accent);
  color: #fff;
  text-decoration: none;
}

.sidebar-signup:hover { background: var(--accent-dark); }

.guest-bar {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 6px 12px;
  margin: 6px auto 0;
  padding: 7px 12px;
  max-width: 760px;
  font-size: 12.5px;
  color: var(--text-muted);
  background: var(--cream-1);
  border: 1px solid var(--border);
  border-radius: 999px;
}

.guest-bar.empty {
  color: var(--danger);
  background: var(--danger-tint);
  border-color: var(--danger);
}

.guest-bar-actions {
  display: inline-flex;
  align-items: center;
  gap: 10px;
}

.guest-link {
  color: var(--text);
  text-decoration: none;
  font-weight: 600;
}

.guest-link:hover { text-decoration: underline; }

.guest-cta {
  padding: 4px 12px;
  border-radius: 999px;
  background: var(--accent);
  color: #fff;
  font-weight: 600;
  text-decoration: none;
}

.guest-cta:hover { background: var(--accent-dark); }

.guest-modal { max-width: 400px; }

.guest-modal-body {
  text-align: center;
  padding: 28px 26px 22px;
}

.guest-modal-mark { margin: 0 auto 8px; }

.guest-modal-body h3 {
  margin: 0 0 8px;
  font-size: 19px;
}

.guest-modal-body p {
  margin: 0 0 18px;
  font-size: 14px;
  line-height: 1.55;
  color: var(--text-muted);
}

.guest-modal-actions {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.guest-modal-dismiss {
  margin-top: 14px;
  background: none;
  border: none;
  color: var(--text-muted);
  font-size: 13px;
  cursor: pointer;
  text-decoration: underline;
}

/* A disabled composer should read as "locked", not "broken". */
.composer textarea:disabled {
  background: transparent;
  color: var(--text-muted);
  cursor: not-allowed;
}

@media (max-width: 760px) {
  .guest-bar {
    border-radius: 12px;
    font-size: 12px;
  }
}

/* ==================== language switcher ==================== */
.lang-switcher {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  padding: 2px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--cream-1);
}

.lang-option {
  padding: 3px 10px;
  border-radius: 999px;
  font-size: 12.5px;
  color: var(--text-muted);
  text-decoration: none;
  white-space: nowrap;
}

.lang-option:hover { color: var(--text); }

.lang-option.active {
  background: var(--surface);
  color: var(--text);
  font-weight: 600;
  box-shadow: 0 1px 3px var(--shadow);
}

/* On the auth pages the switcher sits under the card rather than in a nav. */
.login-wrap .lang-switcher { margin-top: 16px; }

/* In the sidebar it needs to fill the width like the buttons above it. */
.sidebar .lang-switcher {
  display: flex;
  justify-content: center;
  margin: 0 0 6px;
  background: transparent;
  border: none;
}

/* ==================== right-to-left (Arabic) ====================
   Only the rules whose meaning is tied to a physical side are flipped here.
   Anything already using flexbox order, `gap`, or centred text needs no
   change — the browser mirrors those from <html dir="rtl"> on its own,
   which is why this block is short rather than a second stylesheet. */
[dir="rtl"] .sidebar {
  border-right: none;
  border-left: 1px solid var(--border);
  transition: margin-right 0.18s ease;
}

[dir="rtl"] .sidebar.collapsed {
  margin-left: 0;
  margin-right: -260px;
}

[dir="rtl"] .model-picker-panel { left: auto; right: 0; }

[dir="rtl"] .media-download-btn { right: auto; left: 10px; }

[dir="rtl"] .markdown-body ul,
[dir="rtl"] .markdown-body ol { padding-left: 0; padding-right: 22px; }

[dir="rtl"] .markdown-body blockquote {
  border-left: none;
  border-right: 3px solid var(--accent);
  padding-left: 0;
  padding-right: 12px;
}

[dir="rtl"] th, [dir="rtl"] td { text-align: right; }

[dir="rtl"] .admin-header a { margin-left: 0; margin-right: 14px; }

/* Code stays left-to-right even in an Arabic UI: a code block or a model id
   is not Arabic text, and mirroring it makes it unreadable. */
[dir="rtl"] pre,
[dir="rtl"] code,
[dir="rtl"] .model-row-sub,
[dir="rtl"] .otp-input,
[dir="rtl"] .dev-link {
  direction: ltr;
  text-align: left;
}

[dir="rtl"] .markdown-body pre code { text-align: left; }

@media (max-width: 760px) {
  [dir="rtl"] .sidebar {
    left: auto;
    right: 0;
    transform: translateX(100%);
    box-shadow: -2px 0 12px var(--shadow);
  }

  [dir="rtl"] .sidebar.collapsed { margin-right: 0; }
  [dir="rtl"] .sidebar:not(.collapsed) { transform: translateX(0); }

  [dir="rtl"] #sidebar-toggle { left: auto; right: 10px; }
  [dir="rtl"] .topbar-row-1 { padding-left: 0; padding-right: 46px; }
}

/* ==================== admin panel (responsive) ====================
   The panel used to be desktop-only: five wide tables that a phone could
   only show by scrolling sideways, with the Actions column always off the
   edge. Below 820px each table turns into a stack of cards — every cell
   keeps its header via the data-label attribute — so nothing needs
   horizontal scrolling to be usable. */

.admin-header-links { display: flex; flex-wrap: wrap; gap: 14px; align-items: center; }

.panel {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  padding: 18px;
  margin-bottom: 18px;
}

.panel h2 { font-size: 15px; font-weight: 600; margin: 0 0 12px; }

.panel-head {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 12px;
}

.panel-head h2 { margin: 0; }

.table-filter {
  flex: 1;
  min-width: 180px;
  max-width: 340px;
  padding: 7px 10px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--cream-0);
  color: var(--text);
  font-family: inherit;
  font-size: 13px;
}

/* ---------- at-a-glance stats ---------- */
.stat-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 10px;
  margin-bottom: 18px;
}

.stat {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 12px 14px;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.stat-value { font-size: 20px; font-weight: 600; font-family: var(--serif); }
.stat-label { font-size: 12px; color: var(--text-muted); }
.stat-warn { border-color: var(--danger); background: var(--danger-tint); }
.stat-warn .stat-value { color: var(--danger); }

/* ---------- forms ---------- */
.stack-form { display: flex; flex-direction: column; gap: 10px; align-items: stretch; }

.field-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 10px;
}

.field { display: flex; flex-direction: column; gap: 4px; }

.stack-form input[type="text"],
.stack-form input[type="email"],
.stack-form input[type="password"],
.stack-form input[type="file"],
.stack-form textarea,
.stack-form select {
  background: var(--cream-0);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 9px 10px;
  font-family: "SFMono-Regular", Consolas, monospace;
  font-size: 13px;
  width: 100%;
}

.stack-form select { font-family: inherit; }
.stack-form textarea { resize: vertical; min-height: 96px; }

.stack-form button {
  background: var(--accent);
  border: none;
  border-radius: 8px;
  padding: 10px 16px;
  color: #fff;
  font-weight: 600;
  font-size: 14px;
  cursor: pointer;
  width: fit-content;
}

.stack-form button:hover { background: var(--accent-dark); }

.file-note { margin: -4px 0 0; font-size: 12px; }

.admin-help { margin-top: 14px; font-size: 13px; color: var(--text-muted); }
.admin-help summary { cursor: pointer; color: var(--text); font-weight: 600; }
.admin-help pre {
  background: var(--cream-1);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 12px;
  overflow-x: auto;
  font-size: 12px;
  line-height: 1.6;
}

/* ---------- bulk bar + chips ---------- */
.bulk-bar {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
  margin-bottom: 12px;
  padding: 10px;
  background: var(--cream-1);
  border-radius: 10px;
}

.bulk-bar select {
  padding: 7px 10px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--surface);
  color: var(--text);
  font-family: inherit;
  font-size: 13px;
}

.bulk-bar button {
  background: var(--surface);
  color: var(--text);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 7px 12px;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
}

.bulk-bar button:hover { background: var(--cream-2); }
.bulk-bar button.danger { color: var(--danger); border-color: var(--danger); background: var(--surface); }
.bulk-bar button.danger:hover { background: var(--danger-tint); }

.chip-row { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 12px; }

.chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  color: var(--text-muted);
  background: var(--cream-1);
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: 4px 10px;
}

/* ---------- flash messages ---------- */
.flash-stack { display: flex; flex-direction: column; gap: 8px; margin-bottom: 18px; }

.flash {
  padding: 10px 14px;
  border-radius: 10px;
  font-size: 13.5px;
  border: 1px solid var(--border);
  background: var(--surface);
}

.flash-success { background: #e6f3ea; border-color: #b9dcc6; color: #2f6b45; }
.flash-error { background: var(--danger-tint); border-color: var(--danger); color: var(--danger); }
.flash-info { background: var(--cream-2); color: var(--text-muted); }

[data-theme="dark"] .flash-success { background: #22352a; border-color: #37543f; color: #9fd4b1; }

/* ---------- tables ---------- */
.table-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; }

@media (max-width: 820px) {
  .admin-wrap { padding: 16px 12px; }
  .admin-header h1 { font-size: 22px; }

  /* Each row becomes a card, each cell a labelled line. The header row is
     removed rather than hidden with display:none on the cells, because a
     screen reader should get the same content the sighted reader gets. */
  .responsive-table thead { display: none; }

  .responsive-table,
  .responsive-table tbody,
  .responsive-table tr,
  .responsive-table td {
    display: block;
    width: 100%;
  }

  .responsive-table tr {
    border: 1px solid var(--border);
    border-radius: 10px;
    padding: 8px 10px;
    margin-bottom: 10px;
    background: var(--cream-0);
  }

  .responsive-table td {
    border-bottom: none;
    padding: 5px 0;
    display: flex;
    gap: 10px;
    align-items: baseline;
    justify-content: space-between;
    text-align: right;
  }

  .responsive-table td::before {
    content: attr(data-label);
    font-size: 11.5px;
    font-weight: 600;
    color: var(--text-muted);
    text-align: left;
    flex: 0 0 40%;
  }

  /* A cell with no data-label (the "no rows yet" placeholder) shouldn't get
     an empty label column. */
  .responsive-table td:not([data-label]) { display: block; text-align: left; }

  .responsive-table td.error-cell {
    max-width: none;
    white-space: normal;
    word-break: break-word;
  }

  /* Actions need the full width of the card, not a squeezed right column. */
  .responsive-table td.actions {
    flex-direction: column;
    align-items: stretch;
    text-align: left;
    gap: 6px;
    padding-top: 10px;
    margin-top: 4px;
    border-top: 1px solid var(--border);
  }

  .responsive-table td.actions::before { flex: none; margin-bottom: 2px; }
  .responsive-table td.actions form { display: flex; gap: 6px; width: 100%; }
  .responsive-table td.actions button { flex: 1; padding: 9px 12px; }
  .responsive-table td.actions .inline-reset-form { flex-wrap: wrap; }
  .responsive-table td.actions .inline-reset-form input { flex: 1; min-width: 110px; width: auto; }

  .bulk-bar { flex-direction: column; align-items: stretch; }
  .bulk-bar button, .bulk-bar select { width: 100%; }

  .stack-form button { width: 100%; }
  .table-filter { max-width: none; }
}

/* Touch targets: 8px of padding is fine with a mouse and awkward with a
   thumb. This only kicks in on devices without a fine pointer. */
@media (pointer: coarse) {
  .actions button, .bulk-bar button { min-height: 40px; }
}

[dir="rtl"] .responsive-table td { text-align: left; }
[dir="rtl"] .responsive-table td::before { text-align: right; }

/* ==================== admin tabs & pager ====================
   Five stacked sections meant scrolling past a 337-row table to reach the
   users list. Tabs put each section one tap away instead. */
.admin-tabs {
  display: flex;
  gap: 4px;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  padding: 4px;
  margin-bottom: 18px;
  background: var(--cream-1);
  border: 1px solid var(--border);
  border-radius: 12px;
  position: sticky;
  top: 0;
  z-index: 20;
}

.admin-tabs::-webkit-scrollbar { display: none; }

.admin-tab {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  border: none;
  background: none;
  color: var(--text-muted);
  font-family: inherit;
  font-size: 13.5px;
  font-weight: 600;
  padding: 9px 14px;
  border-radius: 9px;
  cursor: pointer;
  white-space: nowrap;
}

.admin-tab:hover { color: var(--text); }

.admin-tab.active {
  background: var(--surface);
  color: var(--text);
  box-shadow: 0 1px 3px var(--shadow);
}

.tab-count {
  font-size: 11px;
  font-weight: 600;
  padding: 1px 7px;
  border-radius: 999px;
  background: var(--cream-2);
  color: var(--text-muted);
}

.admin-tab.active .tab-count { background: var(--accent-tint); color: var(--accent-dark); }

.overview-note p { margin: 0 0 10px; font-size: 14px; line-height: 1.6; }
.overview-note p:last-child { margin-bottom: 0; }

.inline-warn {
  margin: 0;
  padding: 10px 12px;
  border-radius: 9px;
  background: var(--danger-tint);
  border: 1px solid var(--danger);
  color: var(--danger);
  font-size: 13.5px;
  line-height: 1.55;
}

.pager {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  margin-top: 14px;
}

.pager button {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 8px 16px;
  font-family: inherit;
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
  cursor: pointer;
}

.pager button:hover:not(:disabled) { background: var(--cream-2); }
.pager button:disabled { opacity: 0.4; cursor: default; }
.pager-status { font-size: 13px; color: var(--text-muted); }

@media (max-width: 820px) {
  .admin-tabs { border-radius: 0; margin: 0 -12px 16px; border-left: none; border-right: none; }
  .pager button { flex: 1; min-height: 42px; }
}

/* Add-forms collapse so each tab opens on its table. Filling in a form is
   occasional; looking something up in the table is what you're here for
   most of the time, and it shouldn't sit two screens down. */
.panel-collapse { padding: 0; }

.panel-collapse > summary {
  list-style: none;
  cursor: pointer;
  padding: 15px 18px;
  display: flex;
  align-items: center;
  gap: 8px;
}

.panel-collapse > summary::-webkit-details-marker { display: none; }

.panel-collapse > summary::after {
  content: "+";
  margin-left: auto;
  color: var(--text-muted);
  font-size: 17px;
  line-height: 1;
}

.panel-collapse[open] > summary::after { content: "–"; }
.panel-collapse > summary:hover { background: var(--cream-1); border-radius: 12px; }
.panel-collapse[open] > summary:hover { border-radius: 12px 12px 0 0; }
.panel-collapse > summary h2 { margin: 0; }
.panel-collapse > *:not(summary) { margin-left: 18px; margin-right: 18px; }
.panel-collapse > *:last-child:not(summary) { margin-bottom: 18px; }

[dir="rtl"] .panel-collapse > summary::after { margin-left: 0; margin-right: auto; }

/* The wall would be forty chips of scrolling on a phone. Clamp it and fade
   the cut, rather than dropping items and making the "+N more" count lie. */
@media (max-width: 600px) {
  .home-wall-list {
    max-height: 190px;
    overflow: hidden;
    -webkit-mask-image: linear-gradient(to bottom, #000 62%, transparent 100%);
    mask-image: linear-gradient(to bottom, #000 62%, transparent 100%);
  }
}

/* The model row's inline editor plus three buttons overran the table width
   on desktop, pushing Delete past the right edge. Wrapping keeps every
   control reachable without a sideways scroll. */
.actions { flex-wrap: wrap; row-gap: 6px; }
.actions .inline-reset-form input { width: 110px; min-width: 0; }

/* A quiet note when a fallback model answered instead of the selected one.
   Informational, not alarming — the user got their answer. */
.fallback-note {
  margin: 10px 0 0;
  padding: 6px 10px;
  font-size: 12px;
  color: var(--text-muted);
  background: var(--cream-1);
  border-radius: 8px;
  border: 1px solid var(--border);
  line-height: 1.5;
}

/* Image generation timer — counting seconds so the user knows the page
   isn't frozen, it's just waiting for the model. */
.gen-timer {
  color: var(--text-muted);
  font-size: 12px;
  font-variant-numeric: tabular-nums;
  opacity: 0.7;
}
