/* ============================================================================
 *  待办 Web · css/style.css
 *  视觉语言 1:1 复刻 exe（v2/src/ui/app.cpp 的绘制代码）：
 *    · 三种形状：Chamfer 切角矩形 / Skew 平行四边形 / Tag 箭头标签
 *    · 贴纸：每块色先画一份偏移的 ink 色同形状当硬投影
 *    · 背景：对角渐变 + 两处斜条纹带 + 半调网点
 *    · 区块用 Banner 标注，主按钮 accent→accent2 渐变 + ink 硬描边
 *
 *  尺寸全部写成 calc(N * var(--s))，var(--s) = 1px × 界面比例，
 *  对应 exe 里的 S(small, big)：小档 1，大档 4/3。
 * ==========================================================================*/

/* ------------------------------------------------------------- 字体 ----- */
/* 用 unicode-range 分开中英文字体，效果等同 exe 里按字符挑字体的 PickFont */
@font-face {
  font-family: 'DDL-Title';
  src: local('Times New Roman'), local('Times'), local('Liberation Serif');
  unicode-range: U+0000-2E7F, U+FF00-FFEF;
}
@font-face {
  font-family: 'DDL-Title';
  src: local('STZhongsong'), local('华文中宋'), local('SimSun'), local('Songti SC'), local('Noto Serif CJK SC');
  unicode-range: U+2E80-9FFF, U+3000-303F, U+F900-FAFF;
}
@font-face {
  font-family: 'DDL-Body';
  src: local('Saira'), local('Segoe UI'), local('Helvetica Neue'), local('Arial');
  unicode-range: U+0000-2E7F, U+FF00-FFEF;
}
@font-face {
  font-family: 'DDL-Body';
  src: local('DengXian'), local('等线'), local('Microsoft YaHei'), local('PingFang SC'), local('Noto Sans CJK SC');
  unicode-range: U+2E80-9FFF, U+3000-303F, U+F900-FAFF;
}

:root {
  --u: 1;                                   /* 界面比例：小 1 / 大 1.3333 */
  --s: calc(var(--u) * 1px);
  --cut: calc(26 * var(--s));               /* 面板切角 */
  --cut-sm: calc(12 * var(--s));            /* 卡片切角 */
  --titlebar: calc(58 * var(--s));
  --font-title: 'DDL-Title', 'STZhongsong', 'Times New Roman', 'SimSun', serif;
  --font-body: 'DDL-Body', 'DengXian', 'Segoe UI', system-ui, -apple-system, sans-serif;

  /* 主题色（由 js/themes.js 运行时改写） */
  --bg: #FDF2E6; --bg2: #F8E6D2; --ink: #2A1608;
  --surface: #FFFCF9; --surface-alt: #FDF6EE; --border: #E8CFAF;
  --text: #2A1608; --dim: #8C6A45;
  --accent: #D9600A; --accent2: #B91C1C; --accent3: #D9600A;
  --accent-text: #FFFFFF; --danger: #B91C1C;
  --halo: rgba(217,96,10,0.102); --stripe: rgba(0,0,0,0.063);
}

* { box-sizing: border-box; }

html, body {
  margin: 0; padding: 0;
  min-height: 100%;
  color: var(--text);
  font-family: var(--font-body);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}
/* 画布底色只给 html：body 必须透明，否则 z-index:-1 的 #bg 会被 body 背景盖住 */
html { background: var(--bg); }
body { min-height: 100vh; min-height: 100dvh; }
button { font: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer; }
input {
  font: inherit; color: inherit; background: none; border: 0; outline: 0;
  width: 100%; min-width: 0;
}
::selection { background: var(--accent); color: var(--accent-text); }

/* ================================================================ 背景 === */
#bg { position: fixed; inset: 0; z-index: -1; overflow: hidden; }
#bg .grad {
  position: absolute; inset: 0;
  background:
    radial-gradient(130% 110% at 0% 0%, var(--bg) 0%, rgba(0,0,0,0) 62%),
    radial-gradient(130% 110% at 100% 100%, var(--bg2) 0%, rgba(0,0,0,0) 62%),
    linear-gradient(135deg, var(--bg) 0%, var(--bg2) 100%);
}
#bg .glow { position: absolute; inset: 0; opacity: 0; }
html[data-dark="1"] #bg .glow {
  opacity: 1;
  background:
    radial-gradient(90% 70% at 0% 0%, var(--accent) 0%, rgba(0,0,0,0) 70%),
    radial-gradient(80% 60% at 100% 100%, var(--accent) 0%, rgba(0,0,0,0) 70%);
  mix-blend-mode: screen;
  opacity: .075;
}
#bg .s1 {
  position: absolute; right: 0; top: 0; width: 58%; height: 34%;
  background: repeating-linear-gradient(115deg, var(--stripe) 0 7px, rgba(0,0,0,0) 7px 26px);
}
#bg .s2 {
  position: absolute; left: 0; bottom: 0; width: 380px; height: 210px;
  background: repeating-linear-gradient(65deg, var(--stripe) 0 6px, rgba(0,0,0,0) 6px 22px);
}
#bg .dots {
  position: absolute; inset: 0;
  background-image: radial-gradient(circle, var(--halo) 0 1.1px, rgba(0,0,0,0) 1.1px);
  background-size: 11px 11px;
}

/* ========================================================== 通用形状 === */
/* .stk = 贴纸块。内部必须有一个 .shp 层（真正被裁剪 + 加投影的那层）。 */
.stk { position: relative; }
/* 注意渲染顺序：filter 先于 clip-path 生效，所以两者不能放在同一个元素上，
   否则投影和描边会被自己的 clip 切掉。这里 .shp 只负责滤镜，
   真正被裁剪的是它里面的 ::before。.shp 外扩一圈，保证投影有地方画。 */
.stk > .shp {
  position: absolute; inset: calc(-24 * var(--s));
  filter:
    drop-shadow(calc(1.4 * var(--s)) 0 0 var(--stroke))
    drop-shadow(calc(-1.4 * var(--s)) 0 0 var(--stroke))
    drop-shadow(0 calc(1.4 * var(--s)) 0 var(--stroke))
    drop-shadow(0 calc(-1.4 * var(--s)) 0 var(--stroke))
    drop-shadow(var(--ox, calc(5 * var(--s))) var(--oy, calc(6 * var(--s))) 0 var(--ink));
}
.stk > .shp::before {
  content: ''; position: absolute; inset: calc(24 * var(--s));
  clip-path: var(--clip);
  background: var(--fill);
}
.stk > .ct { position: relative; }

.chamfer { --clip: polygon(0 0, calc(100% - var(--c)) 0, 100% var(--c), 100% 100%, var(--c) 100%, 0 calc(100% - var(--c))); --c: var(--cut); }
.chamfer-sm { --clip: polygon(0 0, calc(100% - var(--c)) 0, 100% var(--c), 100% 100%, var(--c) 100%, 0 calc(100% - var(--c))); --c: var(--cut-sm); }
/* Skew：元素本身要比可见宽度多出 --sk，箭头才不会被切掉 */
.skew { --clip: polygon(var(--sk) 0, 100% 0, calc(100% - var(--sk)) 100%, 0 100%); --sk: calc(14 * var(--s)); }
/* Tag：左边直角，右上/右下内收 --cut-t，右边中点外凸 --tip */
.tag {
  --clip: polygon(0 0, calc(100% - var(--tip) - var(--cut-t)) 0, 100% 50%,
                  calc(100% - var(--tip) - var(--cut-t)) 100%, 0 100%);
  --tip: calc(10 * var(--s)); --cut-t: calc(8 * var(--s));
}

/* ========================================================== 标题栏 === */
#titlebar {
  position: relative; z-index: 30;
  height: var(--titlebar);
  background: var(--bg);
  padding: 0 calc(18 * var(--s));
  display: flex; align-items: center; gap: calc(14 * var(--s));
  animation: tbIn .5s cubic-bezier(.22,.61,.36,1) backwards;
}
@keyframes tbIn { from { transform: translateY(-100%); opacity: 0; } to { transform: none; opacity: 1; } }
#titlebar::after {
  content: ''; position: absolute; left: 0; right: 0; bottom: 0;
  height: calc(3 * var(--s)); background: var(--border);
}
#titlebar .accentline {
  position: absolute; left: 0; bottom: 0; height: calc(3 * var(--s));
  width: calc(176 * var(--s)); background: var(--accent);
}
.logo {
  width: calc(34 * var(--s)); height: calc(34 * var(--s));
  --fill: var(--text); --stroke: var(--ink);
  --ox: calc(3 * var(--s)); --oy: calc(3 * var(--s));
  flex: none;
}
.logo .sq { position: absolute; background: var(--bg); }
.appname {
  font-family: var(--font-title); font-weight: 400;
  font-size: calc(19 * var(--s)); letter-spacing: calc(2.2 * var(--s));
  white-space: nowrap;
}
.ver {
  font-family: var(--font-title); font-size: calc(11 * var(--s));
  letter-spacing: calc(1 * var(--s));
  background: var(--accent); color: var(--accent-text);
  padding: calc(3 * var(--s)) calc(8 * var(--s)) calc(3 * var(--s)) calc(6 * var(--s));
  clip-path: polygon(0 0, calc(100% - 5px) 0, 100% 50%, calc(100% - 5px) 100%, 0 100%);
  white-space: nowrap;
}
.pagename {
  font-family: var(--font-title); font-size: calc(13 * var(--s));
  letter-spacing: calc(1.6 * var(--s)); color: var(--accent);
  white-space: nowrap;
}
#titlebar .spacer { flex: 1 1 auto; min-width: calc(8 * var(--s)); overflow: hidden; }
.tbbtns { display: flex; gap: calc(10 * var(--s)); flex: none; }

/* 标题栏上的 Tag 按钮 */
.tbtn {
  font-family: var(--font-title); font-size: calc(14 * var(--s));
  letter-spacing: calc(1.4 * var(--s));
  height: calc(32 * var(--s)); padding: 0 calc(22 * var(--s)) 0 calc(12 * var(--s));
  display: inline-flex; align-items: center; justify-content: center;
  white-space: nowrap;
  --tip: calc(10 * var(--s)); --cut-t: calc(7 * var(--s));
  --ox: calc(4 * var(--s)); --oy: calc(4 * var(--s));
  --fill: var(--surface); --stroke: var(--ink);
  transition: transform .12s ease;
}
.tbtn:active { transform: scale(.96); }
.tbtn.on { --fill: var(--accent); --stroke: var(--accent); color: var(--accent-text); }
.tbtn .ct { position: relative; z-index: 1; }

/* ============================================================= 布局 === */
#stage { position: relative; overflow: hidden; }
.page {
  width: 100%;
  max-width: calc(940 * var(--s));
  margin: 0 auto;
  padding: 0 calc(26 * var(--s)) calc(26 * var(--s));
  position: relative;
}
.page.leaving { position: absolute; left: 0; right: 0; top: 0; pointer-events: none; }
#stage.sliding > .page { will-change: transform; }

/* =========================================================== 输入卡 === */
.inputcard {
  margin-top: calc(40 * var(--s));
  --c: var(--cut); --ox: calc(6 * var(--s)); --oy: calc(7 * var(--s));
  --fill: var(--surface); --stroke: var(--border);
  padding: calc(18 * var(--s));
  min-height: calc(136 * var(--s));
  position: relative;
}
.inputcard .cardstripes {
  position: absolute; right: 0; bottom: 0;
  width: calc(200 * var(--s)); height: calc(74 * var(--s));
  background: repeating-linear-gradient(115deg, var(--stripe) 0 7px, rgba(0,0,0,0) 7px 22px);
  pointer-events: none; z-index: 0;
}
.fields { position: relative; z-index: 1; display: flex; flex-direction: column; gap: calc(10 * var(--s)); }
.frow { display: flex; gap: calc(12 * var(--s)); align-items: stretch; }
.field {
  position: relative; flex: 1 1 auto; min-width: 0;
  height: calc(38 * var(--s));
  --c: calc(8 * var(--s));
  --fill: var(--surface-alt);
  --stroke: var(--border);
  --ox: 0px; --oy: 0px;
  transition: --stroke .2s;
}
.field .ct { height: 100%; display: flex; align-items: center; padding: 0 calc(14 * var(--s)); gap: calc(8 * var(--s)); }
.field.focus .shp {
  filter:
    drop-shadow(calc(1.4 * var(--s)) 0 0 var(--accent))
    drop-shadow(calc(-1.4 * var(--s)) 0 0 var(--accent))
    drop-shadow(0 calc(1.4 * var(--s)) 0 var(--accent))
    drop-shadow(0 calc(-1.4 * var(--s)) 0 var(--accent));
  transition: filter .18s;
}
.field.focus { background: transparent; }
.field input { font-size: calc(16 * var(--s)); flex: 1 1 auto; }
.field input::placeholder { color: var(--dim); opacity: .85; }
.field .tail {
  font-size: calc(13 * var(--s)); color: var(--dim);
  white-space: nowrap; flex: none;
}
.field.focus .tail { color: var(--accent); }
.field.err .tail { color: var(--danger); }
.btn-add {
  flex: none; width: calc(104 * var(--s)); height: calc(38 * var(--s));
  --tip: calc(9 * var(--s)); --cut-t: calc(9 * var(--s));
  --ox: calc(5 * var(--s)); --oy: calc(5 * var(--s));
  --fill: var(--accent); --stroke: var(--ink);
  font-family: var(--font-title); font-size: calc(16 * var(--s));
  letter-spacing: calc(2.6 * var(--s)); color: var(--accent-text);
  display: inline-flex; align-items: center; justify-content: center;
  transition: transform .12s;
}
.btn-add > .shp::before {
  background-image: linear-gradient(90deg, var(--accent), var(--accent2));
}
.btn-add.hot > .shp::before { background-image: linear-gradient(90deg, var(--accent), var(--accent3)); }
.btn-add:active { transform: scale(.96); }
.btn-add .ct { position: relative; z-index: 1; padding-right: calc(9 * var(--s)); }

/* ============================================================ Banner === */
.banner {
  position: absolute; z-index: 5;
  pointer-events: none;   /* 装饰性横幅：.shp 外扩 24px 画投影，会盖住下方输入框 */
  height: calc(46 * var(--s)); padding: 0 calc(24 * var(--s)) 0 calc(14 * var(--s));
  --sk: calc(15 * var(--s));
  --ox: calc(5 * var(--s)); --oy: calc(5 * var(--s));
  --fill: var(--surface-alt); --stroke: var(--ink);
  display: inline-flex; align-items: center; gap: calc(14 * var(--s));
  font-family: var(--font-title); font-size: calc(20 * var(--s));
  letter-spacing: calc(1.6 * var(--s)); white-space: nowrap;
}
.banner.accent { --fill: var(--accent); color: var(--accent-text); }
.banner.accent > .shp::before { background-image: linear-gradient(90deg, var(--accent), var(--accent2)); }
.banner .b-sq {
  width: calc(13 * var(--s)); height: calc(13 * var(--s)); flex: none;
  background: var(--accent); transform: skewX(-14deg);
}
.banner.accent .b-sq { background: var(--accent-text); }
.banner .b-sub {
  font-family: var(--font-body); font-size: calc(13 * var(--s));
  letter-spacing: calc(1 * var(--s)); color: var(--dim); font-weight: 400;
}
/* 主副标题基线对齐 + 间距（原为普通内联，副题会贴住主标题） */
.banner .ct { display: inline-flex; align-items: baseline; gap: calc(9 * var(--s)); }
.banner.accent .b-sub { color: var(--accent-text); opacity: .9; }

/* =========================================================== 列表面板 == */
.listpanel {
  margin-top: calc(54 * var(--s));
  --c: var(--cut); --ox: calc(6 * var(--s)); --oy: calc(7 * var(--s));
  --fill: var(--surface); --stroke: var(--border);
  padding: calc(10 * var(--s)) 0;
  position: relative;
  min-height: calc(220 * var(--s));
}
.listpanel > .shp { z-index: 0; }
.listpanel .lp-stripes {
  position: absolute; right: 0; bottom: 0;
  width: calc(200 * var(--s)); height: calc(74 * var(--s));
  background: repeating-linear-gradient(115deg, var(--stripe) 0 7px, rgba(0,0,0,0) 7px 22px);
  pointer-events: none;
}
.listpanel .lpbanner { position: absolute; left: 0; top: calc(-36 * var(--s)); z-index: 6; pointer-events: none; }
.rows { position: relative; z-index: 1; }

/* ============================================================== 行 === */
.row {
  position: relative;
  height: calc(66 * var(--s));
  --c: var(--cut-sm);
  --ox: calc(5 * var(--s)); --oy: calc(5 * var(--s));
  --fill: var(--surface); --stroke: var(--border);
  margin: 0 calc(16 * var(--s));
  transition: height .28s cubic-bezier(.22,.61,.36,1), opacity .28s, transform .28s;
  animation: rowIn .42s cubic-bezier(.22,.61,.36,1) backwards;
}
@keyframes rowIn {
  from { opacity: 0; transform: translateX(-70px); }
  to   { opacity: 1; transform: none; }
}
.row.hot { --stroke: var(--accent); }
.row.sel { --stroke: var(--accent); --fill: color-mix(in srgb, var(--surface) 87%, var(--accent)); }
.row.editing { --stroke: var(--accent2); --fill: color-mix(in srgb, var(--surface) 84%, var(--accent)); }
.row.done { --fill: var(--surface-alt); }
.row.leaving { height: 0 !important; opacity: 0; transform: translateX(210px); margin-top: 0; }
.row .rail {
  position: absolute; left: calc(1 * var(--s)); top: calc(12 * var(--s));
  width: calc(5 * var(--s)); height: calc(100% - 24 * var(--s));
  background: var(--accent); transform: skewX(-12deg);
}
.row.done .rail { background: var(--dim); }
.row .ct { height: 100%; display: flex; align-items: center; position: relative; z-index: 1; }

.cb {
  flex: none; position: relative;
  width: calc(23 * var(--s)); height: calc(23 * var(--s));
  margin-left: calc(42 * var(--s)); margin-right: calc(7 * var(--s));
  --c: calc(6 * var(--s));
  --ox: calc(2.5 * var(--s)); --oy: calc(2.5 * var(--s));
  --fill: var(--surface-alt); --stroke: var(--text);
  opacity: .85;
}
.cb .ct { height: 100%; display: grid; place-items: center; }
.cb svg { width: calc(16 * var(--s)); height: calc(16 * var(--s)); overflow: visible; }
.cb svg polyline {
  fill: none; stroke: var(--accent-text);
  stroke-width: 2.4; stroke-linecap: square; stroke-linejoin: miter;
  stroke-dasharray: 26; stroke-dashoffset: 26;
  transition: stroke-dashoffset .26s ease-out;
}
.row.done .cb { --fill: var(--accent); --stroke: var(--accent); opacity: 1; }
.row.done .cb svg polyline { stroke-dashoffset: 0; }

.row .tbox { flex: 0 1 auto; min-width: 0; position: relative; overflow: hidden; }
.row .flexsp { flex: 1 1 auto; min-width: 0; }
.row .title {
  font-family: var(--font-title); font-size: calc(18 * var(--s));
  letter-spacing: calc(.8 * var(--s));
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  transition: color .3s, opacity .3s;
}
.row.done .title { color: var(--dim); opacity: .62; }
.row .strike {
  position: absolute; left: 0; top: 50%;
  height: calc(2.2 * var(--s)); width: 0;
  background: var(--dim); opacity: 0;
  transition: width .28s ease-out, opacity .2s;
}
.row.done .strike { width: 100%; opacity: .8; }

.row .chips { flex: none; display: flex; align-items: center; gap: calc(12 * var(--s)); margin-left: calc(12 * var(--s)); }
.chip {
  display: inline-flex; align-items: center; gap: calc(7 * var(--s));
  height: calc(30 * var(--s)); padding: 0 calc(17 * var(--s));
  --tip: calc(5 * var(--s)); --cut-t: calc(5 * var(--s));
  --ox: calc(3 * var(--s)); --oy: calc(3 * var(--s));
  --fill: var(--surface-alt); --stroke: var(--border);
  font-size: calc(12 * var(--s)); letter-spacing: calc(1.2 * var(--s));
  color: var(--dim); white-space: nowrap;
}
.chip .dot { width: calc(6.8 * var(--s)); height: calc(6.8 * var(--s)); border-radius: 50%; background: currentColor; flex: none; }
.chip.sub { --fill: var(--accent2); --stroke: var(--accent2); color: #fff; }
.chip.near { --fill: var(--danger); --stroke: var(--danger); color: #fff; }
.chip.mid { --fill: var(--accent2); --stroke: var(--accent2); color: #fff; }
.chip .ct { position: relative; z-index: 1; display: inline-flex; align-items: center; gap: calc(7 * var(--s)); }

.del {
  flex: none; width: calc(29 * var(--s)); height: calc(29 * var(--s));
  margin: 0 calc(10 * var(--s)) 0 calc(12 * var(--s));
  --tip: calc(4 * var(--s)); --cut-t: calc(4 * var(--s));
  --ox: calc(3 * var(--s)); --oy: calc(3 * var(--s));
  --fill: var(--surface-alt); --stroke: var(--border);
  display: grid; place-items: center;
}
.del .ct { position: relative; z-index: 1; }
.del svg { width: calc(11 * var(--s)); height: calc(11 * var(--s)); }
.del svg line { stroke: var(--dim); stroke-width: 1.9; }
.del.hot { --fill: var(--danger); --stroke: var(--danger); }
.del.hot svg line { stroke: var(--bg); }

.empty { padding: calc(60 * var(--s)) 0; text-align: center; }
.empty .e1 { font-family: var(--font-title); font-size: calc(15 * var(--s)); letter-spacing: calc(3 * var(--s)); }
.empty .e2 { font-size: calc(12 * var(--s)); color: var(--dim); margin-top: calc(14 * var(--s)); }

/* ============================================================== 页脚 === */
.footer {
  display: flex; align-items: center; gap: calc(16 * var(--s));
  margin-top: calc(14 * var(--s));
  min-height: calc(34 * var(--s));
  font-size: calc(11 * var(--s)); letter-spacing: calc(1.2 * var(--s)); color: var(--dim);
}
.footer .grow { flex: 1 1 auto; }
.btn-back, .btn-clear {
  --tip: calc(7 * var(--s)); --cut-t: calc(7 * var(--s));
  --ox: calc(4 * var(--s)); --oy: calc(4 * var(--s));
  --fill: var(--surface); --stroke: var(--ink);
  height: calc(34 * var(--s)); padding: 0 calc(22 * var(--s)) 0 calc(14 * var(--s));
  display: inline-flex; align-items: center; gap: calc(10 * var(--s));
  font-size: calc(14 * var(--s)); letter-spacing: calc(1.6 * var(--s));
  color: var(--text);
}
.btn-back.hot, .btn-clear.hot { --fill: var(--accent); --stroke: var(--ink); color: var(--accent-text); }
.btn-back .ct, .btn-clear .ct { position: relative; z-index: 1; display: inline-flex; align-items: center; gap: calc(10 * var(--s)); }
.btn-back .arw { width: 0; height: 0; border: calc(7 * var(--s)) solid transparent; border-right-color: currentColor; }
.btn-back { padding-left: calc(16 * var(--s)); }
.btn-clear { font-size: calc(13 * var(--s)); }

/* ========================================================= 主题面板 === */
#themePanel {
  position: fixed; z-index: 60; left: 50%; transform: translateX(-50%);
  top: calc(88 * var(--s));
  width: min(calc(504 * var(--s)), calc(100vw - 24px));
  --c: var(--cut); --ox: calc(6 * var(--s)); --oy: calc(7 * var(--s));
  --fill: var(--surface); --stroke: var(--ink);
  padding: calc(14 * var(--s));
}
#themePanel[hidden] { display: none; }
#themePanel .tp-head {
  font-family: var(--font-title); font-size: calc(14 * var(--s));
  letter-spacing: calc(1.8 * var(--s)); margin: 0 0 calc(10 * var(--s)) calc(6 * var(--s));
}
.tgrid { display: grid; grid-template-columns: repeat(3, 1fr); gap: calc(10 * var(--s)); position: relative; z-index: 1; }
.tcard {
  position: relative; height: calc(64 * var(--s));
  border: 0; overflow: hidden;
  clip-path: polygon(0 0, calc(100% - 10px) 0, 100% 10px, 100% 100%, 0 100%);
  display: flex; flex-direction: column; justify-content: center;
  padding: 0 calc(11 * var(--s));
  transition: transform .14s;
}
.tcard:hover { transform: translateY(-2px); }
.tcard.cur { outline: none; }
.tcard .tn { font-family: var(--font-title); font-size: calc(14 * var(--s)); letter-spacing: calc(1.2 * var(--s)); }
.tcard .trow { display: flex; gap: calc(2 * var(--s)); margin-top: calc(6 * var(--s)); }
.tcard .trow i { width: calc(16 * var(--s)); height: calc(7 * var(--s)); display: block; }
.tcard .mark {
  position: absolute; right: calc(7 * var(--s)); top: calc(7 * var(--s));
  font-size: calc(11 * var(--s));
}

/* 换主题时的全屏扫过 */
#wipe {
  position: fixed; inset: 0; z-index: 90; pointer-events: none;
  background: linear-gradient(90deg, var(--accent), var(--accent2));
  transform: translateX(-101%);
}
#wipe.go { animation: wipeGo .5s cubic-bezier(.5,0,.3,1) both; }
@keyframes wipeGo {
  0%   { transform: translateX(-101%); }
  55%  { transform: translateX(0); }
  100% { transform: translateX(101%); }
}

/* ============================================================== Toast === */
#toast {
  position: fixed; z-index: 80; left: 50%; bottom: calc(34 * var(--s));
  transform: translate(-50%, 160%);
  --sk: calc(14 * var(--s)); --tip: 0px; --cut-t: 0px;
  --ox: calc(4 * var(--s)); --oy: calc(5 * var(--s));
  --fill: var(--surface); --stroke: var(--ink);
  padding: calc(10 * var(--s)) calc(26 * var(--s));
  font-size: calc(14 * var(--s)); letter-spacing: calc(1.4 * var(--s));
  opacity: 0; transition: transform .3s cubic-bezier(.22,.61,.36,1), opacity .3s;
  max-width: min(90vw, calc(560 * var(--s)));
  text-align: center;
}
#toast.show { transform: translate(-50%, 0); opacity: 1; }
#toast.err { --stroke: var(--danger); color: var(--danger); }

/* ============================================================== 弹窗 === */
#modal { position: fixed; inset: 0; z-index: 70; display: grid; place-items: center; background: rgba(0,0,0,.35); }
#modal[hidden] { display: none; }
#modal .mbox {
  width: min(calc(560 * var(--s)), calc(100vw - 32px));
  max-height: 84vh; overflow: auto;
  --c: var(--cut); --ox: calc(6 * var(--s)); --oy: calc(7 * var(--s));
  --fill: var(--surface); --stroke: var(--ink);
  padding: calc(20 * var(--s)) calc(22 * var(--s));
}
#modal .mtitle {
  font-family: var(--font-title); font-size: calc(16 * var(--s));
  letter-spacing: calc(1.8 * var(--s)); margin-bottom: calc(12 * var(--s));
}
#modal .mtext { font-size: calc(13 * var(--s)); line-height: 1.9; color: var(--text); }
#modal .mtext code {
  background: var(--surface-alt); padding: 1px 5px;
  font-family: Consolas, 'Courier New', monospace; font-size: .92em;
}
#modal .mbtns { display: flex; gap: calc(12 * var(--s)); justify-content: flex-end; margin-top: calc(18 * var(--s)); flex-wrap: wrap; }
.mbtn {
  height: calc(34 * var(--s)); padding: 0 calc(20 * var(--s));
  --tip: calc(7 * var(--s)); --cut-t: calc(7 * var(--s));
  --ox: calc(3 * var(--s)); --oy: calc(3 * var(--s));
  --fill: var(--surface-alt); --stroke: var(--border);
  font-size: calc(14 * var(--s)); letter-spacing: calc(1.4 * var(--s));
  display: inline-flex; align-items: center;
}
.mbtn.primary { --fill: var(--accent); --stroke: var(--ink); color: var(--accent-text); }
.mbtn.danger { --fill: var(--danger); --stroke: var(--ink); color: #fff; }
.mbtn .ct { position: relative; z-index: 1; }
#modal .mrow { display: flex; flex-direction: column; gap: calc(6 * var(--s)); margin: calc(12 * var(--s)) 0; }
#modal .mrow label { font-size: calc(12 * var(--s)); color: var(--dim); letter-spacing: calc(1 * var(--s)); }
#modal .mrow input[type=text], #modal .mrow input[type=email], #modal .mrow input[type=password] {
  height: calc(38 * var(--s)); padding: 0 calc(12 * var(--s));
  background: var(--surface-alt); color: var(--text);
  border: calc(1.4 * var(--s)) solid var(--border);
  font-size: calc(14 * var(--s));
}
#modal .mnote { font-size: calc(11.5 * var(--s)); color: var(--dim); line-height: 1.8; }

/* ============================================================== 小屏 === */
@media (max-width: 620px) {
  #titlebar { gap: calc(8 * var(--s)); padding: 0 calc(10 * var(--s)); }
  .pagename, .ver { display: none; }
  .tbbtns { gap: calc(6 * var(--s)); }
  .tbtn {
    height: calc(28 * var(--s));
    padding: 0 calc(15 * var(--s)) 0 calc(8 * var(--s));
    font-size: calc(12 * var(--s)); letter-spacing: calc(1 * var(--s));
    --tip: calc(8 * var(--s)); --cut-t: calc(6 * var(--s));
  }
  .page { padding-left: calc(12 * var(--s)); padding-right: calc(12 * var(--s)); }
  .row { margin: 0 calc(10 * var(--s)); }
  .row .title { font-size: calc(16 * var(--s)); }
  .cb { margin-left: calc(24 * var(--s)); margin-right: calc(10 * var(--s)); }
  .row .chips { gap: calc(7 * var(--s)); margin-left: calc(8 * var(--s)); }
  .chip { height: calc(27 * var(--s)); padding: 0 calc(12 * var(--s)); font-size: calc(11 * var(--s)); }
  .del { margin: 0 calc(8 * var(--s)); }
}
@media (max-width: 460px) {
  .appname { display: none; }
  .footer .hint { display: none; }
  .chip.sub { display: none; }
  .btn-clear { padding: 0 calc(16 * var(--s)) 0 calc(10 * var(--s)); font-size: calc(12 * var(--s)); }
}
@media (prefers-reduced-motion: reduce) {
  * { animation-duration: .01ms !important; transition-duration: .01ms !important; }
}

/* ############################################################################
 *  双界面主题
 *    data-ui="miku"  初音界面：切角 + 贴纸硬投影 + 斜条纹网点（上方基础样式）
 *    data-ui="ink"   水墨界面：宣纸 + 笔锋 + 印章，全部覆写在本节
 * ##########################################################################*/

/* ------------------------------------------------------------ 背景艺术层 -- */
#bg .mountains, #bg .bamboo { display: none; }

/* ===================================================== 共用小动画（追加） == */

/* 点勾时的「现场演出」：先演勾线 + 弹跳 + 划线，再真正入库重绘（见 app.js） */
.row.just-done .cb {
  --fill: var(--accent); --stroke: var(--accent); opacity: 1;
  animation: cbPop .34s cubic-bezier(.34,1.56,.64,1);
}
.row.just-done .cb svg polyline { stroke-dashoffset: 0; }
.row.just-done .title { color: var(--dim); opacity: .62; }
.row.just-done .strike { width: 100%; opacity: .8; }
@keyframes cbPop {
  0% { transform: scale(.72); }
  55% { transform: scale(1.24); }
  100% { transform: scale(1); }
}

/* 同步进行中：标题栏「同步」按钮呼吸 */
#btnSync.syncing { animation: syncPulse 1.05s ease-in-out infinite; }
@keyframes syncPulse { 50% { opacity: .42; } }

/* 主题面板 / 弹窗 进场（hidden 移除时自动重播） */
#themePanel { animation: tpIn .24s cubic-bezier(.22,.61,.36,1); }
@keyframes tpIn {
  from { opacity: 0; transform: translateX(-50%) translateY(-12px) scale(.97); }
  to   { opacity: 1; transform: translateX(-50%) translateY(0) scale(1); }
}
#modal .mbox { animation: mboxIn .26s cubic-bezier(.22,.61,.36,1); }
@keyframes mboxIn {
  from { opacity: 0; transform: translateY(16px) scale(.965); }
  to   { opacity: 1; transform: none; }
}

/* 主题面板改成两张卡片 */
.tgrid { grid-template-columns: repeat(2, 1fr); }

/* 删除按钮的 X 线条变色过渡 */
.del svg line { transition: stroke .15s; }

/* ============================================================== 初音界面 == */
/* 高弹好动：贴纸弹跳、回弹按钮、滑出时带倾斜 */
html[data-ui="miku"] .row { animation: rowInPop .46s cubic-bezier(.34,1.4,.64,1) backwards; }
@keyframes rowInPop {
  from { opacity: 0; transform: translateX(-64px) scale(.97); }
  62%  { opacity: 1; transform: translateX(5px) scale(1.004); }
  to   { opacity: 1; transform: none; }
}
html[data-ui="miku"] .row.leaving { transform: translateX(230px) skewX(-8deg); }
/* 悬停不要再 translate 整行：位移会改变命中区域，指针在行边缘时 enter/leave 死循环 = 抽搐。
   改成只换描边/底色（.row.hot 基规则已带 --stroke: accent），视觉位移交给入场动画。 */
html[data-ui="miku"] .row.hot { --fill: color-mix(in srgb, var(--surface) 93%, var(--accent)); }
html[data-ui="miku"] .row.just-done .cb { animation: cbPopMiku .4s cubic-bezier(.34,1.56,.64,1); }
@keyframes cbPopMiku {
  0% { transform: scale(.5) rotate(-10deg); }
  60% { transform: scale(1.32) rotate(2deg); }
  100% { transform: scale(1); }
}
html[data-ui="miku"] .btn-add:active { transform: scale(.9) rotate(-1.2deg); }
html[data-ui="miku"] .tbtn:active { transform: scale(.92); }
html[data-ui="miku"] .tcard:hover { transform: translateY(-3px) rotate(-.6deg); }

/* ============================================================== 水墨界面 == */
html[data-ui="ink"] {
  --font-title: 'Kaiti SC', 'STKaiti', 'KaiTi', 'STXingkai', 'STZhongsong', 'SimSun', serif;
}

/* —— 宣纸底 + 整幅山水墨卷（用户提供）；关掉斜条纹、网点和旧墨竹 —— */
html[data-ui="ink"] #bg .s1,
html[data-ui="ink"] #bg .s2,
html[data-ui="ink"] #bg .dots,
html[data-ui="ink"] #bg .bamboo { display: none; }
html[data-ui="ink"] #bg .grad {
  background: linear-gradient(180deg, rgba(254,253,251,.10) 0%, rgba(247,246,242,.24) 55%, rgba(240,240,236,.40) 100%);
  z-index: 1;
}
html[data-ui="ink"] #bg .mountains {
  display: block; position: absolute; inset: -2% -3%;
  background-image: url("../assets/ink-bg.png");
  background-position: center;
  background-size: cover;
  background-repeat: no-repeat;
  animation: mtDrift 40s ease-in-out infinite alternate;
}
@keyframes mtDrift { from { transform: translateX(-1.4%) scale(1.02); } to { transform: translateX(1.4%) scale(1.05); } }
/* 竖屏/窄窗：横画会被按高度放大，改锚到右侧 70%（塔亭/瀑布/竹枝所在），别只剩中间的空白湖面 */
@media (max-aspect-ratio: 5/4) {
  html[data-ui="ink"] #bg .mountains { background-position: 70% center; }
}

/* —— 贴纸投影换成「软墨影」：细灰描边 + 一团晕开的淡青灰 —— */
html[data-ui="ink"] .stk > .shp {
  filter:
    drop-shadow(calc(1.1 * var(--s)) 0 0 rgba(28,28,32,.30))
    drop-shadow(calc(-1.1 * var(--s)) 0 0 rgba(28,28,32,.30))
    drop-shadow(0 calc(1.1 * var(--s)) 0 rgba(28,28,32,.30))
    drop-shadow(0 calc(-1.1 * var(--s)) 0 rgba(28,28,32,.30))
    drop-shadow(0 calc(9 * var(--s)) calc(16 * var(--s)) rgba(23,50,94,.13));
}

/* —— 面板与行：去掉切角，换成带手抖感的圆角 —— */
html[data-ui="ink"] .inputcard,
html[data-ui="ink"] .listpanel,
html[data-ui="ink"] .row,
html[data-ui="ink"] .field,
html[data-ui="ink"] .banner,
html[data-ui="ink"] .btn-add,
html[data-ui="ink"] .tbtn,
html[data-ui="ink"] .chip,
html[data-ui="ink"] .cb,
html[data-ui="ink"] .mbox,
html[data-ui="ink"] #themePanel,
html[data-ui="ink"] #toast,
html[data-ui="ink"] .mbtn,
html[data-ui="ink"] .btn-back,
html[data-ui="ink"] .btn-clear { --clip: none; }

html[data-ui="ink"] .inputcard > .shp::before,
html[data-ui="ink"] .listpanel > .shp::before { border-radius: 6px 22px 10px 26px / 22px 8px 24px 10px; }
html[data-ui="ink"] .row > .shp::before { border-radius: 4px 14px 6px 16px / 14px 6px 16px 7px; }
html[data-ui="ink"] .field > .shp::before { border-radius: 4px 12px 5px 13px / 11px 5px 12px 5px; }
html[data-ui="ink"] .tbtn > .shp::before,
html[data-ui="ink"] .mbtn > .shp::before,
html[data-ui="ink"] .btn-back > .shp::before,
html[data-ui="ink"] .btn-clear > .shp::before { border-radius: 7px 11px 8px 12px / 11px 8px 12px 7px; }
html[data-ui="ink"] .mbox > .shp::before,
html[data-ui="ink"] #themePanel > .stk > .shp::before,
html[data-ui="ink"] #toast > .shp::before { border-radius: 8px 18px 10px 20px / 18px 9px 20px 10px; }

/* —— 笔锋横幅：一道从左起笔、向右出尖的浓墨 —— */
html[data-ui="ink"] .banner {
  --fill: #1B1B1F; color: #F6F3EA;
  padding-right: calc(34 * var(--s));
}
html[data-ui="ink"] .banner > .shp::before {
  border-radius: 6px 92% 12px 6px / 10px 96% 16px 10px;
  background-image: linear-gradient(100deg,
    #17171B 0%, #23262F 58%, rgba(27,27,33,.92) 84%, rgba(27,27,33,.55) 100%);
}
html[data-ui="ink"] .banner .b-sq { display: none; }
html[data-ui="ink"] .banner .b-sub { color: rgba(246,243,234,.72); }

/* —— 添加按钮：一方带高光的浓墨印章（蓝只留在勾选环等小点缀上） —— */
html[data-ui="ink"] .btn-add > .shp::before {
  border-radius: 8px 10px 9px 11px / 10px 9px 11px 8px;
  background-image: linear-gradient(180deg, #33333A 0%, #16161B 46%, #08080B 100%);
}
html[data-ui="ink"] .btn-add { --ox: 0px; --oy: 0px; }
html[data-ui="ink"] .btn-add.hot > .shp::before { filter: brightness(1.14); }
html[data-ui="ink"] .btn-add:active { transform: scale(.93); }

/* —— 勾选框：空心墨蓝圆环 → 完成时实心 + 白勾 —— */
html[data-ui="ink"] .cb { --fill: var(--surface); --stroke: var(--accent); opacity: 1; }
html[data-ui="ink"] .cb > .shp::before { border-radius: 50%; }
html[data-ui="ink"] .cb > .shp {
  filter:
    drop-shadow(calc(1.5 * var(--s)) 0 0 var(--accent))
    drop-shadow(calc(-1.5 * var(--s)) 0 0 var(--accent))
    drop-shadow(0 calc(1.5 * var(--s)) 0 var(--accent))
    drop-shadow(0 calc(-1.5 * var(--s)) 0 var(--accent));
}
html[data-ui="ink"] .row.done .cb,
html[data-ui="ink"] .row.just-done .cb { --fill: var(--accent); }
html[data-ui="ink"] .row.done .cb svg polyline { stroke: #FFFFFF; }

/* —— 行：白底细墨边，悬停铺一层淡靛蓝墨韵 —— */
html[data-ui="ink"] .row {
  animation: rowInInk .55s cubic-bezier(.25,.8,.35,1) backwards;
  transition: height .3s cubic-bezier(.22,.61,.36,1), opacity .3s, transform .3s, filter .3s;
}
@keyframes rowInInk {
  from { opacity: 0; transform: translateX(-22px); filter: blur(5px); }
  to   { opacity: 1; transform: none; filter: blur(0); }
}
html[data-ui="ink"] .row.hot { --fill: color-mix(in srgb, var(--surface) 93%, var(--accent)); }
html[data-ui="ink"] .row.sel { --fill: color-mix(in srgb, var(--surface) 88%, var(--accent)); }
html[data-ui="ink"] .row.leaving { transform: translateX(96px); filter: blur(6px); }
html[data-ui="ink"] .row .rail { transform: none; border-radius: calc(3 * var(--s)); }

/* —— 日期签：笔框描边；紧急 = 朱砂红印 —— */
html[data-ui="ink"] .chip { --fill: rgba(30,65,120,.045); --stroke: var(--accent); color: var(--accent); }
html[data-ui="ink"] .chip > .shp::before { border-radius: 12px 5px 11px 6px / 6px 11px 5px 12px; }
html[data-ui="ink"] .chip.mid { --fill: rgba(30,65,120,.045); --stroke: var(--accent); color: var(--accent); }
html[data-ui="ink"] .chip.near { --fill: var(--danger); --stroke: var(--danger); color: #FFF; }
html[data-ui="ink"] .chip.sub { --fill: var(--accent2); --stroke: var(--accent2); color: #FFF; }

/* —— 删除钮：只留一道墨 X，悬停转朱砂 —— */
html[data-ui="ink"] .del > .shp { filter: none; }
html[data-ui="ink"] .del > .shp::before { background: transparent; }
html[data-ui="ink"] .del.hot svg line { stroke: var(--danger); }
html[data-ui="ink"] .del.hot { transform: rotate(90deg); }
html[data-ui="ink"] .del { transition: transform .22s cubic-bezier(.34,1.56,.64,1); }

/* —— 标题栏：墨线收尾 + 靛蓝笔锋余韵 —— */
html[data-ui="ink"] #titlebar::after {
  height: calc(2 * var(--s));
  background: linear-gradient(90deg, rgba(28,28,32,.42), rgba(28,28,32,.06) 70%, rgba(28,28,32,0));
}
html[data-ui="ink"] #titlebar .accentline {
  height: calc(2 * var(--s)); width: calc(200 * var(--s));
  background: linear-gradient(90deg, var(--accent), rgba(30,65,120,0));
  border-radius: 0 calc(2 * var(--s)) calc(2 * var(--s)) 0;
}
html[data-ui="ink"] .appname { letter-spacing: calc(4 * var(--s)); font-size: calc(21 * var(--s)); }
html[data-ui="ink"] .ver {
  clip-path: none; border-radius: calc(3 * var(--s));
  padding: calc(3 * var(--s)) calc(7 * var(--s));
}
html[data-ui="ink"] .logo { --fill: var(--text); }

/* —— 换主题扫过：一道带晕边的浓墨 —— */
html[data-ui="ink"] #wipe {
  background: linear-gradient(100deg,
    rgba(18,40,76,0) 0%, var(--accent) 24%, var(--accent2) 76%, rgba(18,40,76,0) 100%);
}

/* —— 主题卡片 / Toast / 输入聚焦 —— */
html[data-ui="ink"] .tcard { clip-path: none; border-radius: 8px 14px 8px 14px / 14px 8px 14px 8px; outline: 1.5px solid var(--border); }
html[data-ui="ink"] .tcard.cur { outline: 2px solid var(--accent); }
html[data-ui="ink"] .field.focus > .shp {
  filter:
    drop-shadow(calc(1.5 * var(--s)) 0 0 var(--accent))
    drop-shadow(calc(-1.5 * var(--s)) 0 0 var(--accent))
    drop-shadow(0 calc(1.5 * var(--s)) 0 var(--accent))
    drop-shadow(0 calc(-1.5 * var(--s)) 0 var(--accent));
  transition: filter .18s;
}

/* ############################################################################
 *  水墨 · 概念图定稿对齐（ui-concepts/22）
 *    · 衬线字贯穿全站          · 卡片 2.2px 深靛墨描边 + 右上切角
 *    · 任务行合并进整卡，行间细墨线，行首竖墨条
 *    · 日期签 = 白底描边印章（急 = 朱砂印），版本号 = 红印章
 * ##########################################################################*/

/* —— 衬线字贯穿：标题、正文、数字同一套宋/楷 —— */
html[data-ui="ink"] { --font-body: 'DDL-Title', 'STZhongsong', 'SimSun', serif; }

/* —— 两张主卡：深靛墨笔粗描边 + 右上斜切角 + 一团晕影 —— */
html[data-ui="ink"] .inputcard,
html[data-ui="ink"] .listpanel {
  --clip: polygon(0 0, calc(100% - calc(20 * var(--s))) 0,
                  100% calc(20 * var(--s)), 100% 100%, 0 100%);
}
html[data-ui="ink"] .inputcard > .shp,
html[data-ui="ink"] .listpanel > .shp {
  filter:
    drop-shadow(calc(2.2 * var(--s)) 0 0 #1D3A6E)
    drop-shadow(calc(-2.2 * var(--s)) 0 0 #1D3A6E)
    drop-shadow(0 calc(2.2 * var(--s)) 0 #1D3A6E)
    drop-shadow(0 calc(-2.2 * var(--s)) 0 #1D3A6E)
    drop-shadow(0 calc(10 * var(--s)) calc(18 * var(--s)) rgba(23,50,94,.14));
}
html[data-ui="ink"] .inputcard .cardstripes,
html[data-ui="ink"] .listpanel .lp-stripes { display: none; }

/* —— 任务行：撕掉单行贴纸，合并成一整张墨迹列表 —— */
html[data-ui="ink"] .row { margin: 0; height: calc(54 * var(--s)); --fill: transparent; }
html[data-ui="ink"] .row > .shp { display: none; }
html[data-ui="ink"] .row:not(:last-child) { border-bottom: 1px solid rgba(29,58,110,.16); }
html[data-ui="ink"] .row.hot     { background: rgba(30,65,120,.055); }
html[data-ui="ink"] .row.sel     { background: rgba(30,65,120,.10); }
html[data-ui="ink"] .row.editing { background: rgba(30,65,120,.13); }

/* 行首一道竖墨条 */
html[data-ui="ink"] .row .rail {
  left: calc(18 * var(--s)); top: calc(13 * var(--s));
  width: calc(4 * var(--s)); height: calc(100% - 26 * var(--s));
  background: var(--accent); border-radius: calc(2 * var(--s));
}
html[data-ui="ink"] .cb { margin-left: calc(38 * var(--s)); }

/* —— 日期签：白底描边印章；紧急 = 朱砂印；进度 = 靛蓝印 —— */
html[data-ui="ink"] .chip {
  --ox: 0px; --oy: 0px;
  height: calc(26 * var(--s)); padding: 0 calc(11 * var(--s));
  letter-spacing: calc(.6 * var(--s));
}
html[data-ui="ink"] .chip,
html[data-ui="ink"] .chip.mid { --fill: #FFFFFF; --stroke: #1E4178; color: #1E4178; }
html[data-ui="ink"] .chip.near { --fill: #FFFFFF; --stroke: #B03A2E; color: #B03A2E; }
html[data-ui="ink"] .chip.sub  { --fill: #FFFFFF; --stroke: #1E4178; color: #1E4178; }
html[data-ui="ink"] .chip > .shp::before { border-radius: 4px 3px 4px 3px / 3px 4px 3px 4px; }
html[data-ui="ink"] .chip .dot { display: none; }

/* —— 版本号：一方朱砂小印 —— */
html[data-ui="ink"] .ver { background: #B03A2E; color: #FFF; }

/* —— 标题栏按钮：白底靛蓝细框方章 —— */
html[data-ui="ink"] .tbtn { --stroke: #1D3A6E; --ox: 0px; --oy: 0px; --fill: #FFFFFF; }
html[data-ui="ink"] .tbtn.on { --fill: #1E4178; --stroke: #1E4178; }

/* —— 输入框：白纸面 + 淡靛细框 —— */
html[data-ui="ink"] .field { --fill: #FFFFFF; --stroke: rgba(29,58,110,.42); }

/* —— 「添」：一方落款的靛蓝印章 —— */
html[data-ui="ink"] .btn-add { --stroke: #16305C; }
html[data-ui="ink"] .btn-add > .shp::before {
  border-radius: 5px;
  background-image: linear-gradient(180deg, #2A4E8C 0%, #1E4178 52%, #16305C 100%);
}

/* —— 笔锋横幅：浓墨里透出一点靛；副题前加间隔点 —— */
html[data-ui="ink"] .banner > .shp::before {
  background-image: linear-gradient(100deg,
    #181C26 0%, #232A3C 58%, rgba(24,28,38,.92) 84%, rgba(24,28,38,.5) 100%);
}
html[data-ui="ink"] .banner .b-sub::before { content: '·'; margin-right: calc(6 * var(--s)); }

/* ############################################################################
 *  水墨 · 第二轮定稿
 *    · 横幅 = 干笔飞白宽墨刷（SVG）   · 完成 = 一道粗毛笔线抹掉事项
 *    · 所有按钮文字居中               · 动画只动 transform/opacity，跑满帧率
 * ##########################################################################*/

/* —— 横幅：整张墨刷贴图，左起笔、右飞白；文字落在刷身实心区 —— */
html[data-ui="ink"] .banner {
  height: calc(88 * var(--s));
  padding: 0 calc(52 * var(--s)) calc(6 * var(--s)) calc(32 * var(--s));
  pointer-events: none;   /* 装饰性横幅，不能挡住下面的输入框 */
}
/* 笔刷实心笔芯在画布上 1/4 处（实测多阈值均 ≈25%），文字中心对齐到笔芯 */
html[data-ui="ink"] .banner .ct { transform: translateY(calc(-19 * var(--s))); }
html[data-ui="ink"] .banner > .shp {
  filter: drop-shadow(0 calc(5 * var(--s)) calc(8 * var(--s)) rgba(0,0,0,.30));
}
html[data-ui="ink"] .banner > .shp::before,
html[data-ui="ink"] .banner.accent > .shp::before {
  border-radius: 0;
  background: url("../assets/brush-banner.png") 0 0 / 100% 100% no-repeat;
}

/* —— 完成演出：一道粗毛笔线从左抹到右，把事项「划掉」 —— */
html[data-ui="ink"] .row .strike {
  height: calc(10 * var(--s)); top: 55%;
  transform: translateY(-50%) rotate(-.6deg);
  background: url("../assets/brush-strike.png") 0 0 / 100% 100% no-repeat,
              url("../assets/brush-strike.png") 0 0 / 100% 100% no-repeat;
  /* 起笔蓄力 → 加速抹过：先慢后狠的一道 */
  transition: width .4s cubic-bezier(.55,.08,.75,.28), opacity .18s;
}
html[data-ui="ink"] .row.done .strike,
html[data-ui="ink"] .row.just-done .strike { width: calc(100% + calc(10 * var(--s))); opacity: 1; }
/* 勾圈落墨：从一滴墨涨成一个圈 */
html[data-ui="ink"] .row.just-done .cb { animation: cbInk .48s cubic-bezier(.3,1.3,.5,1); }
@keyframes cbInk {
  0%   { transform: scale(.35); opacity: .3; }
  55%  { transform: scale(1.18); opacity: 1; }
  100% { transform: scale(1); }
}
/* 标题随抹线一起淡成灰墨 */
html[data-ui="ink"] .row.just-done .title,
html[data-ui="ink"] .row.done .title { transition: color .4s, opacity .4s; }

/* —— 按钮文字居中：去掉切角时代的补偿留白，按字距微调左侧 —— */
html[data-ui="ink"] .tbtn { padding: 0 calc(15 * var(--s)) 0 calc(16.4 * var(--s)); justify-content: center; }
html[data-ui="ink"] .btn-add .ct { padding-right: 0; padding-left: calc(2.6 * var(--s)); }
html[data-ui="ink"] .btn-back,
html[data-ui="ink"] .btn-clear { padding: 0 calc(16 * var(--s)) 0 calc(17.6 * var(--s)); justify-content: center; }
html[data-ui="ink"] .mbtn { padding: 0 calc(20 * var(--s)) 0 calc(21.4 * var(--s)); justify-content: center; }

/* —— 帧率：行内动画一律只动 transform / opacity，不用 blur 滤镜 —— */
@keyframes rowInInk {
  from { opacity: 0; transform: translateX(-18px); }
  to   { opacity: 1; transform: none; }
}
html[data-ui="ink"] .row {
  transition: height .3s cubic-bezier(.22,.61,.36,1), opacity .3s, transform .3s;
}
html[data-ui="ink"] .row.leaving { transform: translateX(56px); opacity: 0; }

/* ============================================================== 登录门 === */
#loginGate { position: fixed; inset: 0; z-index: 80; display: grid; place-items: center; background: var(--bg); }
#loginGate[hidden] { display: none; }
#loginGate .gatecard {
  position: relative;
  width: min(calc(430 * var(--s)), calc(100vw - 32px));
  --c: var(--cut); --ox: calc(6 * var(--s)); --oy: calc(7 * var(--s));
  --fill: var(--surface); --stroke: var(--ink);
  padding: calc(26 * var(--s)) calc(24 * var(--s)) calc(16 * var(--s));
}
#loginGate .mtitle {
  font-family: var(--font-title); font-size: calc(24 * var(--s));
  letter-spacing: calc(3 * var(--s)); margin-bottom: calc(8 * var(--s));
}
#loginGate .mtext { font-size: calc(13 * var(--s)); line-height: 1.9; color: var(--text); }
#loginGate .mrow { display: flex; flex-direction: column; gap: calc(6 * var(--s)); margin: calc(12 * var(--s)) 0; }
#loginGate .mrow label { font-size: calc(12 * var(--s)); color: var(--dim); letter-spacing: calc(1 * var(--s)); }
#loginGate .mrow input {
  height: calc(38 * var(--s)); padding: 0 calc(12 * var(--s));
  background: var(--surface-alt); color: var(--text);
  border: calc(1.4 * var(--s)) solid var(--border);
  font-size: calc(14 * var(--s)); font-family: var(--font-body);
  outline: none;
}
#loginGate .mrow input:focus { border-color: var(--accent); }
#loginGate .mnote { font-size: calc(11.5 * var(--s)); color: var(--dim); line-height: 1.8; min-height: calc(18 * var(--s)); }
#loginGate .mbtns { display: flex; gap: calc(12 * var(--s)); justify-content: flex-end; align-items: center; margin-top: calc(10 * var(--s)); flex-wrap: wrap; }
#loginGate .gateskip {
  margin-right: auto; background: none; border: 0; padding: 0;
  color: var(--dim); font-size: calc(12 * var(--s)); font-family: var(--font-body);
  letter-spacing: calc(1 * var(--s)); cursor: pointer; text-decoration: underline;
}
#loginGate .gateskip:hover { color: var(--accent); }
html[data-ui="ink"] #loginGate .gatecard { --stroke: var(--border); }
html[data-ui="ink"] #loginGate .gatecard > .shp::before { border-radius: 8px 18px 10px 20px / 18px 9px 20px 10px; }
