/* Guangzhou Base Studio · design tokens (single source of truth)
 * 规则：颜色/字阶/间距/圆角/动效一律用这里的命名 token；组件样式里禁止写死值。
 * 形状锁：交互元素 pill，容器面 10px，全站统一。动效只动 color/transform/opacity。
 */
:root {
  /* 色彩：中性 ink/paper + 唯一强调色（印章红） */
  --ink: #0f1216;
  --paper: #ffffff;
  --muted: #5b6470;
  --line: #e3e6ea;
  --surface: #f6f7f9;
  --accent: #b8322a;
  --accent-soft: #f7eceb;
  --on-accent: #ffffff;   /* 强调色底上的文字（按钮），组件内不得写死白 */
  --scrim: rgb(8 10 13 / 0.55);  /* 弹窗遮罩（浅色模式） */

  /* 打印：墨/纸固定黑白，不随深色模式翻转（故单列一组，不在组件里写死 #000/#fff） */
  --print-ink: #000000;
  --print-paper: #ffffff;

  /* 字族：系统栈（无外部字体请求）+ 等宽跑数字 */
  --sans: ui-sans-serif, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  --mono: ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace;

  /* 字阶：clamp 流体；标题一律 roman（禁斜体） */
  --text-display: clamp(34px, 5.2vw, 54px);
  --lh-display: 1.03;
  --tr-display: -0.028em;
  --fw-display: 760;
  --text-display-s: clamp(28px, 4vw, 40px);   /* H1 > 50 字符时降到这一档 */
  --text-h2: clamp(20px, 2.2vw, 25px);
  --lh-h2: 1.22;
  --tr-h2: -0.018em;
  --fw-h2: 700;
  --text-h3: 17px;
  --lh-h3: 1.35;
  --tr-h3: -0.01em;              /* 与 h3{letter-spacing:-.01em} 对称；上游 feat(wa) 的 .wa-popup-title 用了它却没定义 → lint-tokens 红 */
  --fw-h3: 650;
  --text-body: 16.5px;
  --lh-body: 1.62;
  --text-small: 13.5px;
  --lh-small: 1.5;
  --text-label: 11.5px;
  --ls-label: 0.12em;

  /* 行长 */
  --measure: 68ch;
  --measure-narrow: 56ch;
  --maxw: 1080px;
  --maxw-prose: 740px;

  /* 间距：4pt 体系 */
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 22px;
  --space-6: 28px;
  --space-7: 40px;
  --space-8: 56px;
  --space-9: 72px;

  /* 形状 */
  --r-surface: 10px;
  --r-pill: 999px;

  /* 动效 */
  --dur: 150ms;
  --ease-out: cubic-bezier(0.2, 0.8, 0.2, 1);
}

@media (prefers-color-scheme: dark) {
  :root {
    --ink: #f1f3f5;
    --paper: #0b0d10;
    --muted: #98a1ac;
    --line: #23282f;
    --surface: #12161b;
    --accent: #ff6f61;
    --accent-soft: #2a1614;
    --scrim: rgb(0 0 0 / 0.68);  /* 弹窗遮罩（深色模式） */
  }
}


*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{margin:0;background:var(--paper);color:var(--ink);font-family:var(--sans);font-size:var(--text-body);line-height:var(--lh-body);
  font-feature-settings:"kern" 1,"liga" 1;text-rendering:optimizeLegibility}
a{color:inherit;text-underline-offset:3px;text-decoration-thickness:1px}
a:hover{color:var(--accent)}
:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:4px}
.wrap{max-width:var(--maxw);margin:0 auto;padding:0 var(--space-5)}
.mono{font-family:var(--mono);font-variant-numeric:tabular-nums}

/* header */
header.site{border-bottom:1px solid var(--line);background:var(--paper)}
header.site .brand-row{display:flex;align-items:center;justify-content:space-between;gap:16px;flex-wrap:wrap;padding:12px 0}
header.site .nav-row{padding:10px 0 14px;border-top:1px solid var(--line)}
header.site .top-nav{display:flex;gap:16px;flex-wrap:wrap;font-size:14.5px;align-items:center}
header.site .actions{display:flex;align-items:center;gap:14px;margin-left:auto}
.brand{font-weight:700;letter-spacing:-.02em;text-decoration:none;font-size:18px;display:inline-flex;align-items:center;gap:8px}
.brand img{width:28px;height:28px;display:block}
nav.top-nav a{color:var(--muted);text-decoration:none;padding:2px 0}
nav.top-nav a:hover{color:var(--ink)}
nav.top-nav a.on{color:var(--ink);font-weight:600;box-shadow:inset 0 -2px 0 var(--accent)}
.hsearch{display:flex;align-items:center;border:1px solid var(--line);border-radius:8px;background:var(--paper);overflow:hidden}
.hsearch input{border:0;background:transparent;padding:6px 10px;font:inherit;font-size:14px;color:var(--ink);width:220px;outline:none}
.hsearch button{border:0;background:transparent;padding:6px 10px;font:inherit;font-size:13.5px;color:var(--muted);cursor:pointer;white-space:nowrap}
.hsearch button:hover{color:var(--ink)}
.hsearch:focus-within{border-color:var(--accent)}
.cta-btn{background:var(--accent);color:var(--on-accent)!important;text-decoration:none;padding:7px 14px;border-radius:8px;font-size:14px;font-weight:600;white-space:nowrap}
.cta-btn:hover{opacity:.9}
.vh{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
/* search page */
.hsearch-page{display:flex;gap:8px;margin:18px 0 6px;flex-wrap:wrap}
.hsearch-page input{flex:1;min-width:200px;padding:10px 12px;border:1px solid var(--line);border-radius:8px;font:inherit;font-size:15px;background:var(--paper);color:var(--ink);outline:none}
.hsearch-page input:focus{border-color:var(--accent)}
.hsearch-page button{padding:10px 18px;border:0;border-radius:8px;background:var(--accent);color:var(--on-accent);font:inherit;font-weight:600;cursor:pointer}
.sr{margin:10px 0 0}
@media (max-width:720px){
  header.site .hsearch input{width:120px}
  header.site .actions{gap:10px}
}

/* type */
main{padding:var(--space-7) 0 var(--space-9)}
h1{font-size:var(--text-display);line-height:var(--lh-display);letter-spacing:var(--tr-display);font-weight:var(--fw-display);margin:0 0 var(--space-3);max-width:26ch}
h1.long{font-size:var(--text-display-s)}
h2{font-size:var(--text-h2);line-height:var(--lh-h2);letter-spacing:var(--tr-h2);font-weight:var(--fw-h2);margin:var(--space-7) 0 var(--space-3)}
h3{font-size:var(--text-h3);line-height:var(--lh-h3);font-weight:var(--fw-h3);margin:0 0 var(--space-1);letter-spacing:-.01em}
p{margin:0 0 var(--space-4);max-width:var(--measure)}
.lede{color:var(--muted);font-size:var(--text-body)}
/* 中文注册名（lang="zh-Hans"）：英文名下的原文副标题。登记名原文，不做翻译也不做字体归一化 */
.name-zh{color:var(--muted);font-size:var(--text-h3);line-height:var(--lh-h3);margin:calc(-1 * var(--space-2)) 0 var(--space-4);max-width:var(--measure)}
.small{font-size:var(--text-small);line-height:var(--lh-small);color:var(--muted)}
.eyebrow{font-family:var(--mono);font-size:var(--text-label);letter-spacing:var(--ls-label);text-transform:uppercase;color:var(--accent);margin:0 0 var(--space-2);font-weight:600}
.crumb{font-size:13px;color:var(--muted);margin-bottom:16px}
.contact-strip{border-top:1px solid var(--line);padding:18px 0;margin-top:20px}
.contact-strip p{margin:0;font-size:14px;color:var(--muted)}
.contact-strip a{color:var(--accent);text-decoration:none;font-weight:600}
.crumb a{color:var(--muted);text-decoration:none}
.crumb a:hover{color:var(--ink)}

/* hero: 非居中，左右不对称（左文右要点面板） */
.hero{display:grid;grid-template-columns:minmax(0,1.55fr) minmax(0,1fr);gap:var(--space-7);align-items:start;
  padding:var(--space-6) 0 var(--space-6);border-bottom:1px solid var(--line)}
.hero aside{border-left:2px solid var(--accent);padding-left:18px;font-size:14.5px;color:var(--muted)}
.hero aside strong{display:block;color:var(--ink);font-size:16px;margin-bottom:2px}
.hero aside div{padding:9px 0;border-bottom:1px solid var(--line)}
.hero aside div:last-child{border-bottom:0}
/* 1fr 的隐式最小值是 auto(=min-content)：内容含不可断长串（长 URL/长单词）时
   列会被撑到 min-content，320px 视口下溢出（2026-10-29 实测 invitation-letter 溢出 16px）。
   必须写 minmax(0,1fr) 才真正允许收缩。 */
@media (max-width:820px){.hero{grid-template-columns:minmax(0,1fr);gap:22px}}

/* stats */
.stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(140px,100%),1fr));gap:0;border-top:1px solid var(--line);
  border-bottom:1px solid var(--line);margin:26px 0}
.stats div{padding:var(--space-4) var(--space-4) var(--space-4);border-right:1px solid var(--line)}
.stats div:last-child{border-right:0}
.stats b{display:block;font-family:var(--mono);font-size:26px;letter-spacing:-.03em;font-weight:600;font-variant-numeric:tabular-nums}
.stats span{font-size:12.5px;color:var(--muted);text-transform:uppercase;letter-spacing:.08em}

/* timeline（广交会三期 + 换展期） */
.timeline{list-style:none;padding:0;margin:18px 0;border-left:2px solid var(--line)}
.timeline li{position:relative;padding:10px 0 12px 22px}
.timeline li::before{content:"";position:absolute;left:-7px;top:19px;width:12px;height:12px;border-radius:50%;
  background:var(--accent);border:2px solid var(--paper)}
.timeline li.gap::before{background:var(--line)}
.timeline li.gap{color:var(--muted);font-size:14px}
.timeline .when{font-family:var(--mono);font-size:13.5px;color:var(--muted);display:block}

/* rows（市场/集群列表） */
ul.rows{list-style:none;padding:0;margin:16px 0;border-top:1px solid var(--line)}
ul.rows li{padding:13px 0;border-bottom:1px solid var(--line);display:grid;grid-template-columns:minmax(0,1fr) auto;
  gap:6px 18px;align-items:baseline}
ul.rows li a{font-weight:600;text-decoration:none}
ul.rows li .meta{font-size:13.5px;color:var(--muted);grid-column:1 / -1}
ul.rows li .tag{font-family:var(--mono);font-size:11.5px;color:var(--muted);white-space:nowrap}
/* 窄屏：.tag 的 nowrap 会把 grid 的 auto 列撑到 min-content（义乌首页实测 312px，
   320px 视口溢出 32px）→ 允许换行并把两列合并成单列 */
@media (max-width:640px){
  ul.rows li{grid-template-columns:minmax(0,1fr)}
  ul.rows li .tag{white-space:normal}
}
ul.plain{list-style:none;padding:0;margin:14px 0}
ul.plain li{padding:8px 0;border-bottom:1px solid var(--line);font-size:15px}
ul.plain li:last-child{border-bottom:0}
ol{padding-left:22px}
ol li{margin-bottom:10px;max-width:66ch}

/* cards */
.grid{display:grid;gap:16px;grid-template-columns:repeat(auto-fill,minmax(min(290px,100%),1fr));margin:18px 0}
.card{border:1px solid var(--line);border-radius:var(--r-surface);padding:16px 16px 14px;background:var(--surface);
  transition:border-color .15s ease,transform .15s ease}
.card:hover{border-color:var(--accent);transform:translateY(-1px)}
.card h3 a{text-decoration:none}
.card p{margin:2px 0;font-size:14px;color:var(--muted)}

/* industry map · 真实边界地图（方案 A） */
/* 广州南北狭长（viewBox 880x1234），不压高度会把整页拉到 2000px 以上。
   用 max-height 限高：preserveAspectRatio=xMidYMid meet 会保持形状居中，不会拉伸变形。 */
.dmap{display:block;width:100%;height:auto;max-height:min(790px,82vh)}
.dmap-a{text-decoration:none}
.dmap-shapes path{fill:var(--accent);stroke:var(--paper);stroke-width:1.4;stroke-linejoin:round}
.dmap-a:hover .dmap-shapes path{stroke:var(--ink)}
.dmap-lab rect{fill:var(--paper);opacity:.93}
.dmap-n{font-size:12px;font-weight:600;fill:var(--ink)}
.dmap-v{font-size:11px;font-weight:700;fill:var(--accent)}
.dmap-legend{display:flex;align-items:center;gap:4px;font-size:12px;color:var(--muted);margin:10px 0 0}
.dmap-legend i{width:22px;height:10px;background:var(--accent);border-radius:2px}
.dmap-legend span:first-child{margin-right:6px}
.dmap-legend span:last-child{margin-left:6px}
.map-split{display:flex;gap:30px;align-items:flex-start;margin:22px 0 0}
.map-panel{flex:1 1 auto;min-width:0}
.map-side{flex:0 0 300px}
.map-side ul{list-style:none;padding:0;margin:0;border-top:1px solid var(--line)}
.map-side li{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:4px 12px;align-items:baseline;
  padding:9px 0;border-bottom:1px solid var(--line)}
.map-side li a{font-weight:600;text-decoration:none;font-size:14.5px}
.map-side li b{color:var(--accent);font-variant-numeric:tabular-nums;font-size:15px}
.map-side li .meta{grid-column:1 / -1;font-size:12px;color:var(--muted);line-height:1.35}
.map-side h2{font-size:13px;margin:0 0 10px;color:var(--muted);font-weight:500;letter-spacing:.02em}
@media (max-width:820px){.map-split{flex-direction:column}.map-side{flex:1 1 auto;width:100%}}

/* markets index · 方案 A（卡片网格） */
.ovw{margin:2px 0 0;font-size:13px;color:var(--muted);letter-spacing:.01em}
.hero-map .embed{aspect-ratio:auto;height:230px}
.hero-map .embed-credit{font-size:11.5px}
.hero-map .legend{font-size:12px;line-height:1.45;color:var(--muted);margin:8px 0 0}
.ovw b{color:var(--ink);font-weight:700}
.ovw span{margin:0 9px;color:var(--line)}
h2 .count{color:var(--muted);font-weight:400}
.mcard{padding:0;overflow:hidden;display:block;text-decoration:none;color:inherit}
.mcard-img{display:block;width:100%;height:148px;object-fit:cover}
.mcard-body{padding:13px 16px 15px}
.mcard h3{margin:0 0 4px;font-size:15.5px;line-height:1.3;letter-spacing:-.01em}
.mcard-dist{margin:0 0 5px;font-size:12.5px;color:var(--accent)}
.mcard-cat{margin:0;font-size:13px;line-height:1.45;color:var(--muted)}
.mcard-credit{margin:9px 0 0;font-size:10.5px;line-height:1.4;color:var(--muted);word-break:break-word}
@media (max-width:820px){.hero-map .embed{height:200px}}
@media (max-width:640px){.hero-map .embed{height:180px}.mcard-img{height:170px}}

/* data table */
dl.facts{margin:20px 0;border-top:1px solid var(--line)}
dl.facts div{display:grid;grid-template-columns:180px minmax(0,1fr);gap:16px;padding:11px 0;border-bottom:1px solid var(--line)}
dl.facts dt{font-size:13px;color:var(--muted);text-transform:uppercase;letter-spacing:.07em}
dl.facts dd{margin:0;font-size:15.5px}
@media (max-width:640px){dl.facts div{grid-template-columns:1fr;gap:2px}}
table{width:100%;border-collapse:collapse;margin:16px 0;font-size:15px}
/* 宽表（如历届对比 7 列）在窄屏横向滚动，不压缩列宽 */
.scroll{overflow-x:auto;-webkit-overflow-scrolling:touch;margin:16px 0}
.scroll table{margin:0;min-width:640px}
/* 3-4 列数据表（dataTable）：窄屏横向滚动，但不强制最小宽度 ——
   .scroll 的 640px 是给 7 列历届对比表用的，套在小表上反而制造更多滚动 */
.tscroll{overflow-x:auto;-webkit-overflow-scrolling:touch;margin:16px 0}
.tscroll table{margin:0}
th,td{text-align:left;padding:9px 10px;border-bottom:1px solid var(--line);vertical-align:top}
th{color:var(--muted);font-weight:600;width:190px;font-size:13px;text-transform:uppercase;letter-spacing:.06em}
/* 长 URL / 无空格串必须能断行，否则把容器撑爆（td 的最小内容宽度、p 里的源链接都会）。
   实测：集群页正文里的 http://www.zc.gov.cn/... 宽 363px，在 375 视口里溢出 13px。 */
td{overflow-wrap:anywhere;word-break:break-word}
/* 全局兜底：长 URL / 无空格串在**纯文本**里也会出现（例：广交会页的
   "Buyer Service System on the official website: https://buyer.cantonfair.org.cn/register/index"
   是 div 里的文本，不在 <a> 里 → 只给 a/p/li 加规则漏掉它，320px 下溢出 16px）。
   overflow-wrap:anywhere 只在没有正常断点时才断词，普通英文排版不受影响。 */
body{overflow-wrap:anywhere}
/* key-value 表（工厂 / 集群详情）：窄屏改成「标签一行、值一行」堆叠。
   为什么不用 .scroll 横向滚动：这类表只有 2 列、每行是「属性: 值」，
   左右拖才能读全一整行是移动端最差的阅读方式（实测 375px 下溢出 342px）。 */
@media (max-width:640px){
  table.kv{display:block;margin:14px 0}
  table.kv tbody{display:block}
  table.kv tr{display:block;padding:9px 0;border-bottom:1px solid var(--line)}
  table.kv th{display:block;width:auto;padding:0 0 3px;border:0;font-size:12px}
  table.kv td{display:block;padding:0;border:0;font-size:15px;line-height:1.45}
}

/* citation（来源块：本站的信任差异点，刻意做显眼） */
.cite{border:1px solid var(--line);border-left:3px solid var(--accent);border-radius:var(--r-surface);
  padding:12px 14px;margin:18px 0;background:var(--accent-soft);font-size:14px}
.cite .tier{font-family:var(--mono);font-size:11.5px;letter-spacing:.1em;text-transform:uppercase;color:var(--accent);font-weight:600;display:block;margin-bottom:3px}
.cite a{word-break:break-all}

.tagline{border-top:1px solid var(--line);border-bottom:1px solid var(--line);
  padding:14px 0;margin:26px 0;font-family:var(--mono);font-size:13px;color:var(--muted);letter-spacing:.01em}
.sample{border:1px solid var(--accent);border-radius:var(--r-surface);padding:10px 13px;margin:14px 0;font-size:13.5px;color:var(--accent)}

/* photo */
figure{margin:22px 0}
figure img{width:100%;height:auto;display:block;border-radius:var(--r-surface);border:1px solid var(--line)}
figcaption{font-size:12.5px;color:var(--muted);margin-top:8px;line-height:1.5}
figcaption a{color:var(--muted)}
.hero figure{margin:0}

/* verification seal（核验印章：权威感来自「可核验」而不是修饰） */
.seal{border:1px solid var(--accent);border-radius:var(--r-surface);padding:12px 14px;margin:18px 0;
  display:flex;gap:14px;align-items:flex-start;background:var(--paper)}
.seal .mark{flex:0 0 auto;border:2px solid var(--accent);border-radius:50%;width:54px;height:54px;display:grid;
  place-items:center;font-family:var(--mono);font-size:10.5px;letter-spacing:.06em;color:var(--accent);text-align:center;line-height:1.15}
.seal .body{font-size:13.5px;color:var(--muted)}
.seal .body strong{display:block;color:var(--ink);font-size:14.5px;margin-bottom:2px}

/* document reference bar */
.docbar{display:flex;gap:18px;flex-wrap:wrap;border-top:1px solid var(--ink);border-bottom:1px solid var(--line);
  padding:8px 0;margin:22px 0 0;font-family:var(--mono);font-size:11.5px;letter-spacing:.06em;
  text-transform:uppercase;color:var(--muted)}
.docbar b{color:var(--ink);font-weight:600}

/* schematic map */
.map{display:block;width:100%;height:auto;border:1px solid var(--line);border-radius:var(--r-surface);background:var(--surface)}
.map text{font-family:var(--mono);font-size:10px;fill:var(--muted);direction:ltr;unicode-bidi:isolate;paint-order:stroke;stroke:var(--surface);stroke-width:3px}
.map text.lbl{font-family:var(--sans);font-size:13px;fill:var(--ink)}
/* 第三方地图嵌入：固定比例防抖版，iframe 铺满，无 JS 依赖 */
.embed{position:relative;aspect-ratio:16/9;border:1px solid var(--line);border-radius:var(--r-surface);overflow:hidden;background:var(--surface)}
/* 媒体区：地图与照片并排。第三方地图只出横版图，竖版框架下半部会是空白，故一律 16:9 */
.media{display:grid;grid-template-columns:1fr 1fr;gap:var(--space-5);align-items:start;margin:var(--space-7) 0}
.media figure{margin:0}
.media figure img{aspect-ratio:16/9;object-fit:cover;width:100%;height:auto}
.media .embed-credit,.media .small{margin-top:6px}
@media (max-width:820px){.media{grid-template-columns:minmax(0,1fr)}}
.embed iframe{position:absolute;inset:0;width:100%;height:100%;border:0}
.embed-credit{font-size:12.5px;color:var(--muted);margin:6px 0 0}
.legend{font-size:12.5px;color:var(--muted);margin:8px 0 0}

.split{display:grid;grid-template-columns:minmax(0,300px) minmax(0,1fr);gap:34px;align-items:start;margin:22px 0}
@media (max-width:760px){.split{grid-template-columns:1fr;gap:20px}}

/* forms */
form.req{border:1px solid var(--line);border-radius:var(--r-surface);padding:20px;background:var(--surface);margin:24px 0;max-width:640px}
form.req h2{margin-top:0}
form.req label{display:block;font-size:12.5px;color:var(--muted);text-transform:uppercase;letter-spacing:.07em;margin:14px 0 5px}
form.req input,form.req textarea,form.req select{width:100%;padding:10px 11px;border:1px solid var(--line);border-radius:var(--r-surface);
  /* 显式 16px，不用 font:inherit —— 联系方式切换把 input 放进 <label> 后，
     inherit 会拿到 label 的 12.5px（低于 iOS 16px 阈值，聚焦会放大整页；
     2026-10-29 实测）。输入框 16px 也是通用标准，桌面同样适用。 */
  font-family:var(--sans);font-size:16px;background:var(--paper);color:var(--ink)}
form.req input:focus,form.req textarea:focus{border-color:var(--accent);outline:none}
form.req button{margin-top:18px;padding:12px 22px;border:0;border-radius:var(--r-pill);background:var(--accent);color:var(--on-accent);
  font:inherit;font-weight:600;cursor:pointer;transition:transform .12s ease,filter .12s ease;
  /* 显式 min-height：font:inherit 会拿到 body 的 --lh-body（移动端 1.2），
     按钮高度跟着缩水到 42px（低于 44px 触摸标准）。写死下限不受行距调整影响。 */
  min-height:44px}
form.req button:hover{filter:brightness(1.06)}
form.req button:active{transform:translateY(1px)}
form.req .fld{display:block}   /* 不用 flex：flex 会阻断 label 上边距与段落合并，底部表单会整体下移 */
form.req .f2{display:grid;grid-template-columns:1fr 1fr;gap:0 14px}
/* 弹窗里的紧凑版：去掉 intro、两组短字段并两列、间距收紧 -> 900px 视口内 Send 按钮可见 */
form.req.compact{max-width:none;margin:0;padding:0;border:0;background:transparent}
form.req.compact h2{font-size:var(--text-h3);margin-bottom:2px;padding-inline-end:52px}
form.req.compact label{margin:11px 0 4px}
form.req.compact button{margin-top:16px}

/* 需求提交：底部表单保留不动；右侧常驻入口 + 无 JS 居中弹窗（:target 打开，Esc 不支持，靠背景/Close 关闭） */
.reqcta{position:fixed;z-index:30;right:0;top:50%;transform:translateY(-50%);
  writing-mode:vertical-rl;padding:15px 10px;border:1px solid var(--accent);border-inline-end:0;
  border-start-start-radius:var(--r-surface);border-end-start-radius:var(--r-surface);
  background:var(--accent);color:var(--on-accent);font-size:14px;text-decoration:none;letter-spacing:.02em}
.reqcta:hover{color:var(--on-accent);filter:brightness(1.06)}
/* 入口双副本默认隐藏移动副本：桌面只显示大弹窗副本。移动端由样式表末尾
   @media (max-width:1119px) 里的 display:block 重新显示（同特异性、后者胜）。
   不加这条：桌面上两份按钮重叠且移动副本在 DOM 后面压住桌面副本，真实点击会错开小窗（2026-11-02）。 */
.reqcta-mobile{display:none}

/* ===== 悬浮小窗（停留 5s 后出现；纯 CSS 定时，无 JS） =====
   机制：animation 名 + 0s 时长 + 5s 延迟 + forwards —— 0s 时长无过渡帧（硬切），
   5s 后才写入终态，forwards 让终态保持。这是 CSS 能做到「5 秒后自动」的唯一方式
   （CSS 没有定时器，但 animation-delay 有）。
   状态机：
     默认      → 按钮显示、小窗隐藏
     5s 后     → 按钮隐藏、小窗显示
     #req-closed  → 强制回「按钮显示、小窗隐藏」（关掉，本次会话不再弹）
     #requirement-modal → 大弹窗打开，小窗与按钮都让位（用户点了「完整版」）
   关闭用 !important 是必须的：动画填充值（forwards）在层叠中优先于普通声明。 */
.reqw{position:fixed;z-index:30;inset-inline-end:16px;bottom:16px;width:min(280px,calc(100vw - 32px));
  padding:14px;background:var(--paper);border:1px solid var(--line);box-shadow:0 12px 32px var(--scrim);
  border-radius:var(--r-surface);visibility:hidden;
  animation:reqwShow 0s linear 5s forwards}
@keyframes reqwShow{to{visibility:visible}}
/* 5s 后按钮让小窗顶上（仅在有类别的城市：无类别的站点不隐藏按钮，否则按钮消息后没有任何替代入口） */
.reqcta{animation:reqctaHide 0s linear 5s forwards}
body:not(.has-reqw) .reqcta{animation:none}
@keyframes reqctaHide{to{visibility:hidden}}
/* 移动端（≤1119px）与桌面一样 5s 自动弹完整小窗：规则统一放在本样式表**末尾**——
   必须位于下面 reduced-motion 恢复规则之后，才能盖过它的 !important（2026-11-04）。 */
/* 关闭：回到「只有按钮」的初始态。刷新后动画重跑 → 5 秒后再次出现（每次加载重新计时）。 */
body:has(#req-closed:target) .reqw{visibility:hidden!important}
body:has(#req-closed:target) .reqcta{visibility:visible!important;animation:none}
/* 关闭后 1 分钟内跨页面不再自动弹出（head 里的内联脚本按 localStorage 打这个类）。
   抑制期间常驻按钮必须保持可见：否则用户既没有小窗、也没有任何入口（按钮的 5s 隐藏动画
   是给小窗腾位置的，小窗不出现时不能让它也消失）。 */
html.reqw-suppressed .reqw{display:none!important}
html.reqw-suppressed .reqcta{animation:none!important;visibility:visible!important}
/* 大弹窗打开时，小窗与常驻按钮都不再占位 */
body:has(#requirement-modal:target) .reqw{visibility:hidden!important}
body:has(#requirement-modal:target) .reqcta{visibility:hidden!important}

.reqw-close{position:absolute;top:6px;inset-inline-end:8px;display:inline-flex;align-items:center;justify-content:center;
  min-width:44px;min-height:44px;font-size:18px;line-height:1;color:var(--muted);text-decoration:none}
.reqw-close:hover{color:var(--ink)}
.reqw-form{display:grid;gap:8px}
.reqw-cats{border:0;margin:0;padding:0;display:grid;gap:4px}
.reqw-cats legend{font-size:13px;font-weight:600;padding:0;margin-bottom:2px}
.reqw-cats label{display:flex;align-items:center;gap:6px;font-size:13px;line-height:1.2;cursor:pointer}
/* 联系方式切换（邮箱 / WhatsApp）：两个图标，选中亮、未选灰。
   纯 CSS 用 radio + :checked + 兄弟选择器切字段，无 JS（关 JS 时邮箱档照常可用）。 */
.viaswitch{display:grid;gap:6px;margin:2px 0}
.viaswitch-label{font-size:13px;font-weight:600;color:var(--muted);text-transform:uppercase;letter-spacing:.06em}
.viaicons{display:flex;gap:8px;align-items:center}
/* 视觉隐藏但保留键盘焦点与读屏。必须写 input[type=radio]：form.req input 的
   width:100% 与本条同特异性且源码在后，只用 .viaicons input 会被撑成整行宽
   （实测 radio 变 320px 并顶出横向溢出，2026-10-29）。 */
.viaicons input[type=radio]{position:absolute;opacity:0;width:1px;height:1px;margin:0;padding:0;border:0}
.viaicons label{display:inline-flex;align-items:center;gap:6px;min-height:44px;padding:0 12px;
  border:1px solid var(--line);border-radius:var(--r-pill);color:var(--muted);cursor:pointer;
  font-size:13.5px;font-weight:600;transition:border-color .12s,color .12s,background .12s}
.viaicons label:hover{border-color:var(--muted)}
/* 高亮选中项：用 :has() 而不是相邻兄弟选择器 .viaicons input:checked + label。
   实测（2026-10-29）相邻兄弟选择器在「input 是 position:absolute 的视觉隐藏元素」时
   不触发可靠的样式重算 —— 切换 radio 后 matches() 已认新状态，但 label 的 computed
   color 仍是旧值（高亮停在默认档，看着像反了）。:has() 与字段显隐用同一机制，实测有效。 */
.viaswitch:has(input[value=email]:checked) .viaicons label[for$="-email"],
.viaswitch:has(input[value=whatsapp]:checked) .viaicons label[for$="-wa"]{
  border-color:var(--accent);color:var(--accent);background:var(--accent-soft)}
.viaicons input:focus-visible + label{outline:2px solid var(--accent);outline-offset:2px}
.viaicons .ico{width:1.15em;height:1.15em}
.viafields{display:grid;gap:3px}
.viaf{display:grid;gap:3px}
.viaf>span{font-size:13px;font-weight:600}
.viaf-wa{display:none}
/* 双向切换字段：选 WhatsApp → 显示 WA、隐藏邮箱；选邮箱 → 反之。
 * （此前只写了 WhatsApp 方向的规则：切回邮箱后 WA 框残留可见——
 *   2026-10-31 用户实测报告。两条 :has 规则互斥命中，任何选中状态都恰好一套生效。） */
.viaswitch:has(input[value=whatsapp]:checked) .viaf-email{display:none}
.viaswitch:has(input[value=whatsapp]:checked) .viaf-wa{display:grid}
.viaswitch:has(input[value=email]:checked) .viaf-wa{display:none}
/* 悬浮小窗里空间紧：隐藏可见 label，只留 placeholder（读屏靠 aria-label，不受影响） */
.reqw-form .viaf>span{display:none}
.reqw-form .fld{display:grid;gap:3px}
.reqw-form .fld label{font-size:13px;font-weight:600}
.reqw-form input[type=email],.reqw-form textarea{width:100%;padding:8px 9px;border:1px solid var(--line);
  border-radius:var(--r-surface);font:inherit;font-size:16px;background:var(--paper);color:var(--ink)}
.reqw-form button{padding:9px 14px;border:1px solid var(--accent);border-radius:var(--r-pill);
  background:var(--accent);color:var(--on-accent);font:inherit;font-size:13.5px;font-weight:600;cursor:pointer}
.reqw-form button:hover{filter:brightness(1.06)}
.reqw-promise{margin:0;font-size:12px;line-height:1.2;color:var(--muted)}
/* 小窗行内错误（2026-11-14）：手机端 78.9% 的提交因「两个联系字段都空」被服务端 400 拒，
   买家只看到整页错误页、不知道自己漏了什么。改成提交前就地提示 + 聚焦到缺失字段。 */
.reqw-err{margin:0;padding:6px 8px;border-radius:var(--r-surface);background:var(--accent-soft);
  color:var(--ink);font-size:12.5px;line-height:1.35}
.reqw-err[hidden]{display:none}
/* 触屏窄屏：小窗贴满底部，内部可滚（类别 10 项 + 邮箱 + 备注在 390px 宽下会超屏高）。
   62vh 是整窗高度上限，避免自动弹出时压满整屏。 */
@media (max-width:1119px){
  .reqw{inset-inline:12px;bottom:12px;width:auto;max-height:62vh;overflow-y:scroll;
    scrollbar-width:thin;scrollbar-color:var(--muted) var(--surface)}
  .reqw::-webkit-scrollbar{width:8px;-webkit-appearance:none}
  .reqw::-webkit-scrollbar-track{background:var(--surface)}
  .reqw::-webkit-scrollbar-thumb{background:var(--line);border-radius:var(--r-pill);
    border:2px solid var(--surface)}
  .reqw::-webkit-scrollbar-thumb:hover{background:var(--muted)}
}

.modal{display:none}
.modal:target{display:grid;place-items:center;position:fixed;inset:0;z-index:40}
.modal-backdrop{position:absolute;inset:0;background:var(--scrim)}
.modal-panel{position:relative;display:flex;flex-direction:column;width:min(560px,92vw);max-height:88vh;overflow:hidden;
  background:var(--paper);border:1px solid var(--line);border-radius:var(--r-surface);box-shadow:0 18px 50px var(--scrim)}
.modal-body{overflow:auto;padding:24px 22px}
.modal-close{position:absolute;top:12px;inset-inline-end:14px;display:inline-flex;align-items:center;justify-content:center;
  min-width:44px;min-height:44px;margin:-11px -12px;font-size:13.5px;color:var(--muted)}
.modal-close:hover{color:var(--ink)}
@media (max-width:520px){
  /* 手机上弹窗变全屏 sheet：7 个字段在 390px 宽必然要滚，全屏比小面板好操作（必须写在本块之后才生效） */
  .modal-panel{width:100%;height:100%;max-height:100%;border:0;border-radius:0}
}
@media (max-width:1119px){
  .reqcta{writing-mode:horizontal-tb;left:12px;right:12px;top:auto;bottom:12px;transform:none;
    text-align:center;border:1px solid var(--accent);border-radius:var(--r-pill);padding:13px}
  main{padding-bottom:calc(var(--space-9) + 54px)}
}
/* 蜜罐字段：不参与布局、不影响滚动宽度（RTL 下 left:-9999px 会把 html 滚动宽度撑爆） */
.hp{display:none} /* 蜜罐必须 display:none：absolute+clip 会让内部 label 撑出静态盒（实测可见），display:none 整棵子树不渲染 */

.btn{display:inline-block;padding:11px 18px;border:1px solid var(--ink);border-radius:var(--r-pill);text-decoration:none;
  font-size:14.5px;font-weight:600;transition:background .15s ease,color .15s ease}
.btn:hover{background:var(--ink);color:var(--paper)}
.btn.accent{border-color:var(--accent);color:var(--accent)}
.btn.accent:hover{background:var(--accent);color:var(--on-accent)}

footer.site{border-top:1px solid var(--line);padding:26px 0 40px;color:var(--muted);font-size:13.5px}
footer.site .cols{display:flex;gap:34px;flex-wrap:wrap;justify-content:space-between}
/* 语言开关 */
.langs{display:flex;gap:10px;align-items:center;font-size:13px;color:var(--muted);margin-inline-start:auto}
.langs-label{text-transform:uppercase;letter-spacing:.08em;font-size:var(--text-label)}
.langs a{color:var(--muted);text-decoration:none}
.langs a:hover{color:var(--ink)}
.langs a.on{color:var(--ink);font-weight:600;text-decoration:underline}

/* RTL：逻辑属性已用于关键位置；这里兜住少数物理值 */
[dir="rtl"] .hero aside{border-inline-start:2px solid var(--accent);border-inline-end:0;padding-inline-start:var(--space-4);padding-inline-end:0}
[dir="rtl"] .cite{border-inline-start:3px solid var(--accent);border-inline-end:1px solid var(--line)}
[dir="rtl"] table th,[dir="rtl"] dl.facts dt{text-align:start}
[dir="rtl"] .timeline{border-inline-start:2px solid var(--line);border-inline-end:0}
[dir="rtl"] .timeline li{padding-inline-start:22px;padding-inline-end:0}
[dir="rtl"] .timeline li::before{left:auto;inset-inline-start:-7px}

/* 数据表（T3 参考页的表格优先版式） */
table.data{width:100%;border-collapse:collapse;margin:18px 0;font-size:15px}
table.data caption{text-align:start;font-size:var(--text-small);color:var(--muted);padding-bottom:8px}
table.data thead th{position:sticky;top:0;background:var(--paper);text-transform:uppercase;letter-spacing:.06em;
  font-size:var(--text-label);color:var(--muted);border-bottom:1px solid var(--ink);padding:8px 10px;width:auto;text-align:start}
table.data td{padding:10px;border-bottom:1px solid var(--line);vertical-align:top}
table.data td:first-child{font-family:var(--mono);white-space:nowrap;font-variant-numeric:tabular-nums}
table.data tr.dim td{color:var(--muted)}

/* 长文锚点目录（T4 编辑型） */
nav.toc{border-top:1px solid var(--ink);border-bottom:1px solid var(--line);padding:12px 0;margin:18px 0;font-size:14.5px}
nav.toc ol{list-style:none;padding:0;margin:0;display:flex;flex-wrap:wrap;gap:6px 20px}
nav.toc a{color:var(--muted);text-decoration:none}
nav.toc a:hover{color:var(--ink)}
article.prose h2{scroll-margin-top:80px}

/* 可打印清单（邀请函步骤、行前清单） */
ol.check{list-style:none;padding:0;margin:16px 0;counter-reset:c}
ol.check li{position:relative;padding:10px 0 10px 34px;border-bottom:1px solid var(--line);counter-increment:c}
ol.check li::before{content:counter(c);position:absolute;inset-inline-start:0;top:10px;width:22px;height:22px;
  border:1px solid var(--ink);border-radius:4px;display:grid;place-items:center;font-family:var(--mono);font-size:11.5px}
ol.check li:last-child{border-bottom:0}

/* 提示条（表单校验/状态） */
.notice{border:1px solid var(--line);border-inline-start:3px solid var(--accent);border-radius:var(--r-surface);
  padding:12px 14px;margin:16px 0;font-size:15px;background:var(--surface)}
.notice strong{display:block;margin-bottom:4px}

/* compiled 免责页脚小字：与图片署名同视觉层级（必要但不抢戏） */
.compiled-note{margin:18px 0 0;padding-top:10px;border-top:1px solid var(--line);
  font-size:12px;line-height:1.5;color:var(--muted)}

/* s2 图库：两列自适应网格；图片原尺寸缩放（max-width 100%），figcaption 标注品类参考 */
.s2-gallery{margin:18px 0 0}
.s2-gallery h2{font-size:17px;margin:0 0 10px}
.s2-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(min(280px,100%),1fr));gap:10px}
.s2-item{margin:0;padding:0;background:var(--surface);border-radius:var(--r-surface);overflow:hidden}
.s2-item img{display:block;width:100%;height:auto}
.s2-item figcaption{font-size:12px;line-height:1.5;color:var(--muted);padding:7px 10px}

/* 打印：B2B 会把展会与市场信息打出来带走 */
@media print{
  header.site,.langs,form.req,.seal,.crumb,.reqcta,.modal{display:none!important}
  footer.site .cols{display:flex!important}
  body{font-size:11.5pt;background:var(--print-paper);color:var(--print-ink)}
  .wrap{max-width:none;padding:0}
  .hero{grid-template-columns:1fr;gap:10pt;padding:0 0 10pt;border-bottom:1px solid var(--print-ink)}
  h1{font-size:20pt}h2{font-size:13pt;margin:14pt 0 6pt}
  table.data{font-size:10.5pt}
  table.data thead th{position:static}
  a{color:var(--print-ink);text-decoration:none}
  .cite{border:1px solid var(--print-ink);background:var(--print-paper)}
  .cite a::after{content:" (" attr(href) ")";font-size:9pt;word-break:break-all}
  figure{max-width:58%}
  dl.facts,table.data,.timeline,figure,ol.check li{break-inside:avoid}
  ol.check li::before{border:1px solid var(--print-ink)}
}


/* guide cards（市场页攻略区块）：卡片网格，与 card 组件视觉一致但强调来源/导读 */
.guide-grid{display:grid;gap:16px;grid-template-columns:repeat(auto-fill,minmax(min(260px,100%),1fr));margin:18px 0}
.guide-card{display:flex;flex-direction:column;gap:6px;border:1px solid var(--line);border-radius:var(--r-surface);padding:16px 16px 14px;background:var(--surface);
  text-decoration:none;color:var(--ink);transition:border-color .15s ease,transform .15s ease}
.guide-card:hover{border-color:var(--accent);transform:translateY(-1px)}
.guide-card__tag{font-family:var(--mono);font-size:11.5px;letter-spacing:.1em;text-transform:uppercase;color:var(--accent);font-weight:600}
.guide-card__title{font-size:15.5px;font-weight:600;line-height:1.3;margin:2px 0 0;max-width:none;color:var(--ink)}
.guide-card__lede{margin:0;font-size:14px;color:var(--muted);flex:1;max-width:none}
.guide-card__cta{font-size:13px;color:var(--accent);font-weight:600;margin-top:6px}
/* 首篇攻略做 lead 卡（新读者从这里进）；同区的 guide-sub 说明有几篇 */
.guide-card--lead{border-color:var(--accent);background:var(--accent-soft)}
.guide-card--lead .guide-card__title{font-size:17px}
.guide-card--lead .guide-card__cta{font-weight:700}
.guide-sub{max-width:var(--measure)}

/* 实景图 banner：紧跟 hero，通栏、原生比例不裁切（T2 模板「页面由图像定调」） */
.photo-banner{margin:var(--space-6) 0 0}
.photo-banner figure{margin:0}
.photo-banner img{aspect-ratio:auto;object-fit:contain}

/* 紧凑数字条：数字与标签同行，高度约为原 stats 的一半 */
.stats--inline{display:flex;gap:0;border-top:1px solid var(--line);border-bottom:1px solid var(--line);margin:var(--space-5) 0}
.stats--inline div{flex:1;padding:9px 18px;border-right:1px solid var(--line);display:flex;align-items:baseline;gap:8px}
.stats--inline div:last-child{border-right:0}
.stats--inline b{font-family:var(--mono);font-size:17px;letter-spacing:-.02em;font-weight:600;font-variant-numeric:tabular-nums}
.stats--inline span{font-size:12px;color:var(--muted);text-transform:uppercase;letter-spacing:.06em;white-space:nowrap}
@media (max-width:640px){
  .stats--inline{flex-wrap:wrap}
  .stats--inline div{flex:1 1 100%;border-right:0;border-bottom:1px solid var(--line);padding:8px 14px}
  .stats--inline div:last-child{border-bottom:0}
}

/* 提示卡：市场页 highlights 升级（左强调边框 + surface 底），避免与事实表混成一片 */
.hint-cards{display:grid;gap:14px;grid-template-columns:repeat(auto-fit,minmax(min(300px,100%),1fr));margin:16px 0}
.hint-card{border:1px solid var(--line);border-inline-start:3px solid var(--accent);border-radius:var(--r-surface);
  padding:14px 16px;background:var(--surface)}
.hint-card p{margin:0;font-size:15.5px;max-width:none}

/* Where it is：地图与地址事实并排 */
.where-grid{display:grid;grid-template-columns:minmax(0,1.1fr) minmax(0,1fr);gap:var(--space-6);align-items:start;margin:16px 0}
.where-grid .embed{aspect-ratio:16/9}
.where-facts dl.facts{margin-top:0}
@media (max-width:820px){.where-grid{grid-template-columns:1fr;gap:18px}}
/* hero aside 里的地图外链 */
.hero aside a{color:var(--accent);text-decoration:none;font-weight:600}
.hero aside a:hover{text-decoration:underline}
/* inline icon（svg sprite，类似 iconfont）: 继承颜色、1em 默认尺寸。图标 Fill 来自 symbol 路径（currentColor），CSS 不再追加 stroke */
.icon-defs{position:absolute;width:0;height:0;overflow:hidden}
/* CSP 工具类（2026-11-04）：style-src 收紧到 'self' 后，内联 style= 会被浏览器直接拒绝 ——
   表现是「页面照常加载但某处没样式」，肉眼只在特定页面上看得见，所以样式声明一律进这里。
   值是从原内联样式**原样搬来**的（10/18/6px 不在 --space 刻度上，为的是零视觉变化；
   刻度化是另一件事，别和 CSP 改动混在一笔里）。 */
.mt-10{margin:10px 0 0}
.mt-18{margin:18px 0 0}
.mt-6{margin:6px 0 0}
.mb-6{margin:0 0 6px}
.mb-18{margin-bottom:18px}
/* 图例的深浅档位：与 SVG 里的 opacity 同一套值，用 nth-of-type 代替逐个内联 opacity */
.dmap-legend i:nth-of-type(1){opacity:.10}
.dmap-legend i:nth-of-type(2){opacity:.22}
.dmap-legend i:nth-of-type(3){opacity:.36}
.dmap-legend i:nth-of-type(4){opacity:.54}
.dmap-legend i:nth-of-type(5){opacity:.74}
.ico{width:1.1em;height:1.1em;vertical-align:-.15em;display:inline-block;margin-inline-end:.4em;flex-shrink:0}
.ico-sm{width:.85em;height:.85em;margin-inline-end:.3em;vertical-align:-.1em}
.ico-card{width:1em;height:1em;margin-inline-end:.35em;vertical-align:-.1em}
.ico-inline{width:1em;height:1em;margin-inline-end:.45em;vertical-align:-.15em}
/* 触控目标：交互元素最小 44px 高（移动端尤其）。
   2026-10-29 修正：原选择器写的是 nav.top a，而实际结构是 nav.top-nav
   （没有 .top）→ 这条 44px 规则从上线起就没生效过，实测导航链接只有 27px 高。
   两个选择器都保留：老结构 nav.top 与新结构 nav.top-nav 都覆盖。 */
.btn{display:inline-flex;align-items:center;min-height:44px}
nav.top a,nav.top-nav a{display:inline-flex;align-items:center;min-height:44px}
.cta-btn{display:inline-flex;align-items:center;min-height:44px}
.brand{min-height:44px}
/* 需求小窗的移动端形态（2026-10-29 优化）：
   实测原样在 390px 下是 366×591 = 占屏 70%，悬空在屏幕中间把正文全遮住 ——
   一个自称「轻量入口」的组件不该这样。改成贴底抽屉：宽 100%、只圆上方角、
   最高 70vh，正文在它上面始终可见。桌面端保持右下角 280px 卡片不变。 */
@media (max-width:640px){
  .reqw{inset-inline:0;bottom:0;width:100%;max-height:70vh;overflow-y:auto;
    border-radius:var(--r-surface) var(--r-surface) 0 0;border-bottom:0;
    padding:14px 16px calc(14px + env(safe-area-inset-bottom))}
  .reqw-close{top:2px;inset-inline-end:2px}
  .reqw-form button[type=submit]{min-height:44px}
}
/* 类别列表限高滚动：11 个平铺占 249px，移动端吃掉半屏。
   限 180px 后滚动区内约 4 项可见；Other 用 sticky 钉在底部 —— 否则它会被滚出
   可视区（2026-10-29 曾因此让人以为没有「其他」选项）。 */
/* 类别滚动区：限高取「整数项数」，避免露出半截选项（看起来像内容被切掉）。
   节距 = 行 24px（WCAG 触摸下限）+ gap 4px = 28px → 5 项 = 5×28-4 = 136px。
   别按项高算：漏掉 gap 会让最后一项露半截（2026-10-29 实测 133px 露半截）。
   量节距必须在移动视口下量：漏了 setDeviceMetricsOverride 量出来是桌面值。 */
.cats-scroll{display:grid;gap:4px;max-height:136px;overflow-y:auto;align-content:start}
/* Other 在滚动区之外，永远完整可见 + 上分隔线区分 */
.reqw-cats .cats-other{border-top:1px solid var(--line);padding-top:4px}
@media (max-width:640px){
  nav.top,nav.top-nav{gap:12px 18px}
  .crumb a{display:inline-flex;align-items:center;min-height:44px}
  /* 触摸高度：窄屏输入框给足 44px（字号已全局 16px，见 form.req input 规则）。
     注意复选框必须排除：min-height 会把每个类别行撑到 ~55px（2026-10-29 线上
     实测），滚动区里只能看 2.5 项。触摸目标是整行 label，给 label 24px
     （WCAG 2.5.8 AA 下限）即可，复选框本体恢复自然尺寸。 */
  form.req input,.reqw-form input{min-height:44px}
  .reqw-form input[type=checkbox]{min-height:0}
  .reqw-cats label{min-height:24px}
  /* 剩余的内联行高也一并收紧（2026-10-29 用户「移动端整体行间距偏大」）：
     这些元素写死了自己的 line-height，不受 --lh-body 影响，之前那轮漏掉了。
     上限统一 1.3（不跟正文的 1.2 一样紧 —— 图注/署名/表格局部仍需要一点呼吸）。
     排除：.map text.lbl（SVG 坐标系）、.reqw-cats label（已在 1.2）。 */
  figcaption,.s2-item figcaption,.embed-credit,.legend{line-height:1.3}
  table.kv td,.mcard-cat,.mcard-credit,.hero-map .legend,.hero-map .embed-credit,
  .map-side li .meta{line-height:1.3}
  .name-zh,p.small,.small,.guide-sub,.ovw,.prod span,.prod em,.mcard h3{line-height:1.3}

}
/* 字号下限作用域用 1024px（比站内布局断点 820px 更宽，是故意分开的）：
   布局断点管「几列」，字号断点管「视距是否够远」——两者不是一回事。
   640px 只覆盖手机竖屏；820px 仍漏掉**手机横屏**（iPhone 14 = 844、14 Pro Max = 932）；
   1024px 覆盖全部手机横屏 + 平板竖屏 + 小笔记本，桌面主流宽度 1280 起不受影响
   （实测 1440 与改前逐项一致：kvTh 13px / p.small 13.5px / crumb 13px）。 */
@media (max-width:1024px){
  /* 字号下限（2026-10-29 审计后定稿）。
     问题：全站有 33 个元素字号 <14px，其中最小的 10.5px，而这些恰好是**信任要素**
     （图注、来源链接、免责声明、核验印章）——手机上需要眯眼读的文字，偏偏是最该被读到的。
     桌面不动：桌面视距约 60cm、屏幕 1080px 起，13.5px 是可接受的辅助字号。
     只抬两档，保留层级感（不是一刀切同一个值）：
       A 标签/印章级 10.5–12px → 12.5px
       B 说明/来源/图注级 12.5–13.5px → 13.5px
     正文 16.5px 与卡片 14–15.5px 都不动。
     排除 SVG 内部文字（.map text.lbl / .dmap-n）：它们在 viewBox 坐标系里定位，
     改字号会撞地图标签避让判据（responsive 关卡的 mapLabels）。 */
  :root{--text-label:12.5px;--text-small:13.5px}
  /* 行距降档（2026-10-29 用户反馈「移动端整体行间距偏大」）。
     实测 390px 下正文 16.5px / 26.73px = 1.62，每行只有 42 字符 ——
     窄视口下行短，1.62 会让行与行之间显得空，一屏信息量也少。
     正文 1.62 → 1.2、辅助文字 1.5 → 1.35（保持两档之间的层级差）。
     为什么用 token 覆盖而不是逐条改行高：--lh-body 是 body/p/li 的共同来源，
     覆盖一次即全站生效，也不会漏掉某个继承它的组件。
     作用域与字号下限同一条（1024px = 视距判断）；桌面 1280 起保持 1.62。 */
  :root{--lh-body:1.2;--lh-small:1.35}
  .tag,.eyebrow,.cite .tier,.guide-card__tag,.stats span,.stats--inline span,
  .dmap-legend,.hero-map .legend,.hero-map .embed-credit,.prod em{font-size:12.5px}
  figcaption,.s2-item figcaption,.embed-credit,.legend,.mcard-credit,.mcard-dist,.mcard-cat,
  .seal .body,p.small,.sample,.reqw-promise,footer.site,.langs,.timeline .when,
  ul.rows li .meta,.map-side li .meta,.map-side h2,.ovw,.prod span,dl.facts dt,
  table.kv th{font-size:13.5px}
  .crumb,.reqw-cats legend,.reqw-cats label,.reqw-form .fld label{font-size:13.5px}
  /* 上面按「语义分组」列举后仍漏掉的几处（各带更高特异性的原规则，必须显式覆盖）：
     .seal .mark 印章、.docbar 文档参考条、ol.check 步骤序号、ul.rows li .tag、
     table.data 表头（原用 var(--text-label)，已由 :root 重定义覆盖）。 */
  .seal .mark{font-size:12.5px}
  .docbar{font-size:12.5px}
  ol.check li::before{font-size:12.5px}
  ul.rows li .tag{font-size:12.5px}
}

@media (prefers-reduced-motion:reduce){*{transition:none!important;animation:none!important}
/* 例外：询盘小窗的「停留 5s 后出现」不是动效，是 0s 时长的硬切定时（animation-delay 代替定时器，
   没有过渡帧、没有位移/缩放）。全局 animation:none 会把这条定时也杀掉 → 小窗 visibility
   永远是 hidden，开了「减少动态效果」的用户（macOS/iOS 无障碍开关、部分省电模式）
   在整个站点上**永远看不到这个入口**，同时 animationstart 也不触发、req_widget_shown
   埋点归零（2026-11-01 实测：正常模式 6.5s 后 visible，reduce 模式 6.5s 后仍 hidden）。
   故这里把两个纯定时的动画恢复回来；真正的动效仍被上面的全局规则禁掉。 */
.reqw{animation:reqwShow 0s linear 5s forwards!important}
.reqcta{animation:reqctaHide 0s linear 5s forwards!important}
body:not(.has-reqw) .reqcta{animation:none!important}}

/* ===== 移动端（≤1119px）：5s 后自动弹完整小窗（2026-11-04 用户口谕）=====
   桌面与移动端现在是同一套「5s 定时」；区别只在移动端贴底抽屉会压住正文，
   所以小窗限高 + 内部滚动。此前 11-02 改成「不自动弹、点按钮才出」、
   11-03 又改成「peek 条半出 + 点展开」，本次回到整窗自动弹。
   放样式表**最末**的两个原因：
   · 盖过上面 reduced-motion 恢复的 5s 定时（同样 !important，靠源顺序取胜）；
   · 盖过全局关闭抑制 html.reqw-suppressed .reqw{display:none!important} ——
     抑制只拦「自动弹」，关闭后 1 分钟内用户主动点按钮 (:target) 仍要能打开。
   入口双副本：桌面→#requirement-modal（大弹窗），移动→#req-widget（小窗），
   由 .reqcta-desktop / .reqcta-mobile 二选一（同一份 HTML 服务两端，不能按 UA 分流）。
   .reqcta-solo：无小窗的城市移动端回落到大弹窗入口。 */
@media (max-width:1119px){
  /* 5s 到点整窗弹出；!important + 源顺序盖过 reduced-motion 恢复块 */
  .reqw{animation:reqwShow 0s linear 5s forwards!important;overflow-y:auto}
  /* 按钮 5s 后让位给小窗 */
  .reqcta{animation:reqctaHide 0s linear 5s forwards!important}
  body:not(.has-reqw) .reqcta{animation:none!important}
  /* 用户主动点入口（含抑制期）：:target 立即打开，不受 5s 定时限制 */
  .reqw:target{visibility:visible!important;animation:none!important}
  body:has(#req-widget:target) .reqcta{visibility:hidden}
  /* 关闭：回「按钮显示、小窗隐藏」，并停掉自动弹动画 */
  body:has(#req-closed:target) .reqw{visibility:hidden!important;animation:none}
  body:has(#req-closed:target) .reqcta{visibility:visible!important;animation:none}
  /* 入口显隐 */
  .reqcta-desktop{display:none}
  .reqcta-mobile,.reqcta-solo{display:block}
  /* 抑制：关闭 1 分钟内不自动弹，但主动点按钮仍能开 */
  html.reqw-suppressed .reqw{display:none!important}
  html.reqw-suppressed body:has(#req-widget:target) .reqw{display:block!important;visibility:visible!important}
  html.reqw-suppressed .reqcta{animation:none!important;visibility:visible!important}
}


/* Thanks 页 WhatsApp 入口：WhatsApp 品牌绿 + 图标 + badge */
.wa-thanks-row{display:flex;align-items:center;gap:var(--space-3);margin:var(--space-5) 0}
.wa-thanks{display:inline-flex;align-items:center;gap:10px;min-height:44px;padding:0 22px;border:0;
  border-radius:var(--r-pill);background:#25D366; /* tokens-allow: WhatsApp 品牌色 */
  color:var(--ink);font:inherit;font-weight:600;
  text-decoration:none;cursor:pointer;transition:filter .12s ease,transform .12s ease}
.wa-thanks:hover{filter:brightness(1.06)}
.wa-thanks:active{transform:translateY(1px)}
.wa-thanks svg{width:20px;height:20px;flex-shrink:0;fill:var(--ink)}
.wa-thanks .wa-badge{display:inline-flex;align-items:center;justify-content:center;min-width:20px;
  height:20px;padding:0 6px;border-radius:999px;background:var(--ink);color:var(--paper);
  font-size:11px;font-weight:700;line-height:1}
@media (max-width:600px){
  .wa-thanks-row{margin:var(--space-4) 0}
  .wa-thanks{width:100%;justify-content:center}
}
/* 购物车徽标已下线，保留 .prod-grid 即可 */
.prod-grid{display:grid;gap:10px;grid-template-columns:repeat(auto-fill,minmax(210px,1fr));margin:14px 0 6px}
.prod{display:flex;gap:10px;align-items:flex-start;border:1px solid var(--line);border-radius:10px;padding:11px 12px;
  background:var(--paper);cursor:pointer;transition:border-color .12s,background .12s}
/* 品类页商品区（catshop）：左侧商品网格 + 右侧吸顶询价侧边栏 */
.catshop{margin:var(--space-6) 0 var(--space-7)}
.catshop h2{margin-bottom:var(--space-1)}
.catshop-cols{display:grid;grid-template-columns:minmax(0,1fr) 300px;gap:var(--space-5);
  align-items:start;margin-top:var(--space-4)}
.prod-grid{display:grid;gap:var(--space-3);grid-template-columns:repeat(auto-fill,minmax(190px,1fr));margin:0}
.prod{display:flex;flex-direction:column;border:1px solid var(--line);border-radius:var(--r-surface);
  background:var(--paper);overflow:hidden;transition:border-color var(--dur) var(--ease-out)}
.prod:hover{border-color:var(--muted)}
.prod:has(input:checked){border-color:var(--accent);box-shadow:inset 0 0 0 1px var(--accent)}
.prod-img{display:block;height:110px;overflow:hidden;background:var(--surface)}
.prod-img img{width:100%;height:110px;object-fit:cover;display:block}
.prod-ph{display:flex;align-items:center;justify-content:center;height:110px;
  font-family:var(--mono);font-size:24px;font-weight:600;color:var(--muted);background:var(--surface)} /* tokens-allow */
/* CC BY 图的集中署名（商品卡放不下，Wikimedia 认可页面底部统一署名） */
.prod-credits{margin-top:var(--space-3);font-size:11.5px;line-height:1.6;color:var(--muted);max-width:60ch}
.prod-credits a{color:var(--muted);text-decoration:underline}
.prod-credits a:hover{color:var(--ink)}
/* Other 卡：虚线边 + 大加号，视觉上明确是「还有别的」而不是一个具体商品 */
.prod-other{border-style:dashed}
.prod-ph-other{font-size:32px;color:var(--accent);background:var(--accent-soft)}
.prod-other .prod-body em{color:var(--accent)}
.prod-body{display:block;padding:9px 11px 4px;flex:1}
.prod-body b{display:block;font-size:14px;line-height:1.3;font-weight:650}
.prod-body span{display:block;font-size:12px;color:var(--muted);margin-top:2px}
.prod-body em{display:block;font-style:normal;font-size:11.5px;color:var(--muted);margin-top:4px}
.prod-foot{display:block;padding:9px 11px 11px;border-top:1px solid var(--line);margin-top:auto;min-height:52px}
/* 加入购物车：底层原生 checkbox（无 JS 也能勾选提交），有 JS 时外观换成按钮 */
.add-btn{display:block;position:relative;margin:0}
.prod:has(input:checked) .add-btn{display:none}
.add-btn input[type=checkbox]{position:absolute;inset:0;width:100%;height:100%;margin:0;opacity:0;cursor:pointer;z-index:1}
.add-btn .add-on{display:block;padding:0 10px;height:32px;line-height:30px;border:1px solid var(--accent);
  border-radius:var(--r-pill);text-align:center;font-size:13px;font-weight:600;
  color:var(--accent);background:var(--paper);transition:background var(--dur) var(--ease-out)}
.add-btn:hover .add-on{background:var(--accent-soft)}
.add-btn input:focus-visible~.add-on{outline:2px solid var(--accent);outline-offset:2px}
/* 数量步进器：− [100] +（与 Add to cart 同高同位，勾选时原位替换） */
.qty-stepper{display:none;align-items:center;height:32px;border:1px solid var(--line);
  border-radius:var(--r-pill);overflow:hidden;background:var(--surface)}
.prod:has(input:checked) .qty-stepper{display:flex}
/* ± 靠 JS 驱动：默认隐藏，无 JS 时留原生数字箭头做增减 */
.qty-btn{display:none;flex:0 0 28px;height:30px;padding:0;border:0;background:var(--surface);color:var(--ink);
  font-size:15px;line-height:1;cursor:pointer;transition:background var(--dur) var(--ease-out)}
.catshop-js .qty-btn{display:block}
.qty-btn:hover{background:var(--accent-soft);color:var(--accent)}
.qty-btn:active{transform:scale(.94)}
.qty-stepper input{flex:1;min-width:0;width:100%;height:30px;padding:0;border:0;background:transparent;
  text-align:center;font:inherit;font-size:13px;font-weight:600;color:var(--ink)}
.catshop-js .qty-stepper input{-moz-appearance:textfield;appearance:textfield}
.catshop-js .qty-stepper input::-webkit-outer-spin-button,
.catshop-js .qty-stepper input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}
.qty-stepper input:focus{outline:none}
.qty-stepper:focus-within{border-color:var(--accent);box-shadow:0 0 0 2px var(--accent-soft)}
/* 侧边栏：吸顶，内容多时自身滚动 */
/* 侧栏 = 弹性列：清单区内部滚动（min-height:0 是关键），表单区 flex-shrink:0 钉底永可见 */
.cat-inquiry{position:sticky;top:var(--space-4);display:flex;flex-direction:column;gap:var(--space-4);
  border:1px solid var(--line);border-radius:var(--r-surface);background:var(--surface);
  padding:var(--space-4);max-height:calc(100vh - var(--space-6));overflow-y:auto}
.cat-inquiry h3{margin:0 0 var(--space-1);font-size:var(--text-h3);font-weight:var(--fw-h3)}
.cat-inquiry .fld{margin:10px 0 0}
.cat-inquiry .fld label{display:block;font-size:12px;color:var(--muted);
  text-transform:uppercase;letter-spacing:.07em;margin:0 0 4px}
.cat-inquiry input,.cat-inquiry textarea{width:100%;padding:9px 10px;border:1px solid var(--line);
  border-radius:var(--r-surface);font:inherit;font-size:14px;background:var(--paper);color:var(--ink)}
.cat-inquiry input:focus,.cat-inquiry textarea:focus{border-color:var(--accent);outline:none}
.cat-inquiry button[type=submit]{width:100%;margin-top:14px;padding:11px 18px;border:0;border-radius:var(--r-pill);
  background:var(--accent);color:var(--on-accent);font:inherit;font-weight:600;cursor:pointer;
  transition:transform .12s ease,filter .12s ease}
.cat-inquiry button[type=submit]:hover{filter:brightness(1.06)}
.cat-inquiry button[type=submit]:active{transform:translateY(1px)}
.cat-inquiry button[type=submit]:disabled{opacity:.45;cursor:not-allowed;filter:none}
/* 清单设硬上限：10 个商品也不会把表单顶出视口（超出部分在清单内滚动） */
.cat-selected{flex:0 1 auto;min-height:0;max-height:240px;overflow-y:scroll;
  padding-bottom:var(--space-3);border-bottom:1px solid var(--line);
  scrollbar-width:thin;scrollbar-color:var(--muted) var(--surface)}
/* 常显细滚动条：overflow-y:scroll 始终预留滚动槽；自定义 webkit 滚动条会让
   macOS 从浮显样式切成常驻经典样式（系统默认 overlay 滚动时才出现，会让人以为清单被截断）。 */
.cat-selected::-webkit-scrollbar{width:8px;-webkit-appearance:none}
.cat-selected::-webkit-scrollbar-track{background:var(--surface)}
.cat-selected::-webkit-scrollbar-thumb{background:var(--line);border-radius:var(--r-pill);
  border:2px solid var(--surface)}
.cat-selected::-webkit-scrollbar-thumb:hover{background:var(--muted)}
.cat-inquiry-main{flex:0 0 auto}
.cat-selected b{display:block;font-size:12px;color:var(--muted);text-transform:uppercase;
  letter-spacing:.07em;margin-bottom:4px}
.cat-selected ul{list-style:none;margin:8px 0 0;padding:0;display:grid;gap:7px}
.cat-selected li{display:grid;grid-template-columns:1fr auto;gap:1px 8px;
  font-size:12.5px;line-height:1.35;animation:catRow .18s var(--ease-out)}
.cat-selected li .nm{grid-column:1/-1;font-weight:600}
.cat-selected li .n{font-family:var(--mono);color:var(--accent);font-weight:600}
.cat-selected li .rm{background:none;border:0;padding:0;color:var(--muted);cursor:pointer;
  font-size:11.5px;line-height:1.35;text-decoration:underline}
.cat-selected li .rm:hover{color:var(--accent)}
/* li 内数量：桌面显示「300 units」文本；移动抽屉换成 −/+ 步进器 */
.cat-selected li .li-step{display:none}
.cat-selected li .li-step-btn{background:none;border:1px solid var(--line);border-radius:var(--r-pill);
  width:32px;height:32px;font-size:17px;line-height:1;color:var(--ink);cursor:pointer}
.cat-selected li .li-step-btn:active{background:var(--accent-soft);border-color:var(--accent);color:var(--accent)}
.cat-selected li .li-step-n{min-width:52px;text-align:center;font-family:var(--mono);font-weight:600;color:var(--ink)}
@keyframes catRow{from{opacity:0;transform:translateY(-3px)}to{opacity:1;transform:none}}
@media (prefers-reduced-motion:reduce){.cat-selected li{animation:none}}
/* ===== 移动端：右侧栏变全屏底部抽屉 + 吸底结算条（桌面端这两个元素不渲染可见） ===== */
.cat-drawer-close{display:none}
.cat-bar{display:none}
@media (max-width:900px){
  .catshop-cols{grid-template-columns:1fr}
  /* 基础复位（有无 JS 都生效）：侧栏不再吸顶/限高；有 JS 时下面的 .catshop-js 抽屉规则再覆盖成 fixed */
  .cat-inquiry{position:static;max-height:none}
  /* 品类页自带吸底结算条 → 隐藏全局「Post your requirement」底栏，避免两条红条叠在一起 */
  body:has(.catshop) .reqcta{display:none}
  /* 吸底结算条：仅 JS 可用时显示（无 JS 时退化为页面下方普通表单） */
  .cat-bar{display:none;position:fixed;left:0;right:0;bottom:0;z-index:50;
    background:var(--paper);border-top:1px solid var(--line);padding:10px 12px;
    padding-bottom:calc(10px + env(safe-area-inset-bottom,0px));
    box-shadow:0 -4px 18px rgb(15 18 22 / .08)} /* tokens-allow: ink 色 8% 轻投影，无对应阴影 token */
  .catshop-js .cat-bar{display:block}
  .cat-bar-btn{display:flex;width:100%;align-items:center;justify-content:space-between;gap:12px;
    min-height:48px;padding:0 20px;border:0;border-radius:var(--r-pill);
    background:var(--accent);color:var(--on-accent);font:inherit;font-size:15px;font-weight:600;cursor:pointer}
  .cat-bar-btn:active{transform:translateY(1px)}
  .cat-bar-btn:disabled{opacity:.5;cursor:not-allowed}
  /* 给页面底部让出吸底条高度，避免最后一张商品卡被永久遮挡 */
  body:has(.catshop) main{padding-bottom:84px}
  .cat-bar-count{display:inline-flex;align-items:center;gap:6px}
  .cat-bar-count b{font-family:var(--mono);font-variant-numeric:tabular-nums}
  /* 无 JS：aside 是商品列表下方的普通块（位置由单列流式布局决定），吸底条 hidden 不显示。
     有 JS（html.catshop-js）：aside 升级为全屏底部抽屉，默认藏在视口下方，.catshop-drawer-open 滑入。 */
  .catshop-js .cat-inquiry{position:fixed;inset:0;z-index:60;margin:0;max-height:92vh;
    border:0;border-radius:0;padding:calc(var(--space-5) + env(safe-area-inset-top,0px)) var(--space-5)
      calc(var(--space-5) + env(safe-area-inset-bottom,0px));
    transform:translateY(100%);transition:transform .28s var(--ease-out);
    overflow-y:scroll;-webkit-overflow-scrolling:touch;
    scrollbar-width:thin;scrollbar-color:var(--muted) transparent}
  body.catshop-drawer-open .cat-inquiry{transform:translateY(0)}
  body.catshop-drawer-open{overflow:hidden}
  .catshop-js .cat-drawer-close{display:flex;position:absolute;top:calc(var(--space-2) + env(safe-area-inset-top,0px));
    inset-inline-end:var(--space-3);align-items:center;justify-content:center;
    min-width:44px;min-height:44px;border:0;background:none;color:var(--muted);
    font-size:26px;line-height:1;cursor:pointer;z-index:2}
  .cat-drawer-close:hover{color:var(--ink)}
  /* 抽屉内清单不再限高（整屏抽屉自身滚动） */
  .cat-selected{flex:none;max-height:none;overflow:visible}
  .cat-selected::-webkit-scrollbar{display:none}
  .catshop-js .cat-inquiry::-webkit-scrollbar{width:8px;-webkit-appearance:none}
  .catshop-js .cat-inquiry::-webkit-scrollbar-track{background:transparent}
  .catshop-js .cat-inquiry::-webkit-scrollbar-thumb{background:var(--line);border-radius:var(--r-pill);
    border:2px solid var(--surface)}
  .catshop-js .cat-inquiry::-webkit-scrollbar-thumb:hover{background:var(--muted)}
  /* 触控目标全部 ≥44px */
  .add-btn .add-on{height:44px;line-height:42px;font-size:14px}
  .qty-stepper{height:44px}
  .qty-stepper input{height:42px;font-size:16px} /* ≥16px 防 iOS 聚焦自动放大 */
  /* 两列窄卡（约 170px）：± 按钮收窄到 36px（高仍 44 满足触控），给数量数字留足宽 */
  .qty-btn{flex:0 0 36px;height:42px;font-size:20px}
  .cat-inquiry input,.cat-inquiry textarea{font-size:16px;padding:11px 12px}
  .cat-inquiry button[type=submit]{min-height:50px;width:100%}
  .cat-selected li{font-size:14px}
  .cat-selected li .rm{min-height:32px;font-size:13px}
  .cat-selected li{display:grid;grid-template-columns:1fr auto;gap:6px;align-items:center;
    padding:6px 0;border-bottom:1px solid var(--line)}
  .cat-selected li .nm{grid-column:1/-1}
  .cat-selected li .n{display:none}
  .cat-selected li .li-step{display:inline-flex;align-items:center;gap:10px}
  .cat-selected li .li-step-none{display:none}
  .cat-selected li .li-step-btn{width:36px;height:36px;font-size:18px}
  .cat-selected li .li-step-n{font-size:14px;min-width:48px}
  .cat-selected li .rm{min-height:44px;display:inline-flex;align-items:center;font-size:13px}
}
@media (prefers-reduced-motion:reduce){
  .cat-inquiry{transition:none}
}
/* 手机：商品网格一行 2 个（竖版卡片，图在上/信息居中/底部整行操作），与桌面同构仅收窄 */
@media (max-width:600px){
  .catshop-cols{gap:0}
  .prod-grid{grid-template-columns:repeat(2,minmax(0,1fr));gap:10px}
  .prod-img{height:104px}
  .prod-img img{height:104px}
  .prod-ph{height:104px;font-size:22px}
  .prod-body{padding:8px 10px 4px}
  .prod-body b{font-size:13.5px}
  .prod-foot{padding:8px 10px 10px}
}
}
}
