/* ============================================================
   设计令牌 —— 取自「自驾 / 高原 / 公路」本身，不是通用 SaaS 蓝
   纸底（旧地图的暖骨白）· 墨黑（沥青）· 冰川湖青 · 公路落日橙

   两套主题共用同一组语义名：
   浅色 = 摊在副驾上的纸质地图；深色 = 夜里跑长途时的仪表背光。
   深色不是浅色反相：底色压到近黑的墨绿（沥青），强调色提亮一档
   （夜里看得清），文字用暖白而不是纯白（久看不刺眼）。
   ============================================================ */
:root{
  /* —— 面：从页面底往上抬三层 ——
     三层之间必须有"看得见"的明度差，否则卡片只能靠阴影独自撑着。
     旧值 bg→paper→surface 只有 1.06 / 1.13:1 —— 同色系微差最难分辨，
     换块屏幕、开个护眼模式就看不出卡片在哪。现按 1.25 / 1.44:1 重排：
     底压成暖灰，卡片给到纯白，色相不变（还是那张纸）。 */
  --bg:#DCD7CA;        /* 页面底 */
  --paper:#F2EFE6;     /* 抬高一层的纸面（Hero、页脚上沿） */
  --surface:#FFFFFF;   /* 卡片 / 弹窗，最亮的一层 */
  --panel:#FFFFFF;
  --panel2:#F5F2EA;    /* 表单控件、次级填充 */
  --sunken:#E8E3D7;    /* 图片位、骨架屏这类"凹槽" */

  /* —— 字 —— */
  /* --muted 原为 #616B73：落在白卡上 5.44:1、落在 --paper 上 4.73:1 都达标，
     唯独直接铺在页面底 --bg(#DCD7CA) 上时只有 3.79:1（正文需 4.5），
     而 .hint / .sub / .legal-meta 恰好都是这种用法。压深一档到 #575F66：
     on --bg 4.52 / on --paper 5.65 / on 白卡 6.49，三种底全部达标。
     深色主题 --muted 已是 7.46:1，不动。 */
  --ink:#151A1E; --ink2:#3A444C; --ink3:#5B656D; --muted:#575F66;
  --amber-ink:#8F5710;   /* 铺在 --amber-soft 上的琥珀色文字：直接用 --amber 只有 3.3:1 */
  --on-brand:#FFFFFF;  /* 铺在品牌色/强调色上的文字 */
  --on-photo:#FFFFFF;  /* 压在照片、深色封面上的文字（两套主题都用白） */

  /* —— 线 —— */
  /* 边框是卡片边界的主力信号：对白卡 1.65:1（旧值仅 1.32:1） */
  --line:#CFC9BA; --line2:#E3DECF;
  --danger-line:#EBC3BE; --brand-line:#CBDAD5; --amber-line:#F0E2B6;
  --ok-line:#BFE3CD; --accent-line:#F0D3C2;
  --float:rgba(255,255,255,.96); --float-line:rgba(21,26,30,.14);  /* 压在地图上浮着的小面板 */

  /* —— 语义色 —— */
  --brand:#0F6B62; --brand-soft:#E2F0ED; --brand-deep:#0A4A44;
  --teal:#0F6B62; --teal-soft:#E2F0ED;
  --amber:#B8751F; --amber-soft:#FAF0DC;
  --danger:#BF3B33; --danger-soft:#FBE8E6;
  --ok:#2F7A55; --ok-soft:#E7F2EA;
  --purple:#5B4C8A; --purple-soft:#EFECF8;
  /* 强调色：路牌橙 / 落日，只用在主行动点和关键数字上 */
  --accent:#D2561B; --accent-soft:#FDEDE3; --accent-deep:#A8410F;

  /* —— 数据色：图表、分类条、站点类型（同名同义，两套主题各自给值） —— */
  --d-stone:#B5AE9F; --d-gold:#C9962A; --d-brown:#8A6D3B; --d-rose:#B4547E;
  --d-indigo:#6E66B8; --d-warm:#C4651F; --d-sand:#A9A08C;
  --fuel:#8A6D3B; --gold:#C9962A; --rose:#B4547E;

  /* —— 遮罩与浮层 —— */
  --scrim:rgba(10,16,26,.72);                      /* 弹窗背后的压暗 */
  --topbar:rgba(242,239,230,.90);                  /* 顶栏毛玻璃 */
  --cover-grad:linear-gradient(135deg,#0A4A44,#0F6B62);  /* 无封面旅程的兜底底图 */
  --solid-hover:#000000;                           /* 墨色实心按钮的悬停 */
  /* 页脚：整站的"路基"，浅色下比正文更深，深色下比页面更深 */
  --foot-bg:#151A1E; --foot-fg:#C9CBCB; --foot-dim:#8B9295; --foot-strong:#F7F5EF;

  /* —— 车牌：照国标配色，板色本身就是信息 ——
     新能源（纯电、插电混动·增程，能插枪充电）＝渐变绿牌黑字；
     其余（燃油、油电混动）＝蓝牌白字。 */
  --plate-blue:linear-gradient(180deg,#5B87C9 0%,#2F5A9E 52%,#22447E 100%);
  --plate-blue-line:rgba(255,255,255,.34);
  --plate-green:linear-gradient(180deg,#9FD8B2 0%,#59AC81 52%,#31845C 100%);
  --plate-green-line:rgba(11,42,25,.26);

  /* —— 品牌标记：雪山 + 落日 + 一条通向山里的公路 + 一台越野车 —— */
  --logo-bg1:#1B7469; --logo-bg2:#0A423D; --logo-road:#F7F5EF;
  --logo-line:#0A423D; --logo-dot:#EC7B45; --logo-rim:rgba(255,255,255,.16);
  --logo-peak:#073A36;   /* 山体：比天光再沉一档，才有剪影 */

  --pad-x:clamp(14px,3.2vw,34px);  /* 顶栏 / 正文 / 页脚共用同一条左右边线 */
  --topbar-shadow:0 6px 20px rgba(21,26,30,.07);
  --shadow:0 1px 2px rgba(21,26,30,.05), 0 6px 18px rgba(21,26,30,.07);
  --shadow-lg:0 10px 40px rgba(21,26,30,.14);
  --r:14px; --r-lg:18px; --r-pill:999px;
  --ease:cubic-bezier(.22,.61,.36,1);
  --ease-pop:cubic-bezier(.2,.9,.3,1.12);
  /* —— 动效与圆角只有这几档，不要临时造新值 ——
     时长：--t-fast .16s 悬停/颜色这类即时反馈 ｜ --t-mid .2s 小元素状态（chip、开关、图标）
           --t-slow .32s 面板、位移、状态切换 ｜ --t-in .4s 入场（页面/列表/封面淡入）
           —— .4s 这一档是唯一的例外：入场是带位移的整块变化，压到 .32s 会显得急促。
           循环动画（logo 虚线、加载页跑动的公路、地图 ping）不占这些档位，可自定周期。
     缓动：--ease 常规 ｜ --ease-pop 需要一点回弹时
     圆角：2 / 3px 角标 ｜ 6px 小控件 ｜ 8px 输入框与次级块 ｜ 12px 卡片内的块
           14px(--r) 卡片 ｜ 18px(--r-lg) 大面板 ｜ 20px 封面 ｜ 999px 胶囊 */
  --t-fast:.16s; --t-mid:.2s; --t-slow:.32s; --t-in:.4s;
  color-scheme:light;
}

/* ============ 夜间主题：跑长途时的那块仪表盘 ============
   底 #0E1312 是夜里的沥青色（带一点绿，不纯黑，避免屏幕像关机）；
   品牌青与路牌橙各提亮一档，暖白 --ink 代替纯白，长时间阅读不刺眼。 */
[data-theme="dark"]{
  /* 深色同理：底 #0E1312 是这套主题的意图（沥青绿，不是纯黑），不动它，
     改为把表面提亮 —— surface 对 bg 从 1.13:1 提到 1.42:1，卡片自己浮起来 */
  --bg:#0E1312; --paper:#171E1C; --surface:#28322E; --panel:#28322E;
  --panel2:#1E2624; --sunken:#121917;

  /* surface 提亮后，原来那几个次级文字色对它的对比度掉到 4.2~4.4（低于 AA），
     这里同步提亮一档：muted 5.29 / danger 5.33 / rose 5.27 */
  --ink:#E9E7E0; --ink2:#B4BAB6; --ink3:#98A19C; --muted:#9CA6A1;
  --amber-ink:#D9A441;
  --on-brand:#07110F;

  --line:#38423F; --line2:#2D3634;
  --danger-line:#5A2E2A; --brand-line:#26433E; --amber-line:#4A3A1A;
  --ok-line:#2A5340; --accent-line:#5A3626;
  --float:rgba(40,50,46,.94); --float-line:rgba(233,231,224,.18);

  --brand:#38B0A0; --brand-soft:#12302C; --brand-deep:#7FD8CB;
  --teal:#38B0A0; --teal-soft:#12302C;
  --amber:#D9A441; --amber-soft:#33260F;
  --danger:#E88B82; --danger-soft:#361B18;
  --ok:#57AB7D; --ok-soft:#14291F;
  --purple:#A497DA; --purple-soft:#231E38;
  --accent:#EC7A50; --accent-soft:#33190F; --accent-deep:#F3A281;

  --d-stone:#8A8578; --d-gold:#D9A441; --d-brown:#B08652; --d-rose:#C67A9C;
  --d-indigo:#8E86CE; --d-warm:#E08A50; --d-sand:#9C9484;
  --fuel:#B08652; --gold:#D9A441; --rose:#D48FB0;

  --scrim:rgba(3,6,6,.78);
  --topbar:rgba(23,30,28,.88);
  --cover-grad:linear-gradient(135deg,#0B3A34,#155A50);
  --solid-hover:#FFFFFF;
  --foot-bg:#080C0B; --foot-fg:#9AA39E; --foot-dim:#767E7A; --foot-strong:#E9E7E0;

  /* 夜里把两块牌子各压暗一档：贴着近黑的底，太亮的牌会抢掉整行的注意力 */
  --plate-blue:linear-gradient(180deg,#3C639E 0%,#24507F 52%,#1B3762 100%);
  --plate-blue-line:rgba(255,255,255,.22);
  --plate-green:linear-gradient(180deg,#79B294 0%,#4E9573 52%,#2F7350 100%);
  --plate-green-line:rgba(11,42,25,.3);

  /* 夜里把路牌整体提亮一档，才压得住近黑的底 */
  --logo-bg1:#2E9C8E; --logo-bg2:#0E5A50; --logo-road:#F3F1E9;
  --logo-line:#0E5A50; --logo-dot:#F0854F; --logo-rim:rgba(255,255,255,.22);
  --logo-peak:#0A4640;

  --topbar-shadow:0 6px 24px rgba(0,0,0,.55);
  --shadow:0 1px 2px rgba(0,0,0,.5), 0 8px 24px rgba(0,0,0,.4);
  --shadow-lg:0 18px 60px rgba(0,0,0,.62);
  color-scheme:dark;
}

/* ---------- 深色下的两件事：插图和照片，处理方式不同 ----------
   封面、地图这些是本站自己画的"纸面物"：先压亮收饱和，再盖一层跟页面同色的薄纱。
   只靠 brightness 硬压出来的浅米色大卡片会发灰发脏，而且压到能沉下去时细节已经没了；
   叠一层同色纱等于把纸面的白"染"成夜色，亮部塌下去、层次还在。
   不压的话，几张浅米色大插图会把整页照成"深色皮、浅色芯"。
   —— 压暗有两个旋钮：filter（压亮部）和 --art-scrim（盖同色纱）。两者是叠加的，
      以前 filter .78 + 纱 .5 一起上，封面被压得发灰发闷。
      现在按"尺寸越大、越要看得清，就压得越轻"分工：
        .route-hero 大封面 .86 / 纱 .30 ｜ .rcover 卡片 .82 / 纱 .34
        .auto-cover 自动封面 .84 / 纱 .36 ｜ .cv-thumb 封面风格选择器 .90 / 纱 .16（要能挑出六种风格）
        .rt-tiles 卫星底图 .82 / 纱 .26（不动：路线不在纱下，压暗底图反而让路线更跳） */
[data-theme="dark"] .route-hero svg{filter:brightness(.86) saturate(.95) contrast(1.02)}
[data-theme="dark"] .rcover svg,
[data-theme="dark"] .jcover svg{filter:brightness(.82) saturate(.94) contrast(1.02)}
[data-theme="dark"] .auto-cover svg{filter:brightness(.84) saturate(.94) contrast(1.02)}
[data-theme="dark"] .cv-style svg{filter:brightness(.90) saturate(.96) contrast(1.02)}
[data-theme="dark"] .rt-tiles{filter:brightness(.82) saturate(.94) contrast(1.02)}
[data-theme="dark"] .route-hero::after,
[data-theme="dark"] .rcover::after,
[data-theme="dark"] .auto-cover::after,
[data-theme="dark"] .cv-thumb::after,
[data-theme="dark"] .rt-tiles::after{
  content:'';position:absolute;inset:0;z-index:1;pointer-events:none;
  background:var(--bg);opacity:var(--art-scrim,.5);
}
/* 纱的厚度按"这块图要不要看清"来定，写在容器上、由 ::after 继承 */
[data-theme="dark"]{--art-scrim:.34}
[data-theme="dark"] .route-hero{--art-scrim:.30}
[data-theme="dark"] .auto-cover{--art-scrim:.36}
/* 封面风格选择器：六种风格要能分辨，纱必须最薄 */
[data-theme="dark"] .cv-thumb{--art-scrim:.16}
/* 地图瓦片本来就比手绘封面暗，纱要薄一点，不然卫星图会糊成一块；
   路线本身画在 .rt-overlay 上，不在这层纱底下，压暗底图反而让橙色路线更跳 —— .26 不动 */
[data-theme="dark"] .rt-tiles{--art-scrim:.26}
[data-theme="dark"] .jcover,
[data-theme="dark"] .rcover,
[data-theme="dark"] .rtmap{border-color:var(--line)}
/* 用户上传的照片是内容，不能像自绘插图那样压；
   但整版大图（封面、头图、打卡点）在近黑底上还是太跳，压到 .88，
   小缩略图只压 .94 —— 尺寸越小，越不需要跟页面抢亮度 */
[data-theme="dark"] .jcover img,
[data-theme="dark"] .jhead-cover img,
[data-theme="dark"] .spot-img img{filter:brightness(.88)}
[data-theme="dark"] .mthumb,
[data-theme="dark"] .vthumb,
[data-theme="dark"] .up-item,
[data-theme="dark"] .memo-pic,
[data-theme="dark"] .memo-photo,
[data-theme="dark"] .mb-pic-item{filter:brightness(.94)}

*{box-sizing:border-box;-webkit-tap-highlight-color:transparent}
html,body{margin:0;padding:0}
body{
  font-family:-apple-system,BlinkMacSystemFont,"PingFang SC","HarmonyOS Sans SC","Hiragino Sans GB","Source Han Sans SC","Noto Sans CJK SC","Microsoft YaHei",sans-serif;
  background:var(--bg); color:var(--ink); font-size:16px; line-height:1.62;
  -webkit-font-smoothing:antialiased; text-rendering:optimizeLegibility;
  /* dvh：移动端浏览器地址栏收起/展开时不再跳高（vh 会把被工具栏盖住的部分算进去） */
  min-height:100vh; min-height:100dvh; display:flex; flex-direction:column;
}
h1,h2,h3,h4{margin:0;font-weight:650;letter-spacing:-.01em;line-height:1.32}
p{margin:0 0 10px}
a{color:var(--brand);text-decoration:none}
button{font-family:inherit}
input,select,textarea{font-family:inherit;font-size:16px;color:var(--ink)}
img{max-width:100%}
/* 数字统一等宽，表格/里程/金额不会跳动 */
.stat .v,.stat-row b,.tl-km,.chip,.hero-facts b,.km-big,.mv{font-variant-numeric:tabular-nums;font-feature-settings:"tnum" 1}

/* ============ 顶栏 ============ */
.topbar{position:sticky;top:0;z-index:60;background:var(--topbar);backdrop-filter:saturate(160%) blur(16px);border-bottom:1px solid var(--line)}
.tb-inner{max-width:1120px;margin:0 auto;padding:12px var(--pad-x);display:flex;align-items:center;gap:14px}
.brand{display:flex;align-items:center;gap:10px;color:var(--ink)}
/* 品牌标记：一块深松绿路牌 + 一条拐向远处的乡道（见 js/logo.js） */
.lgmark{width:34px;height:34px;flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;line-height:0}
.lgmark .lg-mark{width:100%;height:100%;display:block;overflow:visible}
.lgmark .lg-dash{animation:lgRun 3.2s linear infinite}
@keyframes lgRun{to{stroke-dashoffset:-10.4}}   /* 2.1+3.1 的两倍，循环才接得上 */
.lg-lockup{display:inline-flex;align-items:center;gap:12px}
.lg-words{display:flex;flex-direction:column;line-height:1.18}
.lg-words b{font-size:18px;font-weight:650;letter-spacing:.01em}
.lg-words em{font-style:normal;font-size:11px;color:var(--muted);letter-spacing:.04em}
/* 390px 这类窄屏上顶栏是"挤"而不是"折"：品牌名与右侧按钮都不许换行
   （换行会把「车辙」竖排、把「登录 / 注册」拆成两行） */
.brand-text{font-size:18px;font-weight:650;display:flex;flex-direction:column;line-height:1.15;letter-spacing:.01em;white-space:nowrap}
.brand-text em{font-style:normal;font-size:11px;color:var(--muted);font-weight:400;letter-spacing:.04em}
.tb-nav{display:flex;gap:2px;margin-left:10px}
.tb-nav a{padding:8px 12px;border-radius:var(--r-pill);font-size:14px;color:var(--ink2);position:relative;transition:color .2s var(--ease),background .2s var(--ease)}
.tb-nav a:hover{background:var(--line2)}
.tb-nav a.on{color:var(--ink);font-weight:600;background:transparent}
.tb-nav a.on::after{content:"";position:absolute;left:12px;right:12px;bottom:2px;height:2px;border-radius:2px;background:var(--accent)}
.tb-user{margin-left:auto;display:flex;align-items:center;gap:8px;flex:0 0 auto}
.tb-user .btn,.tb-user .chip{white-space:nowrap}
.avatar{width:30px;height:30px;border-radius:50%;background:var(--ink);color:var(--bg);display:flex;align-items:center;justify-content:center;font-size:14px;font-weight:650;letter-spacing:0}
.tb-name{font-size:14px;color:var(--ink2);max-width:130px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* 主题开关：三态循环（跟随系统 → 浅色 → 深色），图标即当前状态 */
.tb-theme{width:32px;height:32px;border-radius:50%;border:1px solid var(--line);background:var(--surface);color:var(--ink2);cursor:pointer;display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;transition:color .2s var(--ease),border-color .2s var(--ease),transform .32s var(--ease-pop)}
.tb-theme:hover{color:var(--brand);border-color:var(--brand);transform:rotate(-14deg)}
.tb-theme .ic{width:16px;height:16px}

.view{max-width:1120px;margin:0 auto;padding:22px var(--pad-x) 44px;width:100%;flex:1}
.view.narrow{max-width:760px}
/* 页脚做成墨色，给整站一个收尾的「路基」 */
.site-foot{background:var(--foot-bg);color:var(--foot-fg);margin-top:28px}
.foot-inner{max-width:1120px;margin:0 auto;padding:26px var(--pad-x) 30px;font-size:14px;line-height:1.9}
.foot-lockup{margin-bottom:8px}
.foot-lockup .lg-words b{color:var(--foot-strong);font-size:16px}
.foot-lockup .lg-words em{color:var(--foot-dim);font-size:12px}
.foot-sub{font-size:12px;color:var(--foot-dim);max-width:520px}
.foot-links{margin-top:12px;display:flex;flex-wrap:wrap;gap:8px 20px}
.foot-links a{color:var(--foot-fg)}
.foot-links a:hover{color:var(--foot-strong);text-decoration:underline;text-underline-offset:3px}
@media(max-width:600px){.foot-inner{padding-top:20px;padding-bottom:24px}}

/* ============ 通用 ============ */
.btn{border:0;border-radius:var(--r-pill);padding:10px 17px;font-size:14px;font-weight:600;cursor:pointer;background:var(--ink);color:var(--bg);transition:background .2s var(--ease),transform .16s var(--ease),box-shadow .2s var(--ease),border-color .2s var(--ease);display:inline-flex;align-items:center;justify-content:center;gap:6px}
.btn:hover{background:var(--solid-hover);box-shadow:0 6px 16px rgba(21,26,30,.18)}
.btn:active{transform:scale(.97)}
/* 主行动点：路牌橙 */
/* 原用 --accent(#D2561B) 配 --on-brand 白字，实测 4.13:1，14px/600 按正文算需 4.5。
   改用深一档的 --accent-deep(#A8410F) → 6.1:1；悬停再往回提亮一点点，手感不变。 */
.btn.hot{background:var(--accent-deep);color:var(--on-brand)}
.btn.hot:hover{background:var(--accent-deep);color:var(--on-brand);filter:brightness(1.14);box-shadow:0 6px 18px rgba(210,86,27,.28)}
.btn.ghost{background:transparent;color:var(--ink);border:1px solid var(--line)}
.btn.ghost:hover{background:var(--panel);border-color:var(--muted);box-shadow:none}
.btn.soft{background:var(--line2);color:var(--ink2)}
.btn.soft:hover{background:var(--sunken)}
.btn.danger{background:transparent;color:var(--danger);border:1px solid var(--danger-line)}
.btn.danger:hover{background:var(--danger-soft);box-shadow:none}
.btn.sm{padding:6px 14px;font-size:14px;min-height:32px}
.btn.lg{padding:14px 24px;font-size:16px}
.btn.block{width:100%}
/* 原为 opacity:.5 —— 半透明后按钮上的字对底色只剩约 2.8:1，"保存中…"几乎读不出来。
   改成显式配色：底沉到 --sunken、字用 --muted，实测 5.07:1，
   既看得清又一眼能认出"这个当前按不动 / 正在处理"。 */
.btn[disabled]{background:var(--sunken);color:var(--muted);border-color:var(--line2);cursor:not-allowed;transform:none;box-shadow:none}
.btn.ghost[disabled],.btn.danger[disabled]{background:transparent}
.btn .ic{opacity:.9}
.btn.hot .ic{opacity:1}   /* 强调按钮上的图标（如「＋ 记一天」）保持实色，避免和背景糊在一起 */
/* 按钮内图标的「颜色」不在这里写 —— 见文件末尾《按钮内图标配色修正》，
   那里的规则需要排在 .card-head .ic 之后才能盖住它 */
.btn-link{border:0;background:none;color:var(--muted);cursor:pointer;font-size:14px;padding:4px 2px;transition:color .16s var(--ease)}
.btn-link:hover{color:var(--ink);text-decoration:underline;text-underline-offset:3px}

.card{background:var(--panel);border:1px solid var(--line);border-radius:var(--r);box-shadow:var(--shadow);padding:16px;margin-bottom:14px}
.card.pad0{padding:0;overflow:hidden}
/* 卡片标题带一条短竖线，替代「光秃秃一行字」 */
.card h3>.ic,.card-head .ic{color:var(--accent)}
.card-head{display:flex;align-items:center;gap:10px;margin-bottom:12px}
.card-head h2,.card-head h3{font-size:16px}
.card-head .right{margin-left:auto;display:flex;gap:6px;align-items:center}
/* 页面级分区标题（没有白色卡片包裹，直接排在页面流里）：左侧内缩 16px，
   与卡片内标题（1px 边框 + 15px 内边距）落在同一竖线上，避免上下标题错位 */
.card-head.sec{padding-left:16px}

/* ---------- 车辆信息：填一次就定的东西，收起时压成一行摘要 ---------- */
.veh-card .veh-body{display:none}
.veh-card.open .veh-body{display:block}
.veh-card .veh-sum{display:none}
.veh-card:not(.open) .veh-sum{display:flex;flex-wrap:wrap;align-items:center;gap:6px}
.veh-card .veh-sum .vs-name{font-size:14px;font-weight:700;color:var(--ink);letter-spacing:.01em}
.veh-card .veh-sum .vs{font-size:12px;color:var(--ink3);background:var(--panel2);
  border:1px solid var(--line);border-radius:var(--r-pill);padding:2px 10px;white-space:nowrap}

/* ---------- 带固定单位的输入格 ----------
   单位由系统按动力类型给好（kWh / L / kWh/100km / L/100km），用户只填数字。
   以前这几个格子是把单位写进标签、或让用户自己打「8.5 L/100km」，
   现在单位贴在框里当后缀 —— 数字列对齐，也不会有人填出「8.5升每百公里」。 */
.inp-unit{position:relative;display:block}
/* 这个 span 也是 .field 的直接子元素，会被上面 `.field>span` 那条标签样式命中
   （12.5px / 灰色 / 加字距）—— 框里的数字会跟着变小变灰。
   所以要用同等偏重以上的选择器把文字样式还原回输入框该有的样子。 */
.field>span.inp-unit,.inp-unit{font-size:inherit;color:inherit;font-weight:400;letter-spacing:normal}
.inp-unit input[type=number]{width:100%;padding-right:78px;-moz-appearance:textfield;appearance:textfield}
.inp-unit.sm input[type=number]{padding-right:46px}
.inp-unit input[type=number]::-webkit-outer-spin-button,
.inp-unit input[type=number]::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}
.inp-unit i{position:absolute;right:12px;top:50%;transform:translateY(-50%);
  font-style:normal;font-size:12px;color:var(--muted);pointer-events:none;
  white-space:nowrap;letter-spacing:.01em;user-select:none}

/* ---------- 二级选项（混动的插电 / 油电） ----------
   一级已经问过「烧什么」，混动才需要再分一层；视觉上比一级轻一档，
   靠左侧一道竖线归属到上面那个已选中的一级按钮下面。 */
.tabs-inline.sub{margin:0 0 6px;padding-left:12px;border-left:2px solid var(--line2)}
.tabs-inline.sub button{padding:6px 12px;font-size:14px;color:var(--ink3);background:var(--panel2)}
.tabs-inline.sub button.on{background:var(--brand-soft);border-color:var(--brand);
  color:var(--brand-deep);font-weight:600}
/* 二级整块往上贴一点，视觉上从属于上面那个已选中的一级按钮；块底留出 14px，
   跟一级单独出现时的下间距一致，下面的品牌/车系栅格不用再加 margin。 */
#vehFuelSubWrap{margin:-6px 0 14px}

.field{display:flex;flex-direction:column;gap:6px;margin-bottom:14px}
.field>span{font-size:14px;color:var(--muted);font-weight:500;letter-spacing:.04em}
.group-body>.field:last-child{margin-bottom:2px}
/* 品牌 / 车型的自绘下拉：原生 datalist 填过字就不好再展开，这里补一层「总能重选」的候选面板 */
.combo{position:relative}
.combo-panel{position:absolute;left:0;right:0;top:calc(100% + 4px);z-index:70;
  max-height:240px;overflow-y:auto;padding:4px;
  background:var(--surface);border:1px solid var(--line);border-radius:10px;box-shadow:var(--shadow-lg)}
.combo-item{padding:8px 10px;border-radius:6px;font-size:14px;color:var(--ink);cursor:pointer;line-height:1.3}
.combo-item:hover,.combo-item.on{background:var(--brand-soft);color:var(--brand)}
input[type=text],input[type=number],input[type=date],input[type=password],input[type=email],input[type=tel],input[type=search],input[type=url],select,textarea{
  width:100%;border:1px solid var(--line);border-radius:8px;padding:10px 12px;background:var(--panel2);outline:none;transition:border-color .16s var(--ease),box-shadow .16s var(--ease),background .16s var(--ease);
}
input,.code-row input{min-width:0}
input:focus,select:focus,textarea:focus{border-color:var(--brand);background:var(--panel);box-shadow:0 0 0 3px var(--brand-soft)}
/* 上面那条基础规则里的 outline:none 优先级(0,1,1)高于全局 :focus-visible(0,1,0)，
   把键盘焦点圈整个压掉了，只剩一圈 --brand-soft 光晕 —— 而它对输入框底色只有 1.05:1，
   等于没有。这里用 (0,2,1) 补回来：键盘 Tab 进来看到 2px 品牌色描边（对底 5.67:1），
   鼠标点击仍只走温和的边框+底色变化。 */
input:focus-visible,select:focus-visible,textarea:focus-visible{outline:2px solid var(--brand);outline-offset:1px}
/* 禁用态：js/app.js 里有 55 处 .disabled = true，但此前只有 .btn[disabled] 一条规则，
   input / select / 磁贴 / 分类按钮置灰后外观零变化（实测 opacity 与背景都完全不变），
   用户看不出"这个不能点/正在处理"。这里统一补上：背景沉一档、文字转次级色。 */
input:disabled,select:disabled,textarea:disabled{background:var(--sunken);color:var(--muted);cursor:not-allowed;border-color:var(--line2)}
.block-tile:disabled{opacity:.45;cursor:default;transform:none;box-shadow:none}
.cat-pick button:disabled,.star:disabled,.del:disabled,.coord:disabled{opacity:.4;cursor:default}
textarea{resize:vertical;min-height:70px;line-height:1.6}
.grid2{display:grid;grid-template-columns:1fr 1fr;gap:12px}
.grid3{display:grid;grid-template-columns:repeat(3,1fr);gap:12px}
.grid4{display:grid;grid-template-columns:repeat(4,1fr);gap:12px}
@media(max-width:700px){.grid3,.grid4{grid-template-columns:1fr 1fr}}
@media(max-width:460px){.grid2,.grid3,.grid4{grid-template-columns:1fr}}
.sublabel{font-size:14px;color:var(--muted);margin:16px 0 8px;font-weight:600;display:flex;align-items:center;gap:8px}
.sublabel::after{content:"";flex:1;height:1px;background:var(--line2)}
.hint{font-size:12px;color:var(--muted);line-height:1.6;margin-top:6px}
/* 概览下面那两条提示（预算 / 能耗）：不做成裸文字，给个浅底小卡，
   离开页面边线、也和下面的图表拉开距离 */
.budget-tip,.energy-hint{margin:14px 0 18px;padding:12px 14px;border-radius:8px;
  background:var(--panel2);border:1px solid var(--line);font-size:14px;color:var(--ink2);line-height:1.75}
.budget-tip{background:var(--amber-soft);border-color:var(--amber-line);color:var(--amber-ink)}
.budget-tip a{color:var(--amber-ink);font-weight:600;text-decoration:underline;text-underline-offset:3px}
/* 「共充电 438 度 · 电费 ¥844 · 收入 ¥1,800」是中性汇总，不是待办也不是警告 ——
   青绿底压在暖米页面底上既冲突色温、又把它抬成了一个小节，读者会以为要做什么。
   退回中性面板；真正需要行动的是上面那条琥珀色 .budget-tip，保持它独自醒目。 */
.energy-hint{background:var(--panel2);border-color:var(--line);color:var(--ink2)}
.mt8{margin-top:8px}.mt12{margin-top:12px}.mt16{margin-top:16px}

/* 通用 chip 原用 --ink3(#5B656D) 压在 --line2(#E3DECF) 上，实测 4.43:1，差 0.07 不达 AA；
   换成 --ink2(#3A444C) 后 6.9:1。chip 是 12px 小字，宁可深一点。 */
.chip{font-size:12px;border-radius:var(--r-pill);padding:4px 10px;background:var(--line2);color:var(--ink2);display:inline-flex;align-items:center;gap:4px;font-variant-numeric:tabular-nums;letter-spacing:.01em}
.chip.e{background:var(--danger-soft);color:var(--danger)}
.chip.i{background:var(--ok-soft);color:var(--ok)}
.chip.b{background:var(--brand-soft);color:var(--brand)}
.chip.g{background:var(--amber-soft);color:var(--amber-ink)}
.chip.p{background:var(--purple-soft);color:var(--purple)}
.chip.t{background:var(--teal-soft);color:var(--teal)}
.empty{text-align:center;color:var(--muted);font-size:14px;padding:34px 16px;line-height:1.85}
.empty b{color:var(--ink2);display:block;font-size:16px;margin-bottom:4px;font-weight:650}
.empty .ic{display:block;margin:0 auto 10px;color:var(--muted);opacity:.5}

/* -------- 自绘 SVG 图标（替代 emoji） -------- */
.ic{display:inline-block;width:1em;height:1em;flex:0 0 auto;vertical-align:-.14em;line-height:1}
.ic svg{display:block;width:100%;height:100%;stroke:currentColor;stroke-width:1.7;stroke-linecap:round;stroke-linejoin:round;fill:none}
.ic.solid svg{fill:currentColor;stroke:none}
.ic.s16{width:16px;height:16px}.ic.s14{width:14px;height:14px}.ic.s12{width:12px;height:12px}
.ic.s20{width:20px;height:20px}.ic.s24{width:24px;height:24px}
.ic.thin svg{stroke-width:1.4}

/* ============ Hero ============
   不用「渐变底 + 居中大标题 + 两个按钮」那套模板。
   改成纸质地图感的暖白面板：左侧编辑式大标题，右侧一组真实数据，
   底部一条手绘公路线贯穿。 */
.hero{
  position:relative;overflow:hidden;border-radius:var(--r-lg);margin-bottom:22px;
  background:var(--paper);border:1px solid var(--line);
  box-shadow:0 2px 4px rgba(21,26,30,.03), 0 14px 38px rgba(21,26,30,.07);
}
.hero::before{
  /* 极淡的等高线纹理，用重复渐变模拟，不引外部图 */
  content:"";position:absolute;inset:0;pointer-events:none;opacity:.5;
  background:
    repeating-linear-gradient(115deg, transparent 0 22px, rgba(21,26,30,.022) 22px 23px),
    radial-gradient(120% 90% at 88% 8%, rgba(15,107,98,.07), transparent 62%);
}
.hero-inner{position:relative;padding:32px 32px 20px;display:grid;grid-template-columns:minmax(0,1.55fr) minmax(214px,.8fr);gap:24px 34px;align-items:stretch}
.hero-note{font-size:14px;color:var(--muted);margin:14px 0 0;line-height:1.7}
.only-xs{display:none}
@media(max-width:560px){.only-xs{display:inline}}
.hero h1{font-size:36px;line-height:1.2;letter-spacing:-.02em;font-weight:700;margin-bottom:12px;max-width:15em}
/* 用背景渐变画高亮，不依赖 z-index，任何背景色上都不会被盖住 */
.hero h1 em{font-style:normal;color:var(--accent);white-space:nowrap;
  background-image:linear-gradient(rgba(210,86,27,.16),rgba(210,86,27,.16));
  background-repeat:no-repeat;background-size:100% .3em;background-position:0 88%;}
.hero-lede{font-size:16px;color:var(--ink2);line-height:1.85;max-width:36em;margin:0 0 20px}
.hero-actions{display:flex;align-items:center;gap:14px;flex-wrap:wrap}
.hero-actions .btn.lg{padding:14px 26px}
/* 文字型次级行动：下划线箭头，不再是「第二个大按钮」 */
/* 实测 30.5px 高，移动端差一点；下划线的"静止色"也一起给出来，
   否则未悬停时继承的是 --line（浅到几乎看不出这是条链接）。 */
.hero-link{display:inline-flex;align-items:center;gap:6px;font-size:14px;font-weight:600;color:var(--ink);border-bottom:1px solid var(--muted);padding-bottom:2px;min-height:32px;transition:color var(--t-mid) var(--ease),border-color var(--t-mid) var(--ease),gap var(--t-mid) var(--ease)}
.hero-link:active{transform:scale(.98)}
.hero-link:hover{color:var(--accent);border-color:var(--accent);gap:10px}
.hero-link .ic{color:var(--accent)}
/* 右侧真实数据面板：三行等分撑满左栏高度，不留空洞 */
/* Hero 右侧的事实栏：不做"三栏等高数据卡"（那是模板味最重的一处），
   改成三条贴着细线的短句 —— 数字紧跟图标，念出来就是一整句。 */
.hero-facts{display:flex;flex-direction:column;align-self:start;border-top:1px solid var(--line)}
.hero-facts>div{display:flex;align-items:baseline;gap:4px;padding:14px 2px;border-bottom:1px solid var(--line);line-height:1.45}
.hero-facts .ic{color:var(--brand);width:17px;height:17px;align-self:center;margin-right:8px;flex:0 0 auto;opacity:.85}
.hero-facts b{font-size:18px;font-weight:700;line-height:1.2;letter-spacing:-.02em;color:var(--ink)}
.hero-facts span{font-size:14px;color:var(--muted);line-height:1.45}
.hero-facts>div>b+span{margin-left:6px}
/* 底部公路线 */
.hero-road{position:relative;display:block;width:100%;height:46px}
.hero-road svg{display:block;width:100%;height:100%}
/* 首屏脚注 */
.hero-tail{position:relative;display:flex;flex-wrap:wrap;align-items:baseline;gap:6px 22px;font-size:14px;padding:14px 32px 0;border-top:1px solid var(--line2);margin-top:2px}
.hero-tail .ht-n{color:var(--ink2);display:inline-flex;align-items:baseline;gap:6px;white-space:nowrap}
.hero-tail .ht-n b{font-size:18px;font-weight:700;line-height:1;color:var(--ink)}
.hero-tail .ht-t{color:var(--muted)}
.hero-tail .ht-t::before{content:"·";margin-right:10px;color:var(--muted);opacity:.55}
@media(max-width:860px){
  .hero-inner{grid-template-columns:1fr;gap:20px;padding:26px 20px 20px}
  .hero h1{font-size:26px}
  .hero-tail{padding:12px 20px 0}
  .hero-road{height:40px}
}
@media(max-width:600px){
  .hero h1{font-size:26px}
  .hero-tail{flex-direction:column;gap:6px;align-items:flex-start}
  .hero-tail .ht-t::before{content:none;margin:0}
}

/* ============ 旅程卡片 ============ */
.jgrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(258px,1fr));gap:14px}
.jcard{background:var(--panel);border:1px solid var(--line);border-radius:var(--r);overflow:hidden;box-shadow:var(--shadow);cursor:pointer;transition:.16s;display:flex;flex-direction:column}
/* 卡片只有 hover、没有 active：点下去的一瞬间没有任何"按下"的回执，
   手指已经离开了才知道有没有点中。补一个极轻的下沉（不动阴影，避免闪）。 */
.jcard:active{transform:translateY(0) scale(.995)}
.jcard:hover{transform:translateY(-2px);box-shadow:var(--shadow-lg);border-color:var(--muted)}
.jcover{height:auto;aspect-ratio:8/5;background:var(--sunken);position:relative;display:flex;align-items:center;justify-content:center;color:var(--muted);font-size:14px;overflow:hidden;flex:0 0 auto}
.jcover img{width:100%;height:100%;object-fit:cover;display:block}
/* 自动生成封面 */
.auto-cover{position:absolute;inset:0}
.auto-cover svg{width:100%;height:100%;display:block}
/* 封面风格选择器 */
.cover-styles{display:grid;grid-template-columns:repeat(3,1fr);gap:10px;margin-top:8px}
@media (max-width:560px){.cover-styles{grid-template-columns:repeat(2,1fr)}}
.cv-style{appearance:none;border:2px solid var(--line);border-radius:12px;padding:0;background:var(--surface);cursor:pointer;overflow:hidden;text-align:center;transition:border-color .2s,transform .2s,box-shadow .2s}
.cv-style:hover{transform:translateY(-2px);box-shadow:0 6px 18px rgba(21,26,30,.12)}
/* 选中光圈原来是一圈蓝 rgba(22,104,227)，跟墨色体系不是一路；换成品牌青的淡光 */
.cv-style.on{border-color:var(--brand);box-shadow:0 0 0 3px var(--brand-soft)}
.cv-style.on .cv-name{color:var(--brand);font-weight:700}
.cv-thumb{display:block;height:78px;overflow:hidden;position:relative}
.cv-thumb svg{width:100%;height:100%;display:block}
.cv-name{display:block;padding:6px 4px 6px;font-size:12px;color:var(--muted);border-top:1px solid var(--line);background:var(--panel2)}
/* ============ 经典路线 ============ */
.page-head{padding:26px 2px 14px}
.page-head h1{font-size:22px;margin-bottom:6px}
.page-head .sub{font-size:14px;color:var(--muted);line-height:1.7}
/* ---------- 两条 skip link（键盘专用，平时移出视口，聚焦才显形）----------
   形状统一：999px 胶囊 + 12.5px；只有层级与定位方式不同：
     .skip        站点级「跳到主要内容」——墨色实心，fixed 浮在顶栏之上，滚到哪都在；
     .skip-result 页内级「跳到 N 条结果」——品牌青，聚焦时回到文档流，排在结果网格上方。
   焦点圈都用 --ink：描边画在元素外侧、落在页面底色上，浅色深墨、深色暖白，两套主题都看得见；
   若用 --brand，青描边压在青底上等于没有。
   两条都把整套视觉（底/字/字号/圆角/边框/阴影）在 :focus 里显式写全 —— 不这么写，
   index.html 里那段同权重的过渡兜底会用它的 8px 圆角 + 浅卡片底接管一半属性。 */
.skip{position:fixed;left:-9999px;top:8px;z-index:200;width:1px;height:1px;overflow:hidden;
  border:0;box-shadow:none;border-radius:var(--r-pill);
  background:var(--ink);color:var(--bg);font-size:14px;text-decoration:none}
.skip:focus{left:12px;top:8px;width:auto;height:auto;overflow:visible;padding:10px 16px;
  border:0;box-shadow:none;border-radius:var(--r-pill);
  background:var(--ink);color:var(--bg);font-size:14px;
  outline:2px solid var(--ink);outline-offset:2px}
.skip-result{position:absolute;left:-9999px;top:auto;width:1px;height:1px;overflow:hidden;
  border:0;box-shadow:none;border-radius:var(--r-pill);
  background:var(--brand);color:var(--on-brand);font-size:14px;text-decoration:none}
.skip-result:focus{position:static;left:auto;top:auto;width:auto;height:auto;overflow:visible;
  display:inline-block;margin-bottom:10px;padding:8px 12px;
  border:0;box-shadow:none;border-radius:var(--r-pill);
  background:var(--brand);color:var(--on-brand);font-size:14px;
  outline:2px solid var(--ink);outline-offset:2px}
.rgrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(240px,1fr));gap:14px;margin-bottom:20px}
.rcard{background:var(--panel);border:1px solid var(--line);border-radius:var(--r);overflow:hidden;cursor:pointer;transition:transform .2s,box-shadow .2s;display:flex;flex-direction:column}
.rcard:active{transform:translateY(-1px) scale(.995)}
.rcard:hover{transform:translateY(-3px);box-shadow:0 10px 26px rgba(21,26,30,.14)}
.rcover{position:relative;aspect-ratio:8/5;overflow:hidden;background:var(--sunken)}
.rcover svg{width:100%;height:100%;display:block}
.rbody{padding:12px 14px 14px;display:flex;flex-direction:column;gap:6px;flex:1}
.rtitle{font-size:16px;font-weight:700}
.rsub{font-size:14px;color:var(--brand);font-weight:600}
.rmeta{display:flex;flex-wrap:wrap;gap:6px}
.rdesc{font-size:14px;color:var(--muted);line-height:1.65}
/* 难度徽标 */
.chip.lv1{background:var(--ok-soft);color:var(--ok)}
.chip.lv2{background:var(--brand-soft);color:var(--brand)}
.chip.lv3{background:var(--amber-soft);color:var(--amber-ink)}
.chip.lv4{background:var(--danger-soft);color:var(--danger)}
/* 经典线路筛选条 */
.rfilter{background:var(--panel);border:1px solid var(--line);border-radius:var(--r);box-shadow:var(--shadow);padding:12px 14px 8px;margin-bottom:16px}
.rf-row{display:flex;gap:12px;align-items:flex-start;padding:4px 0}
.rf-row+.rf-row{border-top:1px dashed var(--line2);margin-top:6px;padding-top:10px}
.rf-lab{flex:0 0 56px;font-size:12px;color:var(--muted);font-weight:600;padding-top:6px;letter-spacing:.3px}
.rf-chips{display:flex;flex-wrap:wrap;gap:6px;flex:1;min-width:0}
/* 圆角 20px 不在档位上，走胶囊档；
   transition 写成裸的 .16s 等于对「所有属性」生效（含布局触发的），
   只写真正要过渡的几项；min-height 补到 32px（实测 31px，移动端点不准）。 */
.rf-chip{border:1px solid var(--line);background:var(--surface);color:var(--ink2);font-size:14px;border-radius:var(--r-pill);padding:4px 12px;cursor:pointer;min-height:32px;transition:color var(--t-fast) var(--ease),background var(--t-fast) var(--ease),border-color var(--t-fast) var(--ease),transform var(--t-fast) var(--ease);line-height:1.45;font-family:inherit}
.rf-chip:hover{border-color:var(--brand-line);background:var(--brand-soft);color:var(--brand)}
/* 按下要有回执：只有 hover 没有 active，点下去的一瞬间是"没反应"的 */
.rf-chip:active{transform:scale(.97)}
.rf-chip.on{background:var(--brand);border-color:var(--brand);color:var(--on-brand);font-weight:500}
/* 计数原来靠 opacity 压淡 —— 选中态下淡青压在实青底上只有 1.76:1。
   改成用文字色表达层级：未选中 --ink3（4.92），选中 --brand-soft（7.06）。 */
.rf-chip .n{color:var(--ink3);font-size:11px;margin-left:4px}
.rf-chip.on .n{color:var(--brand-soft)}
.rf-foot{display:flex;align-items:center;gap:10px;padding:8px 0 4px;border-top:1px dashed var(--line2);margin-top:6px;font-size:14px;color:var(--muted)}
.rf-foot .btn-link{margin-left:auto}
@media(max-width:640px){
  .rf-lab{flex:0 0 100%;padding-top:0;margin-bottom:2px}
  .rf-row{flex-direction:column;gap:4px}
}
.route-hero{position:relative;border-radius:var(--r);overflow:hidden;margin-bottom:14px;border:1px solid var(--line);box-shadow:var(--shadow)}
.route-hero svg{width:100%;display:block}
.route-head h1{font-size:18px;margin-bottom:4px}
.route-head .rsub{margin-bottom:8px}
.rintro{font-size:14px;line-height:1.8;color:var(--ink2);margin-top:10px}
/* 出发前读一读：四张小卡，标签带图标 */
.guide-rows{display:grid;grid-template-columns:repeat(auto-fit,minmax(236px,1fr));gap:12px}
.grow{display:flex;flex-direction:column;gap:4px;font-size:14px;line-height:1.75;padding:12px 14px;background:var(--panel2);border:1px solid var(--line2);border-radius:12px}
.grow>span{color:var(--muted);font-size:12px;font-weight:650;letter-spacing:.06em;display:inline-flex;align-items:center;gap:6px}
.grow>span .ic{color:var(--accent);width:15px;height:15px}
.grow>div{color:var(--ink2)}
.spot-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(180px,1fr));gap:12px}
.spot{background:var(--panel2);border:1px solid var(--line);border-radius:12px;overflow:hidden;transition:transform .2s var(--ease),box-shadow .2s var(--ease)}
.spot:hover{transform:translateY(-2px);box-shadow:var(--shadow)}
.spot-img{position:relative;aspect-ratio:16/10;background:var(--sunken);overflow:hidden}
.spot-img picture{display:block;width:100%;height:100%}
.spot-img img{width:100%;height:100%;object-fit:cover;display:block}
.spot-img.noimg img{display:none}
.spot-fallback{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;font-size:26px;font-weight:800;color:var(--on-photo);background:var(--cover-grad);letter-spacing:2px}
.spot-img:not(.noimg) .spot-fallback{display:none}
.spot-name{padding:8px 10px 0;font-size:14px;font-weight:700}
.spot-desc{padding:4px 10px 10px;font-size:12px;color:var(--muted);line-height:1.6}
/* 逐日时间线：一条橙色竖线 + 空心节点，像里程碑 */
.tl{position:relative;padding-left:20px}
.tl::before{content:'';position:absolute;left:5px;top:8px;bottom:8px;width:2px;background:linear-gradient(var(--accent),var(--brand));border-radius:2px;opacity:.3}
.tl-item{position:relative;padding:0 0 18px 8px}
.tl-item::before{content:'';position:absolute;left:-19px;top:6px;width:12px;height:12px;border-radius:50%;background:var(--panel);border:3px solid var(--accent)}
/* 小字用 --accent 只有 4.13:1，差一点到 AA；深一档到 6.13:1。
   （hero 大标题上的橙色是 26px+，按大文本标准 3:1 已达标，保持亮橙不换） */
.tl-day{font-size:12px;font-weight:800;color:var(--accent-deep);letter-spacing:1px;margin-bottom:4px}
.tl-route{font-size:14px;display:flex;flex-wrap:wrap;gap:8px;align-items:baseline}
.tl-km{font-size:12px;color:var(--muted);font-weight:600}
.tl-alt{font-size:12px;color:var(--muted);margin:4px 0 6px}
/* 逐日行程里的途经点：当天内部的一条支线。
   比外层 DAY 轴弱一档——细线 + 空心小点，不再给每个点套一整块带边框的胶囊，
   密集排列时边框互相挤压、note 又被 flex:100% 顶到第二行，高度参差不齐，是这版之前最难看的地方。 */
.tl-stops{position:relative;margin:1px 0 10px}
.tl-stops::before{content:'';position:absolute;left:4.25px;top:7px;bottom:7px;width:1.5px;background:var(--line2)}
.tl-stop{position:relative;padding:0 0 10px 18px}
.tl-stop:last-child{padding-bottom:0}
.tl-sdot{position:absolute;left:0;top:6px;width:10px;height:10px;border-radius:50%;
  background:var(--surface);border:2.5px solid var(--d-stone)}
.tl-stop.k-mtn .tl-sdot{border-color:var(--amber)}
.tl-stop.k-water .tl-sdot{border-color:var(--brand)}
.tl-stop.k-cult .tl-sdot{border-color:var(--purple)}
.tl-stop.k-wild .tl-sdot{border-color:var(--ok)}
.tl-shead{display:flex;flex-wrap:wrap;align-items:baseline;gap:6px}
.tl-sname{font-size:14px;font-weight:650;color:var(--ink)}
/* 类型徽章：一行能放下的小胶囊，代替原来千篇一律的 pin 图标 */
/* 同 .chip：--ink3 压在 --line2 上 4.43:1，11px 小字差这一点很难读，换 --ink2（6.9:1） */
.tl-stype{font-size:11px;font-weight:700;line-height:1.5;padding:1px 8px;border-radius:var(--r-pill);
  background:var(--line2);color:var(--ink2);white-space:nowrap}
.tl-stop.k-mtn .tl-stype{background:var(--amber-soft);color:var(--amber-ink)}
.tl-stop.k-water .tl-stype{background:var(--brand-soft);color:var(--brand)}
.tl-stop.k-cult .tl-stype{background:var(--purple-soft);color:var(--purple)}
.tl-stop.k-wild .tl-stype{background:var(--ok-soft);color:var(--ok)}
/* 海拔：高原自驾真正要盯的数字，垭口这类关键点的海拔跟着类型一起上色 */
.tl-salt{font-size:11px;font-weight:700;color:var(--muted);font-variant-numeric:tabular-nums;white-space:nowrap}
.tl-stop.k-mtn .tl-salt{color:var(--amber-ink)}
.tl-snote{font-size:12px;color:var(--muted);line-height:1.7;margin-top:2px}
.tl-tip{font-size:14px;color:var(--amber-ink);background:var(--amber-soft);border:1px solid var(--amber-line);border-radius:8px;padding:8px 10px;line-height:1.6;display:flex;gap:8px;align-items:flex-start}
.tl-tip .ic{color:var(--amber);width:15px;height:15px;margin-top:2px}
/* 微信登录按钮 */
.oauth-divider{display:flex;align-items:center;gap:10px;margin:16px 0 12px;color:var(--muted);font-size:12px}
.oauth-divider::before,.oauth-divider::after{content:'';flex:1;height:1px;background:var(--line)}
.wx-ico{display:inline-flex;vertical-align:-4px;margin-right:8px}
.jhead-cover .auto-cover,.jcover .auto-cover{animation:fadeIn var(--t-in) var(--ease)}
/* 压在照片上的角标：底统一墨色（原来是偏蓝的 rgba(12,20,32)）；
   「公开」用品牌实色 + --on-brand，不再用 rgba(14,165,164,.9)
   —— 那个青底配白字只有 3.0:1，还带透明度、对比度随封面明暗漂移。 */
.jcover .badge{position:absolute;top:9px;left:9px;background:rgba(21,26,30,.62);color:#fff;font-size:11px;padding:4px 8px;border-radius:20px;backdrop-filter:blur(4px)}
.jcover .badge.pub{background:var(--brand);color:var(--on-brand)}
.jbody{padding:12px 14px 14px;display:flex;flex-direction:column;gap:6px;flex:1;min-width:0}
.jtitle{font-size:16px;font-weight:600;line-height:1.32;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;word-break:break-word}
.jdesc{font-size:14px;color:var(--muted);display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;min-height:34px;word-break:break-word}
.jmeta{display:flex;flex-wrap:wrap;gap:6px;margin-top:auto;padding-top:8px}

/* ============ 旅程详情 ============ */
.jhead{border-radius:var(--r-lg);overflow:hidden;box-shadow:var(--shadow);margin-bottom:18px;background:var(--surface);border:1px solid var(--line)}
/* 封面本身是一个「底部对齐」的弹性容器：标题压在图片下缘，
   不再用负外边距叠层（.auto-cover 是绝对定位，负外边距会与父级发生外边距合并，把封面顶出卡片） */
.jhead-cover{aspect-ratio:5/2;min-height:250px;background:var(--cover-grad);position:relative;display:flex;flex-direction:column;justify-content:flex-end;overflow:hidden}
/* aspect-ratio 会把 min-height 反向传递成一个最小宽度（250 × 2.5 = 625px），
   这个最小宽度压过了父级的 100% 拉伸 —— 实测 375px 视口下封面被撑到 625px 宽，
   .jhead 只有 347px 又带 overflow:hidden，于是标题和第三个操作按钮（复制分享链接）
   的右端 14px 被硬裁掉。窄屏改成 16/9 并解除 min-height，让封面回到容器宽度。 */
@media(max-width:700px){
  .jhead-cover{aspect-ratio:16/9;min-height:0}
  .jhead-body h1{font-size:22px}
}
.jhead-cover img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block}
.jhead-cover .ov{position:absolute;inset:0;background:linear-gradient(to top,rgba(8,14,24,.86),rgba(8,14,24,.34) 56%,rgba(8,14,24,.2)),linear-gradient(100deg,rgba(8,14,24,.62),rgba(8,14,24,.14) 58%,rgba(8,14,24,0))}
.jhead-body{position:relative;z-index:2;padding:18px 20px;color:#fff;min-width:0}
/* 超长标题必须能在框内折行：封面是 overflow:hidden，不折就直接被裁掉半行。
   min-width:0 防的是 flex item 默认 min-width:auto —— 那会让它按内容宽度撑开。 */
.jhead-body h1{font-size:26px;margin-bottom:6px;text-shadow:0 2px 10px rgba(0,0,0,.35);overflow-wrap:anywhere;word-break:break-word}
.jhead-body .sub{font-size:14px;opacity:.94;display:flex;flex-wrap:wrap;gap:10px;align-items:center}
.jhead-body .sub .chip{background:rgba(255,255,255,.2);color:#fff;backdrop-filter:blur(4px)}
.jhead-actions{display:flex;gap:8px;margin-top:14px;flex-wrap:wrap}
/* 这个按钮的底恒为 90% 白，所以文字色不能跟着主题走 ——
   深色主题把 --brand 提亮成 #38B0A0（为了压在深色底上可读），
   铺到白底上只剩 2.66:1（实测「编辑这段旅程」）。写死浅色那支品牌青 6.36:1。
   注意：不要"优化"回 var(--brand)。 */
.jhead-actions .btn{background:rgba(255,255,255,.9);color:#0F6B62}
.jhead-actions .btn.ghost{background:rgba(255,255,255,.16);color:#fff;border:1px solid rgba(255,255,255,.45)}
.jhead-actions .btn.ghost:hover{background:rgba(255,255,255,.3)}
.jhead-foot{padding:14px 20px;display:flex;gap:8px;flex-wrap:wrap;border-top:1px solid var(--line2);background:var(--surface)}

/* auto-fill 而非 auto-fit：两组指标卡（行程 / 花费）元素个数不等（4~6 与 2~8），
   auto-fit 会按各自的元素个数折叠空轨道、重新分配宽度 —— 5 个的排成 5 列、
   6 个的排成 6 列，两组竖线对不上。
   auto-fill 保留空轨道，列宽锚定同一基准，两组就落在同一套网格上。
   155px 是量出来的：1440 下内容宽 1052，(1052+12)/(155+12)=6.3 → 稳定 6 列，
   列宽 165px，装得下「9 晚（床车 9 晚）」这类长单位；768 下 4 列、375 下 2 列。 */
.summary{display:grid;grid-template-columns:repeat(auto-fill,minmax(155px,1fr));gap:12px;margin-bottom:18px}
/* 元素个数是动态的（有没有住宿 / 影像 / 油耗都不一样），总会有落单的时候。
   让最后一张跨两列把行尾补齐，比在右边空出一格更像收尾：
   6 列网格里占 2/6，2 列网格里正好是整行。 */
.summary>.stat:last-child:nth-child(odd){grid-column:span 2}
.stat{background:var(--panel);border:1px solid var(--line);border-radius:12px;padding:12px 14px;box-shadow:var(--shadow)}
.stat .k{font-size:12px;color:var(--muted)}
.stat .v{font-size:18px;font-weight:600;margin-top:4px;font-variant-numeric:tabular-nums}
.stat .u{font-size:11px;color:var(--muted);font-weight:400;margin-left:2px}
/* 数值一律墨色。颜色是用来承载语义的（红=超支/负向、绿=结余/正向），不是装饰：
   以前同一排卡片里里程是青、海拔是青、住宿是紫、百公里电耗是红 —— 读者会下意识
   去猜这些颜色在说什么，而它们什么也没说；「电耗」被染成警示红尤其容易误读。
   数值本身靠字号 + 字重已经足够拉出层级。.v.i 保留绿色，它确实表示「结余/赚回」。 */
.v.e,.v.b,.v.t{color:var(--ink)}
.v.i{color:var(--ok)}

.desc-text{font-size:14px;color:var(--ink2);line-height:1.8;white-space:pre-wrap}

/* 攻略 */
.guide-card{background:var(--panel);border:1px solid var(--line);border-radius:var(--r);box-shadow:var(--shadow);padding:14px 16px;margin-bottom:12px}
.guide-card h3{font-size:16px;margin-bottom:8px;display:flex;align-items:center;gap:8px}
.guide-card h3::before{content:"";width:3px;height:15px;border-radius:2px;background:var(--teal)}
.guide-card .body{font-size:14px;color:var(--ink2);white-space:pre-wrap;line-height:1.75}

/* 每日卡片（展示） */
.daypub{background:var(--panel);border:1px solid var(--line);border-radius:var(--r);box-shadow:var(--shadow);margin-bottom:14px;overflow:hidden}
.daypub-head{display:flex;align-items:center;gap:10px;padding:14px 16px;flex-wrap:wrap;border-bottom:1px solid var(--line2)}
.dayno{background:var(--brand-soft);color:var(--brand);font-size:12px;font-weight:600;border-radius:8px;padding:4px 10px}
.daydate{font-size:14px;color:var(--muted)}
.dayroute{font-size:16px;font-weight:600;display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.dayroute .ar{color:var(--brand)}
.daypub-body{padding:14px 16px}
.dmetrics{display:flex;flex-wrap:wrap;gap:6px;margin-top:10px}

.timeline{position:relative;padding-left:22px;margin:12px 0 4px}
.timeline::before{content:"";position:absolute;left:5px;top:6px;bottom:6px;width:2px;background:var(--line)}
.tl{position:relative;padding-bottom:14px;font-size:14px}
.tl:last-child{padding-bottom:0}
.tl-dot{position:absolute;left:-21px;top:5px;width:11px;height:11px;border-radius:50%;background:var(--surface);border:2.5px solid var(--brand)}
.tl.ridge .tl-dot{border-color:var(--amber)}
.tl.view .tl-dot{border-color:var(--teal)}
.tl-name{font-weight:600}
.tl-meta{font-size:12px;color:var(--muted)}

/* ---------- 随记：路上遇到的人、听来的故事 ----------
   录入端一条一行（回车接着写），每条还能挂照片；展示端是一条条小条目 + 缩略图。
   两边共用一个编号，读的时候能对上"我写了几条"。 */
.memo-row{display:flex;align-items:flex-start;gap:8px;margin-bottom:8px}
.memo-row .memo-no{flex:0 0 21px;height:21px;line-height:19px;text-align:center;border-radius:6px;
  font-size:11px;font-weight:700;font-variant-numeric:tabular-nums;margin-top:6px;
  color:var(--muted);background:var(--panel2);border:1px solid var(--line)}
.memo-main{flex:1;min-width:0;display:flex;flex-direction:column;gap:8px}
.memo-row .memo-inp{width:100%;min-width:0}
.memo-side{flex:0 0 auto;display:flex;align-items:center;gap:2px;margin-top:1px}
/* 一条随记下方的照片小条：缩略图 + 右上角小叉 */
.memo-pics{display:flex;flex-wrap:wrap;gap:6px}
.memo-pic{position:relative;width:56px;height:56px;border-radius:8px;overflow:hidden;
  border:1px solid var(--line);background:var(--sunken)}
.memo-pic img{width:100%;height:100%;object-fit:cover;display:block}
.memo-pic .rm{position:absolute;top:0;right:0;width:19px;height:19px;border:0;padding:0;line-height:1;
  border-radius:0 0 0 8px;background:rgba(20,25,35,.62);color:#fff;cursor:pointer;
  display:grid;place-items:center;transition:background .16s var(--ease)}
.memo-pic .rm:hover{background:rgba(20,25,35,.85)}
.memo-pic .rm .ic{width:10px;height:10px}
.memo-pic-add,.memo-del{flex:0 0 30px;width:30px;height:30px;display:grid;place-items:center;padding:0;
  border:1px solid transparent;border-radius:8px;background:none;color:var(--muted);cursor:pointer;
  transition:background .16s var(--ease),color .16s var(--ease),border-color .16s var(--ease)}
.memo-pic-add:hover{background:var(--brand-soft);border-color:var(--brand-line);color:var(--brand)}
.memo-del:hover{background:var(--danger-soft);border-color:var(--danger-line);color:var(--danger)}
.memo-pic-add .ic,.memo-del .ic{width:13px;height:13px}
.memo-pic-add[disabled],.memo-pic-add.busy{opacity:.5;pointer-events:none}
/* 展示端 */
.memo-view{margin-top:12px;display:flex;flex-direction:column;gap:12px}
.memo-view::before{content:'';height:1px;background:var(--line);margin-bottom:1px}
.memo-item{display:flex;gap:10px;align-items:flex-start}
.memo-item .memo-no{flex:0 0 20px;height:20px;line-height:18px;text-align:center;border-radius:6px;
  font-size:11px;font-weight:700;font-variant-numeric:tabular-nums;margin-top:1px;
  color:var(--amber-ink);background:var(--amber-soft);border:1px solid var(--amber-line)}
.memo-item-body{flex:1;min-width:0}
.memo-item p{margin:0;font-size:14px;line-height:1.75;color:var(--ink2)}
.memo-photos{display:flex;flex-wrap:wrap;gap:8px;margin-top:8px}
.memo-photo{width:96px;height:96px;border-radius:12px;overflow:hidden;cursor:zoom-in;
  border:1px solid var(--line);background:var(--sunken);transition:transform .16s var(--ease),box-shadow .16s var(--ease)}
.memo-photo:hover{transform:translateY(-2px);box-shadow:0 8px 20px rgba(21,26,30,.16)}
.memo-photo img{width:100%;height:100%;object-fit:cover;display:block}

/* 媒体 */
.medias{display:grid;grid-template-columns:repeat(auto-fill,minmax(118px,1fr));gap:8px;margin-top:12px}
.mthumb{position:relative;aspect-ratio:1/1;border-radius:8px;overflow:hidden;border:1px solid var(--line);background:var(--sunken);cursor:zoom-in}
.mthumb img{width:100%;height:100%;object-fit:cover;display:block}
/* 图片拉取失败（断网 / 上传损坏）：占位而不是裂图 */
.mthumb img.img-broken,.memo-photo img.img-broken{display:flex;align-items:center;justify-content:center;background:var(--sunken);position:relative}
.mthumb img.img-broken::after,.memo-photo img.img-broken::after{content:"图片加载失败";position:absolute;inset:0;display:flex;align-items:center;justify-content:center;font-size:11px;color:var(--muted);background:repeating-linear-gradient(45deg,var(--sunken),var(--sunken) 8px,var(--line) 8px,var(--line) 9px)}
.medias.vids{grid-template-columns:repeat(auto-fill,minmax(190px,1fr))}
.vthumb{position:relative;border-radius:12px;overflow:hidden;border:1px solid var(--line);background:var(--sunken);cursor:pointer;aspect-ratio:16/10}
.vthumb img,.vthumb video{width:100%;height:100%;object-fit:cover;display:block}
.vplay{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;background:rgba(10,16,26,.24)}
.vplay span{width:44px;height:44px;border-radius:50%;background:rgba(255,255,255,.92);display:flex;align-items:center;justify-content:center;color:var(--brand);font-size:16px;padding-left:4px;box-shadow:0 4px 16px rgba(0,0,0,.25)}
.vname{position:absolute;left:0;right:0;bottom:0;padding:6px 10px;font-size:12px;color:#fff;background:linear-gradient(to top,rgba(8,14,24,.78),transparent);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.locked{background:var(--panel2);border:1px dashed var(--line);border-radius:12px;padding:18px;text-align:center;color:var(--muted);font-size:14px;margin-top:12px}

/* ============ 编辑器 ============ */
.group{border:1px solid var(--line);border-radius:12px;margin-bottom:12px;overflow:hidden;background:var(--surface)}
.group>summary{list-style:none;cursor:pointer;padding:12px 16px;font-size:14px;font-weight:600;display:flex;align-items:center;gap:8px;background:var(--panel2);user-select:none}
.group>summary::-webkit-details-marker{display:none}
.group>summary::before{content:"";width:6px;height:6px;border-right:1.8px solid var(--muted);border-bottom:1.8px solid var(--muted);transform:rotate(-45deg);transition:.2s;margin-left:2px}
.group[open]>summary::before{transform:rotate(45deg)}
.group>summary .cnt{margin-left:auto;font-size:12px;color:var(--muted);font-weight:400}
.group-body{padding:14px 16px;border-top:1px solid var(--line2)}

/* 途经点一行两块：上面「类型 + 名称」，下面「海拔 / 经纬度 / 定位 / 删」
   名称是这一行唯一必须填的字段，给它整行宽度；
   海拔与经纬度是"填完自动带出"的次要信息，退到第二行。 */
.dyn-row{
  display:grid;grid-template-columns:86px minmax(0,1fr) max-content 32px;
  grid-template-areas:"type name name name" "alt coord geo del";
  gap:6px 8px;align-items:center;padding:10px;margin-bottom:8px;
  border:1px solid var(--line);border-radius:12px;background:var(--panel2);
}
.dyn-row>[data-sk="type"]{grid-area:type}
.dyn-row>[data-sk="name"]{grid-area:name}
.dyn-row>[data-sk="alt"]{grid-area:alt}
.dyn-row>[data-sk="coord"]{grid-area:coord}
.dyn-row>.coord{grid-area:geo}
.dyn-row>.del{grid-area:del}
.dyn-row input,.dyn-row select{padding:8px 10px;font-size:14px;background:var(--surface)}
.dyn-row>[data-sk="coord"]{font-variant-numeric:tabular-nums;letter-spacing:-.01em}
/* 海拔是跟着坐标自动算出来的，得和用户手填的数字在外观上分得开：
   自动填 → 品牌淡色底 + 数字用等宽，一眼知道"这个不用我管"；
   正在取 → 沉底灰字，取回来自己就变回正常。改一下就转回手填样式，因为那是用户的数字了。 */
.dyn-row>[data-sk="alt"]{font-variant-numeric:tabular-nums;transition:background .16s var(--ease),border-color .16s var(--ease),color .16s var(--ease)}
.dyn-row>[data-sk="alt"].auto{background:var(--brand-soft);border-color:var(--brand-line);color:var(--brand-deep)}
.dyn-row>[data-sk="alt"].loading{background:var(--sunken);color:var(--muted);cursor:progress}
/* 手机宽度下再折一层：类型｜海拔｜删 一行，名称独占一行，经纬度与定位一行 */
@media(max-width:480px){
  .dyn-row{grid-template-columns:minmax(0,1fr) minmax(0,1fr) auto;grid-template-areas:"type alt del" "name name name" "coord coord geo";row-gap:8px}
  .dyn-row>.coord{justify-self:start}
}
.del{border:1px solid var(--line);background:var(--surface);color:var(--muted);border-radius:8px;width:32px;height:32px;cursor:pointer;font-size:16px;line-height:1;transition:background .16s var(--ease),color .16s var(--ease),border-color .16s var(--ease)}
.del:hover{background:var(--danger-soft);color:var(--danger);border-color:var(--danger-line)}
.coord{font-size:12px;color:var(--brand);background:var(--brand-soft);border:0;border-radius:8px;padding:0 10px;height:34px;cursor:pointer;white-space:nowrap;display:inline-flex;align-items:center;gap:6px}
.coord:hover{background:var(--brand);color:var(--on-brand)}

.charge-card{border:1px dashed var(--line);border-radius:12px;padding:12px;margin-bottom:10px;background:var(--panel2)}
.charge-head{display:flex;align-items:center;gap:8px;margin-bottom:10px}
.charge-head b{font-size:14px;color:var(--brand)}
.charge-head .del{margin-left:auto;width:28px;height:28px;font-size:14px}
.stars{display:flex;gap:4px;align-items:center}
.star{border:0;background:none;padding:0 1px;font-size:18px;line-height:1;color:var(--line);cursor:pointer;transition:color .16s var(--ease),transform .16s var(--ease)}
.star:hover{transform:scale(1.14)}
.star.on{color:var(--amber)}
.price-out{font-size:12px;color:var(--brand);margin-top:8px;background:var(--brand-soft);border-radius:8px;padding:6px 10px;display:inline-block}
/* 充电记录：截图识别与收费标准 */
.btn.xs{padding:2px 8px;font-size:12px;border-radius:6px}
.ocr-btns{display:flex;gap:6px;margin-left:auto;flex-wrap:wrap}
.charge-head .del{margin-left:2px}
.place-hint{display:none;font-size:12px;color:var(--amber-ink);background:var(--amber-soft);border:1px solid var(--amber-line);border-radius:8px;padding:6px 10px;margin-top:6px}
.place-hint .btn{margin-left:2px}
.tariff-box{margin-top:10px;border:1px solid var(--brand-line);background:var(--brand-soft);border-radius:8px;padding:10px 12px}
.tariff-box .tb-head{font-size:14px;font-weight:600;color:var(--brand-deep);margin-bottom:6px}
.tariff-box .tb-head span{font-weight:400;color:var(--muted);font-size:12px;margin-left:4px}
.tariff-box .tb-row{display:flex;align-items:center;gap:8px;font-size:14px;color:var(--ink2);padding:4px 0;border-top:1px dashed var(--brand-line)}
.tariff-box .tb-row:first-of-type{border-top:0}
.tariff-box .tb-row b{color:var(--danger);white-space:nowrap}
.tariff-box .tb-t{flex:1;min-width:0}
.tariff-box .tb-h{font-size:11px;color:var(--muted)}
.tariff-box .tb-srv b{color:var(--brand-deep)}
.tariff-box .tb-note{font-size:12px;color:var(--muted);margin-top:6px;line-height:1.6}
.li-tariff{margin-top:6px;font-size:14px;color:var(--ink2);background:var(--brand-soft);border:1px solid var(--brand-line);border-radius:8px;padding:6px 10px;line-height:1.7}
.uploader{border:1.5px dashed var(--line);border-radius:12px;padding:14px;text-align:center;color:var(--muted);font-size:14px;cursor:pointer;transition:.16s;background:var(--panel2)}
.uploader:hover{border-color:var(--brand);color:var(--brand);background:var(--brand-soft)}
.uploader b{color:var(--brand)}
.up-list{display:flex;flex-wrap:wrap;gap:8px;margin-top:10px}
.up-item{position:relative;width:82px;height:82px;border-radius:8px;overflow:hidden;border:1px solid var(--line);background:var(--sunken)}
.up-item img,.up-item video{width:100%;height:100%;object-fit:cover;display:block}
.up-item.wide{width:150px;height:94px}
.up-item .rm{position:absolute;top:0;right:0;width:21px;height:21px;border:0;border-radius:0 0 0 8px;background:rgba(20,25,35,.62);color:#fff;font-size:12px;cursor:pointer;padding:0;line-height:1}
.up-item .lbl{position:absolute;left:0;right:0;bottom:0;font-size:11px;color:#fff;background:rgba(10,16,26,.6);padding:2px 6px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* 上传进度条：见文件末尾（改成 transform:scaleX 走合成层，不再 transition width） */

.rowline{display:flex;align-items:center;gap:12px;padding:12px 0;border-bottom:1px solid var(--line2);flex-wrap:wrap}
.rowline:last-child{border-bottom:0}
.rowline .lab{font-size:14px}
.rowline .lab small{display:block;font-size:12px;color:var(--muted);font-weight:400;line-height:1.5}
.rowline .ctl{margin-left:auto;display:flex;align-items:center;gap:8px}
.switch{position:relative;width:44px;height:25px;border-radius:20px;background:var(--line);border:0;cursor:pointer;transition:.2s;flex:0 0 auto}
.switch::after{content:"";position:absolute;top:3px;left:3px;width:19px;height:19px;border-radius:50%;background:var(--surface);transition:.2s;box-shadow:0 1px 3px rgba(0,0,0,.2)}
.switch.on{background:var(--brand)}
.switch.on::after{transform:translateX(19px)}

.dayrow{display:flex;align-items:center;gap:10px;padding:10px 12px;border:1px solid var(--line);border-radius:12px;margin-bottom:8px;cursor:pointer;background:var(--surface)}
.dayrow:hover{border-color:var(--muted);background:var(--panel2)}
.dayrow .dn{font-size:12px;color:var(--brand);background:var(--brand-soft);border-radius:6px;padding:2px 8px;flex:0 0 auto}
.dayrow .tt{font-size:14px;font-weight:500}
.dayrow .mm{font-size:12px;color:var(--muted);margin-top:2px}
.dayrow .rt{margin-left:auto;display:flex;gap:6px;align-items:center;flex-wrap:wrap;justify-content:flex-end}
.dayrow .dh{flex:0 0 auto;font-size:16px;line-height:1;color:var(--muted);cursor:grab;user-select:none;padding:4px 2px;letter-spacing:-2px}
.dayrow .dh:active{cursor:grabbing}
.dayrow.dragging{opacity:.45;border-style:dashed;border-color:var(--brand)}
.dayrow.drag-over{border-color:var(--brand);background:var(--brand-soft)}
.btn.ico{padding:0;width:32px;min-width:32px;font-size:14px;line-height:1}
/* 原来这里又写了一遍 .btn[disabled]{opacity:.35;cursor:default}，与上面的规则同选择器、
   位置更后，于是 cursor 被覆盖成 default（.35 因为上面没声明 opacity 而继续生效）——
   形成一条"混血"规则：一半是新写法、一半是老写法。CSS 是按属性逐条层叠的，
   不是整条覆盖，这里只需要补 cursor。 */
.btn[disabled]{cursor:not-allowed}

/* ============ 登录 ============ */
.auth-wrap{max-width:400px;margin:36px auto}
.auth-card{background:var(--surface);border:1px solid var(--line);border-radius:var(--r-lg);box-shadow:var(--shadow-lg);padding:26px}
.auth-card h2{font-size:18px;margin-bottom:4px}
.auth-card .sub{font-size:14px;color:var(--muted);margin-bottom:18px}
.auth-brand{display:flex;align-items:center;gap:12px;margin-bottom:4px}
.auth-logo{width:44px;height:44px;border-radius:12px;background:var(--brand);color:var(--on-brand);display:flex;align-items:center;justify-content:center;font-size:22px;font-weight:700;flex:0 0 auto}
.auth-slogan{font-size:14px;color:var(--muted);margin-top:2px}
.auth-links{display:flex;gap:10px;align-items:center;justify-content:center;margin-top:14px;font-size:14px}
.auth-links a{color:var(--brand);cursor:pointer}
.authtabs{display:flex;gap:6px;background:var(--panel2);border:1px solid var(--line);border-radius:12px;padding:4px;margin-bottom:18px}
.authtabs button{flex:1;border:0;background:none;border-radius:8px;padding:8px;font-size:14px;color:var(--muted);cursor:pointer;font-weight:500}
.authtabs button.on{background:var(--surface);color:var(--brand);box-shadow:0 1px 3px rgba(21,26,30,.08)}
.code-row{display:flex;gap:8px}
.code-row input{flex:1}
.code-row .btn{flex:0 0 auto;white-space:nowrap}
.err{background:var(--danger-soft);color:var(--danger);font-size:14px;border-radius:8px;padding:10px 12px;margin-bottom:12px}
.okmsg{background:var(--ok-soft);color:var(--ok);font-size:14px;border-radius:8px;padding:10px 12px;margin-bottom:12px}

/* ============ 头像 ============ */
.avatar-img{border-radius:50%;object-fit:cover;display:inline-block;flex:0 0 auto;background:var(--sunken)}
.me-ava{display:flex;align-items:center;gap:14px}
.me-ava .me-ava-txt{min-width:0}
.me-ava .hint{margin:4px 0 0;font-size:12px}
.ava-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:10px}
.ava-pick{border:2px solid transparent;background:var(--panel2);border-radius:12px;padding:8px 4px 6px;cursor:pointer;display:flex;flex-direction:column;align-items:center;gap:4px;transition:.16s}
.ava-pick svg{border-radius:50%}
.ava-pick span{font-size:11px;color:var(--muted)}
.ava-pick:hover{background:var(--brand-soft)}
.ava-pick.on{border-color:var(--brand);background:var(--brand-soft)}
.ava-pick.on span{color:var(--brand);font-weight:600}
.ava-review{display:flex;flex-direction:column;gap:10px}
.ava-rv{display:flex;align-items:center;gap:12px;border:1px solid var(--line);border-radius:12px;padding:10px 12px;background:var(--surface)}
.ava-rv img{width:44px;height:44px}
.ava-rv-txt{display:flex;flex-direction:column;min-width:0}
.ava-rv-acts{margin-left:auto;display:flex;gap:8px}

/* ============ 图表 ============ */
.chart-card{background:var(--panel);border:1px solid var(--line);border-radius:var(--r);box-shadow:var(--shadow);padding:16px;margin-bottom:14px}
.chart-card h3{font-size:16px;margin-bottom:2px}
.chart-card .desc{font-size:12px;color:var(--muted);margin-bottom:12px}
.chart-card svg{display:block;width:100%;height:auto;overflow:visible}
/* 住宿方式统计：响应式 HTML 列表，替代原 SVG 固定坐标布局 */
.lodge-stats{display:flex;flex-direction:column;gap:10px;margin-top:4px}
.ls-head{display:grid;grid-template-columns:minmax(0,1.1fr) minmax(0,1.4fr) auto auto;gap:12px;font-size:11px;color:var(--muted);padding:0 4px}
.ls-row{display:grid;grid-template-columns:minmax(0,1.1fr) minmax(0,1.4fr) auto auto;gap:12px;align-items:center;padding:10px 12px;background:var(--panel2);border-radius:12px;border:1px solid var(--line2)}
.ls-name{display:flex;align-items:center;gap:8px;font-size:14px;color:var(--ink);font-weight:500;min-width:0}
.ls-name i{flex:0 0 10px;height:10px;border-radius:3px}
/* 高 20px 的横条，圆角取半高就是胶囊 —— 归到 --r-pill，不再单独占一档 */
.ls-bar{position:relative;height:20px;background:var(--line2);border-radius:var(--r-pill);overflow:hidden;display:flex;align-items:center}
.ls-bar span{position:absolute;left:0;top:0;bottom:0;border-radius:var(--r-pill);opacity:.85}
.ls-bar b{position:relative;z-index:1;margin-left:auto;padding:0 8px;font-size:12px;font-weight:600;color:var(--ink);text-shadow:0 0 4px rgba(255,255,255,.7)}
.ls-total,.ls-avg{text-align:right;font-size:14px;color:var(--ink);font-variant-numeric:tabular-nums;white-space:nowrap}
.ls-avg small{font-size:11px;color:var(--muted);margin-left:2px}
.ls-foot{font-size:12px;color:var(--muted);padding:2px 4px}
@media(max-width:560px){
  .ls-head{display:none}
  .ls-row{grid-template-columns:minmax(0,1fr) auto;gap:8px 10px;padding:10px 12px}
  .ls-name{grid-column:1}
  .ls-total{grid-column:2;text-align:right}
  .ls-bar{grid-column:1/-1;order:3}
  .ls-avg{display:none}
}
.legend{display:flex;flex-wrap:wrap;gap:12px;margin-top:10px;font-size:12px;color:var(--muted)}
.legend i{display:inline-block;width:9px;height:9px;border-radius:3px;margin-right:6px;vertical-align:middle}
.tabs-inline{display:flex;gap:6px;margin-bottom:14px;flex-wrap:wrap}
.tabs-inline button{border:1px solid var(--line);background:var(--surface);border-radius:8px;padding:6px 14px;font-size:14px;cursor:pointer;color:var(--ink2)}
.tabs-inline button.on{background:var(--brand);border-color:var(--brand);color:var(--on-brand)}

/* ============ 充电站台账 ============ */
.st-item{border:1px solid var(--line);border-radius:12px;padding:12px;margin-bottom:10px;background:var(--surface)}
.st-top{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.st-name{font-size:14px;font-weight:600}
.st-brand{font-size:11px;background:var(--brand-soft);color:var(--brand);border-radius:6px;padding:2px 8px}
.st-date{font-size:12px;color:var(--muted);margin-left:auto}
.st-row{display:flex;flex-wrap:wrap;gap:6px;margin-top:8px}
.st-review{font-size:14px;color:var(--ink2);margin-top:10px;background:var(--panel2);border-left:3px solid var(--line);padding:8px 12px;border-radius:0 8px 8px 0;white-space:pre-wrap}
.st-thumbs{display:flex;flex-wrap:wrap;gap:8px;margin-top:10px}
.st-thumbs .mthumb{width:76px;height:76px;aspect-ratio:auto}

/* ============ 弹层 ============ */
.modal{position:fixed;inset:0;background:var(--scrim);display:none;align-items:center;justify-content:center;z-index:300;padding:20px;padding-bottom:calc(20px + env(safe-area-inset-bottom))}
.modal.on{display:flex;animation:fadeIn var(--t-mid) var(--ease)}
.modal-box{background:var(--surface);border-radius:var(--r-lg);box-shadow:var(--shadow-lg);max-width:520px;width:100%;max-height:88dvh;overflow:auto;padding:22px;animation:popIn var(--t-slow) var(--ease-pop)}
.modal-box.wide{max-width:680px}
.modal-box h3{font-size:18px;margin-bottom:8px}
/* 确认弹窗正文：原来是内联的 #3b4859（旧蓝灰），深色下几乎读不出来；
   改类名为的是两套主题都跟着 --ink2 走，也不用在 JS 里写颜色。 */
.cf-txt{color:var(--ink2);font-size:14px;line-height:1.6;margin:0 0 4px}
.modal-actions{display:flex;gap:10px;justify-content:flex-end;margin-top:18px}
.modal-box img,.modal-box video{max-width:100%;border-radius:8px;display:block;margin:0 auto}
.lightbox-box{background:transparent;box-shadow:none;padding:0;max-width:96vw;display:flex;flex-direction:column;align-items:center;gap:10px}
.lightbox-box img{max-height:80vh;max-height:80dvh;border-radius:12px}
.lightbox-box .cap{color:rgba(255,255,255,.85);font-size:14px}
.lightbox-box .x{align-self:flex-end;background:rgba(255,255,255,.16);color:#fff;border:1px solid rgba(255,255,255,.3)}

/* 悬浮提示贴着屏幕底，有 Home 指示条的机型要避开安全区，否则会被压住一半 */
.toast{position:fixed;left:50%;bottom:30px;bottom:calc(30px + env(safe-area-inset-bottom));transform:translate(-50%,20px);background:var(--ink);color:var(--bg);font-size:14px;padding:12px 20px;border-radius:12px;opacity:0;pointer-events:none;transition:.32s;z-index:500;box-shadow:0 10px 30px rgba(0,0,0,.25);max-width:88vw;text-align:center}
.toast.on{opacity:1;transform:translate(-50%,0)}
/* 错误 toast 的底换成 --danger 后，文字必须同步换成"铺在实色上的"文字色：
   沿用 --bg（页面底米色）压在 --danger 上只有 3.76:1。改 --on-brand 后浅色 5.36 / 深色 7.74。 */
.toast.err{background:var(--danger);color:var(--on-brand)}

.spinner{width:16px;height:16px;border:2px solid currentColor;border-right-color:transparent;opacity:.85;border-radius:50%;animation:spin .7s linear infinite;display:inline-block}
@keyframes spin{to{transform:rotate(360deg)}}
.loading-page{text-align:center;padding:60px 0;color:var(--muted);font-size:14px;display:flex;flex-direction:column;align-items:center;gap:14px}
.loading-page .spinner{border-color:var(--line);border-top-color:var(--brand);width:26px;height:26px;border-width:3px;margin-bottom:14px}
/* 加载页：路牌 + 一条跑着的路（比转圈更贴产品） */
.loading-page .lgmark{width:46px;height:46px}
.lp-road{position:relative;width:104px;height:3px;border-radius:2px;background:var(--line);overflow:hidden}
.lp-road i{position:absolute;top:0;left:0;width:38px;height:100%;border-radius:2px;background:var(--accent);animation:lpRun 1.2s cubic-bezier(.45,.05,.55,.95) infinite}
@keyframes lpRun{0%{transform:translateX(-42px)}100%{transform:translateX(106px)}}

/* 路线图 */
.routemap{background:var(--panel2);border:1px solid var(--line);border-radius:12px;overflow:hidden}
.routemap svg{display:block;width:100%;height:auto}
/* 卫星/标准底图路线图 */
/* user-select:none：按住拖动时不要把图例、版权那两行字一起抹成选区（也顺带避免拖出手型的光标） */
.rtmap{position:relative;width:100%;aspect-ratio:840/520;border-radius:12px;overflow:hidden;background:var(--ink);user-select:none;-webkit-user-select:none}
/* 行程回放卡里的地图：按默认 840/520 在宽屏上会占掉六成视口高，
   把下面的海拔剖面与播放控件全挤出首屏，看动画要来回滚。
   这里压成 2:1 的横幅。只作用于回放卡 —— 路线详情页的路线图本来就是那一页的主角，保持原比例。
   注意：svg 用的是 preserveAspectRatio="slice"，画布比框「更瘦」时会被裁掉上下，
   好在路线包围盒四周留了 56 单位空白（见 charts.js routeMap 的 PAD），2:1 下裁掉约 54 单位、仍有余量。 */
.anim-map .rtmap{aspect-ratio:2/1}
.rt-canvas{position:absolute;inset:0;transition:transform .32s ease,transform-origin .32s linear;will-change:transform}
/* 放大后才拦截手势做单指拖动（未放大时不抢页面的滚动）；拖动中关掉过渡，手感跟手不粘滞 */
.rtmap.rt-zoomed{cursor:grab}
/* 1× 也用 pan-x pan-y：放行单指页面滚动、但禁用浏览器自己的捏合 —— 
   否则双指捏合的第一帧发生在 touch-action:auto 元素上，可能被浏览器 pointercancel 掉，
   第一帧缩放就丢了。iOS Safari < 13 不支持 Pointer Events，手势在该平台上不工作（可接受降级）。 */
.rt-canvas{touch-action:pan-x pan-y}
.rtmap.rt-zoomed .rt-canvas{touch-action:none}
.rtmap.rt-dragging,.rtmap.rt-dragging .rt-canvas{cursor:grabbing}
.rtmap.rt-dragging .rt-canvas{transition:none;touch-action:none}
.rt-tiles{position:absolute;inset:0}
/* 瓦片「代」：换层级时新一代先铺上去加载，旧的继续顶着，新图到位再撤 —— 过程中不露白 */
.rt-tilegen{position:absolute;inset:0;transition:opacity .3s ease}
.rt-tilegen.pending{opacity:0}
.rt-tiles img{position:absolute;display:block;user-select:none;-webkit-user-drag:none}
.rtmap.no-tiles .rt-tiles{display:none}
.rt-overlay{position:absolute;inset:0;width:100%;height:100%;display:block}
.rt-overlay text,.rt-overlay .rt-anchor{user-select:none}
/* 注记的反向缩放要与画布缩放同步过渡，否则缩放瞬间会「先缩后弹」 */
.rt-overlay .rt-anchor{transition:transform .32s ease}
.rtmap.rt-dragging .rt-overlay .rt-anchor{transition:none}
/* 1× 视图里先收起海拔小字，把地方让给地名；放大后再一起显示 */
.rt-lb.no-sub .lb-s{display:none}
/* 播放时的进度头：一圈慢慢散开的脉冲，让人一眼看出「车在这儿、在往前走」 */
.rt-ping{transform-box:fill-box;transform-origin:center;animation:rtPing 1.9s cubic-bezier(.22,.6,.36,1) infinite}
@keyframes rtPing{0%{transform:scale(.55);opacity:.85}70%{opacity:.12}100%{transform:scale(2.15);opacity:0}}
/* 图例放在 HTML 层：缩放、拖动都跟着视口，不会被一起放大 */
.rt-legend{position:absolute;left:10px;bottom:10px;z-index:3;display:flex;flex-direction:column;gap:4px;padding:8px 12px;border-radius:8px;background:var(--float);border:1px solid var(--float-line);font-size:12px;color:var(--ink2);pointer-events:none;box-shadow:0 2px 8px rgba(21,26,30,.16)}
.rt-legend span{display:flex;align-items:center;gap:8px;line-height:1.5;white-space:nowrap}
.rt-legend i{width:11px;height:11px;border-radius:50%;flex:none;box-shadow:0 0 0 1px rgba(10,20,35,.12)}
.rt-attr{position:absolute;right:8px;bottom:6px;z-index:3;font-size:11px;color:rgba(255,255,255,.82);background:rgba(10,16,26,.5);padding:2px 8px;border-radius:6px;pointer-events:none;backdrop-filter:blur(2px)}
.rt-ctrls{position:absolute;right:8px;top:8px;z-index:5;display:flex;flex-direction:column;gap:6px}
.rt-ctrls button{width:32px;height:32px;border-radius:8px;border:1px solid rgba(255,255,255,.22);background:rgba(12,20,32,.62);color:#fff;font-size:16px;line-height:1;cursor:pointer;backdrop-filter:blur(3px);transition:background .16s}
.rt-ctrls button:hover{background:rgba(30,44,66,.85)}
.rtmap.rt-full{position:fixed;inset:0;z-index:200;border-radius:0;aspect-ratio:auto;height:100vh;height:100dvh;width:100vw;touch-action:none}
.rtmap.rt-full .rt-ctrls button[data-a="full"]{background:rgba(240,140,30,.85)}
/* 播放动画时的「第 N 天」提示条 */
.rt-daytip{position:absolute;left:50%;top:14px;transform:translate(-50%,-8px);z-index:4;max-width:86%;font-size:14px;color:#fff;background:rgba(12,20,32,.86);border:1px solid rgba(255,255,255,.16);border-radius:20px;padding:8px 16px;opacity:0;transition:opacity .32s ease,transform .32s ease;pointer-events:none;backdrop-filter:blur(4px);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.rt-daytip.on{opacity:1;transform:translate(-50%,0)}
.rt-list{display:flex;flex-wrap:wrap;gap:6px;margin-top:10px}

/* ============ 车辆信息 ============ */
.vehicle-bar{display:flex;align-items:center;gap:10px;background:var(--panel);border:1px solid var(--line);border-radius:var(--r);box-shadow:var(--shadow);padding:12px 16px;margin-bottom:14px;flex-wrap:wrap}
.car-ico{font-size:22px;line-height:1;color:var(--brand);display:inline-flex}
.vb-line{display:flex;flex-wrap:wrap;gap:8px;align-items:center;font-size:14px;color:var(--ink2)}

/* ---------- 车牌 ----------
   等宽＋宽字距是照真牌上的冲压字做的；圆角只给 3px（真牌是折边不是圆角），
   一层内描边模拟那圈白边。颜色本身是信息：绿=能充电，蓝=只加油。 */
.plate-tag{display:inline-flex;align-items:center;line-height:1;vertical-align:middle;
  font-family:ui-monospace,SFMono-Regular,"SF Mono",Menlo,Consolas,"Liberation Mono",monospace;
  font-size:14px;font-weight:700;letter-spacing:.07em;
  padding:4px 6px 4px 8px;border-radius:3px;white-space:nowrap;
  border:1px solid rgba(0,0,0,.24);box-shadow:inset 0 0 0 1px rgba(255,255,255,.16)}
.plate-tag.p-blue{background:var(--plate-blue);color:#fff;box-shadow:inset 0 0 0 1px var(--plate-blue-line)}
.plate-tag.p-green{background:var(--plate-green);color:#0B2A19;box-shadow:inset 0 0 0 1px var(--plate-green-line)}
/* 车牌 + 眼睛按钮贴在一起，中间不留那 7px 的常规间距 */
.vb-plate{display:inline-flex;align-items:center;gap:4px}
.plate-eye{display:inline-grid;place-items:center;width:28px;height:28px;padding:0;
  /* 负外边距：按钮比这行的字高，不抵消掉的话车辆条会比访客视角高出 3px */
  margin:-6px -4px -6px 0;
  border:1px solid transparent;border-radius:6px;background:none;color:var(--ink3);cursor:pointer;
  transition:background var(--t-fast) var(--ease),color var(--t-fast) var(--ease),border-color var(--t-fast) var(--ease)}
.plate-eye:hover{background:var(--panel2);border-color:var(--line);color:var(--ink)}
.plate-eye .ic{width:15px;height:15px}
.plate-eye[disabled]{opacity:.5;cursor:default}

.chip.f{background:var(--amber-soft);color:var(--amber-ink)}
.chip.l{background:var(--purple-soft);color:var(--purple)}
.v.l{color:var(--ink)}

/* 设施多选 */
.chips-pick{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:12px}
.chips-pick button{border:1px solid var(--line);background:var(--surface);border-radius:20px;padding:6px 12px;font-size:14px;color:var(--ink2);cursor:pointer;transition:.16s}
.chips-pick button:hover{border-color:var(--muted);background:var(--panel2)}
.chips-pick button.on{background:var(--brand);border-color:var(--brand);color:var(--on-brand)}

/* 星级（只读） */
.stars-ro{display:inline-flex;gap:1px;color:var(--line);font-size:14px;line-height:1}
.stars-ro .on{color:var(--amber)}

/* 住宿卡片 */
.lod-card{margin-top:12px;border:1px solid var(--line);border-radius:12px;padding:12px 14px;background:var(--panel2)}
.lod-card.carlife{background:var(--ok-soft)}
.lod-head{display:flex;align-items:center;gap:8px;flex-wrap:wrap;font-size:14px}
.lod-type{font-size:12px;background:var(--purple-soft);color:var(--purple);border-radius:6px;padding:4px 10px;font-weight:600}
.lod-card.carlife .lod-type{background:var(--ok-soft);color:var(--ok)}
.li-price{margin-left:auto;font-size:14px;font-weight:600;color:var(--ink)}
.lod-fac{display:flex;flex-wrap:wrap;gap:6px;margin-top:10px}
.lod-env{font-size:14px;color:var(--ink2);margin-top:10px}
.lod-camp{font-size:14px;color:var(--ok);background:var(--ok-soft);border-radius:8px;padding:6px 10px;margin-top:10px;line-height:1.6}
.lod-review{font-size:14px;color:var(--ink2);margin-top:10px;background:var(--surface);border-left:3px solid var(--line);padding:8px 12px;border-radius:0 8px 8px 0;white-space:pre-wrap}
.lod-card.carlife .lod-review{border-left-color:var(--ok-soft)}

/* 台账 */
.ledger-sum{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:14px}
.ls-chip{font-size:12px;background:var(--panel2);border:1px solid var(--line);border-radius:8px;padding:6px 12px;color:var(--ink2);font-variant-numeric:tabular-nums}
.ls-chip b{color:var(--ink);margin-right:6px}
.ledger-item{border:1px solid var(--line);border-radius:12px;padding:12px;margin-bottom:10px;background:var(--surface)}
.li-head{display:flex;align-items:center;gap:8px;flex-wrap:wrap;font-size:14px}
.li-meta{font-size:12px;color:var(--muted);margin-top:6px;line-height:1.7}
.li-review{font-size:14px;color:var(--ink2);margin-top:8px;background:var(--panel2);border-left:3px solid var(--line);padding:8px 12px;border-radius:0 8px 8px 0;white-space:pre-wrap}

/* ============ 旅人编号 ============ */
.member-card{background:var(--surface);border-color:var(--brand-line)}
.mc-badge{display:inline-block;font-size:14px;background:var(--brand);color:var(--on-brand);border-radius:20px;padding:6px 16px;font-weight:500}
.mc-badge b{font-size:16px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;margin:0 2px}
.mc-line{font-size:14px;color:var(--ink2);margin-top:12px;line-height:1.85}
.mc-sub{font-size:14px;color:var(--muted);margin-top:8px}
/* 整条青绿底铺在最上面，冷色压在暖米页面上、色温打架，也把一个「提示」
   抬成了和 hero 同级的分区。改成暖底 + 左侧一道品牌色标记：色温统一了，
   品牌色退成"记号"而不是"底色"。 */
.member-strip{background:var(--panel2);border:1px solid var(--line);border-left:3px solid var(--brand);border-radius:12px;padding:10px 16px;font-size:14px;color:var(--ink2);margin-bottom:14px;display:flex;flex-wrap:wrap;gap:10px;align-items:center}
.member-strip b{color:var(--brand);font-size:16px}
.member-strip span{color:var(--muted);font-size:12px}

/* 欢迎弹窗 */
.welcome{text-align:center}
.w-badge{display:inline-block;font-size:14px;background:var(--brand);color:var(--on-brand);border-radius:20px;padding:6px 16px;font-weight:500;margin-bottom:16px}
.w-badge b{font-size:18px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;margin:0 4px}
.welcome h3{font-size:18px;margin-bottom:12px}
.welcome p{font-size:14px;color:var(--ink2);line-height:1.9;text-align:left}
.w-sub{font-size:14px;color:var(--muted);margin-top:14px;padding-top:14px;border-top:1px dashed var(--line)}
.welcome .modal-actions{justify-content:center}

/* ============ 页脚链接 ============ */
/* 实测 31px，差 1px 到 32；1245 行那条只在移动端补过，桌面端没有。统一到 32。 */
.foot-links a{display:inline-flex;align-items:center;min-height:32px;font-size:12px;color:var(--foot-fg);padding:0 2px;opacity:.92}
/* 这里原来又把 hover 改回 --brand —— 页脚是 --foot-bg(#151A1E) 深底，
   品牌青压上去只有 2.75:1，悬停反而比静止更看不清。
   悬停色沿用上面 261 行那条的 --foot-strong，此处不重复声明。 */

/* ============ 登录/注册 通道切换与条款 ============ */
.chswitch{display:flex;gap:4px;margin-bottom:14px}
.chswitch button{flex:1;border:1px solid var(--line);background:var(--surface);border-radius:8px;padding:8px;font-size:14px;color:var(--muted);cursor:pointer;font-weight:500;transition:.16s}
.chswitch button.on{background:var(--brand-soft);border-color:var(--brand-line);color:var(--brand)}
.agree{display:flex;gap:10px;align-items:flex-start;font-size:14px;color:var(--ink2);line-height:1.7;margin:4px 0 14px;cursor:pointer}
.agree input{margin-top:4px;flex:0 0 auto;width:15px;height:15px;accent-color:var(--brand)}
.agree a{font-weight:500}
.legal-note{margin-top:16px;padding-top:14px;border-top:1px dashed var(--line);font-size:12px;color:var(--muted);line-height:1.85;text-align:left}

/* ============ 规则 / 隐私页 ============ */
.legal h1{font-size:18px;margin-bottom:6px}
.legal-meta{font-size:14px;color:var(--muted);margin-bottom:22px}
.legal-sec{margin-bottom:22px}
/* 章节标题原用 --brand，实测 4.43:1 差一点不达 AA；换深一档的 --brand-deep（7.06:1）。 */
.legal-sec h2{font-size:16px;color:var(--brand-deep);margin-bottom:8px}
.legal-sec p{font-size:14px;color:var(--ink2);line-height:1.95;margin-bottom:8px}
.legal-foot{margin-top:26px;padding:14px 16px;background:var(--panel2);border:1px solid var(--line);border-radius:12px;font-size:14px;color:var(--muted);line-height:1.8}

/* ============ 视频外链 ============ */
.videos{display:flex;flex-direction:column;gap:12px;margin-top:12px}
.vembed{border:1px solid var(--line);border-radius:12px;overflow:hidden;background:var(--surface)}
.vembed iframe{display:block;width:100%;height:auto;aspect-ratio:16/9;border:0}
.vembed-cap{display:flex;align-items:center;gap:10px;padding:10px 12px;font-size:14px;color:var(--ink2);border-top:1px solid var(--line2);flex-wrap:wrap}
.vembed-cap a{margin-left:auto;font-size:14px}
.vplat{font-size:11px;background:var(--brand-soft);color:var(--brand);border-radius:6px;padding:2px 8px;flex:0 0 auto}
.vlink{display:flex;align-items:center;gap:12px;border:1px solid var(--line);border-radius:12px;padding:12px 14px;background:var(--surface);color:var(--ink)}
.vlink:hover{border-color:var(--brand-line);background:var(--panel2)}
.vplay-ico{width:34px;height:34px;border-radius:50%;background:var(--brand-soft);color:var(--brand);display:flex;align-items:center;justify-content:center;font-size:14px;flex:0 0 auto}
.vlink-body{display:flex;flex-direction:column;line-height:1.4;overflow:hidden}
.vlink-body b{font-size:14px;font-weight:500;color:var(--ink)}
.vlink-body small{font-size:12px;color:var(--muted)}
.vr-row{display:flex;gap:8px;flex-wrap:wrap;margin-top:8px}
.vr-row input{flex:1;min-width:200px}
.vr-row input:last-of-type{flex:0 0 170px;min-width:0}
.vlist{display:flex;flex-direction:column;gap:6px;margin-top:10px}
.vrow{display:flex;align-items:center;gap:10px;border:1px solid var(--line);border-radius:8px;padding:8px 12px;font-size:14px;background:var(--panel2)}
.vrow-t{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--ink2)}
.vrow .rm{border:0;background:none;color:var(--muted);font-size:16px;cursor:pointer;padding:0 2px;line-height:1}

/* ============ 导出 ============ */
.export-opts{display:flex;flex-direction:column;gap:4px}
.export-opts .btn.block{margin-top:6px}

/* ============ 封禁页 ============ */
.banned-card{text-align:center;padding:32px 22px}
.banned-card h2{font-size:18px;color:var(--danger);margin-bottom:12px}
.banned-card p{font-size:14px;color:var(--ink2);line-height:1.9;max-width:460px;margin:0 auto 12px}
.ban-reason{display:inline-block;background:var(--danger-soft);color:var(--danger);border-radius:8px;padding:8px 16px;font-size:14px;margin:6px 0 14px}
.banned-card .modal-actions{justify-content:center;margin-top:18px}

/* ============ 管理后台 ============ */
.admin-note{background:var(--amber-soft);border:1px solid var(--amber-line);border-radius:12px;padding:12px 16px;font-size:14px;color:var(--amber-ink);line-height:1.85;margin-bottom:16px}
.tbl-wrap{overflow-x:auto;-webkit-overflow-scrolling:touch}
.tbl{width:100%;border-collapse:collapse;font-size:14px}
.tbl th{text-align:left;font-weight:500;color:var(--muted);font-size:12px;padding:8px 10px;border-bottom:1px solid var(--line);white-space:nowrap}
.tbl td{padding:10px;border-bottom:1px solid var(--line2);vertical-align:top}
.tbl tr:last-child td{border-bottom:0}
.tbl .uid{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12px;color:var(--muted)}
.rpt-list{display:flex;flex-direction:column;gap:10px;margin-top:10px}
.rpt-item{border:1px solid var(--line);border-radius:12px;padding:12px 14px;background:var(--panel2)}
/* 「已处理」原来靠整卡降透明度表达（.6）—— 透明度会连文字一起压，
   实测浅色下 muted 只剩 2.30:1、ink2 只剩 3.07:1，全部跌破 AA，
   用户还得靠"变淡"去猜状态。改成只把底与边框换成次级色，文字保持不透明，
   状态交给「已处理」角标说。
   另外举报内容里常有长 URL / 邮箱，不换行会把整页撑到 1279px 宽。 */
.rpt-item.done{background:var(--sunken);border-color:var(--line2)}
.rpt-head{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-bottom:6px}
.rpt-body{font-size:14px;color:var(--ink);min-width:0;overflow-wrap:anywhere;word-break:break-word}
.rpt-detail{font-size:14px;color:var(--ink2);margin-top:6px;line-height:1.7;min-width:0;overflow-wrap:anywhere;word-break:break-word}
.rpt-meta{font-size:12px;color:var(--muted);margin-top:6px;min-width:0;overflow-wrap:anywhere}
.rpt-acts{display:flex;gap:8px;margin-top:10px;flex-wrap:wrap}

/* ============ 建议与反馈 ============ */
.fb-kinds{display:flex;gap:8px;flex-wrap:wrap;margin-bottom:12px}
.fb-kind{display:inline-flex;align-items:center;gap:6px;padding:8px 14px;border:1px solid var(--line);border-radius:999px;background:var(--surface);font-size:14px;color:var(--ink2);cursor:pointer;min-height:36px}
.fb-kind span{font-size:14px}
.fb-kind.on{border-color:var(--brand);background:var(--brand-soft);color:var(--brand);font-weight:500}
.fb-list{display:flex;flex-direction:column;gap:10px}
.fb-item{border:1px solid var(--line);border-radius:12px;padding:12px 14px;background:var(--panel2)}
/* 同 .rpt-item.done：不降整卡透明度（会把文字压到 2.82:1），改用次级底。 */
.fb-item.done{background:var(--sunken);border-color:var(--line2)}
.fb-head{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-bottom:6px}
.fb-kind-t{font-size:12px;color:var(--brand);background:var(--brand-soft);border-radius:6px;padding:2px 8px}
.fb-st{font-size:12px;color:var(--muted);border:1px solid var(--line);border-radius:6px;padding:1px 8px}
.fb-st.ok{color:var(--ok);border-color:var(--ok-line);background:var(--ok-soft)}
.fb-time{margin-left:auto;font-size:11px;color:var(--muted)}
.fb-body{font-size:14px;color:var(--ink);line-height:1.75;word-break:break-word;white-space:pre-wrap}
.fb-reply{margin-top:8px;font-size:14px;color:var(--ink2);background:var(--ok-soft);border-radius:8px;padding:8px 10px;line-height:1.7;word-break:break-word}
.fb-reply b{color:var(--ok);font-weight:600}
@media(max-width:560px){.fb-kind{padding:10px 14px;font-size:14px}.fb-time{margin-left:0}}

@media(max-width:640px){
  .tbl th:nth-child(4),.tbl td:nth-child(4),.tbl th:nth-child(5),.tbl td:nth-child(5){display:none}
  .vr-row input:last-of-type{flex:1 1 100%}
}

/* ============================================================
   移动端适配（≤560px：顶栏横滚、卡片收紧、触控目标加大）
   ============================================================ */
@media(max-width:560px){
  /* 顶栏：导航可横向滑动，用户名收起 */
  .tb-inner{padding-top:8px;padding-bottom:8px;gap:10px}
  .brand-text em{display:none}
  .brand-text{font-size:16px}
  .lgmark{width:30px;height:30px}
  .tb-nav{overflow-x:auto;-webkit-overflow-scrolling:touch;scrollbar-width:none;margin-left:0;flex:1 1 auto;min-width:0}
  .tb-nav::-webkit-scrollbar{display:none}
  .tb-nav a{padding:8px 10px;font-size:14px;white-space:nowrap}
  /* 窄屏把用户名收起来：顶栏挤不下时最后一项会被切成半截字（曾出现「用」）。
     头像本身就能识别身份，点进去还能看到完整昵称。 */
  .tb-name{display:none}
  .tb-name{display:none}
  /* 页面与卡片收紧 */
  .view{padding-top:14px;padding-bottom:32px}
  .card{padding:14px}
  .hero{padding:20px 16px}
  .hero h1{font-size:18px}
  .page-head h1{font-size:18px}
  .card-head{flex-wrap:wrap;gap:6px}
  /* 按钮与触控目标 */
  .btn{padding:12px 16px;font-size:16px}
  .btn.sm{padding:8px 12px;font-size:14px}
  .btn.block.lg{width:100%;padding:14px;font-size:16px}
  input,select,textarea{font-size:16px}  /* 防 iOS 聚焦自动放大 */
  .del{width:40px;height:40px;font-size:18px}
  .charge-head .del{width:34px;height:34px}          /* 记录卡右上角删除键原本 28px，补齐热区 */
  .coord{padding:8px 10px;font-size:12px}
  /* 触控热区补齐：正文链接 / 筛选 chip / 分段按钮 / 开关 / 滑块 / 勾选框 */
  .foot-links a{display:inline-flex;align-items:center;min-height:32px;padding:0 2px}
  .auth-links a{display:inline-block;padding:8px 4px}
  .legal-note a,.agree a,.hint a,a.hint{padding:10px 0}   /* 正文内链接：只加纵向内边距，不撑行高 */
  .bc-set{display:inline-block;padding:10px 0}            /* 预算卡里的「改预算」链接 */
  .rf-chip{padding:8px 14px}
  .tabs-inline button{min-height:32px}
  .switch::before{content:"";position:absolute;inset:-7px -2px;border-radius:inherit}
  input[type=range]{height:32px}
  input[type=checkbox]{width:18px;height:18px}
  /* 新加的账本表格：行内链接与缩略图的可点区域 */
  .lg-row .lg-t a{display:inline-block;padding:10px 0}
  .lg-row{grid-template-columns:1.9fr .6fr .9fr 1fr .9fr;font-size:14px}
  .aa-row{padding:8px 10px}
  .mb-pic-item{width:62px;height:62px}
  .ml-item .ml-pic{width:38px;height:38px}
  /* 每日列表：按钮多，改成上下两行，别撑出横向滚动 */
  .dayrow{flex-wrap:wrap;gap:8px 10px}
  .dayrow .dh{font-size:18px;padding:6px 2px}
  .dayrow>div:not(.rt){flex:1 1 160px;min-width:0}
  .dayrow .rt{margin-left:0;width:100%;justify-content:flex-end;gap:6px}
  .btn.ico{width:36px;min-width:36px;height:36px}
  /* 弹层贴边 */
  .modal{padding:12px;align-items:flex-end}
  .modal-box{max-height:92vh;max-height:92dvh;border-radius:18px 18px 0 0;padding:18px 16px 22px;
    padding-bottom:calc(22px + env(safe-area-inset-bottom))}
  .modal-box.wide{max-width:100%}
  /* 网格与磁贴 */
  .grid2,.grid3,.grid4{grid-template-columns:1fr 1fr;gap:10px}
  .grid2 .field:first-child:last-child{grid-column:1/-1}
  .blocks{grid-template-columns:repeat(3,1fr)!important}
  .spot-grid{grid-template-columns:1fr 1fr}
  .ava-grid{grid-template-columns:repeat(3,1fr)}
  .rgrid{grid-template-columns:1fr!important}
  .cover-styles{grid-template-columns:repeat(2,1fr)}
  /* 登录页 */
  .auth-wrap{margin:18px 10px}
  .auth-card{padding:20px 18px}
  .auth-card h2{font-size:18px}
  .legal-note{font-size:11px}
  .oauth-divider{margin:14px 0}
  /* 我的页头像行 */
  .me-ava{gap:12px}
  .me-ava .btn{margin-left:auto}
  /* 路线详情 */
  .route-head h1{font-size:18px}
  .rt-meta,.rmeta{flex-wrap:wrap}
  .tl-route{flex-wrap:wrap}
  .tl-km{margin-left:0}
  /* 图例改成一行横排：三行竖排会吃掉地图左下角一大块 */
  .rtmap{aspect-ratio:4/3.4}
  /* 手机上 2:1 只剩 160 多 px 高，路线挤成一条；回到接近 3:2，比原来的 4/3.4 还是矮一截 */
  .anim-map .rtmap{aspect-ratio:3/2}
  .rt-legend{flex-direction:row;align-items:center;font-size:11px;padding:6px 10px;gap:10px;left:8px;bottom:8px}
  .rt-legend i{width:9px;height:9px}
  /* 悬浮「记一笔」避开底部安全区 */
  .fab-wrap{bottom:calc(14px + env(safe-area-inset-bottom))}
  /* 反馈按钮同样避开安全区，并稍微收紧，别在窄屏上压内容 */
  .fb-entry{bottom:calc(20px + env(safe-area-inset-bottom));left:14px;height:40px;padding:0 13px 0 11px;font-size:13px}
  /* 表格横向滚动兜底 */
  .tbl-wrap{overflow-x:auto}
}

/* ============================================================
   动效系统（优雅、克制：淡入上浮 + 微交互，尊重系统减弱动态设置）
   ============================================================ */
@keyframes rise{from{opacity:0;transform:translateY(14px)}to{opacity:1;transform:none}}
@keyframes fadeIn{from{opacity:0}to{opacity:1}}
@keyframes popIn{from{opacity:0;transform:scale(.94) translateY(10px)}to{opacity:1;transform:none}}
@keyframes groupIn{from{opacity:.35;transform:translateY(-4px)}to{opacity:1;transform:none}}
@keyframes starPop{0%{transform:scale(.6)}60%{transform:scale(1.25)}100%{transform:scale(1)}}
@keyframes shimmer{to{background-position:-200% 0}}
@keyframes pulseRing{0%{r:13;opacity:.32}70%{r:22;opacity:0}100%{r:22;opacity:0}}
@keyframes dotBreath{0%,100%{opacity:.55;transform:scale(1)}50%{opacity:1;transform:scale(1.12)}}

/* 页面进入：只给前几块一个短促的上浮，不做「全页依次排队淡入」那种塑料感 */
.view>*{animation:rise var(--t-in) var(--ease) backwards}
.view>*:nth-child(1){animation-delay:.01s}
.view>*:nth-child(2){animation-delay:.05s}
.view>*:nth-child(3){animation-delay:.09s}
.view>*:nth-child(4){animation-delay:.12s}
.view>*:nth-child(n+5){animation-delay:.15s}

/* 滚动渐显（由 JS 挂 .rv，JS 不可用时内容照常显示） */
.rv{opacity:0;transform:translateY(8px);
  transition:opacity .32s var(--ease),transform .32s var(--ease)}
.rv.in{opacity:1;transform:none}

/* 卡片与交互微动效：抬升更轻、边框跟着上色，像纸片被指尖掀起一角 */
.jcard,.stat,.daypub,.chart-card,.guide-card,.st-item,.ledger-item,.spot{transition:transform .2s var(--ease),box-shadow .2s var(--ease),border-color .2s var(--ease),background .2s var(--ease)}
/* 统计块是"读数"不是"卡片"：hover 只换底与边框，不做抬升、不加阴影
   —— 位移和阴影是可点击的语言，给不可点的数字块会误导可供性；数字本身也不跟着变色。 */
.stat:hover{background:var(--panel2);border-color:var(--brand-line)}
.btn{will-change:transform}
.btn:not([disabled]):active{transform:scale(.97)}
.star.on{animation:starPop var(--t-slow) var(--ease-pop)}
.group[open]>.group-body{animation:groupIn var(--t-slow) var(--ease)}
.group>summary{transition:background .16s var(--ease)}
.group>summary:hover{background:var(--panel2)}
.tabs-inline button,.chips-pick button{transition:background .16s var(--ease),color .16s var(--ease),border-color .16s var(--ease),transform .16s var(--ease)}
.tabs-inline button:active,.chips-pick button:active{transform:scale(.96)}

/* 数字滚动占位（JS 驱动） */
.num-anim{font-variant-numeric:tabular-nums}

/* 骨架屏 */
.skeleton{background:linear-gradient(90deg,var(--sunken) 25%,var(--panel2) 45%,var(--sunken) 65%);background-size:200% 100%;animation:shimmer 1.3s linear infinite;border-radius:8px;color:transparent!important}

/* 路线动画光效：光标呼吸圈 + 已走路径微光 */
#rt-cursor circle:first-child{animation:pulseRing 2s ease-out infinite}
#rt-done{filter:drop-shadow(0 1px 5px rgba(15,107,98,.42))}
.route-map-live #rt-base{stroke-dasharray:6 6;animation:rtDash 1.6s linear infinite}
@keyframes rtDash{to{stroke-dashoffset:-12}}

/* 加载页更细腻 */
.loading-page .spinner{animation:spin .8s cubic-bezier(.6,.15,.4,.85) infinite}

/* ============================================================
   动效第二轮：补上「层次感」——滚动、换肤、列表错峰、数据生长
   原则没变：动的是状态变化，不是装饰；能省则省。
   ============================================================ */

/* 顶栏：离开页首才落一道很浅的投影，页面有「浮在内容上」的层次 */
.topbar{transition:box-shadow .32s var(--ease)}
.topbar.scrolled{box-shadow:var(--topbar-shadow)}

/* 换主题：底/字/线在 300ms 里过渡过去（由 JS 短暂挂 .theme-anim，用完就摘） */
html.theme-anim *,html.theme-anim *::before,html.theme-anim *::after{
  transition:background-color .32s var(--ease),color .32s var(--ease),border-color .32s var(--ease),
    fill .32s var(--ease),stroke .32s var(--ease),box-shadow .32s var(--ease)!important}
/* 换肤那一下 JS 会为了重画图表整页重绘（route()），不压住入场动画的话，
   换个主题像换了个页面 —— 所有块重新上浮一遍。这个窗口里入场一律免演。 */
html.theme-anim .view>*,html.theme-anim .jgrid>*,html.theme-anim .rgrid>*,
html.theme-anim .spot-grid>*,html.theme-anim .blocks>*,html.theme-anim .lg-bars>*,
html.theme-anim .ava-grid>*,html.theme-anim .cover-styles>*,html.theme-anim .guide-grid>*{animation:none!important}

/* 主题按钮：切换那一刻图标翻一下，像拨了一下开关 */
.tb-theme.flip .ic{animation:themeFlip var(--t-slow) var(--ease-pop)}
@keyframes themeFlip{
  0%{transform:rotate(-150deg) scale(.4);opacity:.15}
  62%{transform:rotate(14deg) scale(1.14)}
  100%{transform:none;opacity:1}}

/* 列表错峰入场：只排前 8 个，第 9 个之后一起进，长列表不会变成拉链 */
.jgrid>*,.rgrid>*,.spot-grid>*,.blocks>*,.lg-bars>*,
.ava-grid>*,.cover-styles>*,.guide-grid>*{animation:rise var(--t-in) var(--ease) backwards}
.jgrid>:nth-child(1),.rgrid>:nth-child(1),.spot-grid>:nth-child(1),.blocks>:nth-child(1),
.lg-bars>:nth-child(1),.ava-grid>:nth-child(1),.cover-styles>:nth-child(1),.guide-grid>:nth-child(1){animation-delay:.02s}
.jgrid>:nth-child(2),.rgrid>:nth-child(2),.spot-grid>:nth-child(2),.blocks>:nth-child(2),
.lg-bars>:nth-child(2),.ava-grid>:nth-child(2),.cover-styles>:nth-child(2),.guide-grid>:nth-child(2){animation-delay:.05s}
.jgrid>:nth-child(3),.rgrid>:nth-child(3),.spot-grid>:nth-child(3),.blocks>:nth-child(3),
.lg-bars>:nth-child(3),.ava-grid>:nth-child(3),.cover-styles>:nth-child(3),.guide-grid>:nth-child(3){animation-delay:.08s}
.jgrid>:nth-child(4),.rgrid>:nth-child(4),.spot-grid>:nth-child(4),.blocks>:nth-child(4),
.lg-bars>:nth-child(4),.ava-grid>:nth-child(4),.cover-styles>:nth-child(4),.guide-grid>:nth-child(4){animation-delay:.11s}
.jgrid>:nth-child(5),.rgrid>:nth-child(5),.spot-grid>:nth-child(5),.blocks>:nth-child(5),
.lg-bars>:nth-child(5),.ava-grid>:nth-child(5),.cover-styles>:nth-child(5),.guide-grid>:nth-child(5){animation-delay:.135s}
.jgrid>:nth-child(6),.rgrid>:nth-child(6),.spot-grid>:nth-child(6),.blocks>:nth-child(6),
.lg-bars>:nth-child(6),.ava-grid>:nth-child(6),.cover-styles>:nth-child(6),.guide-grid>:nth-child(6){animation-delay:.155s}
.jgrid>:nth-child(7),.rgrid>:nth-child(7),.spot-grid>:nth-child(7),.blocks>:nth-child(7),
.lg-bars>:nth-child(7),.ava-grid>:nth-child(7),.cover-styles>:nth-child(7),.guide-grid>:nth-child(7){animation-delay:.175s}
.jgrid>:nth-child(8),.rgrid>:nth-child(8),.spot-grid>:nth-child(8),.blocks>:nth-child(8),
.lg-bars>:nth-child(8),.ava-grid>:nth-child(8),.cover-styles>:nth-child(8),.guide-grid>:nth-child(8){animation-delay:.19s}
.jgrid>:nth-child(n+9),.rgrid>:nth-child(n+9),.spot-grid>:nth-child(n+9),.blocks>:nth-child(n+9),
.lg-bars>:nth-child(n+9),.ava-grid>:nth-child(n+9),.cover-styles>:nth-child(n+9),.guide-grid>:nth-child(n+9){animation-delay:.2s}

/* 数据条：从左边长出来，而不是一上来就满格 */
.lg-bar .lb-t i{transform-origin:left center;animation:barGrow var(--t-slow) var(--ease) backwards}
@keyframes barGrow{from{transform:scaleX(0)}to{transform:scaleX(1)}}

/* 首屏数字：等宽，滚动时不抖 */
.hero-facts b{font-variant-numeric:tabular-nums}

/* 「先看 N 条经典线路」的箭头指一下路 */
.hero-link{transition:color .2s var(--ease)}
.hero-link .ic{transition:transform .2s var(--ease)}
.hero-link:hover .ic{transform:translateX(3px)}

/* 卡片右上角的小箭头 / 「看详情」也跟着走 */
.guide-card .gc-go .ic,.route-more .ic{transition:transform .2s var(--ease)}
.guide-card:hover .gc-go .ic,.route-more:hover .ic{transform:translateX(2px)}

/* 焦点可见性（键盘可达） */
/* 焦点圈：只给描边，不写 border-radius —— 写了会改掉元素自身的圆角
   （胶囊按钮 999px、卡片 14px 一聚焦就塌成 6px）。
   现代浏览器的 outline 会自动跟随元素自身圆角，不需要手动指定。 */
:focus-visible{outline:2px solid var(--brand);outline-offset:2px}

@media (prefers-reduced-motion: reduce){
  *,*::before,*::after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important;scroll-behavior:auto!important}
  .view>*{animation:none}
  .rv{opacity:1;transform:none}
}

/* ============================================================
   每日记录：分块选择添加 / 快捷记账 / 附近充电站 / 自动保存
   ============================================================ */
/* 快捷添加工具条 */
.quick-add{display:flex;flex-wrap:wrap;gap:8px;align-items:center;margin:2px 0 12px}
.quick-add .qa-t{font-size:14px;color:var(--muted);font-weight:600;margin-right:2px}
.qa-chip{display:inline-flex;align-items:center;gap:6px;border:1px solid var(--line);background:var(--panel);border-radius:var(--r-pill);padding:6px 14px;font-size:14px;color:var(--ink2);cursor:pointer;transition:.16s}
.qa-chip:hover{border-color:var(--brand-line);background:var(--brand-soft);color:var(--brand)}
.qa-chip .n{font-size:11px;background:var(--brand-soft);color:var(--brand);border-radius:8px;padding:0 6px;min-width:16px;text-align:center}
.qa-chip.has{border-color:var(--brand-line);background:var(--brand-soft);color:var(--brand)}
.qa-chip.has .n{background:var(--panel)}

/* 板块磁贴（未添加时展示） */
.blocks{display:grid;grid-template-columns:repeat(auto-fill,minmax(168px,1fr));gap:8px}
.block-tile{display:flex;align-items:center;gap:10px;border:1px dashed var(--line);border-radius:12px;background:var(--panel2);padding:10px 12px;cursor:pointer;color:var(--ink2);font-size:14px;text-align:left;transition:border-color .2s var(--ease),background .2s var(--ease),color .2s var(--ease),transform .2s var(--ease),box-shadow .2s var(--ease)}
.block-tile:hover{border-color:var(--brand);border-style:solid;color:var(--brand);background:var(--brand-soft);transform:translateY(-2px);box-shadow:0 8px 20px rgba(21,26,30,.07)}
.block-tile:active{transform:translateY(0) scale(.985)}
.block-tile .b-txt{min-width:0}
/* 磁贴图标：做成小圆角牌，图标本身随文字色，不用 emoji、不用渐变色块 */
.block-tile .b-ico{width:30px;height:30px;flex:0 0 auto;border-radius:8px;background:var(--surface);border:1px solid var(--line);color:var(--accent);display:inline-flex;align-items:center;justify-content:center;transition:color .2s var(--ease),background .2s var(--ease),border-color .2s var(--ease),transform .2s var(--ease-pop)}
.block-tile .b-ico .ic{width:17px;height:17px}
.block-tile:hover .b-ico{color:var(--on-brand);background:var(--brand);border-color:var(--brand);transform:rotate(-6deg) scale(1.04)}
.block-tile b{font-weight:600}
.block-tile small{display:block;font-size:11px;color:var(--muted);font-weight:400;margin-top:1px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.block-tile:hover small{color:var(--brand)}
.block-tile.has{border-style:solid;border-color:var(--brand-line);background:var(--brand-soft)}

/* 折叠组状态摘要 */
.group>summary .cnt{font-variant-numeric:tabular-nums}
.group>summary .cnt b{color:var(--brand);font-weight:600}
.group>summary .cnt .sep{margin:0 6px;opacity:.5}

/* 花费归类（花多少钱 → 做什么） */
.money-box{border:1px solid var(--amber-line);background:var(--surface);border-radius:12px;padding:12px;margin-bottom:12px}
.mb-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap}
.mb-amt{position:relative;flex:0 0 150px}
.mb-amt input{padding-right:30px;font-size:18px;font-weight:600}
.mb-amt .yen{position:absolute;right:10px;top:50%;transform:translateY(-50%);color:var(--muted);font-size:14px}
.mb-go{flex:0 0 auto}
.cat-pick{display:flex;flex-wrap:wrap;gap:6px;margin-top:10px}
.cat-pick button{border:1px solid var(--line);background:var(--surface);border-radius:18px;padding:6px 12px;font-size:14px;color:var(--ink2);cursor:pointer;transition:.16s}
.cat-pick button:hover{border-color:var(--amber-line);background:var(--amber-soft)}
/* 选中态原为 color:var(--bg)（页面底米色），压在琥珀/品牌实色底上只有 2.61 / 4.43:1。
   选中态的文字应该用"铺在该色上的专属文字色"，而不是页面底色。 */
.cat-pick button.on{background:var(--ink);border-color:var(--ink);color:var(--bg)}
.cat-pick button.on.food{background:var(--amber);color:var(--amber-ink)}
.cat-pick button.on.special{background:var(--brand);color:var(--on-brand)}
.money-log{margin-top:12px;display:flex;flex-direction:column;gap:6px}
.ml-item{display:flex;align-items:center;gap:8px;font-size:14px;background:var(--surface);border:1px solid var(--line);border-radius:8px;padding:6px 10px;animation:rise var(--t-slow) var(--ease) backwards}
.ml-item .ml-cat{font-weight:600;color:var(--ink)}
.ml-item .ml-amt{margin-left:auto;font-weight:600;color:var(--danger);font-variant-numeric:tabular-nums}
.ml-item .ml-note{color:var(--muted);font-size:12px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:30%}
.ml-item .rm{border:0;background:none;color:var(--muted);font-size:16px;cursor:pointer;line-height:1;padding:0 2px}
.ml-item .rm:hover{color:var(--danger)}
.ml-empty{font-size:12px;color:var(--muted)}
/* 单笔花销的配图（早餐 / 门票 / 小票…） */
.ml-item .ml-pics{display:inline-flex;gap:4px;flex:0 0 auto}
.ml-item .ml-pic{width:34px;height:34px;border-radius:6px;overflow:hidden;border:1px solid var(--line);background:var(--sunken);cursor:zoom-in;display:block}
.ml-item .ml-pic img{width:100%;height:100%;object-fit:cover;display:block}
.ml-item .ml-payer{font-size:11px;color:var(--muted);background:var(--panel2);border-radius:20px;padding:2px 8px}
/* 待记录配图的预览条 */
.mb-photos{display:flex;gap:6px;align-items:flex-start;flex-wrap:wrap;margin-top:10px}
.mb-pic-item{position:relative;width:56px;height:56px;border-radius:8px;overflow:hidden;border:1px solid var(--line);background:var(--sunken)}
.mb-pic-item img{width:100%;height:100%;object-fit:cover;display:block}
.mb-pic-item .rm{position:absolute;top:0;right:0;width:20px;height:20px;border:0;border-radius:0 0 0 6px;background:rgba(20,25,35,.62);color:#fff;font-size:12px;cursor:pointer;padding:0;line-height:1}
/* 预算卡里的「改预算」链接（桌面也要够好点） */
.bc-set{display:inline-block;padding:6px 0}
/* 我的自驾账本 */
.lg-bars{display:flex;flex-direction:column;gap:8px}
.lg-bar{display:flex;align-items:center;gap:10px;font-size:14px}
.lg-bar .lb-n{min-width:64px;color:var(--ink2)}
.lg-bar .lb-t{flex:1;height:9px;background:var(--line2);border-radius:6px;overflow:hidden}
.lg-bar .lb-t i{display:block;height:100%;border-radius:6px;transition:width var(--t-slow) var(--ease)}
.lg-bar .lb-v{min-width:118px;text-align:right;color:var(--muted);font-size:12px;font-variant-numeric:tabular-nums}
.lg-tbl{display:flex;flex-direction:column}
.lg-row{display:grid;grid-template-columns:2.2fr .7fr 1fr 1.1fr 1fr;gap:8px;align-items:center;
  padding:10px 4px;border-bottom:1px solid var(--line2);font-size:14px;color:var(--ink2)}
.lg-row:last-child{border-bottom:0}
.lg-hd{font-size:12px;color:var(--muted);border-bottom:1px solid var(--line)}
/* 长标题必须就地截断：这块是 grid，2.2fr 那一列会被超长标题撑开，
   把后面的日期挤到紧贴（表现为「示例 2026-06」连成一片）。 */
.lg-row .lg-t{min-width:0}
.lg-row .lg-t a{font-weight:600;display:block;padding:4px 0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.lg-row .lg-t em{font-style:normal;color:var(--muted);font-size:12px;margin-left:6px}
/* 花费是中性数据，不是警示：同页顶部的「累计花费」本来就是墨色，
   这里染红等于同一种数据给了两种颜色，还会把红色这个"负向"信号白白消耗掉。
   真正的负向（超支）在预算那行单独标红。 */
.lg-row .lg-money{color:var(--ink);font-weight:600;font-variant-numeric:tabular-nums}
/* AA 结算卡片 */
.aa-card{border:1px solid var(--line);background:var(--surface);border-radius:14px;padding:14px 16px;margin:14px 0;box-shadow:var(--shadow)}
.aa-head{display:flex;flex-wrap:wrap;gap:8px;align-items:baseline;justify-content:space-between;margin-bottom:10px}
.aa-head b{font-size:16px;color:var(--ink)}
.aa-share{font-size:12px;color:var(--muted)}
.aa-rows{display:flex;flex-direction:column;gap:6px}
.aa-row{display:flex;align-items:center;gap:10px;font-size:14px;padding:6px 10px;border-radius:8px;background:var(--panel2)}
.aa-row .aa-n{font-weight:600;color:var(--ink);min-width:52px}
.aa-row .aa-p{color:var(--muted);font-size:12px}
.aa-row .aa-d{margin-left:auto;font-variant-numeric:tabular-nums;font-weight:600}
.aa-row.get{background:var(--ok-soft)}.aa-row.get .aa-d{color:var(--ok)}
.aa-row.owe{background:var(--danger-soft)}.aa-row.owe .aa-d{color:var(--danger)}
.aa-row.even .aa-d{color:var(--muted);font-weight:500}
.aa-moves{display:flex;flex-wrap:wrap;gap:8px;margin-top:10px}
.aa-move{font-size:14px;background:var(--brand-soft);color:var(--brand);border-radius:20px;padding:4px 12px}
.aa-move i{font-style:normal;opacity:.6;margin:0 2px}
/* 收入：来源完全自定义 */
.ml-item.in .ml-amt{color:var(--ok)}
.cat-pick button .icat-x{display:inline-block;margin-left:6px;font-style:normal;font-size:11px;color:var(--danger);font-weight:700;line-height:1}
.cat-pick button .icat-x:hover{background:var(--danger);color:var(--on-brand);border-radius:50%;padding:1px 4px}
.icat-edit{border-style:dashed!important;color:var(--brand)!important;background:var(--surface)!important}
.icat-edit:hover{border-color:var(--brand)!important;background:var(--brand-soft)!important}
.inc-add{display:flex;gap:8px;align-items:center;flex-wrap:wrap;margin-top:8px;animation:rise var(--t-slow) var(--ease) backwards}
.inc-add input{flex:1;min-width:170px;max-width:320px}

/* 自动保存指示 */
.save-dot{display:inline-flex;align-items:center;gap:6px;font-size:12px;color:var(--muted)}
.save-dot i{width:7px;height:7px;border-radius:50%;background:var(--muted);display:inline-block}
.save-dot.saving i{background:var(--amber);animation:dotBreath 1s ease infinite}
.save-dot.saved i{background:var(--ok)}

/* 悬浮记一笔按钮 */
.fab{position:fixed;right:22px;bottom:26px;z-index:80;border:0;border-radius:50%;width:54px;height:54px;font-size:22px;color:var(--bg);cursor:pointer;background:var(--ink);box-shadow:0 10px 26px rgba(21,26,30,.34);display:flex;align-items:center;justify-content:center;transition:transform .2s var(--ease-pop),box-shadow .2s var(--ease),background .2s var(--ease)}
.fab:hover{transform:translateY(-3px) scale(1.05);background:var(--accent);box-shadow:0 14px 32px rgba(210,86,27,.4)}
.fab:active{transform:scale(.95)}
.fab-label{position:fixed;right:88px;bottom:38px;z-index:80;background:var(--ink);color:var(--bg);font-size:12px;padding:6px 10px;border-radius:var(--r-pill);opacity:0;pointer-events:none;transition:.2s var(--ease);white-space:nowrap}
.fab-wrap:hover .fab-label{opacity:1}

/* 独立的「反馈」常驻按钮：与右侧「随手记一笔」各管一件事。
   它是全站唯一的反馈入口（页脚链接、「我的」页卡片入口已让位给它），
   不和任何功能混用；样式与 .fab 同源，只是换成左下标件 + 文案胶囊。 */
.fb-entry{position:fixed;left:22px;bottom:26px;z-index:80;border:0;height:44px;padding:0 16px 0 13px;display:flex;align-items:center;gap:7px;font-size:13.5px;font-weight:600;font-family:inherit;color:var(--bg);cursor:pointer;background:var(--ink);border-radius:var(--r-pill);box-shadow:0 10px 26px rgba(21,26,30,.34);transition:transform .2s var(--ease-pop),box-shadow .2s var(--ease),background .2s var(--ease)}
.fb-entry:hover{transform:translateY(-3px);background:var(--accent);box-shadow:0 14px 32px rgba(210,86,27,.4)}
.fb-entry:active{transform:scale(.95)}
.fb-entry:focus-visible{outline:2px solid var(--accent);outline-offset:3px}
.fb-entry svg{width:17px;height:17px;flex:none}

/* 快捷记一笔：分段选择与紧凑表单 */
.seg{display:flex;gap:4px;background:var(--panel2);border:1px solid var(--line);border-radius:12px;padding:4px;margin-bottom:14px}
.seg button{flex:1;border:0;background:none;border-radius:8px;padding:8px 6px;font-size:14px;color:var(--muted);cursor:pointer;font-weight:500;white-space:nowrap}
.seg button.on{background:var(--surface);color:var(--brand);box-shadow:0 1px 3px rgba(21,26,30,.1)}
.qs-loc-row{display:flex;gap:8px;flex-wrap:wrap;margin-bottom:8px}
.charger-list{border:1px solid var(--line);border-radius:12px;overflow:hidden;max-height:230px;overflow-y:auto;margin-bottom:8px}
.charger-item{display:flex;align-items:center;gap:10px;padding:10px 12px;border-bottom:1px solid var(--line2);font-size:14px;cursor:pointer;transition:background .16s}
.charger-item:last-child{border-bottom:0}
.charger-item:hover{background:var(--brand-soft)}
.charger-item.sel{background:var(--brand-soft)}
.charger-item .ci-name{font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.charger-item .ci-meta{font-size:11px;color:var(--muted);margin-top:1px;display:flex;gap:8px;flex-wrap:wrap}
.charger-item .ci-dist{margin-left:auto;font-size:12px;color:var(--brand);font-variant-numeric:tabular-nums;white-space:nowrap}
.charger-empty{padding:16px;text-align:center;font-size:14px;color:var(--muted);line-height:1.8}
.loc-state{display:flex;align-items:center;gap:8px;font-size:14px;color:var(--muted);margin:4px 0 8px}
.loc-state .spinner{border-color:var(--line);border-top-color:var(--brand);width:13px;height:13px;border-width:2px}

/* 展示页每日卡片折叠 */
.daypub .more-toggle{border:0;background:none;color:var(--brand);font-size:14px;cursor:pointer;padding:2px 0;display:inline-flex;align-items:center;gap:4px;margin-top:10px}
.daypub .more-toggle:hover{text-decoration:underline}
.daymore{display:none;margin-top:10px;border-top:1px dashed var(--line);padding-top:10px}
.daymore.on{display:block;animation:groupIn var(--t-slow) var(--ease)}

/* 顶栏微动效：悬停时路牌轻轻掀起、公路中线跑快一点、尾灯亮起来（像是踩了一脚油门） */
.brand .lgmark{transition:transform .32s var(--ease-pop)}
.brand:hover .lgmark{transform:rotate(-7deg) scale(1.07)}
.brand:hover .lg-dash{animation-duration:1.05s}
.brand .lg-lamp{transition:opacity .32s var(--ease)}
.brand:hover .lg-lamp{opacity:1}
@media (prefers-reduced-motion:reduce){.lgmark .lg-dash{animation:none}}
/* 232 行那条 .tb-nav a 已经写全了 color/background 的过渡，这里再来一条同选择器规则
   只会把 transition 整条替换掉（连 duration 写法都倒退回裸数值）。删掉，别留重复。 */

/* ============================================================
   触控热区兜底（全端统一，不只移动端）
   文字链接 / 勾选框 / 滑块 / 开关等小控件，最小可点区域垫到 ≈32–40px，
   减少移动端误触；只加内边距与最小高度，不改变视觉排布。
   ============================================================ */
a.hint{display:inline-flex;align-items:center;min-height:32px}
.btn-link{min-height:32px;padding:6px 4px}
input[type=checkbox]{width:20px;height:20px;vertical-align:middle}
input[type=range]{height:34px}
.switch::before{content:"";position:absolute;inset:-9px -4px;border-radius:inherit}
.more-toggle,.daypub .more-toggle{min-height:32px}
/* 补漏：这几处实测仍未到 32px ——
   .brand 移动端 72×30（顶栏品牌位）；.star 评分星 20×18.5；
   .ml-item .rm 删一笔 14×16；.up-item .rm 删图片 21×21；.charge-head .del 桌面 28×28。
   一律只加内边距与最小尺寸，图标/文字的视觉大小不变。 */
.brand{display:inline-flex;align-items:center;min-height:32px}
.star{padding:6px 5px;min-width:32px;min-height:32px}
.ml-item .rm{padding:8px;margin:-8px 0}
.up-item .rm{width:32px;height:32px}
.charge-head .del{width:32px;height:32px}
/* 登录/注册页的条款链接实测只有 15~17px 高，桌面端也低于 24px。
   只加纵向 padding —— 内联元素的纵向 padding 会扩大可点区域但不参与行盒计算，
   so 热区到 32px 而行距一点不变。别改成 inline-block，那会真的把行撑开。 */
.auth-card a,.auth-links a,.hint a,.legal-note a,.agree a{padding:8px 0}
@media(max-width:560px){
  a.hint,a.hint:link{min-height:36px}
  .btn-link{min-height:36px;padding:10px 6px}
  .switch::before{inset:-10px -5px}
  .brand{min-height:36px}
  .btn.ghost.xs,.btn.sm{min-height:32px}
}

/* ============================================================
   按钮内图标配色修正
   图标统一 stroke:currentColor，而 currentColor 取的是 .ic 自己的 color。
   按钮早已设好文字色，但 .card-head .ic{color:var(--accent)} 这类
   「标题装饰」规则会直接命中 .ic（优先级 2 个类），抢在继承之前把它染成主题橙；
   偏偏 .btn.hot 的底就是这个橙 —— 于是「＋ 记一天」的加号跟背景同色、完全看不见。
   （用户反馈截图正是这个现象。）
   对策：按钮内的图标一律跟按钮文字走；强调按钮恒用 --on-brand（浅色白 / 深色深墨）。
   .btn.hot .ic 有 3 个类，优先级高于任何「标题装饰」规则；整段放在文件末尾，
   保证 .btn .ic 在同级规则里也后来居上。
   ============================================================ */
.btn .ic{color:inherit}
.btn.hot .ic{color:var(--on-brand)}
.btn.ghost .ic{color:inherit}
.btn.soft .ic{color:inherit}
.btn.danger .ic{color:var(--danger)}

/* ============================================================
   触屏没有"悬停"这回事
   手指点一下之后，浏览器会把 :hover 一直保留到下次点别处 —— 卡片就永久停在
   "抬起 + 重阴影"的状态，看起来像被选中了。位移和阴影这类"浮起感"只在真的有
   指针设备时才给；触屏保留底色/边框变化（那些不会产生残留，也还能当点按反馈）。
   注意别把颜色变化一起干掉，否则触屏点按会完全没有回执。
   ============================================================ */
@media (hover:none){
  .jcard:hover,.rcard:hover,.spot:hover,.cv-style:hover,.memo-photo:hover{transform:none;box-shadow:var(--shadow)}
  .block-tile:hover{transform:none;box-shadow:none}
  .fab:hover{transform:none;box-shadow:0 8px 22px rgba(210,86,27,.32)}
  .fb-entry:hover{transform:none;box-shadow:0 8px 22px rgba(210,86,27,.32)}
  .star:hover{transform:none}
  .btn:hover,.btn.hot:hover{box-shadow:none}
}

/* 上传进度条：原来 transition 的是 width，每帧都要重新布局；改成 transform:scaleX() 走合成层。
   用法：JS 只改 --p（0~1），不要再写 width。（当前 .up-bar 暂无 JS 引用，属备用件。） */
.up-bar{position:absolute;left:0;bottom:0;height:3px;background:var(--brand);width:100%;transform-origin:left center;transform:scaleX(var(--p,0));transition:transform var(--t-mid) var(--ease)}
