/* pwa-toolbox shared design tokens + common components.
   Boundary: shared static assets only — each tool keeps its own state
   (localStorage), data files, and service worker. See shared/README.md.
   Tool-specific styles live in each tool's inline <style>, which loads
   after this file and may extend/override it. */

/* ════════════════════════════════════════════════════════════════════════
   3-tier token system (primitive → semantic → component). 师承: shadcn/ui
   语义命名 · Radix 步阶思路 · Material/Carbon 高度梯 · W3C DTCG 分层.
   组件只引语义名 (Tier 2);语义名从原始色阶 (Tier 1) 派生 —— 不硬编码.
   旧名 (--bg/--panel/--text/...) 作 legacy alias 保留 → 现役工具零改动仍可用.
   本次为纯结构重构: 每个旧名解析到与从前完全相同的 hex (value-preserving).
   ════════════════════════════════════════════════════════════════════════ */
:root {
  /* ── Tier 1 · primitives — 裸色阶, 有意义的名字都不直接用它 (低=底 高=字) ── */
  /* 冷中性 slate */
  --slate-1:#0b0d12; --slate-2:#11151c; --slate-3:#222a36; --slate-4:#2a3445;
  --slate-7:#5b6675; --slate-9:#8b98a9; --slate-12:#e6edf3;
  /* 暖中性 espresso */
  --esp-1:#160f08; --esp-2:#181009; --esp-3:#211812; --esp-4:#3c3022;
  --esp-5:#473726; --esp-7:#7a6e58; --esp-9:#b6a489; --esp-12:#f1e7d8;
  /* 功能 hue */
  --green-cool:#56d364; --green-warm:#4ad888; --amber:#c98a3c;
  --gold:#e3b341; --blue:#1f6feb;

  /* ── Tier 1 · light primitives — 仅 [data-mode="light"] 启用, 深色态不引用(纯增量) ──
     Plan B (2026-06-16): light mode = 统一「暖纸 receipt」家族(原冷纸正面 + 奶油背面 → 合一)。
     双轴(2026-06-16,用户定 B「暖度轴」):
       **明度轴** = 输入收(card1)/ 结果浮(card2):井 #dcd6c9 < 输入卡 #e6e1d6 < 页 #eeece6 < card2;ΔL*≈8 拉开。
       **暖度轴** = card2 两面 —— 账单正 #fcf9f2(淡暖)/ 分账背 #f7eed7(浓暖):同明度档、靠暖度浓淡分面,不再压明度轴。
     paper-* = 暖纸浅端(页 / 输入 / 账单正面);cream-* = 暖纸深端(分账背面),仅深一档、同色温、共字色。
     功能色为浅底重选, 取够 AA(≥4.5:1)的深支。 */
  /* 暖纸浅端 warm paper(页 / 输入卡 / 账单正面;低 step=底, 高 step=字) */
  --paper-1:#eeece6; --paper-2:#fcf9f2; --paper-well:#dcd6c9;
  --paper-12:#2c2218; --paper-9:#6b5636; --paper-7:#8c7757;   /* muted #6b5636 在最深井 #dcd6c9 上 4.8:1, 过 AA */
  --paper-border:#e9e2d3; --paper-fold:#ece0c6;
  /* 暖纸深端 warm receipt(分账背面;B 暖度轴 = 比正面更浓暖、明度近, 共字色 = 同卡两面) */
  --cream-1:#efe7d6; --cream-2:#f7eed7; --cream-well:#ece3cc;
  --cream-12:#2c2218; --cream-9:#6b5636; --cream-7:#8c7757;
  --cream-border:#e6dcc2; --cream-fold:#ece0c6;
  /* 浅底功能色(AA on warm paper;amber #8a6314 在分账背 #f5efe3 上 4.7:1) */
  --green-light:#15803d; --amber-light:#8a6314; --blue-light:#0a66c2; --gold-light:#8a6d00;
  /* 暖纸上"被瞥见"的强例外:常规 amber-light 落在暖棕字阶里跳不出,推红一档(#a8480a
     在账单正面 #fcf9f2 上 5.5:1, 过 AA)。仅用于负小费这类需被意识到的异常标记。 */
  --amber-strong-light:#a8480a;

  /* ── Tier 2 · semantic roles (shadcn 命名) — 默认 = 冷(页面/正面/全局) ── */
  --background:var(--slate-1);          /* 整体背景 page */
  --card:var(--slate-2);                /* 卡片背景 */
  --well:var(--slate-1);                /* 内嵌井 / input field */
  --foreground:var(--slate-12);         /* 主文字 */
  --muted-foreground:var(--slate-9);    /* 次文字 */
  --faint:var(--slate-7);               /* 三级 / 提示 */
  --border:var(--slate-3);              /* 分隔线 / 边框 */
  --money:var(--green-cool);            /* 金额 · 常量(微调) */
  --ring:var(--blue);                   /* 焦点 · 常量 */
  --warn:var(--gold);                   /* 警示 (taxback / launcher) */
  --highlight:var(--gold);              /* 装饰高亮 (shuangpin 助记字/连击🔥);信息/反馈勿用 */
  --exception:var(--amber);             /* 例外标记 (plustax 调份) */
  --exception-strong:var(--amber);      /* 需被意识到的强例外 (负小费);暗态 amber 本就跳, light 另配 */
  /* 彩色面上的前景 —— COLORS.md 此前缺这一对,于是 11 个工具各自写死了 #fff / #08110a
     (colors-lint 64 处硬命中里 25 处是这个)。刻意**不随主题变**:它跟的不是页面底色,
     是脚下那块饱和/明亮的**填充**,而那块填充本身就是常量(--ring / --money / 照片 / 暗罩)。 */
  --on-fill:#ffffff;                    /* 饱和填充上的字/图元 (--ring 按钮 · 照片 · 暗罩) */
  --on-bright:#08110a;                  /* 明亮填充上的字 (--money 绿底 · 浅色 chip) */
  --fold:var(--slate-4);                /* 折耳=本面同色系亮一档 (暖见 theme-warm) */
  --fold-crease:var(--slate-1);         /* 折痕 */

  /* ── Tier 2.5 · legacy aliases → semantic — 现役工具引旧名, 值不变, 零改动 ── */
  --bg:var(--background); --panel:var(--card); --line:var(--border);
  --text:var(--foreground); --muted:var(--muted-foreground); --accent:var(--ring);
  --accent-wash:color-mix(in srgb, var(--accent) 12%, transparent);  /* 选中态淡底,跟主题 */
  --green:var(--money);
  /* plustax 背面 + 狗耳(现役)直引暖面色, 行为不变. 同色系折耳重做见 theme-warm + step 2. */
  --surface-split:var(--esp-3); --line-split:var(--esp-4); --flip-accent:var(--amber);

  /* ── Tier 2 · layout & type tokens — density(data-density)+ 字(data-type)轴.
     默认 comfortable/system = value-preserving(等于从前硬编码值). 见 PRESETS.md §2/§4. ── */
  --font-ui: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  --font-display: var(--font-ui);            /* data-type="display" 覆写 */
  --text-base:16px; --leading:1.45; --text-h1:22px; --text-sm:14px;
  --pad-page:16px; --pad-card:18px; --radius-card:16px; --gap-card:14px; --gap-row:10px;
  /* 英雄数(每屏唯一,§2b)+ label 紧行高(label 单行 vs copy 多行,借 Geist 字阶分族) */
  --text-hero:30px; --leading-tight:1.25;
  /* 圆角阶梯(借 Geist sm/md/full;--radius-card 充当 lg,密度感知)。一视图一圆角族。 */
  --radius-sm:8px; --radius-md:12px; --radius-full:9999px;
  /* 动效(借 Geist;能不动就不动):状态 150 / 弹层 200 / 模态 300 + overshoot easing */
  --dur-fast:150ms; --dur-mid:200ms; --dur-slow:300ms; --ease-pop:cubic-bezier(.175,.885,.32,1.1);
  /* 状态叠层:--hover 半透明中性(叠在任何底上都合成正确,默认深态=白α);--scrim 模态遮罩 */
  --hover:rgba(255,255,255,.06); --scrim:rgba(0,0,0,.5);
  /* suite chrome 安全区 — ⚙ FAB(shared/tool-settings.js, position:fixed 右上)占住的角落。
     像 env(safe-area-inset-*) 但针对 chrome:页眉若有右对齐控件,用 padding-right:var(--chrome-inset-right)
     让位。单一真源 —— 改 FAB 尺寸只动这里(= 右距10 + FAB38 ≈ 加呼吸)。 */
  --chrome-inset-right:46px; --chrome-inset-top:48px;
}

/* ── density 轴(data-density)+ 字轴(data-type)— 只换布局/字, 不碰色;组件引上面 token ── */
[data-density="compact"]{ --text-base:14px; --text-h1:19px; --text-sm:13px; --text-hero:26px;
  --pad-page:12px; --pad-card:12px; --radius-card:12px; --gap-card:10px; --gap-row:8px; }
[data-density="airy"]{ --text-base:17px; --text-h1:27px; --text-sm:15px; --text-hero:36px;
  --pad-page:20px; --pad-card:24px; --radius-card:20px; --gap-card:20px; --gap-row:14px; }
[data-type="display"]{ --font-display: ui-serif, Georgia, "Times New Roman", serif; }

/* ── 暖 sub-theme — 任意元素加 [data-theme="warm"] 即进入 espresso 世界 (可复用) ──
   现役 plustax 背面仍用自身 .face.back 旧名覆盖(零改动);step 2 改挂 data-theme=warm
   + 组件切语义名后此层生效, 含同色系折耳 --fold=esp-5. 现为前向定义, 不参与渲染. */
[data-theme="warm"] {
  --background:var(--esp-1); --card:var(--esp-3); --well:var(--esp-2);
  --foreground:var(--esp-12); --muted-foreground:var(--esp-9); --faint:var(--esp-7);
  --border:var(--esp-4); --money:var(--green-warm); --exception:var(--amber);
  --ring:var(--blue); --fold:var(--esp-5); --fold-crease:var(--esp-1);
}

/* ── light mode — 纯增量, 不改任何组件; 默认深色不受影响(无 data-mode 时全走 :root) ──
   语义名重指浅色 primitives, 组件零改(仍引 --foreground/--money/...). Plan B(2026-06-16):
   light 统一暖纸 —— 浅端 paper-*(页/输入/账单正面)= [data-mode="light"];深端 cream-*
   (分账背面)= data-theme="warm" 的后代. 同色温, 靠明度阶分 elevation 与 front/back, 不再冷/暖分面.
   ⚠ 背面用「后代」组合子: plustax 的 data-mode 挂 <html>、data-theme="warm" 挂 .face.back
   (两个不同元素)→ 复合 [data-mode][data-theme] 永不匹配, 必须用空格后代. 两种写法都列, 兼容
   未来把两属性挂同一元素的工具. */
[data-mode="light"] {
  --background:var(--paper-1); --card:var(--paper-2); --well:var(--paper-well);
  --foreground:var(--paper-12); --muted-foreground:var(--paper-9); --faint:var(--paper-7);
  --border:var(--paper-border); --money:var(--green-light); --exception:var(--amber-light);
  --exception-strong:var(--amber-strong-light);
  --ring:var(--blue-light); --warn:var(--gold-light); --highlight:var(--gold-light);
  --fold:var(--paper-fold); --fold-crease:#fffdf8;
  --surface-split:var(--cream-2); --line-split:var(--cream-border); --flip-accent:var(--amber-light);
  --hover:rgba(0,0,0,.05);   /* 浅纸上用黑α(深态白α不可见) */
}
[data-mode="light"][data-theme="warm"],
[data-mode="light"] [data-theme="warm"] {
  --background:var(--cream-1); --card:var(--cream-2); --well:var(--cream-well);
  --foreground:var(--cream-12); --muted-foreground:var(--cream-9); --faint:var(--cream-7);
  --border:var(--cream-border); --money:var(--green-light); --exception:var(--amber-light);
  --ring:var(--blue-light); --fold:var(--cream-fold); --fold-crease:#fffdf8;
}

/* ════ uzu theme 家族 · 打样 sub: uzu-pomo (Pomofocus 师承) ════════════════════
   光态 light 家族 base = 暖纸 + 红 accent;运行态由 [data-state] 整页换饱和底色
   (work 红 ⇄ break 靛),= Pomofocus「环境态:背景即状态指示器」(analysis.md B1)。
   对比度全过 AA(WCAG 实测, themes/uzu/analysis.md):白 on 红 5.08 / 白 on 靛 4.54 /
   墨 on 纸 14.1 / muted on 纸 5.30 / 红accent on 纸 5.44。奶油在饱和底不过(4.15)→
   饱和底正文一律白,奶油只给大字。源池+原则见 shared/themes/uzu/。
   ⚠ 上线前(批量其余 4 sub 后)bump 各 linker sw.js CACHE(COLORS.md §5)。 */
:root {
  /* uzu-pomo primitives — 裸色阶, 组件不直引 */
  --up-red:#ba4949; --up-red-card:#a83c3c; --up-red-well:#9f3838; --up-red-soft:#cf6b6b;
  --up-indigo:#6470c0; --up-indigo-card:#5560a8; --up-indigo-well:#4f5aa0; --up-indigo-soft:#8089cf;
  --up-red-accent:#a83c3c;            /* 红 accent on 纸, 5.44:1 过 AA */
  --up-paper:#f2f0e6; --up-card:#ffffff; --up-well:#e8e6da; --up-fold:#ece7d6;
  --up-ink:#202124; --up-muted:#5f6368; --up-faint:#9aa0a6; --up-border:#e0ddd0;
  --up-ring:#1a73e8; --up-money:#4caf50; --up-exception:#ff994b;  /* uzu 家族常量: Material 蓝/LoopTube 绿/Memozora 橙 */
}
[data-theme="uzu-pomo"] {            /* base / 设置态 — 暖纸 light */
  --background:var(--up-paper); --card:var(--up-card); --well:var(--up-well);
  --foreground:var(--up-ink); --muted-foreground:var(--up-muted); --faint:var(--up-faint);
  --border:var(--up-border); --money:var(--up-money); --ring:var(--up-ring);
  --exception:var(--up-exception); --fold:var(--up-fold); --fold-crease:#fffdf8;
  --warn:var(--gold-light); --highlight:var(--gold-light);  /* 浅纸底金色走深支, 防塌陷 */
}
[data-theme="uzu-pomo"][data-state="work"] {   /* 运行·工作 — 整页砖红, 正文白 */
  --background:var(--up-red); --card:var(--up-red-card); --well:var(--up-red-well);
  --foreground:#ffffff; --muted-foreground:#f1d6d6; --faint:#e6b8b8;
  --border:var(--up-red-soft); --fold:var(--up-red-soft); --fold-crease:#a83c3c;
}
[data-theme="uzu-pomo"][data-state="break"] {  /* 运行·休息 — 整页靛, 正文白 */
  --background:var(--up-indigo); --card:var(--up-indigo-card); --well:var(--up-indigo-well);
  --foreground:#ffffff; --muted-foreground:#dadef5; --faint:#bcc4ee;
  --border:var(--up-indigo-soft); --fold:var(--up-indigo-soft); --fold-crease:#5560a8;
}

/* uzu-memo (Memozora 师承) — Material 蓝 + teal accent · light, 静态(无运行态).
   AA: 墨/白 16.1 · muted 6.05 · 白on蓝 4.51 · 蓝链接 4.51 · teal 4.24(大字). */
[data-theme="uzu-memo"] {
  --background:#f2f0e6; --card:#ffffff; --well:#e8eaed;
  --foreground:#202124; --muted-foreground:#5f6368; --faint:#9aa0a6;
  --border:#dadce0; --money:#4caf50; --ring:#1a73e8; --exception:#ff994b;
  --fold:#ece7d6; --fold-crease:#fffdf8;
  --warn:var(--gold-light); --highlight:var(--gold-light);  /* 浅纸底金色走深支, 防塌陷 */
  --accent-2:#0f8a7e;                 /* teal — retention 曲线/次强调, 大字 */
}

/* uzu-loop (LoopTube 师承) — 深板岩 + Material 绿 · dark.
   AA: 文字 11.1 · muted 5.30 · 绿 6.32 · 白on绿按钮 5.35 · 文字on卡 9.02. */
[data-theme="uzu-loop"] {
  --background:#2a2e41; --card:#363c54; --well:#23273a;
  --foreground:#e8eaed; --muted-foreground:#9aa3b8; --faint:#6b7390;
  --border:#44485d; --money:#5cc862; --ring:#5b8cf0; --exception:#ff994b;
  --fold:#4a5068; --fold-crease:#23273a;
  --accent-2:#4caf50;                 /* 绿填充(配深色字) */
}

/* uzu-dict (Hey Dictionary 师承) — 品牌蓝 + 深底 · dark.
   AA: 文字 14.8 · muted 6.08 · 蓝on底 5.86 · 白on蓝按钮 4.39(大字→按钮用加深 #2f63e8). */
[data-theme="uzu-dict"] {
  --background:#101c27; --card:#18283a; --well:#0c1620;
  --foreground:#e8eef5; --muted-foreground:#8a9bb0; --faint:#5d6f85;
  --border:#26384b; --money:#4caf50; --ring:#6a93f7; --exception:#ff994b;
  --fold:#2a3f56; --fold-crease:#0c1620;
  --brand:#3b6ff5; --brand-strong:#2f63e8;   /* brand 填充 / 白字按钮 */
}

/* uzu-nomad (Nomadable 师承) — teal + 警示红 + 板岩 · light.
   AA: 墨 11.7 · muted 5.48 · 白on teal按钮 4.51 · teal文字 4.51 · 白on红 5.44 · 红 5.44. */
[data-theme="uzu-nomad"] {
  --background:#f5f7f7; --card:#ffffff; --well:#eef2f2;
  --foreground:#323847; --muted-foreground:#5f6b72; --faint:#9aa5ab;
  --border:#dce3e3; --money:#15803d; --ring:#07857c; --exception:#c0392b;
  --fold:#e3eaea; --fold-crease:#ffffff;
  --warn:var(--gold-light); --highlight:var(--gold-light);  /* 浅纸底金色走深支, 防塌陷 */
  --accent-2:#26b5ac;                 /* teal 亮填充(装饰/大字) */
}

/* book (readr 师承 — standalone readr 的原生配色, C2 吸收进主题池) — 冷白书纸 +
   静蓝 accent · light, 静态. 阅读向工具(readr/ruminate/study/aidict)的本命主题.
   AA(WCAG 实测): 墨 on 纸 16.0 / on 卡 16.8 · muted 5.04/5.30 · 蓝 accent 5.04/5.30 ·
   白 on 蓝按钮 5.30 · 红 5.17 · 绿 4.77. faint=三级提示, 家族惯例不作 AA 要求. */
[data-theme="book"] {
  --background:#faf9f7; --card:#ffffff; --well:#f1efeb;
  --foreground:#1d1d1f; --muted-foreground:#6b6b70; --faint:#9a9aa0;
  --border:#e6e4e0; --money:#15803d; --ring:#3b6ea5; --exception:#c0392b;
  --fold:#efece6; --fold-crease:#ffffff;
  --warn:var(--gold-light); --highlight:var(--gold-light);  /* 浅纸底金色走深支, 防塌陷 */
}

/* book-night (readr 师承 · 深) — standalone readr 的原生深色: 暖灰墨底 + 亮静蓝,
   比默认冷 slate 更暖更柔, 书纸的夜面. 深底继承 :root 深色 warn/highlight, 无需防塌陷.
   AA(WCAG 实测): 墨 14.7/13.1 · muted 6.21/5.53 · 蓝 6.88 · 底字on蓝按钮 6.88 ·
   绿 9.02 · 橙 8.20. */
[data-theme="book-night"] {
  --background:#1a1a1c; --card:#242427; --well:#141416;
  --foreground:#ececef; --muted-foreground:#9a9aa0; --faint:#6f6f76;
  --border:#37373b; --money:#56d364; --ring:#6fa8dc; --exception:#ff994b;
  --fold:#2c2c30; --fold-crease:#1a1a1c;
}
* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
html, body { margin:0; background:var(--bg); color:var(--text);
  font:var(--text-base)/var(--leading) var(--font-ui); }
body { padding: max(var(--pad-page), env(safe-area-inset-top)) var(--pad-page) calc(24px + env(safe-area-inset-bottom));
  max-width:640px; margin:0 auto; }
/* full-viewport app-shell tools(自带导航/多栏, e.g. readr)声明式退出单列页框:
   <html data-layout="full">。data-no-chrome 的同族文法 —— 别再每个工具手搓 body 覆盖。 */
[data-layout="full"] body { max-width:none; padding:0; }
/* 桌面手机框(⚙「手机布局」, tool-settings.js 写 data-frame + localStorage suite-frame):
   宽屏上把工具约束到手机宽居中 —— 单列工具变窄列;data-layout="full" 工具从铺满变
   居中带侧边框的"手机"。仅宽屏生效, 真手机上开关不出现也不起作用。 */
@media (min-width: 700px) {
  [data-frame="phone"] body { max-width:430px; }
  [data-frame="phone"][data-layout="full"] body { max-width:430px; margin:0 auto; padding:0;
    border-left:1px solid var(--border); border-right:1px solid var(--border); min-height:100dvh; }
}
h1 { font-size:var(--text-h1); margin:0 0 6px; font-family:var(--font-display); }
p.sub { color:var(--muted); margin:0 0 16px; font-size:var(--text-sm); }
.card { background:var(--panel); border:1px solid var(--line); border-radius:var(--radius-card); padding:var(--pad-card); margin-bottom:var(--gap-card); }

/* no spin buttons — useless for prices */
input[type=number] { -moz-appearance:textfield; }
input[type=number]::-webkit-inner-spin-button,
input[type=number]::-webkit-outer-spin-button { -webkit-appearance:none; margin:0; }

/* dashed-underline inline editable inputs — add class="dashed" to the input;
   the [type] selector outranks the tools' full-width input rules, widths stay
   per-tool via ID rules */
input[type].dashed { padding:2px 4px; font-size:13px; text-align:right; color:var(--text);
  background:transparent; border:none; border-radius:0; border-bottom:1px dashed var(--muted); }
input[type].dashed:focus { border-bottom:1px solid var(--accent); }

/* segmented buttons */
.seg { display:flex; gap:8px; flex-wrap:wrap; }
.seg button { flex:1; min-width:44px; padding:9px 0; font-size:15px; color:var(--text);
  background:var(--bg); border:1px solid var(--line); border-radius:10px; cursor:pointer;
  font-variant-numeric:tabular-nums; }
.seg button.on { border-color:var(--accent); background:var(--accent-wash); }

/* result card — vertical bill rows */
.res { display:flex; flex-direction:column; gap:var(--gap-row); }
.res .row { display:flex; justify-content:space-between; align-items:baseline; gap:12px; }
.res .k { color:var(--muted); font-size:14px; }
.res .v { font-variant-numeric:tabular-nums; font-size:16px; text-align:right; }
.res .big .k { font-size:15px; color:var(--text); }
.res .big .v { font-size:26px; font-weight:700; color:var(--green); }
.res hr { border:0; border-top:1px solid var(--line); margin:2px 0; width:100%; }

/* home-currency conversion row */
.home { display:flex; justify-content:flex-end; align-items:center; flex-wrap:wrap; gap:6px;
  color:var(--muted); font-size:14px; }
.home .rateWrap { display:inline-flex; align-items:center; gap:4px; }
.home .rateWrap input { width:80px; padding:4px 2px; font-size:14px; text-align:right;
  color:var(--text); background:transparent; border:none; border-radius:0;
  border-bottom:1px dashed var(--muted); }
.home .rateWrap input:focus { border-bottom:1px solid var(--accent); }
.rate-note { font-size:12px; color:var(--muted); margin-top:6px; }
/* tappable refresh affordance (ToolboxUI.tapToRefresh) */
[data-refresh] { cursor:pointer; user-select:none; -webkit-user-select:none; }
[data-refresh]:active { opacity:.6; }
.linkbtn { padding:4px 9px; font-size:12px; color:var(--muted); background:none;
  border:1px solid var(--line); border-radius:8px; cursor:pointer; }
.linkbtn:hover { color:var(--text); }

footer { color:var(--muted); font-size:12px; line-height:1.7; margin-top:18px; }
footer a { color:var(--accent); text-decoration:none; }
