/* ============================================================
   共享 UI —— 询盘清单 / 浮动按钮 / 手机菜单 / 回到顶部 / Toast
   三个原型共用。这些是我先前从线上展厅砍掉、必须补回来的东西。
   ============================================================ */

/* ---------- 浮动动作区(右下) ---------- */
.fab-wrap {
  position: fixed; right: 18px; bottom: 18px; z-index: 90;
  display: flex; flex-direction: column; align-items: flex-end; gap: 10px;
}
.fab {
  display: inline-flex; align-items: center; gap: 8px;
  border: none; cursor: pointer; font-family: inherit; font-weight: 600;
  border-radius: 999px; box-shadow: 0 10px 28px rgba(19,35,59,.22);
  transition: transform .3s var(--ease-apple, ease), box-shadow .3s ease;
}
.fab:hover { transform: translateY(-2px); }
.fab-quote { background: var(--accent-fn); color: #fff; font-size: 14px; padding: 13px 22px; }
.fab-wa {
  background: #25d366; color: #fff; width: 48px; height: 48px; padding: 0;
  justify-content: center; align-self: flex-end;
}
.fab-wa svg { width: 26px; height: 26px; }
.fab-top {
  background: var(--card, #fff); color: var(--ink, #13233b);
  border: 1px solid var(--line, rgba(19,35,59,.1));
  width: 40px; height: 40px; padding: 0; justify-content: center; font-size: 16px;
  opacity: 0; pointer-events: none; transition: opacity .35s var(--ease-apple, ease), transform .3s ease;
}
.fab-top.on { opacity: 1; pointer-events: auto; }
@media (max-width: 600px) { .fab-quote { font-size: 13px; padding: 11px 18px; } }

/* ---------- 询盘抽屉 ---------- */
.iq-mask {
  position: fixed; inset: 0; z-index: 100; background: rgba(14,26,43,.45);
  opacity: 0; pointer-events: none; transition: opacity .35s var(--ease-apple, ease);
  backdrop-filter: blur(2px);
}
.iq-mask.on { opacity: 1; pointer-events: auto; }
.iq-panel {
  position: fixed; top: 0; right: 0; bottom: 0; z-index: 101; width: min(460px, 100%);
  background: var(--paper, #f7f4ee); box-shadow: -20px 0 60px rgba(0,0,0,.2);
  transform: translateX(100%); transition: transform .45s var(--ease-apple, cubic-bezier(.28,.11,.32,1));
  display: flex; flex-direction: column;
}
.iq-panel.on { transform: translateX(0); }
.iq-head {
  padding: 22px 24px; border-bottom: 1px solid var(--line, rgba(19,35,59,.1));
  display: flex; align-items: flex-start; justify-content: space-between; gap: 14px;
}
.iq-head h3 { font-family: "Sora", sans-serif; font-size: 1.15rem; margin: 0; letter-spacing: -.02em; }
.iq-head p { margin: 7px 0 0; font-size: .85rem; color: var(--ink-soft, #5c6b80); line-height: 1.5; }
.iq-close {
  border: none; background: transparent; font-size: 24px; line-height: 1; cursor: pointer;
  color: var(--ink-soft, #5c6b80); padding: 0 2px;
}
.iq-body { flex: 1; overflow-y: auto; padding: 20px 24px; }
.iq-empty { font-size: .9rem; color: var(--ink-soft, #5c6b80); line-height: 1.6; }
.iq-items { list-style: none; margin: 0 0 20px; padding: 0; display: grid; gap: 10px; }
.iq-item {
  display: flex; align-items: center; gap: 12px; background: var(--card, #fff);
  border: 1px solid var(--line, rgba(19,35,59,.1)); border-radius: 12px; padding: 10px 12px;
}
.iq-item img { width: 44px; height: 44px; object-fit: contain; flex-shrink: 0; }
.iq-item .m { flex: 1; min-width: 0; }
.iq-item .sku { font-family: ui-monospace, Menlo, monospace; font-size: 11px; color: var(--accent-fn, #b85a1c); }
.iq-item .nm { display: block; font-size: .88rem; font-weight: 600; margin-top: 2px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.iq-item button {
  border: none; background: transparent; cursor: pointer; font-size: 18px;
  color: var(--ink-soft, #5c6b80); padding: 4px 6px; line-height: 1;
}
.iq-form { display: grid; gap: 12px; }
.iq-form label { display: grid; gap: 5px; font-size: 12.5px; font-weight: 600; }
.iq-form input, .iq-form textarea {
  font-family: inherit; font-size: 14px; padding: 10px 13px; border-radius: 11px;
  border: 1px solid var(--line, rgba(19,35,59,.1)); background: var(--card, #fff); color: inherit;
}
.iq-form input:focus, .iq-form textarea:focus { outline: none; border-color: var(--accent, #d2702f); }
.iq-form textarea { min-height: 70px; resize: vertical; }
.iq-row2 { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.iq-submit {
  background: var(--accent-fn, #b85a1c); color: #fff; border: none; border-radius: 999px;
  padding: 13px; font-family: inherit; font-size: 15px; font-weight: 600; cursor: pointer;
}
.iq-status { font-size: 12.5px; color: var(--accent-fn, #b85a1c); min-height: 16px; }

/* ---------- 产品卡上的「加入询盘」 ---------- */
.pcard { position: relative; }
.pcard-sku {
  font-family: ui-monospace, Menlo, monospace; font-size: 11px;
  color: var(--ink-soft, #5c6b80); letter-spacing: .02em;
}
.pcard-add {
  margin-top: 12px; width: 100%; border: 1.5px solid var(--line, rgba(19,35,59,.1));
  background: transparent; color: var(--ink, #13233b); border-radius: 999px;
  padding: 9px; font-family: inherit; font-size: 13px; font-weight: 600; cursor: pointer;
  transition: all .25s var(--ease-apple, ease);
}
.pcard-add:hover { border-color: var(--accent-fn, #b85a1c); color: var(--accent-fn, #b85a1c); }
.pcard-add.in { background: var(--accent-soft, #f3d8c4); border-color: var(--accent-soft, #f3d8c4); color: var(--accent-fn, #b85a1c); }

/* ---------- 产品详情弹窗 ---------- */
.pm-mask {
  position: fixed; inset: 0; z-index: 110; background: rgba(14,26,43,.55);
  opacity: 0; pointer-events: none; transition: opacity .3s var(--ease-apple, ease);
  display: grid; place-items: center; padding: 24px; backdrop-filter: blur(3px);
}
.pm-mask.on { opacity: 1; pointer-events: auto; }
.pm {
  background: var(--paper, #f7f4ee); border-radius: 24px; max-width: 880px; width: 100%;
  max-height: 88vh; overflow-y: auto; padding: 0;
  transform: scale(.96); transition: transform .35s var(--ease-apple, cubic-bezier(.28,.11,.32,1));
}
.pm-mask.on .pm { transform: scale(1); }
.pm-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0; }
.pm-img { background: #fff; display: grid; place-items: center; padding: 28px; border-radius: 24px 0 0 24px; }
.pm-img img { width: 100%; max-height: 340px; object-fit: contain; }
.pm-info { padding: 30px 32px 32px; }
.pm-info .sku { font-family: ui-monospace, Menlo, monospace; font-size: 12px; color: var(--accent-fn, #b85a1c); }
.pm-info h3 { font-family: "Sora", sans-serif; font-size: 1.5rem; margin: 8px 0 0; letter-spacing: -.02em; }
.pm-info .tag { margin: 12px 0 0; font-size: .93rem; color: var(--ink-soft, #5c6b80); line-height: 1.6; }
.pm-spec { list-style: none; margin: 20px 0 0; padding: 0; display: grid; gap: 9px; }
.pm-spec li { display: grid; grid-template-columns: 96px 1fr; gap: 10px; font-size: .88rem; }
.pm-spec .k { color: var(--ink-soft, #5c6b80); }
.pm-swatch { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
.pm-swatch span {
  font-size: 11px; padding: 3px 9px; border-radius: 999px;
  background: var(--card, #fff); border: 1px solid var(--line, rgba(19,35,59,.1));
}
.pm-cta { display: flex; gap: 10px; margin-top: 24px; flex-wrap: wrap; }
.pm-close { position: absolute; top: 14px; right: 16px; }
.pm-wrap { position: relative; }
@media (max-width: 760px) {
  .pm-grid { grid-template-columns: 1fr; }
  .pm-img { border-radius: 24px 24px 0 0; padding: 20px; }
  .pm-info { padding: 24px; }
}

/* ---------- Toast ---------- */
.toast {
  position: fixed; left: 50%; bottom: 26px; z-index: 120; transform: translate(-50%, 14px);
  background: var(--night, #0e1a2b); color: #fff; padding: 12px 22px; border-radius: 999px;
  font-size: 13.5px; box-shadow: 0 14px 40px rgba(0,0,0,.28);
  opacity: 0; pointer-events: none; transition: opacity .3s ease, transform .3s var(--ease-apple, ease);
}
.toast.on { opacity: 1; transform: translate(-50%, 0); }

/* ---------- 手机汉堡菜单 ---------- */
.nav-burger {
  display: none; border: 1px solid var(--line, rgba(19,35,59,.1)); background: transparent;
  width: 40px; height: 40px; border-radius: 11px; cursor: pointer; position: relative;
}
.nav-burger span {
  position: absolute; left: 11px; right: 11px; height: 1.8px; background: var(--ink, #13233b);
  transition: transform .3s var(--ease-apple, ease), opacity .2s ease;
}
.nav-burger span:nth-child(1) { top: 14px; }
.nav-burger span:nth-child(2) { top: 19px; }
.nav-burger span:nth-child(3) { top: 24px; }
.nav-burger.on span:nth-child(1) { transform: translateY(5px) rotate(45deg); }
.nav-burger.on span:nth-child(2) { opacity: 0; }
.nav-burger.on span:nth-child(3) { transform: translateY(-5px) rotate(-45deg); }
@media (max-width: 1020px) {
  .nav-burger { display: block; }
  .nav-links {
    display: grid !important; gap: 0;
    position: fixed; top: 62px; left: 0; right: 0;
    background: var(--paper, #f7f4ee); border-bottom: 1px solid var(--line, rgba(19,35,59,.1));
    padding: 8px 20px 18px; box-shadow: 0 20px 40px rgba(19,35,59,.1);
    transform: translateY(-12px); opacity: 0; pointer-events: none;
    transition: opacity .3s var(--ease-apple, ease), transform .3s var(--ease-apple, ease);
  }
  .nav-links.on { transform: translateY(0); opacity: 1; pointer-events: auto; }
  .nav-links a { padding: 13px 0; border-bottom: 1px solid var(--line, rgba(19,35,59,.06)); font-size: 15px; }
  .nav-links a:last-child { border-bottom: none; }
}

/* 评审开关挪到左下,别跟浮动按钮打架 */
.review-bar { right: auto !important; left: 16px !important; }

@media (prefers-reduced-motion: reduce) {
  .fab, .iq-panel, .iq-mask, .pm, .pm-mask, .toast, .nav-links, .nav-burger span { transition: none !important; }
}

/* ---------- 键盘可达性 ---------- */
/* 鼠标点击不留焦点框,Tab 才显示 —— 与线上 LoginPage 同一策略 */
:focus-visible {
  outline: 2px solid var(--accent, #d2702f);
  outline-offset: 3px;
  border-radius: 4px;
}
:focus:not(:focus-visible) { outline: none; }

/* 跳过导航:键盘用户第一个 Tab 就能直达正文,不用穿过整排导航 */
.skip-link {
  position: absolute; left: 12px; top: -60px; z-index: 200;
  background: var(--night, #0e1a2b); color: #fff; padding: 11px 20px;
  border-radius: 0 0 12px 12px; font-size: 14px; font-weight: 600; text-decoration: none;
  transition: top .2s ease;
}
.skip-link:focus { top: 0; }

/* ---------- 询盘附件 ---------- */
.iq-file { gap: 6px !important; }
.iq-file input[type="file"] {
  font-family: inherit; font-size: 12px; padding: 10px 12px; border-radius: 11px;
  border: 1px dashed var(--line, rgba(19,35,59,.1)); background: var(--card, #fff);
  color: var(--ink-soft, #5c6b80); width: 100%; max-width: 100%;
}
.iq-file input[type="file"]:hover { border-color: var(--accent, #d2702f); }
.iq-hint { font-size: 11.5px; font-weight: 400; color: var(--ink-soft, #5c6b80); }

/* ---------- 多页结构:子页顶部返回 + 当前页高亮 ---------- */
.nav-links .nav-here { opacity: 1 !important; color: var(--ink, #13233b); position: relative; }
.nav-links .nav-here::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: -6px;
  height: 2px; background: var(--accent-fn, #b85a1c); border-radius: 2px;
}
@media (max-width: 1020px) { .nav-links .nav-here::after { display: none; } }

/* ---------- 导航 hover 预览 ----------
   拆成多页之后,标签只剩一个词,买家不知道点进去是什么。
   悬停给一句话 + 一张缩略图,让他在点之前就知道值不值得点。 */
/* 页面第一个区块紧贴吸顶导航。clamp(72px,8vw,112px) 是「区块与区块之间」的
   节奏,用在这里会在导航下面空出 106px(实测)。首屏不需要这么喘。
   只命中子页 —— 首页 nav 后面是 <header class="hero">,选择器落不到。 */
.nav + .section { padding-top: clamp(34px, 4vw, 52px); }

/* 只有描述的卡片用固定宽(否则一整句会拉成一条长线);
   带条目列表的卡片改为 max-content —— 既不换行又不省略,只能让卡片跟着内容长。 */
.navpv {
  position: fixed; z-index: 60; width: 320px;
  background: var(--card, #fff); border: 1px solid var(--line, rgba(19,35,59,.1));
  border-radius: 16px; box-shadow: 0 18px 44px rgba(19,35,59,.14);
  padding: 0; overflow: hidden;
  opacity: 0; transform: translateY(-6px); pointer-events: none;
  transition: opacity .22s var(--ease-apple, ease), transform .22s var(--ease-apple, ease);
}
.navpv.on { opacity: 1; transform: translateY(0); pointer-events: auto; }
/* 链接和卡片之间有 10px 空隙,鼠标穿过去会先触发 mouseleave 把卡片收掉。
   用一条透明的桥把空隙补上,鼠标全程都在「卡片区域」内。 */
.navpv::before {
  content: ""; position: absolute; left: 0; right: 0; top: -14px; height: 14px;
}
.navpv img { width: 100%; height: 128px; object-fit: cover; display: block; background: #efeae1; }
.navpv .b { padding: 14px 16px 16px; }
.navpv .k { font-size: 10.5px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--accent-fn, #b85a1c); }
.navpv strong { display: block; font-family: "Sora", sans-serif; font-size: 1rem; margin-top: 6px; letter-spacing: -.01em; }
.navpv p { margin: 8px 0 0; font-size: .84rem; line-height: 1.5; color: var(--ink-soft, #5c6b80); }
@media (max-width: 1020px) { .navpv { display: none; } }
@media (prefers-reduced-motion: reduce) { .navpv { transition: none; } }

/* ---------- 首屏海报背景 ----------
   ⚠️ 这一招最容易翻车:Leeline 就是白字直接压在杂乱展会照上,副标题几乎读不清。
   所以必须两层遮罩:
     1) 整体压暗(照片本身很亮,不压根本读不了)
     2) 左侧再加一道横向渐变,让文字所在的那一带更暗
   文字区永远落在第二道渐变的深端,不管照片本身亮暗。 */
.hero.hero-bg { background-color: var(--hero-base, var(--night, #0e1a2b)); min-height: 660px; display: flex; align-items: center; }
.hero.hero-bg .wrap { width: 100%; }
.hero.hero-bg::before {
  content: ""; position: absolute; inset: 0; z-index: 0;
  background-image: var(--hero-img);
  /* ⚠️ 不能用 cover。首屏是 2.32:1,图是 4:3 —— cover 会切掉 74% 的图高,
     插画主体整个被裁没。改成 contain 贴右侧:图完整,左边露出首屏自己的
     深色底,正好就是文字要的空位。 */
  background-size: contain;
  background-position: right center;
  background-repeat: no-repeat;
  /* 实测:图自带底色 rgb(5,16,34),比站点底色 rgb(14,26,43) 还暗 ——
     所以 contrast 会把线稿一起压进黑里,brightness 又会让图底比站点底亮、
     露出竖缝。解法是两件一起做:brightness 提亮线稿,同时把首屏底色
     (--hero-base)设成「提亮之后的图底色」,两边自然对齐,缝就不存在。 */
  filter: var(--hero-filter, none);
  /* 左侧淡出:图自带的底色和 CSS 底色不可能完全一致,不淡开会看到竖直接缝 */
  -webkit-mask-image: linear-gradient(100deg, transparent 0%, rgba(0,0,0,.12) 22%, rgba(0,0,0,.55) 44%, #000 62%);
          mask-image: linear-gradient(100deg, transparent 0%, rgba(0,0,0,.12) 22%, rgba(0,0,0,.55) 44%, #000 62%);
}
.hero.hero-bg::after {
  content: ""; position: absolute; inset: 0; z-index: 0;
  background:
    /* 线稿本身没有高光,靠这层暖辉光补一个光源 —— hero-home 那张
       之所以不闷,就是金属碗自带 1% 的亮像素。位置跟着主体走。 */
    radial-gradient(46% 62% at var(--hero-glow, 72% 46%), rgba(210,112,47,.26), rgba(210,112,47,.06) 55%, transparent 78%),
    /* ⚠️ 这套参数是给「本身就暗、左半边留白」的插画调的。
       第一版是给明亮的展会实拍调的(.95/.9),叠在暗插画上会把画面压没。
       换图之后一定要重调这里 —— 图亮就加深,图暗就减轻。 */
    linear-gradient(100deg, rgba(10,18,30,.55) 0%, rgba(10,18,30,.4) 48%, rgba(10,18,30,.08) 74%, rgba(10,18,30,0) 100%),
    linear-gradient(to bottom, rgba(10,18,30,.18), rgba(10,18,30,.42));
  pointer-events: none;
}
.hero.hero-bg .hero-inner { position: relative; z-index: 1; }
/* 有背景图时首屏右侧不再摆产品九宫格,文字给到更宽 */
.hero.hero-bg .hero-inner { grid-template-columns: 1.15fr .85fr; }
.hero.hero-bg .shotgrid { display: none; }
.hero.hero-bg .hero-sub { max-width: 600px; }
@media (max-width: 1020px) {
  /* 手机上 contain 会把插画缩成右上角一小块,基本看不见也占位置。
     换成 cover 贴右侧当纹理,再压重遮罩保证文字可读 —— 窄屏上
     文字优先,图只做氛围。 */
  .hero.hero-bg { min-height: 0; display: block; }
  .hero.hero-bg::before {
    background-size: cover;
    background-position: 72% center;
    -webkit-mask-image: none; mask-image: none;
  }
  .hero.hero-bg::after {
    background: linear-gradient(to bottom, rgba(10,18,30,.86), rgba(10,18,30,.95));
  }
  .hero.hero-bg .hero-inner { grid-template-columns: 1fr; }
}
/* 右下角小字标注照片出处 —— 别让买家以为是图库图 */
.hero-credit {
  position: absolute; right: clamp(18px,5vw,56px); bottom: 18px; z-index: 2;
  font-size: 11.5px; color: rgba(255,255,255,.5); letter-spacing: .02em;
}
@media (max-width: 1020px) { .hero-credit { display: none; } }

/* ---------- 预览面板:列出「这页里面有什么」 ----------
   参考 Asana / Qualtrics 的 icon+标题+说明逐条列法,7–9 条封顶。
   条目多于 4 条时分两栏,否则面板会拖得太长。 */
.navpv.list { width: max-content; max-width: min(720px, calc(100vw - 24px)); }
/* 单列也要 minmax(0,1fr):隐式 auto 轨道的最小尺寸同样是 nowrap 整行宽。
   窄卡片(2 条以内)让它换行而不是省略号 —— 工厂全名被截成
   「Fujian Hi-Tech Zone Youlian Spor…」等于没写。 */
.navpv-list { list-style: none; margin: 12px 0 0; padding: 0; display: grid;
  grid-template-columns: minmax(0,1fr); gap: 2px; }
/* ⚠️ 必须 minmax(0,1fr):1fr 的自动最小尺寸 = nowrap 整行文字宽,
   两列会撑到 567px 塞进 426px 容器,被 overflow:hidden 切掉右边一截,
   而且 text-overflow 也因此永远不触发。 */
.navpv-list.two { grid-template-columns: minmax(0,1fr) minmax(0,1fr); gap: 2px 14px; }
.navpv-list a {
  display: block; padding: 7px 9px; margin: 0 -9px; border-radius: 9px;
  font-size: .84rem; line-height: 1.4; color: var(--ink-soft, #5c6b80);
  text-decoration: none; transition: background .15s ease, color .15s ease;
  /* 不换行也不截断:靠 .navpv.list 的 max-content 把卡片撑到够宽。
     省略号会把标题切成「Can you find the product I ne...」,等于没写。 */
  white-space: nowrap;
}
.navpv-list a::before { content: "› "; color: var(--accent-fn, #b85a1c); font-weight: 700; }
/* 步骤是有先后的,用序号而不是箭头 —— 箭头会让人以为五步可以随便挑一个看。
   ⚠️ 类名必须带 navpv- 前缀:页面自己有个 .steps(How it works 的五步条,
      display:grid + repeat(5,1fr) + li::before 画大号 "01"),
      叫 .steps 会被它整套套上,预览里冒出五列和一堆 01。 */
/* 步骤必须单列:两列是按行铺的,左列读下来是 1 3 5、右列 2 4,
   序号反而把顺序讲错了。 */
.navpv-list.navpv-steps { counter-reset: nvs; grid-template-columns: minmax(0,1fr) !important; }
.navpv-list.navpv-steps a::before { counter-increment: nvs; content: counter(nvs) ". "; }
.navpv-list a:hover { background: var(--paper, #f7f4ee); color: var(--ink, #13233b); }
.navpv-all {
  display: block; margin-top: 12px; padding-top: 11px;
  border-top: 1px solid var(--line, rgba(19,35,59,.1));
  font-size: .84rem; font-weight: 600; color: var(--accent-fn, #b85a1c); text-decoration: none;
}

/* ---------- 深链落点 ---------- */
/* 兜底:即使 JS 没跑,原生跳转也别被吸顶导航盖住 */
[id^="q"], [id^="t"], [id^="c"], [id^="s"], [id^="w"], [id^="d"], [id^="f"], [id^="n"] { scroll-margin-top: 92px; }

/* 落点闪一下 —— 让用户看清「我点的是这条」 */
.dl-hit {
  animation: dlHit 2.2s var(--ease-apple, ease) 1;
  border-radius: 12px;
}
@keyframes dlHit {
  0%   { box-shadow: 0 0 0 0 rgba(210,112,47,0); background-color: rgba(210,112,47,0); }
  12%  { box-shadow: 0 0 0 5px rgba(210,112,47,.16); background-color: rgba(210,112,47,.09); }
  70%  { box-shadow: 0 0 0 5px rgba(210,112,47,.16); background-color: rgba(210,112,47,.09); }
  100% { box-shadow: 0 0 0 0 rgba(210,112,47,0); background-color: rgba(210,112,47,0); }
}
@media (prefers-reduced-motion: reduce) {
  .dl-hit { animation: none; background-color: rgba(210,112,47,.09); }
}

/* ---------- 点阵世界地图 ---------- */
/* 地图给到 2.1fr:旧版投影带着整个南极空屏,陆地只占视口 45% 高,
   看着就小。现在视口裁到实际有陆地的纬度带,同样宽度下大了一倍不止。 */
.rm { display: grid; grid-template-columns: minmax(0,2.1fr) minmax(268px,.82fr); gap: clamp(22px,3vw,40px); align-items: center; }
.rm-map svg { width: 100%; height: auto; display: block; overflow: visible; }
.rm-dots circle { fill: rgba(19,35,59,.28); }

/* 航线:底下一条慢流的虚线打底,上面叠一段短亮线跑过去。
   两条路径 d 完全一样,靠 pathLength="1000" 把长度归一化 ——
   不归一化的话每条航线长度不同,同一套 dasharray 跑出来快慢不一。 */
/* ⚠️ 箭头写在 <defs> 里,marker 内容继承的是 <svg> 的 color,
   不是引用它的那条 path 的 —— 在 .rm-arcs 上设 color 箭头拿不到,会渲染成灰色。
   所以直接给 marker 里的 path 上色。 */
.rm-map svg #rmArrow path { fill: var(--accent, #d2702f); }
.rm-arc { fill: none; stroke: var(--accent, #d2702f); stroke-width: 1.8; stroke-dasharray: 5 7; opacity: .42; animation: rm-flow 2.2s linear infinite; }
.rm-comet { fill: none; stroke: var(--accent, #d2702f); stroke-width: 3.6; stroke-linecap: round; stroke-dasharray: 70 930; stroke-dashoffset: 0; opacity: 1; animation: rm-run 4.2s linear infinite; }
@keyframes rm-flow { to { stroke-dashoffset: -15; } }
@keyframes rm-run  { 0% { stroke-dashoffset: 0; opacity: 0; } 10%,84% { opacity: 1; } 100% { stroke-dashoffset: -1000; opacity: 0; } }

.rm-hub circle { fill: var(--ink, #13233b); stroke: #fff; stroke-width: 2; }
/* paint-order + 白描边:标签压在点阵上,没有底衬就糊成一团 */
.rm-hub text { font-family: "Sora", sans-serif; font-size: 17px; font-weight: 600; fill: var(--ink, #13233b);
  letter-spacing: .01em; paint-order: stroke; stroke: var(--bg, #f7f4ef); stroke-width: 4px; stroke-linejoin: round; }
.rm-reach-g circle:not(.rm-hit) { fill: rgba(210,112,47,.14); stroke: var(--accent, #d2702f); stroke-width: 1.8; opacity: .7; transition: r .25s var(--ease-apple, ease); }
.rm-marker { cursor: pointer; }
/* 透明热区:图上的点半径只有 2-6px,手机上根本点不中。
   r 用 CSS 写(SVG 几何属性可被 CSS 覆盖),⚠️ 必须带单位,写 r:22 无效。 */
.rm-hit { fill: transparent; stroke: none; r: 22px; }
@media (max-width: 640px) { .rm-hit { r: 62px; } }   /* 窄屏点阵被压到 1/3,62 用户单位 ≈ 42 CSS px 触达 */
.rm-marker:focus { outline: none; }
.rm-marker:focus-visible .rm-pin, .rm-marker:focus-visible circle:not(.rm-hit) { stroke: var(--ink, #13233b); stroke-width: 3; }
.rm-pulse { fill: var(--accent, #d2702f); opacity: .18; transform-box: fill-box; transform-origin: center; animation: rm-ping 2.6s ease-out infinite; }
.rm-marker:nth-of-type(2) .rm-pulse { animation-delay: .5s; }
.rm-marker:nth-of-type(3) .rm-pulse { animation-delay: 1s; }
.rm-marker:nth-of-type(4) .rm-pulse { animation-delay: 1.5s; }
.rm-pin { fill: var(--accent, #d2702f); stroke: #fff; stroke-width: 2; transition: r .25s var(--ease-apple, ease); }
.rm-marker.on .rm-pin { r: 9.5; }
.rm-marker.rm-r.on circle:not(.rm-hit) { opacity: 1; r: 8; }
@keyframes rm-ping { 0% { transform: scale(.5); opacity: .3; } 70%,100% { transform: scale(1.5); opacity: 0; } }

.rm-panel { background: var(--card, #fff); border: 1px solid var(--line, rgba(19,35,59,.1)); border-radius: 20px; padding: 26px; min-height: 214px; }
.rm-panel.rm-fade { animation: rm-in .34s var(--ease-apple, ease) both; }
@keyframes rm-in { from { opacity: 0; transform: translateY(6px); } }
.rm-panel .rm-k { font-size: 11px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--accent-fn, #b85a1c); }
.rm-panel strong { display: block; font-family: "Sora", sans-serif; font-size: 1.3rem; margin-top: 9px; letter-spacing: -.02em; }
.rm-panel p { margin: 10px 0 0; font-size: .9rem; line-height: 1.6; color: var(--ink-soft, #5c6b80); }
.rm-c { list-style: none; margin: 16px 0 0; padding: 0; display: grid; gap: 7px; }
.rm-c li { font-size: .92rem; padding-left: 16px; position: relative; }
.rm-c li::before { content: ""; position: absolute; left: 0; top: .52em; width: 6px; height: 6px; border-radius: 50%; background: var(--accent, #d2702f); }
.rm-none { font-style: italic; }
@media (max-width: 860px) { .rm { grid-template-columns: 1fr; } }
@media (prefers-reduced-motion: reduce) {
  .rm-pulse, .rm-arc, .rm-comet, .rm-panel.rm-fade { animation: none; }
  .rm-pulse { opacity: .12; } .rm-comet { opacity: 0; } .rm-pin { transition: none; }
}

/* ---------- Contact us ---------- */
.ct { display: grid; grid-template-columns: repeat(auto-fit, minmax(238px, 1fr)); gap: 16px; }   /* 238 才能在 1068px 容器里排下 4 张,258 会把第 4 张挤到第二行独占一行 */
.ct-card {
  display: block; text-decoration: none; color: inherit;
  background: var(--card, #fff); border: 1px solid var(--line, rgba(19,35,59,.1));
  border-radius: 18px; padding: 22px 22px 20px;
  transition: transform .3s var(--ease-apple, ease), box-shadow .3s var(--ease-apple, ease), border-color .3s ease;
}
a.ct-card:hover { transform: translateY(-3px); box-shadow: 0 16px 38px rgba(19,35,59,.11); border-color: rgba(210,112,47,.4); }
.ct-ico { display: flex; width: 38px; height: 38px; align-items: center; justify-content: center;
  border-radius: 11px; background: var(--paper, #f7f4ee); margin-bottom: 14px; }
.ct-ico .ico { width: 19px; height: 19px; }
.ct-k { font-size: 10.5px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--accent-fn, #b85a1c); }
.ct-card strong { display: block; font-family: "Sora", sans-serif; font-size: 1.02rem; margin-top: 7px; letter-spacing: -.01em; word-break: break-word; }
.ct-card p { margin: 9px 0 0; font-size: .86rem; line-height: 1.6; color: var(--ink-soft, #5c6b80); }
.ct-go { display: block; margin-top: 14px; font-size: .84rem; font-weight: 600; color: var(--accent-fn, #b85a1c); }
.ct-note { color: var(--ink-soft, #5c6b80); font-weight: 500; }
.ct-static { background: var(--paper, #f7f4ee); }
@media (prefers-reduced-motion: reduce) { .ct-card { transition: none; } a.ct-card:hover { transform: none; } }

/* ---------- 离站确认 ---------- */
/* ⚠️ 必须高于 .pm-mask(110)。离站确认可能是从 Contact 弹窗里触发的,
   压在下面的话点了 WhatsApp 什么都不出现,看着就是页面卡死。 */
.lv-mask { position: fixed; inset: 0; z-index: 130; display: flex; align-items: center; justify-content: center;
  padding: 20px; background: rgba(19,35,59,.42); backdrop-filter: blur(3px);
  opacity: 0; pointer-events: none; transition: opacity .22s var(--ease-apple, ease); }
.lv-mask.on { opacity: 1; pointer-events: auto; }
.lv { width: min(400px, 100%); background: var(--card, #fff); border-radius: 20px; padding: 26px;
  box-shadow: 0 26px 70px rgba(19,35,59,.28); transform: translateY(8px) scale(.98);
  transition: transform .26s var(--ease-apple, ease); }
.lv-mask.on .lv { transform: none; }
.lv strong { display: block; font-family: "Sora", sans-serif; font-size: 1.16rem; letter-spacing: -.02em; }
.lv-p { margin: 10px 0 0; font-size: .88rem; line-height: 1.6; color: var(--ink-soft, #5c6b80); }
.lv-btns { display: flex; gap: 10px; margin-top: 20px; }
.lv-btns button { flex: 1; padding: 11px 14px; border-radius: 11px; font: inherit; font-size: .9rem;
  font-weight: 600; cursor: pointer; transition: background .18s ease, border-color .18s ease; }
.lv-no { background: transparent; border: 1px solid var(--line, rgba(19,35,59,.16)); color: var(--ink, #13233b); }
.lv-no:hover { background: var(--paper, #f7f4ee); }
.lv-yes { background: var(--accent, #d2702f); border: 1px solid var(--accent, #d2702f); color: #fff; }
.lv-yes:hover { background: #bd6226; }
@media (prefers-reduced-motion: reduce) { .lv-mask, .lv { transition: none; } }

/* ---------- Contact 弹窗 ---------- */
.ct-modal { max-width: 1000px; padding: 32px 32px 30px; background: var(--paper, #f7f4ee); }
.ct-modal-body .head { margin-bottom: 22px; max-width: 620px; }
.ct-modal-body .head h2 { font-size: clamp(1.5rem, 2.6vw, 2rem); }
.ct-modal-body .head p { margin-top: 10px; }
/* 212 是下限:再窄 sales@aitradepath.com 就会从中间断成两行(实测断在 .c / om)。
   弹窗 1000 - 64 内边距 = 936,4×212+3×14 = 890,刚好排得下四列。 */
.ct-modal-body .ct { grid-template-columns: repeat(auto-fit, minmax(212px, 1fr)); gap: 14px; }
.ct-modal-body .ct-card { padding: 18px 16px 16px; }
/* 邮箱是这里唯一的长不可断词。实测 .96rem 需要 188px、可用 186px —— 差 2px
   就会断成 sales@aitradepath.co / m。降到 .92rem + 收字距后需 ~176px,留 14px 余量。 */
.ct-modal-body .ct-card strong { font-size: .92rem; letter-spacing: -.015em; overflow-wrap: anywhere; }
.ct-modal-body .ct-card p { font-size: .82rem; }
@media (max-width: 620px) { .ct-modal { padding: 26px 20px 22px; } }

/* ---------- 顶部阅读进度条 ---------- */
/* z-index 55:压过吸顶导航(50),但低于各种遮罩(99+)—— 弹窗开着时页面不滚,
   进度条盖在遮罩上面只会显得脏。 */
.sprog {
  position: fixed; top: 0; left: 0; right: 0; height: 3px; z-index: 55;
  background: linear-gradient(90deg, var(--accent, #d2702f), #e8a15c);
  transform: scaleX(0); transform-origin: 0 50%;
  will-change: transform; pointer-events: none;
}
/* 不加 transition —— 进度条要贴着滚动走,补间会让它慢半拍,反而像卡了 */
