/* ==========================================================================
   Speedy Nordic — 共享设计 token / 主题 / 动效层
   --------------------------------------------------------------
   唯一真源：颜色与动效变量都定义在这里，页面内联样式与 subpage.css 只消费。
   动效曲线与时长取自 Emil Kowalski 的 animate 规范，不要自造 cubic-bezier。
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. 亮色 token（默认）
   -------------------------------------------------------------------------- */
:root{
  color-scheme: light;

  /* 表面 */
  --bg:#FFFFFF;
  --bg-2:#F7F6F3;
  --bg-3:#EFEDE8;
  --card:#FFFFFF;
  --line:#E6E3DE;
  --hair:#F0EEE9;
  --row-hover:#FBFAF8;
  --scrim:rgba(255,255,255,.94);
  --hero-a:#FBFAF8;
  --dash:#D8D4CC;
  --muted:#A9A59E;

  /* 文字 */
  --ink:#1E1E1E;
  --ink-2:#5C5C5C;
  --ink-3:#8C8C8C;

  /* 品牌 */
  --red:#E1251B;
  --red-d:#B41C13;
  --red-l:#FDECEA;

  /* 反相面（页脚 / CTA / 深色卡片） */
  --dark:#242424;

  /* 极光青：只用来指「北欧端」，永远和品牌红（中国端）成对出现。
     不要拿它当通用强调色 —— 强调色仍然只有红。 */
  --aurora:#0A8F7A;
  /* 首屏光幕三团色：北欧青 / 中国红 / 高空冷蓝。直接写 rgba 而不用 color-mix，
     微信内置浏览器的旧内核不认 color-mix，整条声明会失效。 */
  --wash-n:rgba(16,170,140,.26);
  --wash-c:rgba(225,37,27,.16);
  --wash-s:rgba(70,120,255,.13);
  /* 卡片聚光 */
  --spot:rgba(225,37,27,.07);
  /* 深色面板的两角辉光：两种主题下面板都是深色，所以不分主题 */
  --panel-glow:
    radial-gradient(90% 70% at 0% 0%, rgba(45,212,170,.15), transparent 60%),
    radial-gradient(90% 80% at 100% 100%, rgba(225,37,27,.22), transparent 62%);

  /* 圆角 */
  --r:12px;
  --r-lg:18px;

  /* 动效 —— 曲线 */
  --ease-out:cubic-bezier(0.23, 1, 0.32, 1);      /* UI 入场：快出、柔停 */
  --ease-in-out:cubic-bezier(0.77, 0, 0.175, 1);   /* 屏内位移 / 形变 */
  --ease-drawer:cubic-bezier(0.32, 0.72, 0, 1);    /* iOS 抽屉曲线 */
  /* 动效 —— 时长 */
  --d-press:160ms;   /* 按压反馈 */
  --d-quick:180ms;   /* 悬停 / 颜色 */
  --d-ui:220ms;      /* 状态切换 */
  --d-reveal:640ms;  /* 滚动揭示（营销面，可长于 300ms）。
                        _tools/theme-test.js 在滚到底后只等 950ms，
                        本值 + 最大阶梯延迟 220ms 必须小于它，否则测试会误判成「卡住」 */
}

/* --------------------------------------------------------------------------
   2. 暗色 token
   data-theme 由 <head> 内的引导脚本在首次绘制前写入，避免闪白。
   -------------------------------------------------------------------------- */
:root[data-theme="dark"]{
  color-scheme: dark;

  --bg:#0F0F0E;
  --bg-2:#171614;
  --bg-3:#1E1D1A;
  --card:#171614;
  --line:#2C2A26;
  --hair:#252420;
  --row-hover:#1A1917;
  --scrim:rgba(15,15,14,.90);
  --hero-a:#141311;
  --dash:#3A3833;
  --muted:#6E6B65;

  --ink:#F3F2EF;
  --ink-2:#ABA8A2;
  --ink-3:#7D7A74;

  --red:#FF5A4A;
  --red-d:#FF7C6F;
  --red-l:#2B1512;

  --dark:#1E1D1B;

  --aurora:#4FE3C1;
  --wash-n:rgba(45,212,170,.25);
  --wash-c:rgba(255,90,74,.22);
  --wash-s:rgba(90,130,255,.18);
  --spot:rgba(255,90,74,.10);
}

/* --------------------------------------------------------------------------
   3. 基础
   -------------------------------------------------------------------------- */
html{
  scroll-behavior:smooth;
  /* 锚点跳转时给吸顶导航让位，否则标题会被压在导航下面 */
  scroll-padding-top:88px;
}
::selection{background:var(--red);color:#FFF}
/* hidden 属性要压得住组件自己写的 display（.phone、.gal-item.empty 都是 display:flex），
   否则「没内容就不显示」的板块会照样露出来 */
[hidden]{display:none !important}

/* 键盘可见焦点（鼠标点击不触发，避免脏样式） */
:where(a,button,input,select,textarea,[tabindex]):focus-visible{
  outline:2px solid var(--red);
  outline-offset:2px;
  border-radius:6px;
}

/* 品牌标识：原图是深灰字压在**不透明白底**上（所有 alpha 都是 255），
   所以任何 CSS filter 都会把整块白底一起翻转 —— 实测 invert+hue-rotate 会把
   深灰字染成粉色，brightness(0)+invert 则整块变成白砖。
   改为另存一张暗色专用图（白底抠透、字改浅色、红提亮），
   两张图叠在同一个 .brand 里靠 data-theme 切换显隐。
   引导脚本在首次绘制前就写好了 data-theme，因此不会先亮后暗闪一下。 */
.brand{display:flex;align-items:center}
.brand .logo-d{display:none}
:root[data-theme="dark"] .brand .logo-l{display:none}
:root[data-theme="dark"] .brand .logo-d{display:block}

/* 吸顶导航在暗色下用深色底 */
:root[data-theme="dark"] header:not(.sub){background:var(--scrim)}
:root[data-theme="dark"] header.sub{background:var(--scrim)}

/* 反相面在暗色下比页面亮，加一条描边让边界清楚 */
:root[data-theme="dark"] footer:not(.sub),
:root[data-theme="dark"] .cta,
:root[data-theme="dark"] .flow,
:root[data-theme="dark"] .door.dark{
  border:1px solid var(--line);
}
:root[data-theme="dark"] footer:not(.sub){border-width:1px 0 0}

/* 语言选中态：亮色=深底白字，暗色=浅底深字，两种主题都保持高对比 */
.lang button.on{background:var(--ink);color:var(--bg)}

/* 步骤条：底轨是浅线，实线随揭示从左到右画出来，四步依次接力。
   JS 没跑时元素没有 data-reveal，实线直接是画完的状态。 */
.step{position:relative;border-top-color:var(--line)}
.step::before{
  content:"";position:absolute;left:0;right:0;top:-2px;height:2px;background:var(--ink);
  transform-origin:left;
  transition:transform 620ms var(--ease-in-out);
}
.step[data-reveal]:not([data-visible])::before{transform:scaleX(0)}
.step:nth-child(2)::before{transition-delay:160ms}
.step:nth-child(3)::before{transition-delay:320ms}
.step:nth-child(4)::before{transition-delay:480ms}

/* 行内弱化文字：不写死颜色，随主题走。
   原先是 style="color:#8C8C8C"，在暗色下会对不上浅底，故改用具名类。 */
.dim{color:var(--ink-3)}

/* --------------------------------------------------------------------------
   4. 主题切换按钮
   -------------------------------------------------------------------------- */
.nav-tools{display:flex;align-items:center;gap:10px;flex:0 0 auto}

.theme{
  position:relative;flex:0 0 auto;width:34px;height:34px;padding:0;
  display:grid;place-items:center;
  border:1px solid var(--line);border-radius:999px;background:transparent;
  color:var(--ink-2);cursor:pointer;font-family:inherit;
  transition:
    color var(--d-quick) ease,
    border-color var(--d-quick) ease,
    transform var(--d-press) var(--ease-out);
}
.theme svg{
  width:16px;height:16px;grid-area:1 / 1;
  transition:opacity var(--d-ui) var(--ease-out), transform var(--d-ui) var(--ease-out);
}
/* 亮色：显示月亮（点了去暗色）；暗色：显示太阳 */
.theme .ic-sun{opacity:0;transform:rotate(-60deg) scale(.8)}
.theme .ic-moon{opacity:1;transform:rotate(0deg) scale(1)}
:root[data-theme="dark"] .theme .ic-sun{opacity:1;transform:rotate(0deg) scale(1)}
:root[data-theme="dark"] .theme .ic-moon{opacity:0;transform:rotate(60deg) scale(.8)}

.theme:active{transform:scale(.94)}

/* 悬停位移类动效只在真指针设备启用 —— 触摸屏点按会误触 :hover */
@media (hover:hover) and (pointer:fine){
  .theme:hover{color:var(--ink);border-color:var(--ink-3)}
}

/* --------------------------------------------------------------------------
   5. 滚动揭示
   data-reveal 由 assets/ui.js 在运行时添加：JS 不可用时属性不存在，
   内容默认可见 —— 失败方向是「没有动效」，不是「内容消失」。
   -------------------------------------------------------------------------- */
/* 只动 opacity 和 transform。试过加 filter:blur 做「由虚到实」，实测放弃：
   几十个元素同时逐帧重算模糊，没有 GPU 的环境（无头浏览器、低端机、微信内置浏览器）
   帧间隔明显变长，滚动判定也跟着变慢。 */
[data-reveal]{
  opacity:0;
  transform:translateY(22px) scale(.985);
  transition:
    opacity var(--d-reveal) var(--ease-out),
    transform var(--d-reveal) var(--ease-out);
  transition-delay:var(--reveal-delay, 0ms);
}
[data-reveal][data-visible]{opacity:1;transform:none}

/* 首屏大标题：从一条看不见的底线后面升上来（裁切 + 上移），比普通揭示更慢一点、更有分量 */
.hero h1[data-reveal]{
  clip-path:inset(0 0 100% 0);transform:translateY(48px);
  transition:opacity var(--d-reveal) var(--ease-out), transform 900ms var(--ease-out), clip-path 900ms var(--ease-out);
  transition-delay:var(--reveal-delay, 0ms);
}
.hero h1[data-reveal][data-visible]{clip-path:inset(-20% -5% -30% -5%);transform:none}

/* 表格、图表这类「正在被读的数据」只做淡入，不做位移 */
[data-reveal="fade"]{transform:none}

/* 图片经 JS 插入时淡入，避免硬弹 */
.gal-item img,
.phone img{transition:opacity 320ms var(--ease-out)}
@starting-style{
  .gal-item img,
  .phone img{opacity:0}
}

/* 切换主题的瞬间必须关掉所有 CSS 过渡。
   否则 View Transition 抓取「新状态」快照时，带 color/background 过渡的元素还停在
   旧颜色上，交叉淡入会淡出成一场空，动画结束后才硬切 —— 比不做还糟。 */
.no-transition,
.no-transition *,
.no-transition *::before,
.no-transition *::after{transition:none !important}

/* --------------------------------------------------------------------------
   6. 跨页面过渡（View Transitions，渐进增强）
   -------------------------------------------------------------------------- */
@view-transition{navigation:auto}

::view-transition-old(root){animation:180ms var(--ease-out) both sn-vt-out}
::view-transition-new(root){animation:260ms var(--ease-out) both sn-vt-in}

@keyframes sn-vt-out{to{opacity:0}}
@keyframes sn-vt-in{from{opacity:0}}

/* 品牌标识在两页之间做「同一元素」的形变，而不是各自淡入淡出 */
.brand{view-transition-name:sn-brand}

/* 切主题：新主题从按钮位置以圆形铺开（坐标由 ui.js 写进 --vt-x / --vt-y）。
   只在 html.vt-theme 期间生效，跨页导航仍走上面的交叉淡入。
   两张快照必须改回 normal 混合：UA 默认的 plus-lighter 是给交叉淡入用的，
   两张不透明快照叠在一起会直接过曝。 */
:root.vt-theme .brand{view-transition-name:none}
:root.vt-theme::view-transition-old(root),
:root.vt-theme::view-transition-new(root){mix-blend-mode:normal}
:root.vt-theme::view-transition-old(root){animation:none}
:root.vt-theme::view-transition-new(root){animation:560ms var(--ease-in-out) both sn-vt-iris}
@keyframes sn-vt-iris{
  from{clip-path:circle(0 at var(--vt-x,50%) var(--vt-y,0px))}
  to{clip-path:circle(150vmax at var(--vt-x,50%) var(--vt-y,0px))}
}

/* --------------------------------------------------------------------------
   6b. 氛围与质感层（2026-10-13 Mike 点名要「高级炫酷」后加）
   纪律没变：只动 transform / opacity；循环动画全站只有首页航线图一处
   （样式在 index.html 的 .route）；其余全部是「响应用户动作」的反馈。
   -------------------------------------------------------------------------- */

/* 首屏光幕：左上北欧青、右下中国红。四个页面的 .hero 共用。
   底部淡出靠最上面那层「透明 → 页面底色」的渐变，不用 mask。
   这一层是**静态**的，别给它加漂移动画：试过 24s 一个来回的缓慢漂移，
   肉眼几乎看不出，代价却是一个永远在动的大图层 —— 实测它让「切主题」的
   快照捕获慢了近 1 秒（无头浏览器中位 1607ms，去掉后 370ms）。 */
.hero{position:relative;isolation:isolate;overflow:hidden}
.hero::before{
  content:"";position:absolute;inset:-25% -15% 0;z-index:-1;pointer-events:none;
  background:
    linear-gradient(transparent 55%, var(--bg)),
    radial-gradient(38% 46% at 14% 26%, var(--wash-n), transparent 72%),
    radial-gradient(36% 44% at 88% 62%, var(--wash-c), transparent 72%),
    radial-gradient(30% 36% at 56% 4%, var(--wash-s), transparent 72%);
}

/* 标题强调词：只有一个时保持品牌红（各页面自己的 `h1 em{color}`）；
   英文首页有两个（Nordic / Chinese），前一个改成极光青，正好一端一色。
   试过青 → 红的渐变字：两色在 sRGB 里插值会经过一段灰褐色，发脏，弃用。
   inline-block 让强调词不被拆到两行 —— 中文没有词边界，否则会断成「市 / 场」这种。 */
h1 em{display:inline-block;max-width:100%}
h1 em:first-of-type:not(:only-of-type){color:var(--aurora)}
h1,h2{text-wrap:balance}
/* 中文不做行长均衡：均衡算法只管两行等长，照样会把词从中间劈开 */
:lang(zh-CN) :is(h1,h2){text-wrap:wrap}

/* 红色主按钮：底部带一层同色辉光，悬停时一道高光扫过 */
.btn-red{position:relative;overflow:hidden;box-shadow:0 8px 22px -10px var(--red)}
.btn-red::after{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(105deg, transparent 36%, rgba(255,255,255,.34) 50%, transparent 64%);
  transform:translateX(-120%);
}

/* 阅读进度：吸顶导航底边一条青 → 红的细线。纯 CSS 滚动时间线，
   不支持的浏览器（目前是 Firefox）就是没有这条线。 */
@supports (animation-timeline:scroll()){
  header::after{
    content:"";position:absolute;left:0;right:0;bottom:-1px;height:2px;pointer-events:none;
    background:linear-gradient(90deg, var(--aurora), var(--red));
    transform-origin:left;transform:scaleX(0);
    animation:sn-progress linear both;
    animation-timeline:scroll(root);
  }
}
@keyframes sn-progress{to{transform:scaleX(1)}}

/* 卡片聚光：光斑跟着指针走（坐标由 ui.js 写进 --mx / --my）。
   ::before 是卡片内的柔光，::after 是只露出 1px 的边框高光。
   卡片本体不再做悬停位移 —— 原先那条 `transition:transform` 会整条顶掉
   滚动揭示的过渡（opacity 没了过渡、阶梯延迟也被清零），揭示实际只剩一下硬弹。 */
.door,.more-card,.ch-card,.card,.info-card{position:relative;isolation:isolate}
.door.dark{--spot:rgba(255,255,255,.07)}
@media (hover:hover) and (pointer:fine){
  :is(.door,.more-card,.ch-card,.card,.info-card)::before,
  :is(.door,.more-card,.ch-card,.card,.info-card)::after{
    content:"";position:absolute;inset:-1px;border-radius:inherit;pointer-events:none;
    opacity:0;transition:opacity var(--d-ui) ease;
  }
  :is(.door,.more-card,.ch-card,.card,.info-card)::before{
    z-index:-1;
    background:radial-gradient(380px circle at var(--mx,50%) var(--my,50%), var(--spot), transparent 68%);
  }
  :is(.door,.more-card,.ch-card,.card,.info-card)::after{
    padding:1px;
    background:radial-gradient(240px circle at var(--mx,50%) var(--my,50%), var(--red), transparent 72%);
    -webkit-mask:linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    -webkit-mask-composite:xor;mask-composite:exclude;
  }
  :is(.door,.more-card,.ch-card,.card,.info-card):hover::before,
  :is(.door,.more-card,.ch-card,.card,.info-card):hover::after{opacity:1}

  .btn-red:hover::after{transform:translateX(120%);transition:transform 640ms var(--ease-out)}

  .nav-links a{position:relative}
  .nav-links a::after{
    content:"";position:absolute;left:0;right:0;bottom:-6px;height:1.5px;background:var(--red);
    transform:scaleX(0);transform-origin:left;transition:transform var(--d-ui) var(--ease-out);
  }
  .nav-links a:hover::after{transform:scaleX(1)}
}

/* --------------------------------------------------------------------------
   7. 无障碍降级
   -------------------------------------------------------------------------- */

/* 减弱动态：去掉位移与旋转，保留帮助理解的淡入 */
@media (prefers-reduced-motion: reduce){
  html{scroll-behavior:auto}
  [data-reveal]{
    transform:none;
    transition:opacity 200ms ease;
    transition-delay:0ms;
  }
  .hero h1[data-reveal]{clip-path:none;transform:none;transition:opacity 200ms ease}
  /* 航线上的流光收起、步骤线直接画完、按钮高光不扫 */
  .route *{animation:none !important}
  .route .comet,.route .ring{display:none}
  .step::before{transition:none}
  .btn-red::after{display:none}
  .theme svg{transition:opacity 120ms ease}
  .theme .ic-sun,.theme .ic-moon,
  :root[data-theme="dark"] .theme .ic-sun,
  :root[data-theme="dark"] .theme .ic-moon{transform:none}
  .theme:active,
  .btn:active,
  .door:active,
  .card:active,
  .ch-card:active,
  .more-card:active{transform:none}

  /* 跨页过渡改为纯交叉淡入，不位移 */
  ::view-transition-old(root){animation:120ms ease both sn-vt-out}
  ::view-transition-new(root){animation:140ms ease both sn-vt-in}
  ::view-transition-group(*){animation:none}
}

/* 降低透明度：毛玻璃换成实底 */
@media (prefers-reduced-transparency: reduce){
  header,
  header.sub{
    background:var(--bg);
    -webkit-backdrop-filter:none;
    backdrop-filter:none;
  }
}

/* 提高对比度 */
@media (prefers-contrast: more){
  :root{
    --ink-2:#3A3A3A;
    --ink-3:#555555;
    --line:#9A948A;
  }
  :root[data-theme="dark"]{
    --ink-2:#DAD7D0;
    --ink-3:#B4B1AA;
    --line:#5A5750;
  }
  header,
  header.sub{background:var(--bg)}
}

/* --------------------------------------------------------------------------
   8. 打印：强制亮色，避免省墨模式下整页变黑
   -------------------------------------------------------------------------- */
@media print{
  :root{
    color-scheme:light;
    --bg:#FFFFFF;--bg-2:#FFFFFF;--card:#FFFFFF;
    --ink:#000000;--ink-2:#333333;--ink-3:#555555;--line:#BBBBBB;
  }
  [data-reveal]{opacity:1 !important;transform:none !important}
  .hero::before,header::after{display:none}
}
