/*
 * "Calm Light" -- see DESIGN.md. Modelled on Claude's own design language
 * (reference: Claude Calm Light): quiet, editorial and spacious. Ink-black
 * text and primary buttons, a warm near-white ground, a terracotta accent
 * spent only on brand and small emphasis, a light serif for headlines and
 * Inter for the interface. Depth from hairline ink borders and soft shadow.
 */

/* Fonts are served from this site (static/fonts/, OFL), not Google Fonts, so a
   visit sends no request -- and no IP -- to a third party, and the CSP can
   allow fonts from 'self' only. */
@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url("/static/fonts/inter-variable.woff2") format("woff2");
}

/* Newsreader: a warm, literary text serif (Tiempos register) for headlines
   and the wordmark, kept at light weights so it reads calm, not loud. */
@font-face {
  font-family: "Newsreader";
  font-style: normal;
  font-weight: 300 600;
  font-display: swap;
  src: url("/static/fonts/newsreader-variable.woff2") format("woff2");
}

:root {
  /* Warm near-white ground, clean white surfaces (Claude Calm Light). */
  --bg: #FCFCFB;
  --surface: #FFFFFF;
  --surface-2: #F5F4F1;
  --surface-3: #EEECE6;
  --border: rgba(11, 11, 11, 0.10);
  --border-strong: rgba(11, 11, 11, 0.18);
  --text: #0B0B0B;
  --text-soft: #666666;
  --text-faint: #6C6A62;
  /* Terracotta accent -- brand and small emphasis only, never a surface. */
  --accent: #C6613F;
  --accent-hover: #B2532F;
  --accent-soft: #F7EDE7;
  --accent-soft-2: #EDD8CD;
  --accent-text: #A1492B;
  --on-accent: #FFFFFF;
  /* Ink-black primary action (the strongest thing on screen). */
  --primary: #0B0B0B;
  --on-primary: #FFFFFF;
  --mark: #F7EDE7;
  --mark-edge: #C6613F;
  --danger: #D92D20;
  --danger-soft: #FDECEA;
  --heart: #C6613F;
  --success: #3C8C63;

  --shadow-xs: 0 1px 2px rgba(11, 11, 11, 0.04);
  --shadow-sm: 0 1px 2px rgba(11, 11, 11, 0.05), 0 1px 3px rgba(11, 11, 11, 0.03);
  --shadow-md: 0 6px 20px -6px rgba(11, 11, 11, 0.10), 0 2px 5px rgba(11, 11, 11, 0.04);
  --shadow-lg: 0 20px 48px -16px rgba(11, 11, 11, 0.16);
  --ring: 0 0 0 3px color-mix(in srgb, var(--accent) 30%, transparent);

  --font: "Inter", "Segoe UI", system-ui, -apple-system, sans-serif;
  --display: "Newsreader", Georgia, "Times New Roman", serif;
  --mono: ui-monospace, "SF Mono", "Cascadia Code", Consolas, monospace;

  --text-xs: 0.75rem;
  --text-sm: 0.8125rem;
  --text-md: 0.9375rem;
  --text-lg: 1.0625rem;
  --text-title: clamp(2.2rem, 1.5rem + 3vw, 3.4rem);

  /* Rounding rhythm from the reference: controls 10, panels 16, cards 24. */
  --radius-sm: 10px;
  --radius: 16px;
  --radius-lg: 24px;
  --ease: cubic-bezier(0.2, 0.7, 0.2, 1);
  --spring: cubic-bezier(0.2, 0.7, 0.2, 1);

  color-scheme: light;
}

/* Dark: follows the system unless the reader picked light in the top bar
   (theme.js sets data-theme), or always when they picked dark. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    /* Warm dark: a lamp-lit desk, not a black void. */
    --bg: #15130F;
    --surface: #1C1A15;
    --surface-2: #232019;
    --surface-3: #2C281F;
    --border: #2C2820;
    --border-strong: #3A352A;
    --text: #F2EFE8;
    --text-soft: #A8A396;
    --text-faint: #958F81;
    --accent: #E08763;
    --accent-hover: #EB9674;
    --accent-soft: #2A1D16;
    --accent-soft-2: #3A281E;
    --accent-text: #E79C7D;
    --on-accent: #15130F;
    --primary: #F2EFE8;
    --on-primary: #15130F;
    --mark: #2A1D16;
    --mark-edge: #E08763;
    --danger: #F07167;
    --danger-soft: #2C1512;
    --heart: #E08763;
    --success: #E08763;

    --shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.45);
    --shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.5);
    --shadow-md: 0 10px 28px -8px rgba(0, 0, 0, 0.62), 0 2px 6px rgba(0, 0, 0, 0.4);
    --shadow-lg: 0 26px 60px -14px rgba(0, 0, 0, 0.78);
    color-scheme: dark;
  }
}

:root[data-theme="dark"] {
  --bg: #15130F;
  --surface: #1C1A15;
  --surface-2: #232019;
  --surface-3: #2C281F;
  --border: #2C2820;
  --border-strong: #3A352A;
  --text: #F2EFE8;
  --text-soft: #A8A396;
  --text-faint: #958F81;
  --accent: #E08763;
  --accent-hover: #EB9674;
  --accent-soft: #2A1D16;
  --accent-soft-2: #3A281E;
  --accent-text: #E79C7D;
  --on-accent: #15130F;
  --primary: #F2EFE8;
  --on-primary: #15130F;
  --mark: #2A1D16;
  --mark-edge: #E08763;
  --danger: #F07167;
  --danger-soft: #2C1512;
  --heart: #E08763;
  --success: #E08763;

  --shadow-xs: 0 1px 2px rgba(0, 0, 0, 0.45);
  --shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.5);
  --shadow-md: 0 10px 28px -8px rgba(0, 0, 0, 0.62), 0 2px 6px rgba(0, 0, 0, 0.4);
  --shadow-lg: 0 26px 60px -14px rgba(0, 0, 0, 0.78);
  color-scheme: dark;
}

* {
  box-sizing: border-box;
}

/* Any class that sets `display` would otherwise override the hidden attribute. */
[hidden] {
  display: none !important;
}

html,
body {
  margin: 0;
  height: 100%;
}

body {
  display: flex;
  flex-direction: column;
  /* The opening pages scroll as a normal document, so the footer is a real
     footer reached by scrolling -- not a bar bolted to the viewport. */
  min-height: 100dvh;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font);
  font-size: var(--text-md);
  line-height: 1.55;
  font-feature-settings: "cv11", "ss01";
  -webkit-font-smoothing: antialiased;
}

/* A conversation is an app shell: the composer is the floor, the messages
   scroll inside their card, and the marketing footer steps aside. */
body[data-view="chat"] {
  height: 100dvh;
  overflow: hidden;
}

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

::selection {
  background: var(--accent-soft-2);
}

a {
  color: inherit;
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

.icon {
  width: 16px;
  height: 16px;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* ---------- Logo ---------- */

.logo {
  display: inline-grid;
  width: 30px;
  height: 30px;
  flex: none;
  border-radius: 9px;
  box-shadow: var(--shadow-sm);
}

.logo svg {
  width: 100%;
  height: 100%;
}

.logo-bg { fill: var(--accent); }
.logo-page { fill: #FFFFFF; }
.logo-mark { fill: #FFD43B; }

.logo-sm {
  width: 26px;
  height: 26px;
  border-radius: 8px;
}

/* ---------- Top bar ---------- */

.topbar {
  flex: none;
  width: 100%;
  max-width: 1440px;
  margin: 0 auto;
  padding: 14px 24px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  text-decoration: none;
  font-family: var(--display);
  font-weight: 560;
  font-size: 1.12rem;
  letter-spacing: -0.01em;
}

.topbar-links {
  display: flex;
  align-items: center;
  gap: 8px;
}

.theme-btn {
  display: inline-grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface);
  color: var(--text-soft);
  box-shadow: var(--shadow-xs);
  cursor: pointer;
  transition: color 0.15s, border-color 0.15s, transform 0.2s var(--ease);
}

.theme-btn:hover {
  color: var(--text);
  border-color: var(--border-strong);
}

.theme-btn:active {
  transform: rotate(-20deg) scale(0.94);
}

.theme-btn .icon {
  display: none;
  animation: fade 0.2s ease-out;
}

.theme-btn[data-choice="system"] .icon-system,
.theme-btn[data-choice="light"] .icon-light,
.theme-btn[data-choice="dark"] .icon-dark {
  display: block;
}

.pill-link {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 6px 12px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface);
  box-shadow: var(--shadow-xs);
  font-size: var(--text-sm);
  font-weight: 550;
  color: var(--text-soft);
  text-decoration: none;
  transition: color 0.15s, border-color 0.15s, box-shadow 0.15s, transform 0.15s var(--ease);
}

.pill-link:hover {
  color: var(--text);
  border-color: var(--border-strong);
  box-shadow: var(--shadow-sm);
  transform: translateY(-1px);
}

/* Google sign-in: signed-in chip in the top bar and the guest allowance note. */
.user-chip {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 3px 4px 3px 4px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface);
  box-shadow: var(--shadow-xs);
  font-size: var(--text-sm);
  color: var(--text-soft);
}

.user-avatar {
  display: inline-grid;
  place-items: center;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: var(--accent-soft-2);
  color: var(--accent-text);
  font-weight: 650;
  font-size: var(--text-xs);
}

.user-name {
  max-width: 14ch;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-weight: 550;
  color: var(--text);
}

.user-signout {
  padding: 4px 10px;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: var(--text-soft);
  font: inherit;
  font-size: var(--text-xs);
  cursor: pointer;
  transition: background 0.15s, color 0.15s;
}

.user-signout:hover {
  background: var(--accent-soft);
  color: var(--text);
}

.guest-note {
  max-width: 62ch;
  margin: 14px 0 0;
  padding: 9px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--accent-soft);
  font-size: var(--text-sm);
  line-height: 1.5;
  color: var(--text-soft);
}

.guest-note strong {
  color: var(--text);
  font-weight: 600;
}

/* ---------- Signed-in workspace ---------- */

/* Guests: the wrapper is invisible and the document shelf lays out as before.
   Signed in: chats and documents become ONE sidebar panel, and the opening page
   stops looking like the marketing landing page. */
.side {
  display: contents;
}

body[data-auth="user"] .side {
  flex: none;
  width: 268px;
  display: flex;
  flex-direction: column;
  min-height: 0;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--surface);
  box-shadow: var(--shadow-sm);
  overflow: hidden;
}

body[data-auth="user"] .side .chats,
body[data-auth="user"] .side .shelf {
  width: auto;
  border: 0;
  border-radius: 0;
  box-shadow: none;
  background: none;
}

body[data-auth="user"] .side .chats {
  flex: 1 1 auto;
  min-height: 140px;
}

body[data-auth="user"] .side .shelf {
  flex: none;
  max-height: 55%;
  overflow-y: auto;
  border-top: 1px solid var(--border);
}

/* The home of a signed-in user is a quiet start-a-chat screen, not the pitch. */
body[data-auth="user"] .eyebrow-badge,
body[data-auth="user"] .hero-demo,
body[data-auth="user"] .features,
body[data-auth="user"] .privacy-note {
  display: none;
}

body[data-auth="user"] #upload-view {
  justify-content: center;
}

body[data-auth="user"] .intro-title {
  font-size: clamp(1.6rem, 3vw, 2.2rem);
}

/* ---------- Saved chats (signed-in sidebar) ---------- */

.chats {
  flex: none;
  width: 248px;
  display: flex;
  flex-direction: column;
  gap: 10px;
  min-height: 0;
  padding: 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--surface);
  box-shadow: var(--shadow-sm);
}

.chats[hidden] {
  display: none;
}

.chats-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 2px 2px 0;
}

.chat-list {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin: 0;
  padding: 0;
  overflow-y: auto;
  list-style: none;
}

.chat-item {
  position: relative;
  display: flex;
  align-items: center;
  border-radius: var(--radius-sm);
  transition: background 0.15s;
}

.chat-item:hover,
.chat-item:focus-within {
  background: var(--accent-soft);
}

.chat-item.active {
  background: var(--accent-soft-2);
}

.chat-open {
  flex: 1;
  min-width: 0;
  padding: 8px 10px;
  border: 0;
  background: none;
  color: var(--text);
  font: inherit;
  font-size: var(--text-sm);
  text-align: left;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  cursor: pointer;
}

.chat-item.active .chat-open {
  font-weight: 600;
}

.chat-actions {
  display: none;
  flex: none;
  gap: 2px;
  padding-right: 4px;
}

.chat-item:hover .chat-actions,
.chat-item:focus-within .chat-actions,
.chat-item.confirming .chat-actions {
  display: flex;
}

.chat-act {
  display: inline-grid;
  place-items: center;
  min-width: 26px;
  height: 26px;
  padding: 0 4px;
  border: 0;
  border-radius: 6px;
  background: none;
  color: var(--text-faint);
  font: inherit;
  font-size: var(--text-xs);
  cursor: pointer;
}

.chat-act:hover {
  background: var(--surface);
  color: var(--text);
}

.chat-act.danger:hover,
.chat-item.confirming .chat-act.danger {
  background: var(--danger-soft);
  color: var(--danger);
  font-weight: 600;
}

.chat-act svg {
  width: 14px;
  height: 14px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.chat-rename {
  flex: 1;
  min-width: 0;
  margin: 3px 4px;
  padding: 5px 8px;
  border: 1px solid var(--border-strong);
  border-radius: 6px;
  background: var(--surface);
  color: var(--text);
  font: inherit;
  font-size: var(--text-sm);
}

.chat-empty {
  margin: 0;
  padding: 4px 6px;
  font-size: var(--text-xs);
  line-height: 1.5;
  color: var(--text-faint);
}

body:not([data-auth="user"]) .chats {
  display: none;
}

/* ---------- Log-in dialog ---------- */

.signin-dialog {
  width: min(400px, calc(100vw - 32px));
  text-align: center;
}

.signin-logo {
  display: inline-block;
  width: 44px;
  height: 44px;
  margin-bottom: 10px;
}

.signin-logo svg {
  width: 100%;
  height: 100%;
}

.signin-dialog h2 {
  margin: 0 0 6px;
  font-family: var(--font-display, inherit);
}

.signin-lead {
  margin: 0 0 14px;
  color: var(--text-soft);
  font-size: var(--text-sm);
  line-height: 1.5;
}

.signin-perks {
  margin: 0 0 18px;
  padding: 12px 14px;
  border-radius: var(--radius-sm);
  background: var(--accent-soft);
  text-align: left;
  list-style: none;
  font-size: var(--text-sm);
  color: var(--text-soft);
}

.signin-perks li {
  position: relative;
  padding: 3px 0 3px 22px;
}

.signin-perks li::before {
  content: "";
  position: absolute;
  left: 2px;
  top: 0.62em;
  width: 10px;
  height: 6px;
  border-left: 2px solid var(--accent);
  border-bottom: 2px solid var(--accent);
  transform: rotate(-45deg);
}

.btn-google {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  width: 100%;
  padding: 11px 16px;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background: var(--surface);
  color: var(--text);
  box-shadow: var(--shadow-xs);
  font: inherit;
  font-size: var(--text-base, 0.95rem);
  font-weight: 600;
  cursor: pointer;
  transition: box-shadow 0.15s, border-color 0.15s, transform 0.15s var(--ease);
}

.btn-google svg {
  width: 20px;
  height: 20px;
}

.btn-google:hover {
  box-shadow: var(--shadow-sm);
  transform: translateY(-1px);
}

.btn-google:disabled {
  opacity: 0.6;
  cursor: progress;
  transform: none;
}

.signin-dialog .error-text {
  margin: 12px 0 0;
  text-align: left;
}

.signin-fine {
  margin: 14px 0 6px;
  font-size: var(--text-xs);
  line-height: 1.5;
  color: var(--text-faint);
}

.signin-close {
  margin: 0;
}

@media (max-width: 900px) {
  body[data-auth="user"] .side {
    width: auto;
  }

  body[data-auth="user"] .side .shelf {
    max-height: none;
  }

  .chats {
    width: auto;
    padding: 8px;
    gap: 6px;
    max-height: 168px;
    border-radius: var(--radius);
  }
}

.slip-section {
  margin: 2px 0 4px;
  font-size: var(--text-xs);
  color: var(--text-faint);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.shelf-note {
  margin: 0 0 10px;
  font-size: var(--text-xs);
  line-height: 1.4;
  color: var(--text-faint);
}

.link-button {
  padding: 0;
  border: 0;
  background: none;
  color: var(--accent-text);
  font: inherit;
  font-weight: 550;
  text-decoration: underline;
  cursor: pointer;
}

button.pill-link {
  font-family: inherit;
  cursor: pointer;
}

button.pill-link:disabled {
  opacity: 0.6;
  cursor: progress;
}

/* Version + AI-provider health, in the top bar -- shown in a conversation,
   where the footer (which carries the same in the opening page) is hidden. */
.topbar-status {
  display: none;
  align-items: center;
  gap: 7px;
  padding: 5px 11px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface);
  box-shadow: var(--shadow-xs);
  font-family: var(--font);
  font-size: 0.7rem;
  font-weight: 600;
  color: var(--text-soft);
  text-decoration: none;
  transition: color 0.15s, border-color 0.15s;
}

body[data-view="chat"] .topbar-status:not([hidden]) {
  display: inline-flex;
}

.topbar-status:hover {
  color: var(--text);
  border-color: var(--border-strong);
}

.topbar-status-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--success);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--success) 20%, transparent);
}

.topbar-status[data-state="cooling"] .topbar-status-dot {
  background: var(--mark-edge);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--mark-edge) 22%, transparent);
  animation: breathe 1.6s ease-in-out infinite;
}

.topbar-status[data-state="down"] .topbar-status-dot {
  background: var(--danger);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--danger) 22%, transparent);
}

/* ---------- Layout ---------- */

.layout {
  flex: 1 0 auto;
  display: flex;
  gap: 20px;
  width: 100%;
  max-width: 1440px;
  margin: 0 auto;
  padding: 0 24px 20px;
}

/* On the opening pages the content fills the first screen so the footer sits
   just below the fold, the way a colophon closes a book. */
body:not([data-view="chat"]) .layout {
  min-height: calc(100dvh - 76px);
}

body[data-view="chat"] .layout {
  flex: 1 1 auto;
  min-height: 0;
}

.desk {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
}

/* Only the conversation scrolls inside itself; the opening pages let the
   whole document scroll instead. */
body[data-view="chat"] .desk {
  min-height: 0;
  overflow: hidden;
}

/* The document sidebar only exists once there is something in it. */
body:not([data-view="chat"]) .shelf {
  display: none;
}

/* ---------- Buttons ---------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  font-family: inherit;
  font-size: var(--text-sm);
  font-weight: 550;
  line-height: 1.2;
  padding: 8px 14px;
  border-radius: var(--radius-sm);
  border: 1px solid transparent;
  background: none;
  color: var(--text);
  cursor: pointer;
  white-space: nowrap;
  transition: background-color 0.15s, border-color 0.15s, color 0.15s, box-shadow 0.15s, opacity 0.15s, transform 0.1s;
}

.btn:active:not(:disabled) {
  transform: scale(0.98);
}

.btn:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

.btn-primary {
  background: var(--primary);
  color: var(--on-primary);
  box-shadow: var(--shadow-xs), inset 0 1px 0 rgba(255, 255, 255, 0.12);
}

.btn-primary:hover:not(:disabled) {
  background: #262626;
  box-shadow: var(--shadow-sm);
}

.btn-block {
  width: 100%;
  padding: 10px 14px;
}

.btn-ghost {
  color: var(--text-soft);
}

.btn-ghost:hover:not(:disabled) {
  color: var(--text);
  background: var(--surface-2);
}

.btn-danger:hover:not(:disabled) {
  color: var(--danger);
  background: var(--danger-soft);
}

.btn-xs {
  padding: 4px 8px;
  font-size: var(--text-xs);
  gap: 5px;
  border-radius: 6px;
}

.btn-xs .icon {
  width: 13px;
  height: 13px;
}

/* Small secondary actions created by app.js (follow-ups, copy, sources). */
.btn-text {
  padding: 5px 11px;
  font-size: var(--text-xs);
  font-weight: 550;
  color: var(--text-soft);
  background: var(--surface);
  border-color: var(--border);
  border-radius: 999px;
}

.btn-text:hover:not(:disabled) {
  color: var(--text);
  border-color: var(--border-strong);
  background: var(--surface-2);
}

.btn-icon {
  display: inline-grid;
  place-items: center;
  width: 26px;
  height: 26px;
  border: none;
  border-radius: 6px;
  background: none;
  cursor: pointer;
  color: var(--text-faint);
  transition: color 0.15s, background-color 0.15s;
}

.btn-icon svg {
  width: 13px;
  height: 13px;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
}

.btn-icon:hover {
  color: var(--danger);
  background: var(--danger-soft);
}

/* ---------- Upload hero ---------- */

.title-page {
  margin: auto;
  width: 100%;
  max-width: 780px;
  padding: 16px 0 6vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}

.eyebrow-badge {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 5px 12px 5px 10px;
  margin-bottom: 20px;
  border: 1px solid var(--accent-soft-2);
  border-radius: 999px;
  background: var(--accent-soft);
  color: var(--accent-text);
  font-size: var(--text-xs);
  font-weight: 600;
}

.eyebrow-badge .icon {
  width: 14px;
  height: 14px;
}

.intro-title {
  font-family: var(--display);
  font-weight: 400;
  font-size: var(--text-title);
  line-height: 1.12;
  letter-spacing: -0.005em;
  margin: 0 0 20px;
  text-wrap: balance;
}

.intro-body {
  font-size: var(--text-lg);
  line-height: 1.6;
  color: var(--text-soft);
  margin: 0 0 26px;
  max-width: 56ch;
  text-wrap: pretty;
}

/* A small, honest preview of the signature: a question answered with its exact
   pages cited. Illustrative (aria-hidden), styled like the real conversation. */
.hero-demo {
  width: 100%;
  max-width: 520px;
  margin: 0 0 30px;
  padding: 16px 18px;
  text-align: left;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
}

.hero-demo-cap {
  margin: 0 0 8px;
  font-size: var(--text-xs);
  font-weight: 600;
  color: var(--text-faint);
}

.hero-demo-q {
  margin: 0 0 10px;
  font-weight: 550;
  color: var(--text);
}

.hero-demo-a {
  display: flex;
  gap: 10px;
}

.hero-demo-a p {
  margin: 1px 0 0;
  font-size: var(--text-sm);
  line-height: 1.6;
  color: var(--text-soft);
}

.hero-demo-mark {
  flex: none;
  display: grid;
  place-items: center;
  width: 24px;
  height: 24px;
  border-radius: 7px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  color: var(--text-faint);
  font-size: 0.58rem;
  font-weight: 650;
}

/* Non-interactive citation chip used only in the hero preview. */
.cite-static {
  margin-left: 4px;
}

.dropzone {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  width: 100%;
  max-width: 560px;
  cursor: pointer;
  padding: 30px 24px 26px;
  border: 1.5px dashed var(--border-strong);
  border-radius: var(--radius-lg);
  background: var(--surface);
  box-shadow: var(--shadow-sm);
  transition: border-color 0.2s, background-color 0.2s, box-shadow 0.2s, transform 0.2s var(--ease);
}

.dropzone:hover {
  border-color: var(--accent);
  box-shadow: var(--shadow-md);
  transform: translateY(-2px);
}

.dropzone.dragging {
  border-color: var(--accent);
  border-style: solid;
  background: var(--accent-soft);
  box-shadow: var(--ring), var(--shadow-md);
  transform: scale(1.01);
}

.dropzone-icon {
  display: grid;
  place-items: center;
  width: 46px;
  height: 46px;
  margin-bottom: 6px;
  border-radius: var(--radius);
  background: var(--accent-soft);
  color: var(--accent);
  transition: transform 0.25s var(--ease);
}

.dropzone:hover .dropzone-icon,
.dropzone.dragging .dropzone-icon {
  transform: translateY(-3px);
}

.dropzone-icon svg {
  width: 22px;
  height: 22px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.9;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.dropzone-title {
  font-family: var(--display);
  font-weight: 600;
  font-size: var(--text-lg);
}

.dropzone-title u {
  color: var(--accent);
  text-decoration-thickness: 1.5px;
  text-underline-offset: 3px;
}

.dropzone-hint {
  font-size: var(--text-sm);
  color: var(--text-faint);
}

.features {
  list-style: none;
  margin: 26px 0 0;
  padding: 0;
  width: 100%;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 12px;
  text-align: left;
}

.features li {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
  font-size: var(--text-sm);
  color: var(--text-soft);
  line-height: 1.45;
}

.features .icon {
  width: 18px;
  height: 18px;
  margin-top: 1px;
  color: var(--accent);
}

.features strong {
  display: block;
  color: var(--text);
  font-weight: 600;
}

.privacy-note {
  max-width: 62ch;
  margin: 18px 0 0;
  font-size: var(--text-xs);
  line-height: 1.55;
  color: var(--text-faint);
}

.error-text {
  color: var(--danger);
  background: var(--danger-soft);
  border-radius: var(--radius-sm);
  padding: 8px 12px;
  font-size: var(--text-sm);
  margin: 14px 0 0;
}

/* ---------- Reading card ---------- */

.reading-card {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  width: 100%;
  max-width: 440px;
  padding: 34px 28px;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--surface);
  box-shadow: var(--shadow-md);
}

.reading-line {
  font-family: var(--display);
  font-size: var(--text-lg);
  font-weight: 600;
  margin: 6px 0 0;
  overflow-wrap: anywhere;
}

.reading-sub {
  margin: 0;
  font-size: var(--text-sm);
  color: var(--text-faint);
}

/* A slim indeterminate bar so the wait reads as progress, not a hang. */
.reading-progress {
  width: 100%;
  max-width: 260px;
  height: 3px;
  margin: 18px 0 2px;
  border-radius: 999px;
  background: var(--surface-2);
  overflow: hidden;
}

.reading-progress > span {
  display: block;
  height: 100%;
  width: 40%;
  border-radius: 999px;
  background: var(--accent);
  animation: reading-slide 1.3s ease-in-out infinite;
}

@keyframes reading-slide {
  0% { transform: translateX(-120%); }
  100% { transform: translateX(320%); }
}

/* A rotating fact about documents, to make the wait feel alive. */
.reading-fact {
  margin: 14px 0 0;
  min-height: 2.6em;
  max-width: 42ch;
  font-size: var(--text-sm);
  line-height: 1.5;
  color: var(--text-soft);
  opacity: 0;
  transform: translateY(4px);
  transition: opacity 0.3s ease, transform 0.3s ease;
}

.reading-fact.show {
  opacity: 1;
  transform: none;
}

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

.spinner-lg {
  width: 34px;
  height: 34px;
  border-width: 3px;
}

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

/* ---------- Sidebar ---------- */

.shelf {
  flex: none;
  width: 272px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  min-height: 0;
  padding: 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--surface);
  box-shadow: var(--shadow-sm);
}

.shelf-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 2px 2px 0;
}

.shelf-title {
  margin: 0;
  font-size: var(--text-xs);
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--text-faint);
}

.doc-list {
  list-style: none;
  margin: 0 -6px;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
  overflow-y: auto;
  min-height: 0;
  flex: 1;
}

.doc-item {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 4px 10px;
  padding: 9px 8px;
  border-radius: 10px;
  transition: background-color 0.15s;
}

.doc-item:hover {
  background: var(--surface-2);
}

.doc-check {
  position: relative;
  display: grid;
  place-items: center;
  width: 32px;
  height: 32px;
  border-radius: 8px;
  background: var(--accent-soft);
  cursor: pointer;
  transition: background-color 0.15s, opacity 0.15s;
}

.doc-include {
  position: absolute;
  inset: 0;
  opacity: 0;
  margin: 0;
  cursor: pointer;
}

.doc-check:focus-within {
  box-shadow: var(--ring);
}

.doc-icon {
  width: 14px;
  height: 18px;
  fill: var(--surface);
  stroke: var(--accent);
  stroke-width: 1.3;
}

.doc-icon .tick {
  fill: none;
  stroke: var(--accent);
  stroke-width: 1.7;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.doc-check:has(.doc-include:not(:checked)) {
  background: var(--surface-3);
}

.doc-include:not(:checked) + .doc-icon {
  stroke: var(--text-faint);
}

.doc-include:not(:checked) + .doc-icon .tick {
  display: none;
}

.doc-item:has(.doc-include:not(:checked)) .doc-name {
  color: var(--text-faint);
  text-decoration: line-through;
}

.doc-info {
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-width: 0;
}

.doc-name {
  font-weight: 600;
  font-size: var(--text-sm);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.doc-meta {
  font-size: var(--text-xs);
  color: var(--text-faint);
}

.doc-buttons {
  grid-column: 2;
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-left: -8px;
}

.shelf-actions {
  padding-top: 10px;
  border-top: 1px solid var(--border);
}

.shelf-links {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.shelf-links .btn {
  justify-content: flex-start;
  width: 100%;
  padding: 7px 8px;
}

.add-status {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: var(--text-xs);
  color: var(--text-faint);
}

.add-status .spinner {
  width: 12px;
  height: 12px;
}

/* ---------- Conversation ---------- */

.sheet-chat {
  position: relative;
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--surface);
  box-shadow: var(--shadow-sm);
  overflow: hidden;
}

.messages {
  container-type: inline-size;
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 18px;
  padding: 24px clamp(16px, 4vw, 44px) 28px;
  scrollbar-gutter: stable;
}

.msg {
  max-width: 68ch;
  margin: 0;
}

/* The reader's question: a bubble on the right. */
.msg-user {
  align-self: flex-end;
  max-width: min(80%, 60ch);
  margin-top: 8px;
  padding: 10px 14px;
  border-radius: 14px 14px 4px 14px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  color: var(--text);
  font-weight: 450;
  line-height: 1.55;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

/* Everything the assistant says carries a small avatar on the left. */
.msg-assistant {
  position: relative;
  padding-left: 42px;
}

.msg-assistant::before {
  content: "AI";
  position: absolute;
  left: 0;
  top: 0;
  display: grid;
  place-items: center;
  width: 26px;
  height: 26px;
  border-radius: 7px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  color: var(--text-faint);
  font-size: 0.6rem;
  font-weight: 650;
  letter-spacing: 0.03em;
}

.msg-text {
  font-size: var(--text-md);
  line-height: 1.7;
  overflow-wrap: anywhere;
  margin: 0;
  padding-top: 3px;
}

/* Note/pending messages hold plain text directly, so keep their line breaks. */
.msg-note .msg-text,
.msg-pending .msg-text {
  white-space: pre-wrap;
}

/* ---------- Rendered Markdown in an answer (premium, ChatGPT-grade) ---------- */

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

.md-p {
  margin: 0 0 0.85em;
  white-space: pre-wrap;
}

.md-h {
  font-weight: 600;
  line-height: 1.3;
  letter-spacing: -0.01em;
  margin: 1.1em 0 0.5em;
}

h4.md-h { font-size: 1.1rem; }
h5.md-h { font-size: 1rem; }

.md-list {
  margin: 0 0 0.85em;
  padding-left: 1.4em;
}

.md-list li {
  margin: 0.28em 0;
  padding-left: 0.2em;
  line-height: 1.65;
}

.md-list li::marker {
  color: var(--text-faint);
}

ul.md-list li::marker {
  color: var(--accent);
}

.md-list ul.md-list,
.md-list ol.md-list {
  margin: 0.28em 0 0.2em;
}

/* Inline code */
.msg-text code {
  font-family: var(--mono);
  font-size: 0.86em;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: 5px;
  padding: 0.1em 0.38em;
}

/* Fenced code block */
.msg-text pre {
  margin: 0 0 0.85em;
  padding: 12px 14px;
  background: var(--surface-2);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow-x: auto;
}

.msg-text pre code {
  font-family: var(--mono);
  font-size: 0.84rem;
  line-height: 1.6;
  background: none;
  border: none;
  padding: 0;
  white-space: pre;
}

.msg-text blockquote {
  margin: 0 0 0.85em;
  padding: 0.3em 0 0.3em 1em;
  border-left: 3px solid var(--accent-soft-2);
  color: var(--text-soft);
}

.msg-text strong { font-weight: 650; color: var(--text); }
.msg-text em { font-style: italic; }

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

/* Tables */
.md-table {
  width: 100%;
  border-collapse: collapse;
  margin: 0 0 0.9em;
  font-size: var(--text-sm);
  display: block;
  overflow-x: auto;
}

.md-table th,
.md-table td {
  border: 1px solid var(--border);
  padding: 7px 11px;
  text-align: left;
  vertical-align: top;
}

.md-table thead th {
  background: var(--surface-2);
  font-weight: 650;
}

.md-table tbody tr:nth-child(even) {
  background: color-mix(in srgb, var(--surface-2) 55%, transparent);
}

.msg-heading {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin: 2px 0 8px;
  padding: 3px 10px;
  border-radius: 999px;
  background: var(--surface-2);
  font-size: var(--text-xs);
  font-weight: 600;
  color: var(--text-soft);
}

.msg-note .msg-text,
.msg-pending .msg-text {
  color: var(--text-soft);
}

/* "Searching your documents…" with three bouncing dots. */
.msg-pending .msg-text {
  display: inline-flex;
  align-items: center;
  gap: 3px;
}

.msg-pending .msg-text::after {
  content: "";
  width: 5px;
  height: 5px;
  margin-left: 8px;
  border-radius: 50%;
  color: var(--accent);
  background: currentColor;
  box-shadow: 9px 0, 18px 0;
  animation: dots 1.1s ease-in-out infinite;
}

@keyframes dots {
  0%, 60%, 100% { box-shadow: 9px 0, 18px 0; opacity: 0.5; }
  20% { box-shadow: 9px -3px, 18px 0; opacity: 1; }
  40% { box-shadow: 9px 0, 18px -3px; opacity: 1; }
}

/* Two shimmering skeleton lines under the label, so the wait reads as "an
   answer is coming" rather than a frozen screen. */
.msg-pending::after {
  content: "";
  display: block;
  width: min(460px, 80%);
  height: 12px;
  margin: 14px 0 22px;
  border-radius: 6px;
  background:
    linear-gradient(90deg, var(--surface-2) 25%, var(--surface-3) 37%, var(--surface-2) 63%) 0 0 / 200% 100%,
    linear-gradient(var(--surface-2), var(--surface-2)) 0 22px / 65% 12px no-repeat;
  box-shadow: 0 22px 0 -1px transparent;
  animation: shimmer 1.4s linear infinite;
}

@keyframes shimmer {
  to { background-position: -200% 0, 0 22px; }
}

/* ---------- Thinking (the model's reasoning, ChatGPT-style) ---------- */

.thinking {
  margin: 0 0 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface-2);
  overflow: hidden;
  animation: rise 0.3s var(--ease) both;
}

.thinking-toggle {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 8px 12px;
  border: none;
  background: none;
  font: inherit;
  font-size: var(--text-xs);
  font-weight: 600;
  color: var(--text-soft);
  cursor: pointer;
  text-align: left;
}

.thinking-toggle:hover {
  color: var(--text);
}

.thinking-spark {
  width: 13px;
  height: 13px;
  flex: none;
  border-radius: 50%;
  background: conic-gradient(from 0deg, var(--accent), color-mix(in srgb, var(--accent) 20%, transparent), var(--accent));
  -webkit-mask: radial-gradient(circle 4px at center, transparent 97%, #000);
  mask: radial-gradient(circle 4px at center, transparent 97%, #000);
}

.thinking.live .thinking-spark {
  animation: spin 0.9s linear infinite;
}

/* While actively thinking, a faint accent border draws a glance; when done the
   spark settles to a quiet dot. */
.thinking.live {
  border-color: color-mix(in srgb, var(--accent) 30%, var(--border));
}

.thinking-done .thinking-spark {
  background: var(--text-faint);
  animation: none;
}

.thinking.live .thinking-label {
  background: linear-gradient(90deg, var(--text-faint) 25%, var(--text) 50%, var(--text-faint) 75%) 0 0 / 200% 100%;
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
  animation: shimmer-text 1.6s linear infinite;
}

@keyframes shimmer-text {
  to { background-position: -200% 0; }
}

.thinking-label {
  flex: 1;
  min-width: 0;
}

.thinking-chevron {
  width: 8px;
  height: 8px;
  flex: none;
  border-right: 1.6px solid currentColor;
  border-bottom: 1.6px solid currentColor;
  transform: rotate(45deg);
  transition: transform 0.2s var(--ease);
  opacity: 0.7;
}

.thinking.open .thinking-chevron {
  transform: rotate(-135deg);
}

.thinking-body {
  max-height: 0;
  overflow: hidden;
  transition: max-height 0.25s var(--ease);
}

.thinking.open .thinking-body {
  max-height: 320px;
}

.thinking-text {
  max-height: 268px;
  overflow-y: auto;
  margin: 0;
  padding: 0 12px 12px 33px;
  font-size: var(--text-xs);
  line-height: 1.6;
  color: var(--text-faint);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.msg-error {
  align-self: stretch;
  max-width: 68ch;
  color: var(--danger);
  background: var(--danger-soft);
  border: 1px solid color-mix(in srgb, var(--danger) 25%, transparent);
  border-radius: var(--radius);
  padding: 10px 14px;
  font-size: var(--text-sm);
}

/* Page citation inside an answer: a clickable chip. */
.cite {
  font-family: var(--font);
  font-size: 0.7rem;
  font-weight: 650;
  line-height: 1;
  display: inline-flex;
  align-items: center;
  vertical-align: 0.12em;
  margin: 0 1px 0 5px;
  padding: 3px 7px;
  border-radius: 999px;
  border: 1px solid var(--accent-soft-2);
  background: var(--accent-soft);
  color: var(--accent-text);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
  transition: background-color 0.15s, color 0.15s, border-color 0.15s;
}

button.cite {
  cursor: pointer;
}

button.cite:hover {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--on-accent);
}

/* ---------- Answer + source cards ---------- */

.answer {
  max-width: none;
}

.answer-main {
  max-width: 68ch;
  min-width: 0;
}

.notes-toggle {
  margin-top: 10px;
}

.notes {
  display: none;
  margin-top: 12px;
}

.notes.open {
  display: block;
}

/* A refusal's passages: searched, not evidence -- quiet and folded away. */
.notes-caption {
  margin: 0 0 8px 2px;
  font-size: var(--text-xs);
  color: var(--text-faint);
}

.notes-searched .slip {
  background: transparent;
  border-style: dashed;
  color: var(--text-soft);
}

.notes-searched .slip-page {
  color: var(--text-soft);
  font-weight: 600;
}

.notes-searched .slip-page::before {
  background: var(--text-faint);
}

.slip:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

.slips {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.slip {
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface-2);
  scroll-margin: 24px;
  font-size: var(--text-sm);
  transition: border-color 0.15s, background-color 0.25s, box-shadow 0.2s;
}

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

.slip-page {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: var(--text-xs);
  font-weight: 650;
  color: var(--text);
  overflow-wrap: anywhere;
}

.slip-page::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--accent);
  flex: none;
}

.slip-score {
  font-size: 0.68rem;
  color: var(--text-faint);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

.slip-text {
  margin: 0;
  font-size: var(--text-sm);
  line-height: 1.55;
  color: var(--text-soft);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

/* A clicked citation lights up its passage. */
.slip.marked {
  background: var(--mark);
  border-color: var(--mark-edge);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--mark-edge) 25%, transparent);
  animation: pulse 0.5s var(--ease);
}

.slip.marked .slip-text {
  color: var(--text);
}

@keyframes pulse {
  from { transform: scale(0.98); }
}

/* Wide enough for a side column: the answer's sources are always visible
   beside it. */
@container (min-width: 860px) {
  .answer.has-notes {
    display: grid;
    grid-template-columns: minmax(0, 68ch) minmax(220px, 300px);
    justify-content: space-between;
    column-gap: 40px;
    align-items: start;
  }

  .answer.has-notes .notes-toggle {
    display: none;
  }

  .answer.has-notes .notes {
    display: block;
    margin-top: 0;
  }

  .answer.has-notes .notes::before {
    content: "Sources";
    display: block;
    margin: 0 0 8px 2px;
    font-size: 0.68rem;
    font-weight: 600;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    color: var(--text-faint);
  }

  /* Source cards stay short until one is cited or opened. */
  .slip:not(.marked):not(.expanded) .slip-text {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 4;
    overflow: hidden;
  }

  .slip {
    cursor: pointer;
  }

  .slip:hover:not(.marked) {
    border-color: var(--border-strong);
    background: var(--surface);
    box-shadow: var(--shadow-sm);
  }
}

/* ---------- Motion ---------- */

/* Things settle into place with a soft spring, the way a page is laid down --
   not the uniform fade-up-on-everything of a template. */
@keyframes rise {
  0% { opacity: 0; transform: translateY(10px); }
  60% { opacity: 1; }
  100% { opacity: 1; transform: none; }
}

@keyframes settle {
  0% { opacity: 0; transform: translateY(14px) scale(0.985); }
  100% { opacity: 1; transform: none; }
}

@keyframes fade {
  from { opacity: 0; }
  to { opacity: 1; }
}

.msg-enter,
.doc-enter {
  animation: settle 0.4s var(--spring) both;
}

.answer.has-notes .slip {
  animation: settle 0.42s var(--spring) both;
  animation-delay: calc(var(--i, 0) * 70ms + 120ms);
}

.view-enter {
  animation: fade 0.28s ease-out both;
}

/* The opening page arrives in reading order with a gentle stagger. */
#upload-view > * {
  animation: settle 0.55s var(--spring) both;
}

#upload-view > .eyebrow-badge { animation-delay: 40ms; }
#upload-view > .intro-title { animation-delay: 110ms; }
#upload-view > .intro-body { animation-delay: 190ms; }
#upload-view > .dropzone { animation-delay: 270ms; }
#upload-view > .features { animation-delay: 350ms; }
#upload-view > .privacy-note { animation-delay: 420ms; }

.reading-card {
  animation: rise 0.35s var(--ease) both;
}

/* ---------- Composer (the bottom bar) ----------
   A floating rounded box holds attach, the question and send/stop; the line
   under it says what will be searched and how to operate it. */

.composer {
  flex: none;
  padding: 4px clamp(12px, 3vw, 32px) 14px;
  background: var(--surface);
}

.composer-box {
  display: flex;
  align-items: flex-end;
  gap: 6px;
  padding: 7px;
  border: 1px solid var(--border-strong);
  border-radius: 18px;
  background: var(--surface);
  box-shadow: var(--shadow-md);
  transition: border-color 0.15s, box-shadow 0.2s;
}

.composer-box:focus-within {
  border-color: var(--accent);
  box-shadow: var(--ring), var(--shadow-md);
}

.question-input {
  flex: 1;
  min-width: 0;
  font-family: inherit;
  font-size: var(--text-md);
  line-height: 1.5;
  color: var(--text);
  background: transparent;
  padding: 8px 4px;
  border: none;
  resize: none;
  max-height: 168px; /* about 6 lines, then it scrolls */
}

.question-input::placeholder {
  color: var(--text-faint);
}

.question-input:focus {
  outline: none;
}

.question-input:disabled {
  opacity: 0.6;
}

.composer-icon,
.composer-send,
.composer-stop {
  flex: none;
  display: inline-grid;
  place-items: center;
  width: 38px;
  height: 38px;
  border-radius: 12px;
  border: none;
  cursor: pointer;
  transition: background-color 0.15s, color 0.15s, opacity 0.15s, transform 0.15s var(--ease);
}

.composer-icon svg,
.composer-send svg,
.composer-stop svg {
  width: 18px;
  height: 18px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.9;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.composer-icon {
  color: var(--text-faint);
  background: none;
}

.composer-icon:hover {
  color: var(--text);
  background: var(--surface-2);
}

.composer-send {
  border-radius: 50%;
  color: var(--on-accent);
  background: var(--primary);
  box-shadow: var(--shadow-sm);
}

.composer-send:hover:not(:disabled) {
  background: #262626;
  transform: translateY(-1px);
}

.composer-send:disabled {
  color: var(--text-faint);
  background: var(--surface-3);
  box-shadow: none;
  cursor: not-allowed;
}

.composer-send:active:not(:disabled),
.composer-stop:active {
  transform: scale(0.94);
}

.composer-stop {
  border-radius: 50%;
  color: var(--on-accent);
  background: var(--text);
}

.composer-stop svg {
  fill: currentColor;
  stroke: none;
}

.composer-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 16px;
  margin-top: 8px;
  padding: 0 8px;
  font-size: var(--text-xs);
  color: var(--text-faint);
}

.scope-label {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-weight: 550;
  color: var(--text-soft);
}

.scope-label:not(:empty)::before {
  content: "";
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--success);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--success) 22%, transparent);
}

.scope-label.scope-empty {
  color: var(--danger);
}

.scope-label.scope-empty::before {
  background: var(--danger);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--danger) 20%, transparent);
}

.composer-hint {
  margin-left: auto;
}

kbd {
  font-family: inherit;
  font-size: 0.68rem;
  font-weight: 550;
  padding: 1px 5px;
  border: 1px solid var(--border);
  border-bottom-width: 2px;
  border-radius: 5px;
  background: var(--surface-2);
  color: var(--text-soft);
}

/* A streamed answer shows a blinking caret where the next words will land. */
.msg-text.streaming::after {
  content: "";
  display: inline-block;
  width: 3px;
  height: 1.05em;
  margin-left: 3px;
  vertical-align: -0.18em;
  border-radius: 2px;
  background: var(--accent);
  animation: caret 1s steps(1) infinite;
}

@keyframes caret {
  50% { opacity: 0; }
}

.answer-stopped {
  margin: 8px 0 0;
  font-size: var(--text-sm);
  color: var(--text-faint);
  font-style: italic;
}

/* A PDF dragged over the conversation: the sheet shows it will be added. */
body.drop-target .sheet-chat {
  border-color: var(--accent);
  box-shadow: var(--ring), var(--shadow-md);
}

body.drop-target .sheet-chat::after {
  content: "Drop the PDF to add it";
  position: absolute;
  inset: 10px;
  display: grid;
  place-items: center;
  font-weight: 600;
  color: var(--accent-text);
  border: 2px dashed var(--accent);
  border-radius: var(--radius);
  background: color-mix(in srgb, var(--accent-soft) 88%, transparent);
  pointer-events: none;
  animation: fade 0.15s ease-out both;
}

/* Starter questions: three quiet placeholders hold the spot while the model
   writes tailored ones, which then replace them in place -- one appearance,
   never a list that vanishes and comes back (see showSuggestions). */
.suggestions {
  display: flex;
  flex-direction: column;
  gap: 8px;
  max-width: 760px;
  padding-left: 42px;
}

.suggestion-list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
  gap: 8px;
}

.suggestion-skeleton {
  height: 42px;
  border-radius: var(--radius);
  border: 1px solid var(--border);
  background: linear-gradient(90deg, var(--surface-2) 25%, var(--surface-3) 37%, var(--surface-2) 63%) 0 0 / 200% 100%;
  animation: shimmer-pill 1.4s linear infinite;
}

@keyframes shimmer-pill {
  to { background-position: -200% 0; }
}

.suggestions-label {
  margin: 0;
  font-size: var(--text-xs);
  font-weight: 600;
  color: var(--text-faint);
}

.suggestion {
  font-family: inherit;
  font-size: var(--text-sm);
  line-height: 1.45;
  text-align: left;
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 10px 13px;
  cursor: pointer;
  box-shadow: var(--shadow-xs);
  transition: border-color 0.15s, box-shadow 0.2s, transform 0.2s var(--ease), background-color 0.15s;
  animation: rise 0.35s var(--ease) both;
}

.suggestion:nth-of-type(2) { animation-delay: 60ms; }
.suggestion:nth-of-type(3) { animation-delay: 120ms; }
.suggestion:nth-of-type(4) { animation-delay: 180ms; }

.suggestion:hover {
  border-color: var(--accent);
  background: var(--accent-soft);
  box-shadow: var(--shadow-sm);
  transform: translateY(-1px);
}

.suggestion:active {
  transform: scale(0.99);
}

/* Ask the LLM to rewrite its answer for the reader, or copy it. */
.answer-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 14px 0 0;
}

/* Which provider and model wrote the answer. */
.answered-by {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-left: auto;
  padding: 4px 4px 4px 0;
  font-size: 0.7rem;
  color: var(--text-faint);
  white-space: nowrap;
}

.answered-by-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--accent);
  opacity: 0.7;
}

/* While a question is being answered, other ways of asking are paused. */
body.busy .suggestion,
body.busy .follow-up {
  opacity: 0.45;
  pointer-events: none;
}

/* Shown only near the 1000-character limit. */
.char-count {
  font-size: var(--text-xs);
  color: var(--text-faint);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

.char-count.at-limit {
  color: var(--danger);
}

/* ---------- Jump to latest ---------- */

.jump-latest {
  position: absolute;
  left: 50%;
  bottom: 110px;
  z-index: 2;
  display: grid;
  place-items: center;
  width: 36px;
  height: 36px;
  margin-left: -18px;
  border: 1px solid var(--border);
  border-radius: 50%;
  background: var(--surface);
  color: var(--text-soft);
  box-shadow: var(--shadow-md);
  cursor: pointer;
  animation: rise 0.25s var(--ease) both;
  transition: color 0.15s, transform 0.15s var(--ease);
}

.jump-latest:hover {
  color: var(--accent);
  transform: translateY(1px);
}

.jump-latest svg {
  width: 18px;
  height: 18px;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.9;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* ---------- Toasts ---------- */

/* Top centre, under the top bar: clear of the composer and the footer. */
.toasts {
  position: fixed;
  left: 50%;
  top: 64px;
  z-index: 50;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  pointer-events: none;
}

.toast {
  padding: 9px 16px;
  border-radius: 999px;
  background: var(--text);
  color: var(--bg);
  font-size: var(--text-sm);
  font-weight: 500;
  box-shadow: var(--shadow-lg);
  white-space: nowrap;
  animation: toast-in 0.28s var(--ease) both;
}

.toast.leaving {
  animation: toast-out 0.22s ease-in both;
}

@keyframes toast-in {
  from { opacity: 0; transform: translateY(-10px) scale(0.96); }
}

@keyframes toast-out {
  to { opacity: 0; transform: translateY(-6px); }
}

/* ---------- Footer ----------
   A real footer: it closes the opening page like a colophon (credit, the
   stack it's built on, links, version), reached by scrolling. In a
   conversation it steps aside -- the composer is the floor -- and the version
   and provider health move to the top bar. */

body[data-view="chat"] .site-footer {
  display: none;
}

.site-footer {
  flex: none;
  width: 100%;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 6px 20px;
  padding: 16px max(24px, calc((100% - 1440px) / 2 + 24px));
  border-top: 1px solid var(--border);
  background: var(--surface);
  font-size: var(--text-sm);
  color: var(--text-soft);
}

.footer-providers {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
}

.footer-label {
  font-size: 0.66rem;
  font-weight: 700;
  letter-spacing: 0.08em;
  color: var(--text-faint);
}

.provider-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-wrap: wrap;
  gap: 4px 12px;
}

.provider {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: var(--text-xs);
  font-weight: 550;
  color: var(--text-soft);
  white-space: nowrap;
  animation: fade 0.3s ease-out both;
}

.provider-dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--success);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--success) 20%, transparent);
}

.provider[data-state="cooling"] .provider-dot {
  background: var(--mark-edge);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--mark-edge) 22%, transparent);
  animation: breathe 1.6s ease-in-out infinite;
}

.footer-links {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 2px;
}

.footer-links a:not(.version-badge),
.footer-link-button {
  font: inherit;
  font-weight: 500;
  color: var(--text-soft);
  text-decoration: none;
  padding: 4px 8px;
  border: none;
  border-radius: 7px;
  background: none;
  cursor: pointer;
  transition: color 0.15s, background-color 0.15s;
}

.footer-links a:not(.version-badge):hover,
.footer-link-button:hover {
  color: var(--text);
  background: var(--surface-2);
}

.footer-credit {
  white-space: nowrap;
}

.footer-credit strong {
  color: var(--text);
  font-weight: 600;
}

.heart {
  display: inline-block;
  color: var(--heart);
  transform-origin: center;
  animation: beat 2.4s ease-in-out infinite;
}

@keyframes beat {
  0%, 60%, 100% { transform: scale(1); }
  10% { transform: scale(1.22); }
  20% { transform: scale(0.96); }
  30% { transform: scale(1.12); }
}

.version-badge {
  margin-left: 6px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 2px 9px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--surface-2);
  font-family: var(--font);
  font-size: 0.7rem;
  font-weight: 600;
  color: var(--text-soft);
  text-decoration: none;
  transition: border-color 0.15s, color 0.15s;
}

.version-badge::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--success);
}

.version-badge:hover {
  border-color: var(--accent);
  color: var(--accent-text);
}

/* ---------- Privacy dialog ---------- */

.dialog {
  width: min(480px, calc(100% - 32px));
  padding: 24px 24px 20px;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--surface);
  color: var(--text);
  box-shadow: var(--shadow-lg);
}

.dialog[open] {
  animation: pop 0.22s var(--ease) both;
}

.dialog::backdrop {
  background: rgba(10, 10, 14, 0.45);
  backdrop-filter: blur(3px);
}

@keyframes pop {
  from { opacity: 0; transform: translateY(8px) scale(0.98); }
}

.dialog h2 {
  margin: 0 0 12px;
  font-size: 1.125rem;
  letter-spacing: -0.01em;
}

.dialog ul {
  margin: 0 0 20px;
  padding-left: 18px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  font-size: var(--text-sm);
  color: var(--text-soft);
}

.dialog form {
  display: flex;
  justify-content: flex-end;
}

/* ---------- Short screens (e.g. 1366x768 laptops): a tighter start page ---------- */

@media (max-height: 820px) and (min-width: 861px) {
  .title-page {
    padding: 4px 0 2vh;
  }

  .eyebrow-badge {
    margin-bottom: 12px;
  }

  .intro-title {
    font-size: clamp(1.9rem, 1.2rem + 2.2vw, 2.6rem);
    margin-bottom: 10px;
  }

  .intro-body {
    font-size: var(--text-md);
    margin-bottom: 18px;
  }

  .dropzone {
    padding: 18px 24px 16px;
  }

  .dropzone-icon {
    width: 38px;
    height: 38px;
    margin-bottom: 2px;
  }

  .features {
    margin-top: 14px;
  }

  .features li {
    padding: 9px 12px;
  }

  .privacy-note {
    margin-top: 10px;
  }
}

/* ---------- Small screens: sidebar becomes a strip above the conversation ---------- */

@media (max-width: 860px) {
  .composer {
    padding: 4px 8px 8px;
  }

  .composer-hint {
    display: none; /* no physical keyboard to hint at */
  }

  /* The composer's attach button adds documents on small screens. */
  #add-btn {
    display: none;
  }

  .topbar {
    padding: 10px 14px;
    gap: 10px;
  }

  /* The wordmark is dropped on a crowded phone top bar; the logo
     carries identity here, and the hero says the name in full. */
  .brand-name {
    display: none;
  }

  /* GitHub becomes icon-only on phones to leave room for the status pill. */
  .pill-link span {
    display: none;
  }

  .user-name {
    display: none;
  }

  .pill-link {
    padding: 7px;
  }

  .topbar-status {
    padding: 5px 9px;
  }

  .layout {
    flex-direction: column;
    gap: 10px;
    padding: 0 10px 10px;
  }

  .title-page {
    padding: 4px 6px 4vh;
  }

  .features {
    grid-template-columns: 1fr;
    gap: 6px;
  }

  .features li {
    padding: 9px 12px;
  }

  .shelf {
    width: auto;
    padding: 8px;
    gap: 8px;
    flex-direction: row;
    align-items: center;
    border-radius: var(--radius);
  }

  .shelf-head {
    display: none;
  }

  .doc-list {
    flex-direction: row;
    gap: 6px;
    margin: 0;
    overflow-x: auto;
    overflow-y: hidden;
  }

  .doc-item {
    flex: none;
    width: 220px;
    padding: 6px 8px;
    border: 1px solid var(--border);
    background: var(--surface-2);
  }

  .shelf-actions {
    padding: 0;
    border: none;
  }

  .shelf-links {
    flex-direction: column;
  }

  /* Icon-only here; the text stays in the DOM (font-size 0) so the buttons
     keep their accessible names. */
  .shelf-links .btn {
    width: auto;
    padding: 6px;
    font-size: 0;
    gap: 0;
  }

  .shelf-links .btn .icon {
    width: 17px;
    height: 17px;
  }

  .messages {
    padding: 16px 12px 20px;
    gap: 14px;
  }

  .msg-assistant {
    padding-left: 0;
    padding-top: 36px;
  }

  .suggestions {
    padding-left: 0;
    grid-template-columns: 1fr;
  }

  .msg-user {
    max-width: 88%;
  }

  /* Credit on the left with the version pill balanced to its right, then the
     links centred on their own row -- so the version pill never crowds the
     text links. The live provider pills are a desktop nicety, dropped here. */
  .site-footer {
    position: relative;
    flex-direction: column;
    align-items: flex-start;
    gap: 8px;
    padding: 11px 16px calc(11px + env(safe-area-inset-bottom));
    font-size: var(--text-xs);
    text-align: left;
  }

  .footer-providers {
    display: none;
  }

  .footer-credit {
    display: block;
    max-width: calc(100% - 78px); /* clear of the version pill on the right */
  }

  .footer-links {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: flex-start;
    gap: 0 2px;
    margin: 0 -7px;
  }

  .footer-links a:not(.version-badge),
  .footer-link-button {
    padding: 3px 7px;
  }

  /* The version pill sits at the top-right, aligned with the credit line,
     out of the links flow so the links stay evenly spaced. */
  .version-badge {
    position: absolute;
    top: 11px;
    right: 16px;
    margin: 0;
  }

  .answered-by {
    margin-left: 0;
  }

  .toasts {
    top: 58px;
  }
}

@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    animation-delay: 0s !important;
    transition: none !important;
  }

  /* The opening page and the footer heart keep their normal, quick motion
     even under "reduce motion". On Windows with "Show animations" off the
     browser reports reduced motion for everyone, and the blanket rule above
     made the page pop in all at once with a dead heart; a short settle-in and
     a small heartbeat are the product's character, not a vestibular trigger.
     Everything else stays reduced. */
  #upload-view > * {
    animation: settle 0.55s var(--spring) both !important;
  }
  #upload-view > .eyebrow-badge { animation-delay: 40ms !important; }
  #upload-view > .intro-title { animation-delay: 110ms !important; }
  #upload-view > .intro-body { animation-delay: 190ms !important; }
  #upload-view > .dropzone { animation-delay: 270ms !important; }
  #upload-view > .features { animation-delay: 350ms !important; }
  #upload-view > .privacy-note { animation-delay: 420ms !important; }

  .heart {
    animation: beat 2.4s ease-in-out infinite !important;
  }
  .suggestion-skeleton {
    animation: shimmer-pill 1.8s linear infinite !important;
  }

  /* A spinner means "working" -- keep it turning (just slower) even when
     other motion is reduced, so it never looks frozen/broken. */
  .spinner,
  .add-status .spinner {
    animation: spin 1s linear infinite !important;
  }
}

.human-box {
  display: flex;
  justify-content: center;
  min-height: 70px;
  margin: var(--space-3, 12px) 0;
}
