/* ============================================================
   LLM API 前端整改 · 共享设计层 app.css
   暖调编辑式轻奢 — 配合 Tailwind CDN + tokens 注入使用。
   来源:样板 /root/tmp/llmapi-redesign/app.css(2026-06-07 落地,需求见 docs/前端UI整改-需求.md)。
   字体改为自托管(专题0):英文 @import /static/fonts.css;中文走系统宋/黑兜底(见下 --serif/--sans 变量链)。
   ============================================================ */
@import url('/static/fonts.css');

:root{
  --clay:#D97757; --clay-deep:#C2603C; --clay-soft:#E59C7E; --wash:#FBEDE3;
  --canvas:#FAF7F2; --surface:#FFFFFF; --surface-2:#FBF8F4; --well:#F4EFE8;
  --border:#ECE7DF; --hair:rgba(42,35,32,0.06);
  --ink:#1F1F1F; --ink-soft:#4A4642; --muted:#8A857C; --faint:#B5AFA6;
  --espresso:#2A2320; --espresso-ink:#ECE3DB; --espresso-label:#9A8E84; --espresso-sub:#B8ADA3;
  --c-confirmed:#3E6B4E; --c-confirmed-bg:#E8F0E8;
  --c-pending:#A06A1E;   --c-pending-bg:#FBF1DF;
  --c-blocked:#B5544A;   --c-blocked-bg:#F8E9E6;
  --viz-confirmed:#6F9A7B; --viz-pending:#D9A45E;
  /* 字体组合:英文自托管(Fraunces 衬线 / Plus Jakarta Sans 无衬线 / JetBrains Mono 等宽);
     中文不自托管,标题走系统宋体(Songti SC 等),正文走系统黑体(PingFang SC 等)。
     'Noto Serif SC'/'Noto Sans SC' 保留在链中作占位:若未加载则浏览器自动跳过,
     落到后面的系统中文字体;将来若要自托管思源宋/黑,补 @font-face 即生效。 */
  /* 每款英文字体后紧跟 '* Fallback'(占位尺寸对齐的系统字体,见 fonts.css):
     消除"系统字体→英文字体"替换时的布局抖动(CLS)。中文仍走后面的系统宋/黑。 */
  --serif:'Fraunces','Fraunces Fallback','Noto Serif SC',Georgia,'Songti SC',serif;
  --sans:'Plus Jakarta Sans','Plus Jakarta Sans Fallback','Noto Sans SC','PingFang SC','Hiragino Sans GB',system-ui,sans-serif;
  --mono:'JetBrains Mono','JetBrains Mono Fallback','SF Mono',ui-monospace,monospace;
  --ease:cubic-bezier(0.16,1,0.3,1);
}

/* ---- base ---- */
/* 统一外壳行为:永远为竖向滚动条预留槽位,避免短页(无滚动条)↔长页(有滚动条)
   切换时可用宽度变化导致居中内容左右"跳动"。一处定义,全站生效。 */
html{
  scrollbar-gutter:stable;          /* 现代浏览器:恒定预留槽位(叠加式滚动条系统自动 0 宽,不会误留白) */
}
@supports not (scrollbar-gutter:stable){
  html{ overflow-y:scroll; }        /* 兜底(旧版 Safari 等):滚动条轨道始终可见,宽度恒定 */
}
/* 整页换肤(底色+基础字体)收敛到 .redesign 类:只有改造过、在 <body> 挂了 class="redesign"
   的页面才套用,未改造页面零影响(渐进式铺开,见 docs/前端UI整改-需求.md §6 批次)。
   组件类(.card / .btn-clay / .badge 等)不受此限,全局可用,在哪用在哪生效。 */
body.redesign{
  font-family:var(--sans);
  background:var(--canvas); color:var(--ink-soft);
  -webkit-font-smoothing:antialiased; text-rendering:optimizeLegibility; letter-spacing:-0.003em;
}
body.redesign ::selection{background:var(--wash);color:var(--clay-deep)}

/* ---- editorial display type ---- */
.font-display{font-family:var(--serif);font-weight:500;letter-spacing:-0.03em;line-height:1.05}
.font-serif-it{font-family:var(--serif);font-style:italic;font-weight:400}
.num{font-variant-numeric:tabular-nums}
.mono{font-family:var(--mono)}
.label-mono{font-family:var(--mono);text-transform:uppercase;letter-spacing:0.1em;font-size:11px;color:var(--faint)}

/* ---- surfaces / cards ---- */
.card{background:var(--surface);border:1px solid var(--border);border-radius:14px;transition:box-shadow .25s var(--ease),border-color .25s var(--ease)}
.card:hover{box-shadow:0 2px 10px rgba(42,35,32,.05)}
.card-2{background:var(--surface-2);border:1px solid var(--border);border-radius:12px}
.well{background:var(--well);border:1px solid var(--border);border-radius:11px}

/* dark-luxury surface (one per page) */
.card-dark{position:relative;overflow:hidden;background:var(--espresso);border:1px solid #221C19;border-radius:16px;color:var(--espresso-ink)}
.card-dark::after{content:"";position:absolute;top:-30%;right:-15%;width:55%;height:80%;background:radial-gradient(circle,rgba(217,119,87,.18),transparent 65%);pointer-events:none}
.card-dark .label-mono{color:var(--espresso-label)}

/* ---- buttons ---- */
.btn-clay{display:inline-flex;align-items:center;justify-content:center;gap:8px;font-weight:550;letter-spacing:-0.01em;border:0;cursor:pointer;border-radius:9px;padding:12px 24px;background:var(--clay);color:#fff;transition:background .18s var(--ease),transform .12s var(--ease),box-shadow .2s var(--ease)}
.btn-clay:hover{background:var(--clay-deep);box-shadow:0 6px 18px rgba(217,119,87,.25)}
.btn-clay:active{transform:scale(.98)}
.btn-ghost{display:inline-flex;align-items:center;justify-content:center;gap:8px;font-weight:550;border:1px solid var(--border);background:var(--surface);color:var(--ink);border-radius:9px;padding:12px 24px;transition:border-color .18s var(--ease),box-shadow .2s var(--ease)}
.btn-ghost:hover{border-color:#DAD3C8;box-shadow:0 2px 10px rgba(42,35,32,.05)}
.btn-dark{display:inline-flex;align-items:center;justify-content:center;gap:8px;font-weight:550;border:0;cursor:pointer;border-radius:9px;padding:12px 24px;background:var(--ink);color:#fff;transition:background .18s var(--ease)}
.btn-dark:hover{background:#34302b}

/* ---- form controls ---- */
.field{width:100%;background:var(--surface);border:1px solid var(--border);border-radius:9px;padding:11px 14px;font-size:14.5px;color:var(--ink);transition:border-color .15s var(--ease),box-shadow .15s var(--ease)}
.field::placeholder{color:var(--faint)}
.field:focus{outline:none;border-color:var(--clay);box-shadow:0 0 0 3px rgba(217,119,87,.12)}
.field-label{display:block;font-size:12.5px;color:var(--muted);margin-bottom:7px;font-weight:500}

/* ---- pills / badges ---- */
.pill{display:inline-flex;align-items:center;gap:6px;font-size:11px;font-family:var(--mono);letter-spacing:0.04em;padding:3px 10px;border-radius:9999px;background:var(--wash);color:var(--clay-deep)}
.badge{display:inline-flex;align-items:center;gap:6px;font-size:12px;padding:3px 10px;border-radius:9999px;font-weight:500}
.badge::before{content:"";width:6px;height:6px;border-radius:50%}
.badge-ok{background:var(--c-confirmed-bg);color:var(--c-confirmed)} .badge-ok::before{background:var(--c-confirmed)}
.badge-pending{background:var(--c-pending-bg);color:var(--c-pending)} .badge-pending::before{background:var(--c-pending)}
.badge-blocked{background:var(--c-blocked-bg);color:var(--c-blocked)} .badge-blocked::before{background:var(--c-blocked)}
.badge-clay{background:var(--wash);color:var(--clay-deep)} .badge-clay::before{background:var(--clay)}

/* ---- copy tile ---- */
.copy-tile{display:flex;align-items:center;gap:10px;width:100%;padding:11px 13px;background:var(--surface-2);border:1px solid var(--border);border-radius:9px;cursor:pointer;text-align:left;transition:border-color .15s var(--ease),background .15s var(--ease)}
.copy-tile:hover{border-color:var(--clay);background:#fff}
.copy-tile code{flex:1;min-width:0;font-family:var(--mono);font-size:13.5px;color:var(--ink);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.copy-tile .ico{color:var(--faint);flex:none}
.copy-tile:hover .ico{color:var(--clay)}

/* ---- ticket coupon ---- */
.ticket{position:relative;display:flex;align-items:center;gap:12px;border:1px solid var(--border);border-radius:11px;background:var(--surface-2);padding:18px 18px 18px 22px;overflow:hidden;transition:box-shadow .2s var(--ease),border-color .2s var(--ease),opacity .3s}
.ticket:hover{border-color:#E7D2C6;box-shadow:0 2px 12px rgba(217,119,87,.08)}
.ticket::before{content:"";position:absolute;left:0;top:0;bottom:0;width:3px;background:var(--clay)}
.ticket .perf{position:absolute;top:0;bottom:0;right:118px;border-left:1px dashed var(--border)}
.ticket .perf::before,.ticket .perf::after{content:"";position:absolute;left:-6px;width:12px;height:12px;border-radius:50%;background:var(--surface);border:1px solid var(--border)}
.ticket .perf::before{top:-6px} .ticket .perf::after{bottom:-6px}
.ticket .amt{font-family:var(--serif);font-size:28px;line-height:1;color:var(--clay);font-weight:500;font-variant-numeric:tabular-nums}
.ticket.expiring-soon{border-color:#E6B4AA;background:#FBEFEC} .ticket.expiring-soon::before{background:var(--c-blocked)}
.ticket.expired{opacity:.5;filter:grayscale(.55)} .ticket.expired::before{background:var(--faint)}

/* ---- table ---- */
.tbl{width:100%;border-collapse:collapse}
.tbl th{text-align:left;font-family:var(--mono);font-size:11px;text-transform:uppercase;letter-spacing:0.08em;color:var(--faint);font-weight:500;padding:0 12px 12px 0;border-bottom:1px solid var(--border)}
.tbl td{padding:13px 12px 13px 0;border-bottom:1px solid var(--border);font-size:14px;color:var(--ink-soft)}
.tbl tbody tr:last-child td{border-bottom:0}
.tbl tbody tr{transition:background .15s var(--ease)}
.tbl tbody tr:hover td{background:var(--surface-2)}

/* ---- nav / footer chrome ---- */
.nav{position:sticky;top:0;z-index:50;background:rgba(250,247,242,.72);backdrop-filter:saturate(180%) blur(14px);-webkit-backdrop-filter:saturate(180%) blur(14px);border-bottom:1px solid var(--hair)}
.nav-link{font-size:14.5px;color:var(--muted);text-decoration:none;transition:color .15s var(--ease)}
.nav-link:hover{color:var(--ink)}
.nav-link.active{color:var(--ink)}
.brand{display:flex;align-items:center;gap:9px;font-weight:600;font-size:18px;color:var(--ink);letter-spacing:-0.02em;text-decoration:none}
.brand .mark{width:30px;height:30px;border:1px solid var(--border);border-radius:8px;display:grid;place-items:center;background:var(--surface);color:var(--clay)}

/* ---- ambient warm glow (decorative) ---- */
.ambient{position:fixed;inset:0;z-index:0;pointer-events:none;overflow:hidden}
.ambient::before{content:"";position:absolute;top:-15%;left:60%;width:46vw;height:46vw;background:radial-gradient(circle,rgba(217,119,87,.06),transparent 62%);border-radius:50%}

/* ---- scroll reveal ---- */
.reveal{opacity:0;transform:translateY(14px)}
.reveal.in{opacity:1;transform:none;transition:opacity .6s var(--ease),transform .6s var(--ease)}

/* sidebar (dashboard / admin) */
.side-link{display:flex;align-items:center;gap:11px;padding:10px 13px;border-radius:9px;color:var(--muted);text-decoration:none;font-size:14.5px;position:relative;transition:background .15s var(--ease),color .15s var(--ease)}
.side-link svg{width:18px;height:18px;flex:none}
.side-link:hover{background:var(--surface-2);color:var(--ink)}
.side-link.active{background:var(--wash);color:var(--clay-deep);font-weight:550}
.side-link.active::before{content:"";position:absolute;left:0;top:9px;bottom:9px;width:3px;border-radius:3px;background:var(--clay)}
