/* ==========================================================================
   Claudai — warm paper, ink text, terracotta accent.
   ========================================================================== */

:root {
  --bg:            #FAF9F5;
  --bg-side:       #F0EEE6;
  --bg-raised:     #FFFFFF;
  --ink:           #1F1E1D;
  --ink-soft:      #3D3D3A;
  --ink-muted:     #6B6A66;
  --ink-faint:     #96958F;
  --line:          #E3E0D6;
  --line-strong:   #D3CFC2;
  --accent:        #D97757;
  --accent-deep:   #C2603D;
  --accent-wash:   #F7EDE7;
  --ok:            #4A7C59;
  --warn:          #B07437;
  --err:           #B4483A;

  --radius:        14px;
  --radius-lg:     22px;
  --shadow-sm:     0 1px 2px rgba(31,30,29,.05);
  --shadow:        0 4px 16px rgba(31,30,29,.07);
  --shadow-lg:     0 12px 40px rgba(31,30,29,.12);

  --serif:  "Georgia", "Times New Roman", "Songti SC", "SimSun", serif;
  --sans:   "Segoe UI", -apple-system, "Helvetica Neue", "Microsoft YaHei", "PingFang SC", sans-serif;
  --mono:   "Cascadia Mono", "Consolas", "SFMono-Regular", monospace;

  --sidebar-w: 268px;
}

* { box-sizing: border-box; }

/* The `hidden` attribute must beat our own layout display rules.
   Browsers implement it as `[hidden] { display: none }` in the UA sheet, which
   any class of ours that sets `display` overrides — and several do
   (.modal-backdrop, .hero, .thread are all flex). Without this, the login
   modal stayed on screen after a successful login. */
[hidden] { display: none !important; }

/* Nothing in the main pane is shown until the app knows what to show.
   The greeting is in the markup, so it painted immediately — and then the restored
   conversation replaced it a moment later, so a returning customer saw "今天想做什么？"
   flash and vanish on every load. The operator reported exactly that.
   Which of the two belongs on screen is not known until the session is read, so
   neither is painted until then. The sidebar stays visible: it is correct already
   and hiding it would make the whole page blank rather than just undecided. */
body.booting .hero,
body.booting .thread,
body.booting .composer-wrap { visibility: hidden; }

html, body {
  margin: 0;
  height: 100%;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 15px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

button, input, textarea { font: inherit; color: inherit; }
a { color: inherit; text-decoration: none; }

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

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

.sidebar {
  width: var(--sidebar-w);
  flex: 0 0 var(--sidebar-w);
  background: var(--bg-side);
  border-right: 1px solid var(--line);
  display: flex;
  flex-direction: column;
  padding: 14px 12px 10px;
  transition: margin-left .22s ease;
}
.sidebar.collapsed { margin-left: calc(var(--sidebar-w) * -1); }

.sidebar-top { display: flex; flex-direction: column; gap: 10px; }

.brand { display: flex; align-items: center; gap: 9px; padding: 4px 6px 2px; }
.brand-mark { width: 24px; height: 24px; color: var(--accent); flex: none; }
.brand-name { font-family: var(--serif); font-size: 17px; letter-spacing: .2px; }

.new-task {
  display: flex; align-items: center; gap: 8px;
  width: 100%; padding: 9px 12px;
  background: var(--bg-raised);
  border: 1px solid var(--line-strong);
  border-radius: 10px;
  cursor: pointer;
  font-size: 14px;
  transition: background .15s, border-color .15s;
}
.new-task:hover { background: #fff; border-color: var(--accent); }
.new-task svg { width: 16px; height: 16px; color: var(--accent); }

.sidebar-nav { display: flex; flex-direction: column; gap: 1px; margin-top: 14px; }
.nav-item {
  display: flex; align-items: center; gap: 9px;
  padding: 8px 10px; border-radius: 9px;
  font-size: 14px; color: var(--ink-soft);
  transition: background .15s;
}
.nav-item:hover { background: rgba(0,0,0,.045); }
.nav-item.active { background: rgba(0,0,0,.06); color: var(--ink); }
.nav-item svg { width: 17px; height: 17px; flex: none; opacity: .75; }

.sidebar-recents { flex: 1; overflow-y: auto; margin-top: 18px; }
.recents-label {
  font-size: 11.5px; letter-spacing: .7px; text-transform: uppercase;
  color: var(--ink-faint); padding: 0 10px 7px;
}
.recent-item {
  display: block; padding: 7px 10px; border-radius: 8px;
  font-size: 13.5px; color: var(--ink-soft);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  cursor: pointer; transition: background .15s;
}
.recent-item:hover { background: rgba(0,0,0,.045); }

.sidebar-foot { border-top: 1px solid var(--line); padding-top: 10px; display: flex; flex-direction: column; gap: 8px; }
.balance-chip {
  display: flex; align-items: center; gap: 7px;
  padding: 7px 11px; border-radius: 9px;
  background: var(--bg-raised); border: 1px solid var(--line);
  font-size: 13.5px; font-variant-numeric: tabular-nums;
}
.balance-chip .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--ok); flex: none; }

/* The quota the tasks actually consume. Shown next to the money so the two are
   never confused: money is what you paid, TOKEN is what is left to spend. */
.token-chip {
  display: flex; align-items: center; justify-content: space-between; gap: 7px;
  padding: 7px 11px; border-radius: 9px;
  background: var(--bg-raised); border: 1px solid var(--line);
  font-size: 13px; font-variant-numeric: tabular-nums;
}
.token-chip .token-label {
  font-size: 10.5px; letter-spacing: .6px; color: var(--ink-faint);
}
.token-chip.low { border-color: #E8C9C3; }
.token-chip.low #tokenValue { color: var(--err); }
.balance-chip.low .dot { background: var(--warn); }
.balance-chip.empty .dot { background: var(--err); }

.account { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 2px 4px 0; font-size: 13px; }
.account-name { color: var(--ink-soft); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.account button { background: none; border: 0; color: var(--ink-faint); cursor: pointer; font-size: 12.5px; padding: 3px 5px; border-radius: 6px; }
.account button:hover { color: var(--ink); background: rgba(0,0,0,.05); }

/* ─────────────────────────────── main ─────────────────────────────── */

.main { flex: 1; display: flex; flex-direction: column; min-width: 0; position: relative; }

.sidebar-toggle {
  position: absolute; top: 12px; left: 12px; z-index: 20;
  width: 34px; height: 34px; border-radius: 9px;
  background: transparent; border: 1px solid transparent;
  color: var(--ink-muted); cursor: pointer;
  display: none; align-items: center; justify-content: center;
}
.sidebar-toggle:hover { background: rgba(0,0,0,.05); }
.sidebar-toggle svg { width: 18px; height: 18px; }
.sidebar.collapsed ~ .main .sidebar-toggle { display: flex; }

.hero {
  flex: 1; display: flex; align-items: center; justify-content: center;
  padding: 24px 24px 0;
}
.hero-inner { text-align: center; max-width: 720px; margin-bottom: 5vh; }
.hero-mark { color: var(--accent); margin-bottom: 20px; }
.hero-mark svg { width: 52px; height: 52px; }
.hero-title {
  font-family: var(--serif); font-weight: 400;
  font-size: clamp(30px, 4.4vw, 44px);
  line-height: 1.15; margin: 0 0 12px; letter-spacing: -.4px;
}
.hero-sub { color: var(--ink-muted); font-size: 16px; margin: 0; line-height: 1.7; }

.hero-cards {
  display: grid; grid-template-columns: repeat(3, 1fr);
  gap: 11px; margin-top: 34px; text-align: left;
}
@media (max-width: 720px) {
  .hero-cards { grid-template-columns: 1fr; }
}
.hero-card {
  display: flex; flex-direction: column; gap: 5px;
  padding: 15px 16px; border-radius: 13px;
  background: var(--bg-raised); border: 1px solid var(--line);
  transition: border-color .15s, box-shadow .15s, transform .15s;
}
.hero-card:hover { border-color: var(--accent); box-shadow: var(--shadow); transform: translateY(-2px); }
.hero-card-kicker { font-size: 11.5px; letter-spacing: .5px; color: var(--accent-deep); }
.hero-card strong { font-size: 15px; }
.hero-card span:last-child { font-size: 13px; color: var(--ink-muted); line-height: 1.55; }

/* ─────────────────────────── mode switch ─────────────────────────── */

.mode-bar {
  max-width: 760px; margin: 0 auto 10px;
  display: flex; gap: 7px;
}

/**
 * Capability level. Shares the mode chips' shape because it is the same kind of
 * choice, but is drawn lighter so it reads as a secondary setting rather than
 * competing with the primary one.
 */
.tier-bar {
  display: flex; align-items: center; flex-wrap: wrap; gap: 8px;
  max-width: 760px; margin: 0 auto 10px; padding: 0 2px;
}
.tier-label { font-size: 12.5px; color: var(--ink-faint); flex: none; }
.tier-chips { display: flex; gap: 6px; flex-wrap: wrap; }
.tier-chip {
  padding: 5px 13px; border-radius: 999px; cursor: pointer;
  font-size: 13px; color: var(--ink-soft);
  background: transparent; border: 1px solid var(--line);
  transition: border-color .15s, color .15s, background .15s;
}
.tier-chip:hover { border-color: var(--accent); color: var(--accent-deep); }
.tier-chip.active {
  border-color: var(--accent); color: var(--accent-deep);
  background: var(--accent-wash); font-weight: 600;
}
.tier-hint { font-size: 12px; color: var(--ink-faint); flex: 1 1 auto; min-width: 0; }
.mode-chip {
  padding: 6px 15px; border-radius: 999px; cursor: pointer;
  font-size: 13.5px; color: var(--ink-muted);
  background: transparent; border: 1px solid var(--line-strong);
  transition: background .15s, color .15s, border-color .15s;
}
.mode-chip:hover { border-color: var(--accent); color: var(--accent-deep); }
.mode-chip.active {
  background: var(--accent); border-color: var(--accent); color: #fff;
  box-shadow: 0 2px 10px rgba(217,119,87,.24);
}

/* task mode gets a warmer frame so the cost difference is visible */
.composer.agent-mode { border-color: var(--accent); }

/* ────────────────────────────── thread ────────────────────────────── */

.thread {
  flex: 1; overflow-y: auto;
  padding: 68px 24px 24px;
  scroll-behavior: smooth;
}
.thread-inner { max-width: 760px; margin: 0 auto; display: flex; flex-direction: column; gap: 26px; }

.turn { display: flex; flex-direction: column; gap: 10px; }

.turn-user { align-items: flex-end; }
.bubble-user {
  background: var(--bg-side);
  border: 1px solid var(--line);
  border-radius: 18px 18px 4px 18px;
  padding: 11px 16px; max-width: 78%;
  white-space: pre-wrap; word-break: break-word;
}

.turn-bot { align-items: flex-start; }
.bot-head { display: flex; align-items: center; gap: 9px; color: var(--ink-muted); font-size: 13px; }
.bot-avatar { width: 22px; height: 22px; color: var(--accent); flex: none; }
.bot-body { padding-left: 31px; width: 100%; }

.stream-line {
  display: flex; align-items: baseline; gap: 10px;
  color: var(--ink-muted); font-size: 14px; min-height: 22px;
}
.stream-stage { color: var(--ink-soft); }
.spinner {
  width: 11px; height: 11px; border-radius: 50%;
  border: 2px solid var(--line-strong); border-top-color: var(--accent);
  animation: spin .8s linear infinite; flex: none;
}
@keyframes spin { to { transform: rotate(360deg); } }

.progress-track { height: 3px; background: var(--line); border-radius: 3px; overflow: hidden; margin-top: 10px; }
.progress-fill { height: 100%; width: 0; background: var(--accent); transition: width .4s ease; }

/* result card */

.result {
  background: var(--bg-raised); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 18px; box-shadow: var(--shadow-sm);
}
.result-title { font-family: var(--serif); font-size: 20px; margin: 0 0 4px; }
.result-thesis { color: var(--ink-muted); font-size: 14px; margin: 0 0 16px; }

/* Answer with no pipeline behind it. Styled as a normal reply, deliberately
   indistinguishable from a "capability" result — the user asked for an outcome,
   not for a particular pipeline, and the product should never look like it is
   falling back to something lesser. */
.answer {
  background: var(--bg-raised); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 18px; box-shadow: var(--shadow-sm);
}

/* Rendered Markdown. Scoped to .md so it cannot leak into chrome. */
.md { font-size: 15px; line-height: 1.75; color: var(--ink); overflow-wrap: anywhere; }
.md > :first-child { margin-top: 0; }
.md > :last-child { margin-bottom: 0; }
.md h3, .md h4, .md h5, .md h6 {
  font-family: var(--serif); line-height: 1.35; margin: 20px 0 8px;
}
.md h3 { font-size: 19px; }
.md h4 { font-size: 17px; }
.md h5, .md h6 { font-size: 15px; }
.md p { margin: 0 0 10px; }
.md ul, .md ol { margin: 0 0 10px; padding-left: 22px; }
.md li { margin: 0 0 4px; }
.md strong { font-weight: 600; }
.md a { color: var(--accent); text-decoration: underline; text-underline-offset: 2px; }
.md code {
  font-family: ui-monospace, "Cascadia Mono", Consolas, monospace;
  font-size: 13px; background: var(--bg-sunken, #F1EFE9);
  padding: 1px 5px; border-radius: 4px;
}
.md pre {
  background: var(--bg-sunken, #F1EFE9); border: 1px solid var(--line);
  border-radius: 9px; padding: 12px 14px; overflow-x: auto; margin: 0 0 12px;
}
.md pre code { background: none; padding: 0; font-size: 12.5px; line-height: 1.6; }
.md blockquote {
  margin: 0 0 12px; padding: 2px 0 2px 14px;
  border-left: 3px solid var(--line); color: var(--ink-muted);
}
.md table { border-collapse: collapse; width: 100%; margin: 0 0 12px; font-size: 14px; }
.md th, .md td { border: 1px solid var(--line); padding: 7px 10px; text-align: left; }
.md th { background: var(--bg-sunken, #F1EFE9); font-weight: 600; }
.md hr { border: none; border-top: 1px solid var(--line); margin: 16px 0; }

/* plain chat reply */
.chat-text { white-space: pre-wrap; word-break: break-word; line-height: 1.72; }

/* transient confirmation */
.toast {
  position: fixed; left: 50%; bottom: 34px; transform: translate(-50%, 12px);
  background: var(--ink); color: var(--bg);
  padding: 10px 18px; border-radius: 11px; font-size: 13.5px;
  box-shadow: var(--shadow-lg); z-index: 200;
  opacity: 0; transition: opacity .25s, transform .25s;
  pointer-events: none; max-width: 80vw; text-align: center;
}
.toast.show { opacity: 1; transform: translate(-50%, 0); }

.result video { width: 100%; border-radius: 11px; background: #050510; display: block; }

.specs { display: flex; flex-wrap: wrap; gap: 7px; margin-top: 14px; }
.spec {
  font-size: 12.5px; font-variant-numeric: tabular-nums;
  background: var(--bg-side); border: 1px solid var(--line);
  border-radius: 7px; padding: 3px 9px; color: var(--ink-soft);
}

.downloads { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 16px; }
.dl {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 8px 14px; border-radius: 9px; font-size: 13.5px;
  background: var(--accent); color: #fff; border: 1px solid var(--accent);
  transition: background .15s;
}
.dl:hover { background: var(--accent-deep); }
.dl.ghost { background: transparent; color: var(--ink-soft); border-color: var(--line-strong); }
.dl.ghost:hover { background: var(--bg-side); }
.dl svg { width: 15px; height: 15px; }
/* A <button> sits next to the <a> download links and must look identical: a button
   brings its own font and cursor, so without this it renders one size off. */
button.dl { font: inherit; cursor: pointer; }

.billing {
  margin-top: 16px; padding-top: 13px; border-top: 1px solid var(--line);
  display: flex; flex-wrap: wrap; gap: 6px 18px;
  font-size: 12.5px; color: var(--ink-faint); font-variant-numeric: tabular-nums;
}
.billing b { color: var(--ink-soft); font-weight: 600; }

.notice {
  padding: 13px 16px; border-radius: 11px; font-size: 14px;
  border: 1px solid var(--line); background: var(--bg-raised);
}
.notice.error { border-color: #E8C9C3; background: #FCF2F0; color: var(--err); }

/* Recipe page: pick a direction first, then load only that direction's wordings.
   Many small buttons beat one long list once there are dozens of skills. */
.skill-chips { display: flex; flex-wrap: wrap; gap: 8px; margin: 4px 0 20px; }
.skill-chip {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 8px 13px; border-radius: 999px; font: inherit; font-size: 13.5px;
  color: var(--muted); background: var(--bg-raised); border: 1px solid var(--line);
  cursor: pointer;
}
.skill-chip:hover { color: var(--ink); border-color: var(--muted); }
.skill-chip.active { color: var(--ink); border-color: var(--accent); background: #fff; }
.recipe-list { display: block; }

/* 失败了给一条出路：一句话 + 一个按钮，不要变成一场对话。 */
.bug-report { margin-top: 10px; border-top: 1px dashed var(--line); padding-top: 10px; }
.bug-hint { margin: 0 0 8px; font-size: 13px; color: var(--muted); }
.bug-actions { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.bug-send {
  padding: 8px 14px; border-radius: 9px; font: inherit; font-size: 13.5px; cursor: pointer;
  background: var(--accent); color: #fff; border: 1px solid var(--accent);
}
.bug-send:disabled { opacity: .65; cursor: default; }
.bug-shot {
  padding: 8px 14px; border-radius: 9px; font: inherit; font-size: 13.5px; cursor: pointer;
  background: transparent; color: var(--muted); border: 1px solid var(--line);
}
.bug-shot:hover { color: var(--ink); border-color: var(--muted); }
.bug-state { font-size: 13px; color: var(--muted); }

/* Stop a running task. Quiet on purpose: it is an escape hatch, not an invitation. */.stop-btn {
  display: inline-flex; align-items: center;
  margin-top: 10px; padding: 7px 13px; border-radius: 9px;
  font: inherit; font-size: 13px; cursor: pointer;
  color: var(--muted); background: transparent; border: 1px solid var(--line);
}
.stop-btn:hover { color: var(--err); border-color: #E8C9C3; }
.stop-btn:disabled { opacity: .6; cursor: default; }

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

.composer-wrap { padding: 12px 24px 20px; background: linear-gradient(to top, var(--bg) 62%, transparent); }
.composer {
  max-width: 760px; margin: 0 auto;
  background: var(--bg-raised);
  border: 1px solid var(--line-strong);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow);
  padding: 15px 15px 11px;
  transition: border-color .15s, box-shadow .15s;
}
.composer:focus-within { border-color: var(--accent); box-shadow: 0 6px 26px rgba(217,119,87,.14); }

.composer textarea {
  width: 100%; border: 0; outline: 0; resize: none;
  background: transparent; font-size: 16px; line-height: 1.55;
  max-height: 210px; padding: 0 3px;
}
.composer textarea::placeholder { color: var(--ink-faint); }

.composer-bar { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-top: 10px; }
.composer-left { display: flex; align-items: center; gap: 10px; }

.icon-btn {
  width: 32px; height: 32px; border-radius: 9px;
  border: 1px solid var(--line); background: transparent;
  color: var(--ink-muted); cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
}
.icon-btn:hover { background: var(--bg-side); color: var(--ink); }
.icon-btn svg { width: 17px; height: 17px; }
.icon-btn.recording { background: var(--accent-wash); border-color: var(--accent); color: var(--accent); animation: pulse 1.4s ease-in-out infinite; }
@keyframes pulse { 50% { opacity: .55; } }

.hint { font-size: 12.5px; color: var(--ink-faint); }

.send {
  width: 34px; height: 34px; border-radius: 10px; flex: none;
  border: 0; background: var(--accent); color: #fff; cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
  transition: background .15s, opacity .15s;
}
.send:disabled { background: var(--line-strong); cursor: not-allowed; }
.send:not(:disabled):hover { background: var(--accent-deep); }
.send svg { width: 18px; height: 18px; }

.composer-note { max-width: 760px; margin: 9px auto 0; text-align: center; font-size: 12.5px; color: var(--ink-faint); }
.composer-note strong { color: var(--ink-muted); font-weight: 600; }

/* ─────────────────────────────── modal ─────────────────────────────── */

.modal-backdrop {
  position: fixed; inset: 0; z-index: 100;
  background: rgba(31,30,29,.42);
  display: flex; align-items: center; justify-content: center;
  padding: 24px; backdrop-filter: blur(3px);
}
.modal {
  background: var(--bg-raised); border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg); padding: 32px;
  width: 100%; max-width: 404px; text-align: center;
}
.modal-mark { margin-bottom: 14px; }
.modal-title { font-family: var(--serif); font-weight: 400; font-size: 25px; margin: 0 0 7px; }
.modal-sub { color: var(--ink-muted); font-size: 14px; margin: 0 0 22px; }
.modal-sub strong { color: var(--accent); font-weight: 600; }

.field { display: block; text-align: left; margin-bottom: 13px; }
.field span { display: block; font-size: 13px; color: var(--ink-muted); margin-bottom: 5px; }
.field input {
  width: 100%; padding: 11px 13px;
  border: 1px solid var(--line-strong); border-radius: 10px;
  background: var(--bg); outline: 0; transition: border-color .15s, box-shadow .15s;
}
.field input:focus { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-wash); background: #fff; }

.form-error { color: var(--err); font-size: 13px; margin: 0 0 12px; text-align: left; }

.primary-btn {
  width: 100%; padding: 12px; border: 0; border-radius: 11px;
  background: var(--accent); color: #fff; font-size: 15px; cursor: pointer;
  transition: background .15s;
}
.primary-btn:hover { background: var(--accent-deep); }
.primary-btn:disabled { background: var(--line-strong); cursor: not-allowed; }

.modal-foot { margin: 18px 0 0; font-size: 13.5px; color: var(--ink-muted); }
.link-btn { background: none; border: 0; color: var(--accent); cursor: pointer; padding: 0 3px; font-size: 13.5px; }
.link-btn:hover { text-decoration: underline; }

/* ──────────────────────── sub pages (examples/skills/wallet) ───────────── */

.page { flex: 1; overflow-y: auto; }
.page-inner { max-width: 880px; margin: 0 auto; padding: 58px 24px 96px; }
.page-title { font-family: var(--serif); font-weight: 400; font-size: clamp(27px, 3.6vw, 36px); margin: 0 0 10px; }
.page-lede { color: var(--ink-muted); font-size: 16px; margin: 0 0 34px; max-width: 62ch; }

.section-title {
  font-family: var(--serif); font-weight: 400; font-size: 21px;
  margin: 40px 0 14px; padding-bottom: 9px; border-bottom: 1px solid var(--line);
}
.section-title:first-of-type { margin-top: 0; }
/* A lede or an explanation paragraph often sits directly above a section
   heading; without this the heading collides with it. */
.page-lede + .recipe-why + .section-title,
.recipe-why + .section-title { margin-top: 44px; }

.recipe {
  background: var(--bg-raised); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 20px; margin-bottom: 18px;
}
.recipe-head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.recipe-name { font-size: 16.5px; font-weight: 600; margin: 0; }
.recipe-use { color: var(--ink-muted); font-size: 13.5px; }
.recipe-prompt {
  font-family: var(--mono); font-size: 13.5px; line-height: 1.65;
  background: var(--bg-side); border: 1px solid var(--line);
  border-left: 3px solid var(--accent);
  border-radius: 9px; padding: 13px 15px; margin: 14px 0 0;
  white-space: pre-wrap; word-break: break-word;
}

/* prompt block with its copy affordance pinned top-right */
.prompt-wrap { position: relative; margin: 14px 0; }
.prompt-wrap .recipe-prompt { margin: 0; padding-right: 88px; }

.copy-btn {
  position: absolute; top: 9px; right: 9px;
  font-size: 12.5px; padding: 4px 11px; border-radius: 7px;
  background: var(--bg-raised); color: var(--ink-soft);
  border: 1px solid var(--line-strong); cursor: pointer;
  transition: background .15s, color .15s, border-color .15s;
}
.copy-btn:hover { border-color: var(--accent); color: var(--accent-deep); }
.copy-btn.copied { background: var(--accent); border-color: var(--accent); color: #fff; }
.recipe-why { font-size: 14px; color: var(--ink-soft); margin: 0 0 4px; }
.recipe-why b { color: var(--ink); }
.recipe video { width: 100%; border-radius: 10px; background: #050510; margin-top: 14px; display: block; }
.recipe-actions { display: flex; gap: 8px; margin-top: 14px; flex-wrap: wrap; }

.tag {
  display: inline-block; font-size: 11.5px; letter-spacing: .3px;
  padding: 2px 9px; border-radius: 999px;
  background: var(--accent-wash); color: var(--accent-deep); border: 1px solid #EFD9CE;
}
.tag.muted { background: var(--bg-side); color: var(--ink-muted); border-color: var(--line); }
.tag.ok { background: #EBF2EC; color: var(--ok); border-color: #D5E4D9; }

.skill-row {
  display: grid; grid-template-columns: 1fr auto; gap: 8px 18px;
  padding: 16px 0; border-bottom: 1px solid var(--line);
}
.skill-name { font-weight: 600; font-size: 15px; font-family: var(--mono); }
.skill-desc { color: var(--ink-muted); font-size: 13.5px; grid-column: 1; }
.skill-meta { color: var(--ink-faint); font-size: 12px; grid-column: 1; font-variant-numeric: tabular-nums; }
.skill-status { grid-row: 1 / 4; grid-column: 2; align-self: start; }

.empty-note {
  padding: 26px; text-align: center; color: var(--ink-faint); font-size: 14px;
  border: 1px dashed var(--line-strong); border-radius: var(--radius);
}

table.ledger { width: 100%; border-collapse: collapse; font-size: 13.5px; }
table.ledger th { text-align: left; color: var(--ink-faint); font-weight: 500; font-size: 12px; padding: 0 10px 8px 0; border-bottom: 1px solid var(--line); }
table.ledger td { padding: 9px 10px 9px 0; border-bottom: 1px solid var(--line); font-variant-numeric: tabular-nums; }
table.ledger td.num { text-align: right; }
.amount-in { color: var(--ok); }
.amount-out { color: var(--ink-soft); }

.topup-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 12px; margin: 18px 0 10px; }
.topup-card {
  border: 1px solid var(--line-strong); border-radius: 12px; padding: 18px 14px;
  background: var(--bg-raised); cursor: pointer; text-align: center;
  transition: border-color .15s, box-shadow .15s;
}
.topup-card:hover { border-color: var(--accent); box-shadow: var(--shadow-sm); }
.topup-card.selected { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-wash); }
.topup-amount { font-family: var(--serif); font-size: 24px; }
.topup-credits { color: var(--ink-muted); font-size: 13px; margin-top: 3px; }

/* ────────────────────────────── responsive ────────────────────────────── */

@media (max-width: 860px) {
  .sidebar { position: fixed; z-index: 60; height: 100dvh; box-shadow: var(--shadow-lg); }
  .sidebar.collapsed { margin-left: calc(var(--sidebar-w) * -1); }
  .sidebar-toggle { display: flex; }

  /**
   * Tap-anywhere scrim behind the open sidebar.
   *
   * This is a real element in the DOM, not a pseudo-element. A `.sidebar::after`
   * version looked identical but did not receive touches on a phone, so the only
   * way out of the menu was the hamburger — which the open menu covers.
   *
   * z-index 59 sits below the sidebar (60) and below the toggle (61), so the
   * panel stays interactive and the button stays reachable.
   */
  .nav-scrim {
    display: block;
    position: fixed;
    inset: 0;
    z-index: 59;
    background: rgba(20, 16, 12, .32);
    /* Taps are handled in JS; this only stops them reaching the page behind. */
    touch-action: none;
  }
  .nav-scrim[hidden] { display: none; }

  /* The toggle must stay above both the scrim and the panel, or the only control
     that closes the sidebar becomes unreachable the moment it opens.

     Height is pinned here on purpose. Switching `position` from absolute to
     relative made the button a flex item of `.main`, and the flex layout sized
     it to its content — 22px tall instead of 44. An explicitly sized box is the
     fix; `position:absolute` was doing this implicitly before. */
  .sidebar-toggle {
    position: relative;
    z-index: 61;
    width: 44px;
    height: 44px;
    flex: none;
    align-self: flex-start;
  }

  .thread { padding: 60px 16px 16px; }
  .composer-wrap { padding: 10px 14px 16px; }
  .page-inner { padding: 56px 18px 80px; }
  .bubble-user { max-width: 90%; }
}


/* ── phone verification ─────────────────────────────────────────────────── */
/* These rows sit inside <label class="field">, whose rules (.field span is a
   block with a bottom margin, .field input is full width) would stack the
   button under the input and stretch it across the row. The selectors below are
   scoped to .captcha-row so they outrank .field rather than fighting it. */
#phoneBlock .captcha-row {
  display: flex; align-items: stretch; gap: 8px; margin: 0;
}
#phoneBlock .captcha-row > span { display: contents; }
#phoneBlock .captcha-row input,
#phoneBlock .captcha-row .captcha-question { flex: 1 1 auto; min-width: 0; width: auto; }
#phoneBlock .captcha-question {
  display: flex; align-items: center;
  padding: 11px 13px; border-radius: 10px;
  background: var(--bg-raised); border: 1px solid var(--line);
  font-variant-numeric: tabular-nums; font-size: 15px; letter-spacing: .4px;
  color: var(--ink);
}
#phoneBlock .ghost-btn,
#phoneBlock .link-btn {
  flex: 0 0 auto; width: auto; align-self: stretch;
  display: inline-flex; align-items: center;
  padding: 0 14px; margin: 0;
  border-radius: 10px; cursor: pointer; white-space: nowrap;
  background: var(--bg-raised); border: 1px solid var(--line-strong);
  color: var(--ink); font-size: 13.5px;
}
#phoneBlock .ghost-btn:hover:not(:disabled),
#phoneBlock .link-btn:hover { border-color: var(--accent); color: var(--accent); }
#phoneBlock .ghost-btn:disabled { opacity: .6; cursor: default; }
#phoneBlock { border-top: 1px solid var(--line); margin-top: 4px; padding-top: 14px; }

/* ══════════════════════════════════════════════════════════════════════════
   触屏可用性
   ──────────────────────────────────────────────────────────────────────────
   实测（tools/probe_responsive.mjs，360/375/393/820/1440/320 六种尺寸）发现的
   问题，集中修在这里，避免散落在各条原始样式里被以后改动覆盖掉。

   衡量标准：手指点击区高度。苹果建议 44pt、安卓建议 48dp；
   桌面用鼠标时 22px 就够，所以下面按设备区分阈值，不给桌面加无意义的膨胀。
   ══════════════════════════════════════════════════════════════════════════ */

/* 账户按钮是「登录 / 注册」的入口，是移动端最关键的点击目标之一。
   原来只有 26px 高（padding 3px 5px + 12.5px 字），手指很难点中。 */
.account button { min-height: 32px; padding: 6px 8px; }

/* 品牌名标签原来是 10.5px，是全站唯一小于 11px 的文字。
   必须写成和原规则同级的选择器：原规则是 .token-chip .token-label（两个类），
   只写单类 .token-label 会被它压掉，表现就是「改了没生效」。 */
.token-chip .token-label { font-size: 11px; }

@media (max-width: 860px) {
  /* 侧栏导航项：38px → 44px，达到手指可点标准。 */
  .nav-item { min-height: 44px; }

  /* 品牌区是回首页的链接：33px → 44px。 */
  .brand { min-height: 44px; }

  /* 侧栏开关：34px → 44px。这是移动端唯一的导航入口，必须好点。 */
  .sidebar-toggle { width: 44px; height: 44px; }

  .new-task { min-height: 44px; }

  /* 账户区的退出/登录按钮在原样式基础上再抬一点。 */
  .account button { min-height: 40px; }

  /* iOS Safari 在字号小于 16px 的输入框获得焦点时会自动放大页面，
     这个缩放会让布局错位、用户还得手动缩回去。16px 是唯一的解法。 */
  input, textarea, select { font-size: 16px; }

  /* 触屏上 hover 会粘住：点过的按钮一直保持悬停样式，看起来像选中了。 */
  .nav-item:hover, .new-task:hover, .account button:hover { background: transparent; }
  .nav-item.active:hover { background: rgba(0,0,0,.06); }

  /* 内容区去掉桌面端的左右留白，让手机屏幕宽度用在正文上。 */
  .page-inner { padding-left: 16px; padding-right: 16px; }

  /* Capability chips need a real tap height on a phone. */
  .tier-chip { min-height: 36px; display: inline-flex; align-items: center; }
  .tier-bar { gap: 6px; }

  /* 首页输入区。textarea 原来只有一行高（约 25px），手机上几乎点不到；
     它是这个产品最主要的输入口，必须是最大最好点的目标。 */
  .composer textarea { min-height: 48px; padding-top: 4px; }
  .composer { padding: 12px 14px 10px; }

  /* 模式切换（任务模式 / 快速对话）：36px → 44px。 */
  .mode-chip { min-height: 44px; display: inline-flex; align-items: center; }

  /* 发送按钮和语音按钮：32px / 34px → 44px。 */
  .send, .icon-btn { min-width: 44px; min-height: 44px; }

  /* 示例页的复制按钮：30px → 40px。它被点得很多，但不必到 44。 */
  .copy-btn { min-height: 40px; padding-top: 8px; padding-bottom: 8px; }

  /* 示例页的「直接发送这条 / 下载成片」：40px → 44px。 */
  .recipe-actions .primary-btn,
  .recipe-actions .ghost,
  .recipe-actions a,
  .recipe-actions button { min-height: 44px; display: inline-flex; align-items: center; }
}

/* 很窄的屏幕（320px 级）再压一档内边距。 */
@media (max-width: 360px) {
  .page-inner { padding-left: 12px; padding-right: 12px; }
  .modal { margin: 10px; }
}

/* The one-time offer of a proven prompt wording.
   Styled as a quiet strip rather than a modal: it is advice, and advice that
   blocks the interface is an obstacle. The primary action is the link out; the
   escape hatch is rendered as a ghost button so it is clearly available. */
.intent-bar {
  margin: 0 0 12px; padding: 14px 16px;
  background: var(--bg-raised); border: 1px solid var(--line);
  border-left: 3px solid var(--accent);
  border-radius: var(--radius);
}
.intent-head { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; }
.intent-head strong { font-size: 15px; }
.intent-why { color: var(--ink-faint); font-size: 12.5px; }
.intent-body { margin: 6px 0 12px; color: var(--ink-muted); font-size: 14px; line-height: 1.6; }
.intent-actions { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }

/* operator view */
.stat-grid { display:grid; gap:12px; margin-bottom:8px; grid-template-columns:repeat(auto-fill,minmax(200px,1fr)); }
#kinds table, #runs table { width:100%; border-collapse:collapse; font-size:13.5px; }
#kinds td, #runs td, #runs th { border:1px solid var(--line); padding:6px 10px; text-align:left; }
#runs th { background:var(--bg-sunken,#F1EFE9); font-weight:600; }
#runs { overflow-x:auto; }

/* The customer's switches, under the balance.
   Deliberately not a modal or a settings page: these change what the product
   costs, so they belong next to the number they affect. */
.pref-panel { padding: 10px 12px 4px; border-top: 1px solid var(--line); }
.pref-panel:empty { display: none; }
.pref-row + .pref-row { margin-top: 10px; }
.pref-switch { display: flex; align-items: center; gap: 8px; cursor: pointer; }
.pref-switch input { width: 15px; height: 15px; accent-color: var(--accent); cursor: pointer; }
.pref-name { font-size: 13.5px; font-weight: 500; }
.pref-why { margin: 4px 0 0 23px; font-size: 12px; line-height: 1.5; color: var(--ink-faint); }

/* The one-line rule on the start screen.
   Quiet, above the cards: it is advice, not an announcement, and it must not
   compete with the input or the examples. */
.hero-rule {
  max-width: 620px; margin: 14px auto 2px; padding: 12px 16px;
  background: var(--bg-raised); border: 1px solid var(--line);
  border-left: 3px solid var(--accent); border-radius: var(--radius);
  text-align: left;
}
.hero-rule p { margin: 0; font-size: 13.5px; line-height: 1.6; }
.hero-rule-why { margin-top: 6px !important; font-size: 12.6px; color: var(--ink-faint); }
.hero-rule-why a { color: var(--accent); text-decoration: none; }
.hero-rule-why a:hover { text-decoration: underline; }

/* Lead line of the rule: larger than the reasoning below it, because everything
   under it is justification and this is the instruction. */
.hero-rule-lead { font-size: 14.5px !important; line-height: 1.65 !important; margin-bottom: 7px !important; }
.hero-rule-lead b { color: var(--ink); }

/* Phone notice in place of the mode chips. */
.mode-mobile-note {
  margin: 0; font-size: 13px; color: var(--ink-muted); line-height: 1.5;
  padding: 6px 10px; background: var(--bg-raised);
  border: 1px solid var(--line); border-radius: var(--radius);
}
.mode-mobile-why { color: var(--ink-faint); font-size: 12.3px; }

/* Payment-method picker on the wallet page.
   Two equal buttons rather than a dropdown: the customer has one of the two, and a
   dropdown hides the option they need behind a click. */
.channel-picker { display: flex; gap: 10px; margin: 14px 0 6px; }
.channel-btn {
  flex: 1; padding: 11px 14px; font-size: 14.5px; cursor: pointer;
  background: var(--bg-raised); color: var(--ink);
  border: 1px solid var(--line); border-radius: var(--radius);
}
.channel-btn.active { border-color: var(--accent); box-shadow: inset 0 0 0 1px var(--accent); font-weight: 600; }
.channel-hint { margin: 0 0 12px; font-size: 12.5px; color: var(--ink-faint); }

/* In-product help.
   A small ? next to the thing it explains, and nothing else visible until it is
   clicked. The brief was that the main page must not look busy and that guidance
   should appear when needed, so the help layer adds no permanent UI of its own. */
.guide-dot {
  width: 17px; height: 17px; margin-left: 6px; padding: 0; flex: 0 0 auto;
  font-size: 11px; line-height: 15px; font-weight: 600; cursor: pointer;
  color: var(--ink-faint); background: transparent;
  border: 1px solid var(--line); border-radius: 50%;
  vertical-align: middle;
}
.guide-dot:hover { color: var(--accent); border-color: var(--accent); }
.guide-modal {
  position: fixed; inset: 0; z-index: 60; display: none;
  align-items: center; justify-content: center; padding: 20px;
  background: rgba(0,0,0,.45);
}
.guide-modal.open { display: flex; }
.guide-card {
  position: relative; width: 100%; max-width: 460px; max-height: 82vh; overflow-y: auto;
  padding: 22px 22px 18px; background: var(--bg-raised); color: var(--ink);
  border: 1px solid var(--line); border-radius: var(--radius);
}
.guide-title { margin: 0 0 6px; font-size: 17px; }
.guide-for { margin: 0 0 14px; font-size: 13.5px; color: var(--ink-dim); }
.guide-steps { margin: 0 0 14px; padding-left: 20px; font-size: 14px; line-height: 1.85; }
.guide-note { margin: 0; font-size: 12.5px; color: var(--ink-faint); }
.guide-close {
  position: absolute; top: 10px; right: 12px; width: 26px; height: 26px;
  font-size: 19px; line-height: 1; cursor: pointer; color: var(--ink-faint);
  background: transparent; border: 0;
}
.guide-close:hover { color: var(--ink); }

/* Progressive navigation.
   Hidden until the customer has finished something, because a menu of features is
   noise to someone who has not yet seen the product work. [hidden] is set in the
   markup, so the rule that displays them must be explicit or nothing shows. */
.sidebar-nav [data-progressive][hidden] { display: none; }
.nav-hint {
  margin: 6px 14px 0; font-size: 12px; line-height: 1.7;
  color: var(--ink-faint);
}

/* The empty state, reduced to a greeting.
   The previous version carried a mark, three paragraphs of philosophy and two
   cards. A stranger on an unfamiliar site reads that as a sales pitch, which is
   the opposite of the credibility the screen needs. */
.hero-inner { max-width: 620px; margin: 0 auto; text-align: center; }
.hero-title { font-size: 30px; line-height: 1.35; margin: 0 0 10px; }
.hero-sub { font-size: 15px; color: var(--ink-muted); margin: 0; }

/* Invite redemption on the recharge page.
   The input is wide and the button small: the code is what the person is holding
   and copying, so it gets the room, and a large button next to a long string
   invites a mis-click. */
.redeem-row { display: flex; gap: 10px; align-items: stretch; max-width: 420px; }
.redeem-input {
  flex: 1; min-width: 0; padding: 10px 12px;
  font-family: var(--mono); font-size: 15px; letter-spacing: 1.5px;
  color: var(--ink); background: var(--bg-raised);
  border: 1px solid var(--line); border-radius: var(--radius);
}
.redeem-input:focus { outline: none; border-color: var(--accent); }

/* Invite-code controls on the operator page. Compact: this page is read by one
   person who wants to see the whole list at once. */
.invite-form { display: flex; flex-wrap: wrap; gap: 14px; align-items: flex-end; }
.invite-field { display: flex; flex-direction: column; gap: 4px; font-size: 12.5px; color: var(--ink-muted); }
.invite-field input {
  padding: 8px 10px; font-size: 14px; color: var(--ink);
  background: var(--bg-raised); border: 1px solid var(--line); border-radius: 10px;
}
.invite-field input[type=number] { width: 120px; }
.invite-field input[type=text] { width: 190px; }
.invite-codes {
  margin-top: 10px; padding: 12px; word-break: break-all;
  font-family: var(--mono); font-size: 14px; letter-spacing: 1px;
  background: var(--accent-wash); border: 1px solid var(--line); border-radius: 10px;
}
.invite-amt {
  width: 110px; padding: 5px 8px; font-size: 13px; color: var(--ink);
  background: var(--bg-raised); border: 1px solid var(--line); border-radius: 8px;
}
.mini-btn {
  padding: 4px 10px; font-size: 12.5px; cursor: pointer;
  color: var(--ink-soft); background: var(--bg-raised);
  border: 1px solid var(--line); border-radius: 8px;
}
.mini-btn:hover { border-color: var(--accent); color: var(--accent); }

/* The introduction a visitor sees before signing in.
   Centred and narrow: it is one idea, not a page to scan. The examples are the part
   that does the work — "AI can help with work" is a claim, and a concrete sentence
   the product can actually execute is evidence. */
.hero-intro { max-width: 620px; }
.hero-examples {
  list-style: none; margin: 22px 0 26px; padding: 0;
  text-align: left; font-size: 14px; line-height: 1.75;
  color: var(--ink-soft);
}
.hero-examples li {
  padding: 8px 0 8px 22px; position: relative;
  border-bottom: 1px solid var(--line);
}
.hero-examples li:last-child { border-bottom: 0; }
.hero-examples li::before {
  content: "·"; position: absolute; left: 6px; top: 7px;
  color: var(--accent); font-weight: 700; font-size: 18px;
}
.hero-cta {
  display: inline-block; min-width: 190px; padding: 12px 26px;
  font-size: 15.5px; font-weight: 600; cursor: pointer;
}
.hero-foot {
  margin: 16px 0 0; font-size: 13px; color: var(--ink-faint);
}
.hero-foot a { color: var(--accent); text-decoration: none; }
.hero-foot a:hover { text-decoration: underline; }

/* A one-line explanation under a field, used when the page changes something the
   customer already filled in. Small and quiet: it is an explanation, not an alarm. */
.field-hint {
  display: block; margin-top: 6px;
  font-size: 12.5px; line-height: 1.6; color: var(--ink-muted);
}

/* Shown when this computer is not paired with the helper. One line, one link: the
   customer needs to know what to do next, not why the architecture needs it. */
.helper-banner {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  margin: 0 0 10px; padding: 10px 14px;
  font-size: 13.5px; line-height: 1.6;
  color: var(--ink-soft);
  border: 1px solid color-mix(in srgb, var(--warn, #d9a13b) 40%, var(--line));
  border-radius: 10px;
  background: color-mix(in srgb, var(--warn, #d9a13b) 8%, transparent);
}
.helper-banner a { color: var(--accent); text-decoration: none; font-weight: 600; }
.helper-banner a:hover { text-decoration: underline; }

/* Whether THEIR computer is connected, stated in both directions.
   The banner above only appears when it is not — which left the good state
   unsaid, and a person cannot tell "connected" from "the page has not checked
   yet". A dot plus four words, under the box where a task is started. */
.helper-chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 0; border: 0; background: none;
  font: inherit; font-size: 12.5px; line-height: 1.6;
  color: var(--ink-faint);
}
.helper-chip .dot {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--ok, #3f9d6b); flex: none;
}
.helper-chip[data-state="offline"] { color: var(--ink-soft); cursor: pointer; }
.helper-chip[data-state="offline"] .dot { background: var(--warn, #d9a13b); }
.helper-chip[data-state="offline"]:hover { color: var(--ink); text-decoration: underline; }
/* Our own server did not answer. Not the same thing as their computer being
   offline, and it must not look like a failure of theirs. */
.helper-chip[data-state="unknown"] { color: var(--ink-faint); }
.helper-chip[data-state="unknown"] .dot { background: var(--line-strong, #b9b3aa); }

/* A reply restored from the customer's own computer. Same typography as a live
   reply, because from the reader's side it is the same thing. */
.bot-text {
  font-size: 14.5px; line-height: 1.75; color: var(--ink);
  white-space: pre-wrap; word-break: break-word;
}

/* The conversation currently on screen. Quiet, not a selection highlight: this is a
   location marker, and a louder treatment would compete with the reply bubble. */
.recent-item.active {
  color: var(--ink);
  background: color-mix(in srgb, var(--accent) 10%, transparent);
}

/* --------------- file drop --------------- */
.composer { position: relative; }

/*
 * A full-composer veil rather than a highlighted border. A border says this area is
 * different; the veil says the whole thing accepts this. Non-interactive so it never
 * steals the drop event it is describing.
 */
.drop-veil {
  position: absolute; inset: -6px; z-index: 5; pointer-events: none;
  display: flex; align-items: center; justify-content: center;
  border: 2px dashed color-mix(in srgb, var(--accent) 60%, transparent);
  border-radius: 16px;
  background: color-mix(in srgb, var(--accent) 8%, var(--surface, #fff));
  backdrop-filter: blur(1px);
}
.drop-veil-inner {
  display: flex; align-items: center; gap: 8px;
  font-size: 13.5px; color: var(--accent); font-weight: 600;
}
.drop-veil-inner svg { width: 20px; height: 20px; }

.attach-list {
  display: flex; flex-wrap: wrap; gap: 6px; padding: 0 2px 8px;
}
.attach-chip {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 4px 3px 9px; border-radius: 8px;
  background: color-mix(in srgb, var(--ink) 6%, transparent);
  font-size: 12.5px; max-width: 240px;
}
.attach-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.attach-x {
  border: 0; background: none; cursor: pointer; color: var(--ink-faint);
  font-size: 15px; line-height: 1; padding: 0 3px;
}
.attach-x:hover { color: var(--ink); }

/* A quiet button under the composer: it answers a question the customer asks once, and
   should not compete with the thing they came to do. */
.folder-btn {
  display: inline-flex; align-items: center; gap: 6px;
  margin: 0 0 8px; padding: 5px 10px;
  border: 1px solid color-mix(in srgb, var(--ink) 12%, transparent);
  border-radius: 8px; background: none; cursor: pointer;
  font-size: 12.5px; color: var(--ink-soft, #666);
}
.folder-btn:hover { border-color: color-mix(in srgb, var(--accent) 50%, transparent); color: var(--accent); }
.folder-btn svg { width: 15px; height: 15px; }

/* 主动反馈：常驻入口 + 弹窗。不放在失败卡片里，因为要收集的是「我们没意识到的」问题。 */
.sidebar-report {
  margin: 10px 12px 4px; padding: 9px 12px; width: calc(100% - 24px);
  border-radius: 10px; border: 1px dashed var(--line); background: transparent;
  color: var(--muted); font: inherit; font-size: 12.5px; cursor: pointer; text-align: left;
}
.sidebar-report:hover { color: var(--ink); border-color: var(--muted); }

.report-modal {
  position: fixed; inset: 0; z-index: 90; display: grid; place-items: center;
  background: rgba(20, 16, 14, .38); backdrop-filter: blur(2px);
}
.report-modal[hidden] { display: none; }
.report-card {
  width: min(460px, calc(100vw - 32px)); background: var(--bg, #fff);
  border: 1px solid var(--line); border-radius: 16px; padding: 22px 22px 16px;
  box-shadow: 0 24px 60px rgba(0, 0, 0, .18);
}
.report-card h2 { margin: 0 0 6px; font-size: 18px; }
.report-sub { margin: 0 0 12px; font-size: 13px; color: var(--muted); }
.report-card textarea {
  width: 100%; box-sizing: border-box; border: 1px solid var(--line); border-radius: 10px;
  padding: 10px 12px; font: inherit; font-size: 14px; resize: vertical; background: transparent;
  color: var(--ink);
}
.report-shot { display: inline-block; margin: 10px 0 2px; font-size: 13px; color: var(--muted); cursor: pointer; }
.report-shot:hover { color: var(--ink); }
.report-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 14px; }
.report-cancel {
  padding: 8px 14px; border-radius: 9px; border: 1px solid var(--line);
  background: transparent; color: var(--muted); font: inherit; font-size: 13.5px; cursor: pointer;
}
.report-send {
  padding: 8px 16px; border-radius: 9px; border: 1px solid var(--accent);
  background: var(--accent); color: #fff; font: inherit; font-size: 13.5px; cursor: pointer;
}
.report-send:disabled { opacity: .6; cursor: default; }
.report-state { margin: 10px 0 0; font-size: 13px; color: var(--muted); min-height: 18px; }

/* 额度不够那一刻：给数字和一步到位的入口，不是一行红字。 */
.quota-card {
  margin-top: 10px; border: 1px solid var(--line); border-radius: 14px;
  padding: 16px 18px; background: var(--panel, #fff);
}
.quota-title { margin: 0 0 10px; font-size: 15px; }
.quota-rows { display: grid; gap: 6px; margin-bottom: 10px; }
.quota-row { display: flex; justify-content: space-between; font-size: 14px; }
.quota-k { color: var(--muted); }
.quota-v { font-variant-numeric: tabular-nums; }
.quota-hint { margin: 0 0 12px; font-size: 13px; color: var(--muted); }

/* 上次聊到哪：一条窄条，只在有历史时出现。 */
.recent-strip {
  display: flex; align-items: center; gap: 8px; margin: 0 0 8px;
  padding: 8px 10px; border: 1px solid var(--line); border-radius: 10px;
  background: var(--panel, #fff); font-size: 13px;
}
.recent-label { color: var(--muted); white-space: nowrap; }
.recent-item {
  flex: 1; min-width: 0; text-align: left; background: none; border: 0; padding: 0;
  font: inherit; color: var(--ink); cursor: pointer; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap;
}
.recent-item:hover { color: var(--accent); }
.recent-close {
  border: 0; background: none; color: var(--muted); font-size: 15px; cursor: pointer;
  padding: 0 4px; line-height: 1;
}

/* 充值页转化：推荐档角标 + 常见问题。 */
.topup-badge {
  position: absolute; top: -9px; left: 12px; padding: 2px 8px; border-radius: 999px;
  background: var(--accent); color: #fff; font-size: 11px; letter-spacing: .5px;
}
.topup-card { position: relative; }
.faq { display: grid; gap: 8px; margin: 0 0 26px; }
.faq-row {
  border: 1px solid var(--line); border-radius: 10px; padding: 10px 14px;
  background: var(--panel, #fff);
}
.faq-row summary { cursor: pointer; font-size: 14px; }
.faq-row p { margin: 8px 0 0; font-size: 13.5px; color: var(--muted); }

/* 搜历史（批 5）—— 默认收着，点一下才展开。 */
.hist-search { margin: 0 0 10px; }
.hist-toggle {
  background: none; border: 0; color: var(--muted, #8a8a8a);
  font-size: 13px; cursor: pointer; padding: 2px 0; text-decoration: underline;
}
.hist-toggle:hover { color: var(--fg, #ddd); }
.hist-panel { margin-top: 8px; }
.hist-input {
  width: 100%; box-sizing: border-box; padding: 9px 12px; border-radius: 10px;
  border: 1px solid var(--line, #333); background: var(--panel, #141414);
  color: inherit; font-size: 14px;
}
.hist-input:focus { outline: none; border-color: var(--accent, #5b8cff); }
.hist-results { margin-top: 8px; display: grid; gap: 6px; }
.hist-hit {
  text-align: left; padding: 8px 10px; border-radius: 10px; cursor: pointer;
  border: 1px solid var(--line, #333); background: var(--panel, #141414);
  font-size: 13px; line-height: 1.5; color: inherit;
}
.hist-hit:hover { border-color: var(--accent, #5b8cff); }
.hist-empty { color: var(--muted, #8a8a8a); font-size: 13px; padding: 6px 2px; }

/* 恢复聊天记录（运营 10-18 要求做得像样）
   10-20 修：这里原来用了 `var(--panel, #141414)`，但主题里根本没有 --panel，
   于是浅色界面里弹出一块近黑面板，文字又是深色 —— 用户看到的就是「黑框、点不动」。
   全部改成主题变量，不要再用暗色兜底。 */
.hist-search { margin: 0 0 12px; }
.hist-toggle {
  display: inline-flex; align-items: center; gap: 6px;
  background: none; border: 0; padding: 4px 0; cursor: pointer;
  color: var(--ink-muted); font-size: 13.5px; letter-spacing: 0.2px;
  transition: color 0.15s ease;
}
.hist-toggle:hover { color: var(--ink); }
.hist-toggle-icon { font-size: 15px; line-height: 1; }
.hist-panel {
  margin-top: 10px; padding: 12px; border-radius: 14px;
  border: 1px solid var(--line); background: var(--bg-raised);
  box-shadow: var(--shadow);
}
.hist-input {
  width: 100%; box-sizing: border-box; padding: 10px 13px; border-radius: 11px;
  border: 1px solid var(--line-strong); background: var(--bg);
  color: var(--ink); font-size: 14px;
}
.hist-input::placeholder { color: var(--ink-faint); }
.hist-input:focus { outline: none; border-color: var(--accent); }
.hist-list, .hist-results {
  margin-top: 10px; display: grid; gap: 6px;
  max-height: 320px; overflow-y: auto;
}
.hist-thread, .hist-hit {
  display: flex; flex-direction: column; gap: 3px;
  width: 100%; text-align: left; cursor: pointer;
  padding: 10px 12px; border-radius: 11px; font-size: 13.5px; line-height: 1.45;
  border: 1px solid var(--line); background: var(--bg); color: var(--ink);
  transition: border-color 0.15s ease, background 0.15s ease, transform 0.08s ease;
}
.hist-thread:hover, .hist-hit:hover {
  border-color: var(--accent); background: var(--accent-wash);
}
.hist-thread:active, .hist-hit:active { transform: scale(0.995); }
.hist-thread-title { font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.hist-thread-meta { color: var(--ink-muted); font-size: 12px; }
.hist-empty { color: var(--ink-muted); font-size: 13px; padding: 8px 2px; }
.hist-restored {
  margin: 10px 0 4px; padding: 8px 12px; border-radius: 10px;
  background: var(--accent-wash); color: var(--accent-deep); font-size: 12.5px;
}


    .tier-note {
      font-size: 12.5px; line-height: 1.6; color: var(--ink-faint);
      margin: 6px 0 10px; max-width: 640px;
    }
    .tier-note br { display: none; }

/* ===== Claude 风格覆盖（运营 10-19）===== */
:root {
  --paper: #faf9f5;
  --paper-2: #f5f2ea;
  --line: #e7e2d6;
  --ink-strong: #1f1e1d;
  --ink-soft: #6b6a67;
}

body {
  background: var(--paper);
  color: var(--ink-strong);
  -webkit-font-smoothing: antialiased;
}

/* 输入区：一整块圆角卡片 */
.composer {
  background: #fffdf9;
  border: 1px solid var(--line);
  border-radius: 18px;
  box-shadow: 0 1px 2px rgba(31, 30, 29, 0.04), 0 8px 24px rgba(31, 30, 29, 0.04);
  padding: 14px 16px 10px;
}

.composer textarea {
  font-size: 15.5px;
  line-height: 1.65;
  resize: none;
  background: transparent;
  border: 0;
  outline: none;
}

.composer textarea::placeholder { color: #a8a49b; }

.composer-bar { margin-top: 8px; }

/* 发送按钮：圆形、暖色、不要巨块 */
.composer .send {
  width: 34px;
  height: 34px;
  border-radius: 10px;
  background: var(--accent, #d97757);
  color: #fff;
  border: 0;
}
.composer .send:disabled { opacity: 0.35; }

/* 模式切换：像分段控件 */
.mode-bar { gap: 6px; }
.mode-chip {
  border-radius: 999px;
  padding: 6px 14px;
  font-size: 13.5px;
  border: 1px solid var(--line);
  background: transparent;
  color: var(--ink-soft);
}
.mode-chip.active {
  background: var(--accent, #d97757);
  border-color: var(--accent, #d97757);
  color: #fff;
}

/* 说明文字更轻 */
.tier-note {
  font-size: 12.5px;
  line-height: 1.6;
  color: var(--ink-soft);
  margin: 8px 0 4px;
}

/* 侧栏更轻，去掉重分割 */
.sidebar { background: var(--paper-2); }

/* ------------------------------------------------------------ 长任务模式 */
.long-card {
  border: 1px solid var(--line, #e6e2da);
  border-radius: 14px;
  padding: 16px 18px;
  margin: 10px 0;
  background: var(--paper, #fff);
  color: #2f2c27;
}
/* The card is always paper-white, even in the dark shell. Inheriting the
   shell's light ink made the plan invisible on white. */
.long-card .long-title,
.long-card .long-step .ls-text,
.long-card .long-fact .lf-v { color: #2f2c27; }
.long-card .long-kicker,
.long-card .long-steps-title,
.long-card .long-step .ls-out,
.long-card .long-fact .lf-k { color: #6f6a61; }
.long-card .long-step.skipped .ls-text,
.long-card .long-step.failed .ls-text { color: #b4533a; }
.long-card .long-secondary { color: #2f2c27; }
.long-kicker {
  font-size: 12px;
  letter-spacing: 0.08em;
  color: var(--ink-soft, #8a857c);
  margin-bottom: 6px;
}
.long-title {
  font-size: 18px;
  line-height: 1.4;
  margin: 2px 0 12px;
}
.long-steps {
  margin: 10px 0 12px;
  padding: 12px 14px;
  border-radius: 12px;
  background: var(--paper-2, #f7f5f1);
}
.long-steps-title {
  font-size: 12.5px;
  color: var(--ink-soft, #8a857c);
  margin-bottom: 6px;
}
.long-steplist {
  list-style: none;
  margin: 0;
  padding: 0;
}
.long-step {
  display: flex;
  align-items: baseline;
  gap: 8px;
  padding: 5px 0;
  font-size: 14px;
  line-height: 1.5;
}
.long-step .ls-icon { width: 18px; flex: 0 0 18px; }
.long-step .ls-text { flex: 1 1 auto; }
.long-step .ls-out {
  color: var(--ink-soft, #8a857c);
  font-size: 12.5px;
  max-width: 46%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.long-step .ls-err {
  color: #b4533a;
  font-size: 12.5px;
  width: 100%;
  padding-left: 26px;
}
.long-step.done .ls-text { color: var(--ink, #2f2c27); }
.long-step.running .ls-text { font-weight: 600; }
.long-step.skipped .ls-text,
.long-step.failed .ls-text { color: #b4533a; }
.long-facts { margin: 6px 0 12px; }
.long-fact {
  display: flex;
  gap: 10px;
  padding: 3px 0;
  font-size: 14px;
  line-height: 1.6;
}
.long-fact .lf-k { color: var(--ink-soft, #8a857c); flex: 0 0 88px; }
.long-fact .lf-v { flex: 1 1 auto; }
.long-actions { display: flex; gap: 10px; flex-wrap: wrap; margin-top: 12px; }
.long-primary,
.long-secondary {
  border-radius: 999px;
  padding: 9px 18px;
  font-size: 14px;
  border: 1px solid var(--line, #e6e2da);
  cursor: pointer;
}
.long-primary {
  background: var(--accent, #d97757);
  border-color: var(--accent, #d97757);
  color: #fff;
}
.long-primary:disabled { opacity: 0.5; cursor: default; }
.long-secondary { background: transparent; color: var(--ink, #2f2c27); }
.long-edit { display: flex; gap: 8px; margin-top: 10px; }
.long-edit input {
  flex: 1 1 auto;
  min-width: 0;
  border: 1px solid var(--line, #e6e2da);
  border-radius: 10px;
  padding: 8px 12px;
  font-size: 14px;
  background: var(--paper, #fff);
}

/* 每步确认（LangGraph interrupt） */
.long-confirm-opt {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-top: 10px;
  font-size: 13px;
  color: var(--ink-soft, #8a857c);
  cursor: pointer;
}
.long-confirm-opt input { width: 15px; height: 15px; }
.long-confirm {
  margin: 10px 0;
  padding: 12px 14px;
  border: 1px solid var(--accent, #d97757);
  border-radius: 12px;
  background: var(--paper-2, #f7f5f1);
}
.long-confirm .lc-q { font-size: 14px; font-weight: 600; }
.long-confirm .lc-next { margin-top: 4px; font-size: 13px; color: var(--ink-soft, #8a857c); }

/* 每步成品：能在步骤行里直接打开 */
.ls-open {
  border: 1px solid var(--line, #e6e2da);
  background: var(--paper, #fff);
  color: var(--ink, #2f2c27);
  border-radius: 999px;
  padding: 2px 10px;
  font-size: 12px;
  cursor: pointer;
  flex: 0 0 auto;
}
.lc-files {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
  margin-top: 8px;
}
