/* 前台企业官网样式（响应式：PC / 平板 / 手机）。调色板走 :root 变量，见下 */

/* 主题变量（全站外观的唯一旋钮）。这里的默认值与 includes/theme.php 的 token 表逐字相同：
   两边不一致会让「默认主题」下 theme.php 与 style.css 各说一套。站点根的 theme.php 在本表之后
   加载，只覆写与默认值不同的那几条，所以主题整档 404 时前台仍是下面这套出厂样式。
   覆盖面：颜色（含正文近黑、卡片描边、引用/代码底）、渐变、投影、圆角与描边粗细、字体族、
   字号阶梯、行高、间距节奏、以及导航/按钮/卡片的内距与悬停位移。判定某颗该不该收进来的标准是
   「换一套主题会不会想动它」——余下的字面值（2em 之类的一次性尺寸、成功失败条的语义色）都不在该列。 */
:root {
  --cms-brand: #1f6ae0;
  --cms-brand-strong: #1755b5;
  --cms-brand-deep: #0e3f86;
  --cms-brand-bright: #1f7ae0;
  --cms-brand-soft: #eef3fb;
  --cms-brand-tint: #eef4ff;
  --cms-accent: #e0454f;
  --cms-text: #1c2333;
  --cms-heading: #22314f;
  --cms-text-body: #45506a;
  --cms-text-muted: #66708a;
  --cms-text-faint: #8a93a6;
  --cms-text-ghost: #97a2b8;
  --cms-text-strong: #333d55;
  --cms-text-deep: #2c3550;
  --cms-text-muted-alt: #56617d;
  --cms-heading-deep: #1c2740;
  --cms-text-placeholder: #b8c3d6;
  --cms-line: #dfe5ef;
  --cms-line-strong: #cfd7e4;
  --cms-line-soft: #e9edf5;
  --cms-line-faint: #eef1f7;
  --cms-line-card: #e6ebf5;
  --cms-line-input: #dbe2ee;
  --cms-surface: #fff;
  --cms-surface-alt: #f6f8fc;
  --cms-surface-dim: #f2f5fa;
  --cms-inset: #eef2f8;
  --cms-surface-table: #fafbfe;
  --cms-blockquote-bg: #f5f8ff;
  --cms-code-bg: #f5f7fb;
  --cms-header-bg: #fff;
  --cms-hero-fg: #fff;
  /* 压在品牌色上的文字（按钮、选中页码、当前分类、弹窗主按钮、徽标）。单列一颗是因为主色可被
     「主色微调」换成任意十六进制：换成亮黄一类的浅色时，白字只剩 1.x:1，派生器会把它翻成同色相深档 */
  --cms-on-brand: #fff;
  --cms-footer-bg: #10254d;
  --cms-footer-fg: #b9c6e4;
  --cms-footer-title: #fff;
  --cms-footer-line: rgba(255,255,255,.08);
  /* 两档渐变的默认值里写的是 var() 而不是色值字面量：覆写主色族时首屏与徽标自动跟上，
     也让「出厂六位色只出现在 :root 一处」那条断言继续成立 */
  --cms-hero-bg: linear-gradient(135deg, var(--cms-brand-deep), var(--cms-brand-bright));
  --cms-mark-bg: linear-gradient(135deg, var(--cms-brand-deep), var(--cms-brand-bright));
  /* 投影默认值用八位十六进制而不是 rgba()：主题侧的阴影闸门吃不进含逗号的函数式颜色，
     与旧的 rgba(20,40,80,.08) 相比透明度最多差 1/255（.08 → 0x14 = .078） */
  --cms-shadow-header: 0px 1px 8px #14285014;
  --cms-shadow-card: 0px 12px 30px #1428501f;
  --cms-shadow-pop: 0px 12px 24px #1428501f;
  --cms-shadow-modal: 0px 24px 60px #10254d38;
  --cms-radius: 10px;
  --cms-radius-xs: calc(var(--cms-radius) / 2);
  --cms-radius-sm: calc(var(--cms-radius) - 2px);
  --cms-radius-lg: calc(var(--cms-radius) + 2px);
  --cms-radius-xl: calc(var(--cms-radius) + 4px);
  --cms-border-width: 1px;
  --cms-header-h: 68px;
  --cms-container: 1160px;
  --cms-gutter: 20px;
  --cms-font: "Microsoft YaHei", system-ui, -apple-system, sans-serif;
  /* 与 --cms-font 逐字相同是硬要求：闸门吃不进 var()，标题只能拿一份字面量默认值 */
  --cms-heading-font: "Microsoft YaHei", system-ui, -apple-system, sans-serif;
  --cms-fs-body: 15px;
  --cms-fs-hero: 30px;
  --cms-fs-section: 26px;
  --cms-fs-title: 18px;
  --cms-fs-item: 17px;
  --cms-fs-meta: 14px;
  --cms-fs-small: 13px;
  --cms-fs-tiny: 12px;
  --cms-lh-body: 1.7;
  --cms-lh-loose: 1.9;
  --cms-space-hero: 90px;
  --cms-space-section: 60px;
  --cms-space-sec-head: 28px;
  --cms-space-grid: 22px;
  --cms-space-card: 18px;
  --cms-space-row: 22px;
  --cms-space-list-row: 14px;
  --cms-space-page-top: 44px;
  --cms-space-page-bottom: 64px;
  --cms-space-footer-top: 40px;
  --cms-space-footer-block: 48px;
  --cms-nav-gap: 26px;
  --cms-nav-pad-y: 8px;
  --cms-nav-pad-x: 16px;
  --cms-btn-pad-y: 11px;
  --cms-btn-pad-x: 30px;
  /* 页面里「按钮」组件的圆角。不是 --cms-radius-sm（那档派生自卡片圆角、出厂算下来 8px）：
     渲染器过去写死 6px，收进变量前换主题会出现「卡片变方、正文按钮还是圆的」。
     本表里没人 var() 它，引用点在 includes/render.php 的 cms_node_button()（随页面输出的组件规则） */
  --cms-btn-radius: 6px;
  --cms-card-lift: 4px;
}
* { box-sizing: border-box; margin: 0; padding: 0; }
body { font-family: var(--cms-font); color: var(--cms-text); font-size: var(--cms-fs-body); line-height: var(--cms-lh-body); background: var(--cms-surface); }
/* 标题字族单独立档：默认值与 --cms-font 逐字相同，所以出厂零差异；只有主题显式换了字族，标题才会跟着走 */
h1, h2, h3, h4, h5, h6 { font-family: var(--cms-heading-font); }
a { color: inherit; text-decoration: none; }
img { max-width: 100%; display: block; }
.container { max-width: var(--cms-container); margin: 0 auto; padding: 0 var(--cms-gutter); }
main { min-height: 60vh; }

/* ---------- 页头 ---------- */
.site-header { position: sticky; top: 0; z-index: 50; background: var(--cms-header-bg); box-shadow: var(--cms-shadow-header); }
.nav-wrap { display: flex; align-items: center; height: var(--cms-header-h); gap: var(--cms-nav-gap); }
.brand { display: flex; align-items: center; gap: 10px; }
.brand-mark { display: grid; place-items: center; width: 40px; height: 40px; border-radius: var(--cms-radius); background: var(--cms-mark-bg); color: var(--cms-on-brand); font-size: 20px; font-weight: 800; }
/* 站点 LOGO（需求 E1）：与 .brand-mark 同占位（40px 高），按原始比例宽自适应，不把标志拉变形 */
.brand-logo { display: block; height: 40px; width: auto; max-width: 180px; object-fit: contain; }
.brand-name { font-size: var(--cms-fs-title); font-weight: 700; line-height: 1.2; }
.brand-name em { display: block; font-size: 11px; color: var(--cms-text-faint); font-style: normal; font-weight: 400; }
/* 页头导航树（includes/header.php 渲染「导航菜单」那一棵树，需求 D5）：
   一级横向排，下级面板绝对定位；current=当前项，trail=当前项的各级父链 */
.site-nav { margin-left: auto; }
.nav-root { display: flex; align-items: center; gap: 6px; list-style: none; }
.nav-item { position: relative; }
.nav-link { display: block; padding: var(--cms-nav-pad-y) var(--cms-nav-pad-x); border-radius: var(--cms-radius-sm); color: var(--cms-text-body); white-space: nowrap; }
.nav-link:hover { color: var(--cms-brand); background: var(--cms-brand-soft); }
.nav-item.current > .nav-link { color: var(--cms-brand); background: var(--cms-brand-soft); font-weight: 700; }
.nav-item.trail > .nav-link { color: var(--cms-brand); }
.nav-sub, .nav-sub-toggle { display: none; }
/* 下级只在有指针悬停能力的设备上用 hover / focus-within（键盘 Tab 走 focus-within）露出 */
@media (hover: hover) {
  .nav-item:hover > .nav-sub, .nav-item:focus-within > .nav-sub {
    display: block; position: absolute; top: calc(100% + 6px); left: 0; z-index: 40;
    min-width: 172px; padding: 6px; list-style: none; background: var(--cms-surface);
    border: var(--cms-border-width) solid var(--cms-line-card); border-radius: var(--cms-radius); box-shadow: var(--cms-shadow-pop);
  }
  /* 第三级往右飞：往下飞会掉出第二级面板的下边界，鼠标一移就收起 */
  .nav-sub .nav-sub { top: -7px; left: calc(100% + 4px); }
}
/* 触屏与窄屏没有可靠的 hover，改成点 ▾ 展开；没有 JS 时下级不显示，一级导航照常可用 */
@media (hover: none), (max-width: 720px) {
  .nav-item > .nav-sub-toggle {
    display: inline-block; position: absolute; top: 8px; right: 2px; padding: 6px 10px;
    border: var(--cms-border-width) solid var(--cms-line-strong); border-radius: var(--cms-radius-sm); background: var(--cms-surface); color: var(--cms-text-body); font-size: var(--cms-fs-tiny); cursor: pointer;
  }
  .nav-item.open > .nav-sub { display: block; padding: 4px 0 4px 14px; list-style: none; }
}
.nav-tel { display: flex; align-items: center; gap: 6px; color: var(--cms-brand); font-weight: 700; white-space: nowrap; }
.nav-toggle { display: none; margin-left: 8px; border: var(--cms-border-width) solid var(--cms-line-strong); background: var(--cms-surface); border-radius: var(--cms-radius-sm); padding: 6px; cursor: pointer; color: var(--cms-text-body); }

/* ---------- 首页 Hero ---------- */
/* 只有静态那一块（站名 + 标语 + CTA）：首页轮播原先靠 .slides/.slide/.hero-dots + main.js 的
   #heroSlides 定时器，随 banners 退役一起删了，图片轮播请用装修器的 carousel 组件（.cms-carousel*） */
.hero { padding: var(--cms-space-hero) 0; color: var(--cms-hero-fg); text-align: center; background: var(--cms-hero-bg); }
/* 30px 正是 UA 给 h1 的 2em（继承 15px 正文）——收进变量后出厂档计算值不变 */
.hero h1 { font-size: var(--cms-fs-hero); }
.hero p { opacity: .85; margin: 10px 0 26px; }

/* ---------- 区块 ---------- */
.section { padding: var(--cms-space-section) 0; }
.section-alt { background: var(--cms-surface-alt); }
.sec-head { display: flex; align-items: baseline; justify-content: space-between; margin-bottom: var(--cms-space-sec-head); }
.sec-head h2 { font-size: var(--cms-fs-section); }
.sec-head a { color: var(--cms-brand); font-size: var(--cms-fs-meta); }
.empty { color: var(--cms-text-faint); padding: 30px 0; text-align: center; }

/* 卡片栅格 */
.grid { display: grid; gap: var(--cms-space-grid); }
.grid-4 { grid-template-columns: repeat(4, 1fr); }
.grid-3 { grid-template-columns: repeat(3, 1fr); }
.card { background: var(--cms-surface); border: var(--cms-border-width) solid var(--cms-line-soft); border-radius: var(--cms-radius-lg); overflow: hidden; transition: .25s; display: flex; flex-direction: column; }
.card:hover { transform: translateY(calc(-1 * var(--cms-card-lift))); box-shadow: var(--cms-shadow-card); }
.card-img { aspect-ratio: 8 / 5; background: var(--cms-inset); overflow: hidden; }
.card-img img { width: 100%; height: 100%; object-fit: cover; }
.card-body { padding: var(--cms-space-card); display: flex; flex-direction: column; gap: 8px; flex: 1; }
.card-body h3 { font-size: var(--cms-fs-item); }
.card-body p { color: var(--cms-text-muted); font-size: var(--cms-fs-small); flex: 1; }
.tag { display: inline-block; align-self: flex-start; font-size: var(--cms-fs-tiny); color: var(--cms-brand); background: var(--cms-brand-soft); border-radius: var(--cms-radius-xs); padding: 2px 8px; }
.price { color: var(--cms-accent); font-weight: 700; }
.price.big { font-size: 24px; margin: 14px 0; }

/* 新闻列表 */
.news-list { display: flex; flex-direction: column; }
.news-item { display: flex; gap: var(--cms-gutter); padding: var(--cms-space-row) 4px; border-bottom: var(--cms-border-width) solid var(--cms-line-soft); align-items: center; }
.news-item:hover h3 { color: var(--cms-brand); }
.news-date { flex-shrink: 0; width: 74px; text-align: center; color: var(--cms-text-faint); background: var(--cms-surface-alt); border-radius: var(--cms-radius); padding: 10px 0; }
.news-date span { display: block; font-size: var(--cms-fs-section); font-weight: 800; color: var(--cms-brand); line-height: 1.1; }
.news-date em { font-style: normal; font-size: var(--cms-fs-tiny); }
.news-main { min-width: 0; }
.news-main h3 { font-size: var(--cms-fs-item); margin-bottom: 4px; }
.news-main p { color: var(--cms-text-muted); font-size: var(--cms-fs-small); }
.news-main .meta { color: var(--cms-text-faint); font-size: var(--cms-fs-tiny); margin-top: 6px; }
.news-thumb { flex-shrink: 0; width: 160px; aspect-ratio: 8/5; border-radius: var(--cms-radius); overflow: hidden; }
.news-thumb img { width: 100%; height: 100%; object-fit: cover; }

.about-brief h2 { font-size: var(--cms-fs-section); margin-bottom: 16px; }
.about-brief p { color: var(--cms-text-muted); max-width: 760px; }
.btn-line { display: inline-block; margin-top: 14px; color: var(--cms-brand); border: var(--cms-border-width) solid var(--cms-brand); padding: 8px 22px; border-radius: var(--cms-radius-sm); font-size: var(--cms-fs-meta); }
.btn-line:hover { background: var(--cms-brand); color: var(--cms-on-brand); }
.btn-main { display: inline-block; background: var(--cms-brand); color: var(--cms-on-brand); border: 0; padding: var(--cms-btn-pad-y) var(--cms-btn-pad-x); border-radius: var(--cms-radius-sm); font-size: var(--cms-fs-body); cursor: pointer; }
.btn-main:hover { background: var(--cms-brand-strong); }

/* ---------- 内页 ---------- */
.page-pad { padding: var(--cms-space-page-top) var(--cms-gutter) var(--cms-space-page-bottom); }
.page-head { font-size: var(--cms-fs-section); margin-bottom: 24px; }
.pager { display: flex; gap: 8px; justify-content: center; margin-top: 30px; }
.pager a { min-width: 36px; height: 36px; display: grid; place-items: center; border: var(--cms-border-width) solid var(--cms-line); border-radius: var(--cms-radius-sm); color: var(--cms-text-body); }
.pager a.on { background: var(--cms-brand); border-color: var(--cms-brand); color: var(--cms-on-brand); }
.cat-bar { display: flex; flex-wrap: wrap; gap: 10px; margin-bottom: 26px; }
.cat-bar a { padding: 6px 18px; border-radius: 20px; border: var(--cms-border-width) solid var(--cms-line); color: var(--cms-text-body); font-size: var(--cms-fs-meta); }
.cat-bar a.on { background: var(--cms-brand); border-color: var(--cms-brand); color: var(--cms-on-brand); }

.article h1 { font-size: var(--cms-fs-section); margin-bottom: 8px; }
.article-meta { color: var(--cms-text-faint); font-size: var(--cms-fs-small); margin-bottom: 24px; }
.article-cover { border-radius: var(--cms-radius-lg); margin-bottom: 24px; max-height: 420px; width: 100%; object-fit: cover; }
.article p { margin-bottom: 14px; color: var(--cms-text-strong); }
.back-line { margin-top: 30px; }
.back-line a { color: var(--cms-brand); }
/* 正文白名单标签的样式（includes/richtext.php 只会产出这些标签） */
.article-body p { margin: 0 0 14px; color: var(--cms-text-strong); line-height: var(--cms-lh-loose); }
.article-body h2, .article-body h3, .article-body h4 { margin: 26px 0 12px; color: var(--cms-heading-deep); }
.article-body ul, .article-body ol { margin: 0 0 16px; padding-left: 24px; color: var(--cms-text-strong); line-height: var(--cms-lh-loose); }
.article-body blockquote { margin: 0 0 16px; padding: 12px 18px; border-left: 4px solid var(--cms-brand); background: var(--cms-blockquote-bg); color: var(--cms-text-body); }
.article-body pre { margin: 0 0 16px; padding: 14px 16px; background: var(--cms-code-bg); border-radius: var(--cms-radius); overflow-x: auto; font-size: var(--cms-fs-small); line-height: var(--cms-lh-body); }
.article-body code { background: var(--cms-line-faint); padding: 1px 6px; border-radius: var(--cms-radius-xs); font-size: var(--cms-fs-small); }
.article-body pre code { background: none; padding: 0; }
.article-body img { max-width: 100%; border-radius: var(--cms-radius); margin: 0 0 16px; }
.article-body hr { border: none; border-top: var(--cms-border-width) solid var(--cms-line); margin: 24px 0; }
.article-body a { color: var(--cms-brand); }
.article-body mark { background: var(--cms-surface)2b8; padding: 0 3px; }
.contact-line { margin-top: 24px; color: var(--cms-text-muted); }

.product-detail .pd-top { display: grid; grid-template-columns: 1fr 1fr; gap: 34px; margin-bottom: 36px; align-items: start; }
.pd-cover { border-radius: var(--cms-radius-lg); width: 100%; object-fit: cover; }
.pd-info h1 { font-size: var(--cms-fs-section); margin: 10px 0; }
.pd-summary { color: var(--cms-text-muted); }
.pd-sub-title { font-size: 19px; border-left: 4px solid var(--cms-brand); padding-left: 12px; margin-bottom: 18px; }
/* 产品详情：图集（封面之外的那几张）、规格参数表、正文富文本容器（M5.4 / 需求 D2） */
.pd-gallery { display: grid; grid-template-columns: repeat(auto-fill, minmax(148px, 1fr)); gap: 12px; margin-bottom: 34px; }
.pd-gallery img { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; border-radius: var(--cms-radius); border: var(--cms-border-width) solid var(--cms-line-soft); }
.pd-specs { width: 100%; border-collapse: collapse; margin-bottom: 34px; }
.pd-specs th, .pd-specs td { text-align: left; padding: 10px 14px; border-bottom: var(--cms-border-width) solid var(--cms-inset); font-size: var(--cms-fs-meta); vertical-align: top; }
.pd-specs th { width: 30%; color: var(--cms-text-muted); font-weight: 500; background: var(--cms-surface-table); }
.pd-body { line-height: 1.85; color: var(--cms-text-deep); }
.card-img.card-noimg { display: flex; align-items: center; justify-content: center; font-size: 34px; color: var(--cms-text-placeholder); }

/* 联系页 */
.contact-grid { display: grid; grid-template-columns: 300px 1fr; gap: 40px; }
.contact-info p { margin-bottom: 12px; color: var(--cms-text-body); }
.contact form label { display: block; font-size: var(--cms-fs-small); color: var(--cms-text-body); margin: 12px 0 5px; }
.contact input, .contact textarea { width: 100%; padding: 10px 12px; border: var(--cms-border-width) solid var(--cms-line-strong); border-radius: var(--cms-radius-sm); font-size: var(--cms-fs-meta); font-family: inherit; }
.form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.form-ok { background: #e7f8ef; color: #187a44; border: var(--cms-border-width) solid #bfe9d2; border-radius: var(--cms-radius-sm); padding: 12px 16px; margin-bottom: 16px; }
.form-err { background: #fdecec; color: #a2262e; border: var(--cms-border-width) solid #f6c8cb; border-radius: var(--cms-radius-sm); padding: 12px 16px; margin-bottom: 16px; }
.contact .btn-main { margin-top: 18px; }

/* ---------- 页脚 ---------- */
.site-footer { background: var(--cms-footer-bg); color: var(--cms-footer-fg); margin-top: var(--cms-space-footer-top); }
.footer-grid { display: grid; grid-template-columns: 2fr 1fr 1.4fr; gap: 34px; padding: var(--cms-space-footer-block) var(--cms-gutter) 34px; }
.footer-brand { color: var(--cms-footer-title); font-size: 20px; font-weight: 700; margin-bottom: 10px; }
.footer-col h4 { color: var(--cms-footer-title); font-size: var(--cms-fs-body); margin-bottom: 12px; }
.footer-col a { display: block; color: var(--cms-footer-fg); line-height: 2; font-size: var(--cms-fs-meta); }
.footer-col p { font-size: var(--cms-fs-meta); line-height: 2; }
.footer-about p { font-size: var(--cms-fs-small); opacity: .8; }
.footer-bottom { border-top: var(--cms-border-width) solid var(--cms-footer-line); padding: 16px 0; font-size: var(--cms-fs-tiny); opacity: .6; text-align: center; }
/* 备案号：与版权同一行，中间空开一点；继承页脚深色，但留一条下划线表明它可点 */
.footer-icp { color: inherit; margin-left: 12px; text-decoration: underline; }

/* ---------- 拖拽页面组件（样式主体由渲染器内联输出，此处仅补基础排版） ---------- */
.cms-page { padding: 0 0 40px; }
/* 顶层容器只清纵向：margin 简写会连渲染器给的 margin-left/right:auto 一起抹掉
   （.cms-page > .cms-container 的特异性高于生成规则里的 [data-id="…"]），
   结果宽屏上盒子贴左、右侧空出一大片。横向留给基线样式自己做居中。 */
.cms-page > .cms-container { margin-top: 0; margin-bottom: 0; }
.cms-block { margin: 0; }
.cms-text p { margin: 0 0 12px; color: var(--cms-text-body); line-height: var(--cms-lh-loose); }
.cms-text p:last-child { margin-bottom: 0; }
.cms-image img { display: block; }
.cms-image-empty { display: grid; place-items: center; width: 100%; min-height: 160px; background: var(--cms-surface-dim); color: var(--cms-text-ghost); font-size: var(--cms-fs-small); border: var(--cms-border-width) dashed var(--cms-line); border-radius: var(--cms-radius-sm); }

/* 图片轮播：子组件即幻灯片。无 JS 时只显示第一张、控件隐藏（控件可见性挂在 .is-js 上，由 main.js 添加） */
.cms-carousel-track { display: grid; height: 100%; }
.cms-carousel-slide { grid-area: 1 / 1; opacity: 0; visibility: hidden; transition: opacity .5s ease; }
.cms-carousel-slide.is-on { opacity: 1; visibility: visible; }
.cms-carousel-slide > * { display: block; height: 100%; }
/* 填充方式由轮播根上的 --cms-slide-fit 继承下来（渲染器只在非默认档才写那条属性，
   所以从没设过的页面走的还是这里的 cover 回落值）。属性名全小写，渲染器的驼峰转换不会碰它 */
.cms-carousel-slide img { width: 100%; height: 100%; object-fit: var(--cms-slide-fit, cover); }
.cms-carousel-prev, .cms-carousel-next {
  position: absolute; top: 50%; transform: translateY(-50%); width: 38px; height: 56px;
  border: 0; border-radius: var(--cms-radius-sm); background: rgba(16, 37, 77, .42); color: #fff;
  font-size: 22px; line-height: 1; cursor: pointer;
}
.cms-carousel-prev { left: 14px; }
.cms-carousel-next { right: 14px; }
.cms-carousel-dots { position: absolute; left: 0; right: 0; bottom: 14px; display: flex; justify-content: center; gap: 8px; }
.cms-carousel-dot { width: 9px; height: 9px; padding: 0; border: 0; border-radius: 50%; background: rgba(255, 255, 255, .55); cursor: pointer; }
.cms-carousel-dot.is-on { background: var(--cms-surface); }
.cms-carousel:not(.is-js) .cms-carousel-prev,
.cms-carousel:not(.is-js) .cms-carousel-next,
.cms-carousel:not(.is-js) .cms-carousel-dots { display: none; }
.cms-block { width: 100%; }

/* ---------- M4.5 条目型组件 ---------- */
/* 图文卡片 */
.cms-card { background: var(--cms-surface); border: var(--cms-border-width) solid var(--cms-line-card); border-radius: var(--cms-radius-lg); }
.cms-card-media { display: block; }
.cms-card-media img { display: block; width: 100%; height: 100%; object-fit: cover; }
.cms-card-noimg { display: grid; place-items: center; min-height: 150px; background: var(--cms-surface-dim); border: var(--cms-border-width) dashed var(--cms-line); color: var(--cms-text-ghost); font-size: var(--cms-fs-small); }
.cms-card-body { padding: var(--cms-space-card) var(--cms-gutter) var(--cms-gutter); }
.cms-card-badge { display: inline-block; margin-bottom: 8px; padding: 3px 9px; border-radius: 999px; background: var(--cms-brand-tint); color: var(--cms-brand); font-size: var(--cms-fs-tiny); }
.cms-card-title { margin: 0 0 8px; font-size: var(--cms-fs-title); line-height: 1.45; color: var(--cms-heading); }
.cms-card-text p { margin: 0 0 10px; color: var(--cms-text-muted-alt); font-size: var(--cms-fs-meta); line-height: 1.85; }
.cms-card-text p:last-child { margin-bottom: 0; }
.cms-card-more { display: inline-block; margin-top: 12px; color: var(--cms-brand); font-size: var(--cms-fs-meta); font-weight: 500; text-decoration: none; }
.cms-card-more:hover { text-decoration: underline; }
.cms-card[data-layout="left"] { display: grid; grid-template-columns: 200px 1fr; gap: 4px; }
.cms-card[data-layout="left"] .cms-card-media { min-height: 100%; }
.cms-card[data-layout="left"] .cms-card-body { padding: var(--cms-space-card) var(--cms-gutter) var(--cms-space-card) 0; }

/* 列表 */
.cms-list { margin: 0; padding: 0; list-style: none; }
.cms-list-item { display: flex; gap: 14px; padding: var(--cms-space-list-row) 0; border-bottom: var(--cms-border-width) solid var(--cms-line-faint); }
.cms-list-item:last-child { border-bottom: 0; }
.cms-list-thumb { flex: 0 0 72px; width: 72px; height: 54px; border-radius: var(--cms-radius-sm); overflow: hidden; background: var(--cms-surface-dim); }
.cms-list-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.cms-list-main { display: block; flex: 1 1 auto; min-width: 0; }
.cms-list-title { display: block; color: var(--cms-heading); font-size: 16px; font-weight: 500; line-height: 1.6; text-decoration: none; }
a.cms-list-title:hover { color: var(--cms-brand); }
.cms-list-text { display: block; margin-top: 4px; color: var(--cms-text-muted); font-size: var(--cms-fs-meta); line-height: 1.8; }
.cms-list-meta { display: block; margin-top: 6px; color: var(--cms-text-ghost); font-size: var(--cms-fs-tiny); }

/* FAQ：用原生 <details>，展开收起不需要 JS，也没有内容丢失问题 */
.cms-faq-item { border: var(--cms-border-width) solid var(--cms-line-card); border-radius: var(--cms-radius); background: var(--cms-surface); margin-bottom: 10px; }
.cms-faq-item:last-child { margin-bottom: 0; }
.cms-faq-q { padding: var(--cms-space-list-row) 40px var(--cms-space-list-row) var(--cms-nav-pad-x); font-size: var(--cms-fs-body); font-weight: 500; color: var(--cms-heading); cursor: pointer; list-style: none; position: relative; }
.cms-faq-q::-webkit-details-marker { display: none; }
.cms-faq-q::after { content: '+'; position: absolute; right: 16px; top: 12px; font-size: var(--cms-fs-title); color: var(--cms-text-ghost); }
.cms-faq-item[open] .cms-faq-q::after { content: '−'; }
.cms-faq-item[open] .cms-faq-q { border-bottom: var(--cms-border-width) solid var(--cms-line-faint); }
.cms-faq-a { padding: 12px 16px 16px; }
.cms-faq-a p { margin: 0 0 10px; color: var(--cms-text-muted-alt); font-size: var(--cms-fs-meta); line-height: var(--cms-lh-loose); }
.cms-faq-a p:last-child { margin-bottom: 0; }

/* 标签页：服务端平铺输出全部内容，导航与切换样式都挂在 main.js 加的 .is-js 上 */
.cms-tabs:not(.is-js) .cms-tabs-nav { display: none; }
.cms-tabs-nav { display: flex; flex-wrap: wrap; gap: 4px; border-bottom: var(--cms-border-width) solid var(--cms-line-card); }
.cms-tab-btn { padding: 10px 16px; border: 0; border-bottom: 2px solid transparent; background: none; color: var(--cms-text-muted); font: inherit; font-size: var(--cms-fs-body); cursor: pointer; }
.cms-tab-btn.is-on { color: var(--cms-brand); border-bottom-color: var(--cms-brand); font-weight: 500; }
.cms-tab-panel { padding: 16px 2px; }
.cms-tabs.is-js .cms-tab-panel { display: none; }
.cms-tabs.is-js .cms-tab-panel.is-on { display: block; }
.cms-tab-panel p { margin: 0 0 10px; color: var(--cms-text-body); font-size: var(--cms-fs-meta); line-height: var(--cms-lh-loose); }
.cms-tab-panel p:last-child { margin-bottom: 0; }

/* 弹窗：<dialog> 默认带 open 属性、以行内形态显示内容；main.js 接管后摘掉 open 并切换成遮罩弹窗。
   position:static 是必需的——UA 给非模态 open dialog 定了 position:absolute，不覆盖就会脱离文档流压住后面的内容 */
.cms-modal-dialog { position: static; margin: 0; padding: 0; border: 0; background: none; color: inherit; max-width: none; width: auto; overflow: visible; }
.cms-modal-box h3:first-child { margin-top: 0; }
.cms-modal-open { padding: 10px 26px; border: 0; border-radius: var(--cms-radius-sm); background: var(--cms-brand); color: var(--cms-on-brand); font: inherit; font-size: var(--cms-fs-body); cursor: pointer; }
.cms-modal-open:hover { background: var(--cms-brand-strong); }
.cms-modal-title { margin: 0 0 12px; font-size: 19px; color: var(--cms-heading); }
.cms-modal-body p { margin: 0 0 10px; color: var(--cms-text-body); font-size: var(--cms-fs-meta); line-height: var(--cms-lh-loose); }
.cms-modal-body p:last-child { margin-bottom: 0; }
.cms-modal-close { margin-top: 16px; padding: 8px 18px; border: var(--cms-border-width) solid var(--cms-line-strong); border-radius: var(--cms-radius-sm); background: var(--cms-surface); color: var(--cms-text-body); font: inherit; font-size: var(--cms-fs-meta); cursor: pointer; }
/* .is-js 下 dialog 变成铺满视口的透明点击层（点空白即关闭），卡片样式落在 .cms-modal-box。
   display 必须再限定 [open]：作者规则会盖掉 UA 的 dialog:not([open]){display:none}，否则关掉后仍可见 */
.cms-modal.is-js .cms-modal-dialog[open] { position: fixed; inset: 0; display: flex; width: auto; max-width: none; height: auto; margin: 0; padding: 24px; overflow: auto; }
.cms-modal.is-js .cms-modal-box { width: min(560px, 100%); margin: auto; padding: 26px 28px; border: var(--cms-border-width) solid var(--cms-line); border-radius: var(--cms-radius-xl); background: var(--cms-surface); color: var(--cms-heading); box-shadow: var(--cms-shadow-modal); }
.cms-modal.is-js .cms-modal-dialog::backdrop { background: rgba(12, 26, 53, .55); }

/* 联系表单：字段由渲染器写死，样式只负责排布；成功/失败提示条出现在标题与表单之间 */
.cms-form { max-width: 640px; }
.cms-form-title { margin: 0 0 14px; font-size: 20px; color: var(--cms-heading); }
.cms-form-ok, .cms-form-err { margin: 0 0 14px; padding: 10px 14px; border-radius: var(--cms-radius-sm); font-size: var(--cms-fs-meta); line-height: var(--cms-lh-body); }
.cms-form-ok { border: var(--cms-border-width) solid #b7e3c8; background: #f0fbf4; color: #1c6b40; }
.cms-form-err { border: var(--cms-border-width) solid #f0c2c6; background: #fef4f5; color: #96323c; }
.cms-form-row { margin-bottom: 14px; }
.cms-form-label { display: block; margin-bottom: 6px; color: var(--cms-text-body); font-size: var(--cms-fs-meta); }
.cms-form-input { width: 100%; padding: 10px 12px; border: var(--cms-border-width) solid var(--cms-line-input); border-radius: var(--cms-radius-sm); background: var(--cms-surface); color: var(--cms-text); font: inherit; font-size: var(--cms-fs-body); }
.cms-form-input:focus { border-color: var(--cms-brand); outline: none; }
textarea.cms-form-input { resize: vertical; line-height: 1.8; }
.cms-form-submit { padding: var(--cms-btn-pad-y) var(--cms-btn-pad-x); border: 0; border-radius: var(--cms-radius-sm); background: var(--cms-brand); color: var(--cms-on-brand); font: inherit; font-size: var(--cms-fs-body); cursor: pointer; }
.cms-form-submit:hover { background: var(--cms-brand-strong); }
/* 蜜罐要「看不见但仍在文档里」：display:none 会让不少机器人直接跳过该字段，移出视口才留得住诱饵 */
.cms-form-hp { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }

/* 数据绑定组件（新闻资讯 / 产品展示）：条目由服务端取数，两种类型共用这一套排布。
   列数只有 data-cols 四个取值，样式表里写死四条，不为它生成行内 CSS 规则 */
.cms-feed-head { margin: 0 0 14px; font-size: 22px; line-height: 1.4; color: var(--cms-heading); }
.cms-feed { margin: 0; padding: 0; list-style: none; display: grid; grid-template-columns: minmax(0, 1fr); gap: 0 24px; }
.cms-feed[data-cols="2"] { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.cms-feed[data-cols="3"] { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.cms-feed[data-cols="4"] { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.cms-feed-item { display: flex; gap: 14px; padding: var(--cms-space-list-row) 0; border-bottom: var(--cms-border-width) solid var(--cms-line-faint); min-width: 0; }
.cms-feed-thumb { flex: 0 0 96px; width: 96px; height: 64px; border-radius: var(--cms-radius-sm); overflow: hidden; background: var(--cms-surface-dim); }
.cms-feed-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.cms-feed-main { display: block; flex: 1 1 auto; min-width: 0; }
.cms-feed-title { display: block; color: var(--cms-heading); font-size: 16px; font-weight: 500; line-height: 1.6; text-decoration: none; }
a.cms-feed-title:hover { color: var(--cms-brand); }
.cms-feed-text { display: block; margin-top: 4px; color: var(--cms-text-muted); font-size: var(--cms-fs-meta); line-height: 1.8; }
.cms-feed-meta { display: block; margin-top: 6px; color: var(--cms-text-ghost); font-size: var(--cms-fs-tiny); }
.cms-feed-empty { grid-column: 1 / -1; padding: 16px 0; color: var(--cms-text-ghost); font-size: var(--cms-fs-meta); }
.cms-feed-more { margin: 16px 0 0; font-size: var(--cms-fs-meta); }
.cms-feed-more a { color: var(--cms-brand); text-decoration: none; }
.cms-feed-more a:hover { text-decoration: underline; }

@media (max-width: 720px) {
  .cms-card[data-layout="left"] { grid-template-columns: 1fr; }
  .cms-card[data-layout="left"] .cms-card-body { padding: 4px 20px 20px; }
  /* 产品网格在窄屏一律两列：一列会把一屏压成一条滚动，三列则每张卡片窄到放不下标题 */
  .cms-feed[data-cols="3"], .cms-feed[data-cols="4"] { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .cms-feed-thumb { flex-basis: 72px; width: 72px; height: 54px; }
}

/* ---------- 主题版式：页头三档 + 页脚三档（需求 C-7「多套全站模板一键切换」） ---------- */
/* body 上的 data-header / data-footer 由 includes/header.php 写，取值口径见 includes/theme.php。
   这一节刻意放在「响应式」之前：窄屏那组规则用 !important 之外的方式覆盖版式是不够的（特异性相同、
   靠源码顺序决胜），所以「居中档的下拉面板定位」这类结构差异在下方各自再补一条窄屏规则。 */

/* 居中档：站名行 + 导航行两行排。此档下 .site-header 不再是 containing block（sticky 只在
   classic/topbar 档生效），绝对定位的下拉面板会以 viewport 为参照掉到页面顶部，所以整段
   下拉定位在本档重写一份。 */
body[data-header="center"] .nav-wrap { flex-direction: column; align-items: center; height: auto; padding: 18px 0 10px; gap: 12px; }
body[data-header="center"] .brand { margin: 0; }
body[data-header="center"] .site-nav { margin-left: 0; }
body[data-header="center"] .nav-tel { display: none; }
body[data-header="center"] .nav-item > .nav-sub { top: calc(100% + 6px); left: 50%; transform: translateX(-50%); }
body[data-header="center"] .nav-sub .nav-sub { top: -7px; left: calc(100% + 4px); transform: none; }

/* 顶栏档：导航独立细条排在第一行，站名与汉堡在第二行。sticky 从整页头转移到站名行——
   细条先滚走、站名行吸顶，是让第一行不必永远占位的最小改法（.nav-band 的父级即 .nav-wrap）。 */
body[data-header="topbar"] .site-header { position: static; }
body[data-header="topbar"] .nav-band { order: -1; width: 100%; margin-left: 0; padding: 5px 0; border-bottom: var(--cms-border-width) solid var(--cms-line-faint); }
body[data-header="topbar"] .nav-band .nav-root { justify-content: center; gap: 2px; }
body[data-header="topbar"] .nav-band .nav-link { padding: 4px 12px; font-size: var(--cms-fs-small); }
body[data-header="topbar"] .nav-wrap { position: sticky; top: 0; z-index: 50; flex-wrap: wrap; height: auto; padding-top: 10px; padding-bottom: 10px; row-gap: 4px; background: var(--cms-header-bg); box-shadow: var(--cms-shadow-header); }

/* 页脚两栏档：第三栏（联系方式）落到第二行，靠既有的 .footer-grid 换行自然完成 */
body[data-footer="cols2"] .footer-grid { grid-template-columns: 2fr 1fr; row-gap: 28px; }
/* 页脚单行档：PHP 侧只渲染站名那一列，这里只调排布与留白 */
body[data-footer="simple"] .footer-grid { display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px 18px; padding: 26px 20px 18px; }
body[data-footer="simple"] .footer-brand { margin-bottom: 0; }
body[data-footer="simple"] .footer-bottom { text-align: left; }

/* ---------- 主题槽位排版（增补-7 P2：换主题连正文里的排版一起换） ---------- */
/* 槽位的结构由 includes/render.php 的 cms_node_slot 输出，排版全在这里按 [data-slot][data-variant]
   分配。变体键与 includes/theme.php 的 cms_theme_slot_defs() 一一对应，主题切换只换 data-variant，
   槽位内的文字/图/链接逐字不动。配色一律走 var()，本节不出现任何裸十六进制（与主题令牌同源）。
   DOM 顺序恒为 media → body(copy→actions)；各档靠 order / display 重排，不靠改结构。 */
.cms-slot { padding: var(--cms-space-section) var(--cms-gutter); background: var(--cms-surface); color: var(--cms-text-body); }
.cms-slot-inner { max-width: var(--cms-container); margin: 0 auto; display: grid; grid-template-columns: 1fr; gap: 30px; align-items: center; }
.cms-slot-media img { width: 100%; height: auto; object-fit: cover; border-radius: var(--cms-radius-lg); box-shadow: var(--cms-shadow-card); }
.cms-slot-media:empty { display: none; }
.cms-slot-body { min-width: 0; }
.cms-slot-title { font-family: var(--cms-heading-font); color: var(--cms-heading); font-size: var(--cms-fs-section); line-height: 1.25; margin: 0 0 14px; }
.cms-slot-text p { margin: 0 0 12px; color: var(--cms-text-body); font-size: var(--cms-fs-body); line-height: var(--cms-lh-loose); }
.cms-slot-text p:last-child { margin-bottom: 0; }
.cms-slot-actions { margin-top: 22px; display: flex; flex-wrap: wrap; gap: 12px; }
.cms-slot-btn { display: inline-block; padding: var(--cms-btn-pad-y) var(--cms-btn-pad-x); border-radius: var(--cms-btn-radius); font-size: var(--cms-fs-body); text-decoration: none; border: var(--cms-border-width) solid transparent; cursor: pointer; line-height: 1.4; }
.cms-slot-btn-primary { background: var(--cms-brand); color: var(--cms-on-brand); }
.cms-slot-btn-primary:hover { background: var(--cms-brand-strong); }
.cms-slot-btn-ghost { background: transparent; color: var(--cms-brand); border-color: var(--cms-brand); }
.cms-slot-btn-ghost:hover { background: var(--cms-brand-soft); }

/* 首屏三档 */
.cms-slot[data-slot="hero"] { padding-top: var(--cms-space-hero); padding-bottom: var(--cms-space-hero); }
.cms-slot[data-variant="hero-split"] .cms-slot-inner { grid-template-columns: 1.05fr .95fr; }
.cms-slot[data-variant="hero-split"] .cms-slot-body { order: -1; } /* 文左图右 */
.cms-slot[data-variant="hero-split"] .cms-slot-title { font-size: var(--cms-fs-hero); }
.cms-slot[data-variant="hero-center"] { text-align: center; background: var(--cms-surface-alt); }
.cms-slot[data-variant="hero-center"] .cms-slot-media { display: none; }
.cms-slot[data-variant="hero-center"] .cms-slot-inner { max-width: 780px; }
.cms-slot[data-variant="hero-center"] .cms-slot-title { font-size: var(--cms-fs-hero); }
.cms-slot[data-variant="hero-center"] .cms-slot-actions { justify-content: center; }
.cms-slot[data-variant="hero-cover"] { position: relative; color: var(--cms-hero-fg); overflow: hidden; }
.cms-slot[data-variant="hero-cover"] .cms-slot-media { position: absolute; inset: 0; z-index: 0; }
.cms-slot[data-variant="hero-cover"] .cms-slot-media img { width: 100%; height: 100%; border-radius: 0; box-shadow: none; }
.cms-slot[data-variant="hero-cover"]::before { content: ""; position: absolute; inset: 0; z-index: 1; background: var(--cms-hero-bg); opacity: .82; }
.cms-slot[data-variant="hero-cover"] .cms-slot-inner { position: relative; z-index: 2; max-width: 820px; min-height: 320px; align-content: center; text-align: center; }
.cms-slot[data-variant="hero-cover"] .cms-slot-title { font-size: var(--cms-fs-hero); color: var(--cms-hero-fg); }
.cms-slot[data-variant="hero-cover"] .cms-slot-text p { color: var(--cms-hero-fg); }
.cms-slot[data-variant="hero-cover"] .cms-slot-actions { justify-content: center; }
.cms-slot[data-variant="hero-cover"] .cms-slot-btn-ghost { color: var(--cms-on-brand); border-color: var(--cms-on-brand); }
/* 实心钮与 cta-banner 同一档处理，理由逐字相同：首屏底就是 heroBg（一条品牌色渐变），
   而实心钮底是 --cms-brand —— 两者同色相，实测「智慧仓储」上按钮底 rgb(13,111,208)、
   紧邻首屏 rgb(56,129,204)，对比度 1.23:1（UI 元素下限是 3:1），按钮整个糊在底里。
   这里原先只写了描边钮那一半，是 cta-banner 那套处理的**漏写**，不是有意分档：
   主色越靠近首屏底色的主题越看不见，而首屏底本来就是主色派生的，所以恒有这个问题。
   翻成留白底 + 主色字（与 cta-banner 同一条规则），日后的 hero-cover 主题不必各修一遍。 */
.cms-slot[data-variant="hero-cover"] .cms-slot-btn-primary { background: var(--cms-surface); color: var(--cms-brand); }
.cms-slot[data-variant="hero-cover"] .cms-slot-btn-primary:hover { background: var(--cms-brand-soft); }

/* 图文带三档 */
.cms-slot[data-variant="band-left"] .cms-slot-inner { grid-template-columns: 1fr 1fr; } /* 图左（DOM 已 media 先） */
.cms-slot[data-variant="band-right"] .cms-slot-inner { grid-template-columns: 1fr 1fr; }
.cms-slot[data-variant="band-right"] .cms-slot-body { order: -1; } /* 文左图右 */
.cms-slot[data-variant="band-stack"] { text-align: center; background: var(--cms-surface-alt); }
.cms-slot[data-variant="band-stack"] .cms-slot-inner { max-width: 860px; }
.cms-slot[data-variant="band-stack"] .cms-slot-actions { justify-content: center; }

/* 行动号召三档 */
.cms-slot[data-variant="cta-banner"] { background: var(--cms-brand); color: var(--cms-on-brand); text-align: center; }
.cms-slot[data-variant="cta-banner"] .cms-slot-inner { max-width: 820px; }
.cms-slot[data-variant="cta-banner"] .cms-slot-media { display: none; }
.cms-slot[data-variant="cta-banner"] .cms-slot-title { color: var(--cms-on-brand); }
.cms-slot[data-variant="cta-banner"] .cms-slot-text p { color: var(--cms-on-brand); opacity: .92; }
.cms-slot[data-variant="cta-banner"] .cms-slot-actions { justify-content: center; }
/* 主色整幅底上，实心钮若还是主色会「色压色」看不见，翻成留白底；描边钮用反白 */
.cms-slot[data-variant="cta-banner"] .cms-slot-btn-primary { background: var(--cms-surface); color: var(--cms-brand); }
.cms-slot[data-variant="cta-banner"] .cms-slot-btn-primary:hover { background: var(--cms-brand-soft); }
.cms-slot[data-variant="cta-banner"] .cms-slot-btn-ghost { color: var(--cms-on-brand); border-color: var(--cms-on-brand); }
.cms-slot[data-variant="cta-banner"] .cms-slot-btn-ghost:hover { background: rgba(255,255,255,.14); }
.cms-slot[data-variant="cta-inline"] { background: var(--cms-surface-alt); }
.cms-slot[data-variant="cta-inline"] .cms-slot-media { display: none; }
.cms-slot[data-variant="cta-inline"] .cms-slot-body { display: flex; align-items: center; justify-content: space-between; gap: 22px; flex-wrap: wrap; }
.cms-slot[data-variant="cta-inline"] .cms-slot-copy { min-width: 0; }
.cms-slot[data-variant="cta-inline"] .cms-slot-actions { margin-top: 0; }
.cms-slot[data-variant="cta-card"] { background: var(--cms-surface-alt); }
.cms-slot[data-variant="cta-card"] .cms-slot-inner { max-width: 760px; text-align: center; padding: 42px 34px; background: var(--cms-surface); border: var(--cms-border-width) solid var(--cms-line-card); border-radius: var(--cms-radius-xl); box-shadow: var(--cms-shadow-card); }
.cms-slot[data-variant="cta-card"] .cms-slot-media { display: none; }
.cms-slot[data-variant="cta-card"] .cms-slot-actions { justify-content: center; }

/* 槽位窄屏一律竖排：两列档收成单列，图回到正文上方，内联档的按钮换到文字下面左对齐 */
@media (max-width: 720px) {
  .cms-slot .cms-slot-inner { grid-template-columns: 1fr; gap: 20px; }
  .cms-slot .cms-slot-inner > * { order: 0; }
  .cms-slot .cms-slot-media { order: -1; }
  .cms-slot[data-variant="cta-inline"] .cms-slot-body { flex-direction: column; align-items: flex-start; }
  .cms-slot[data-variant="cta-inline"] .cms-slot-actions { margin-top: 16px; }
  .cms-slot[data-variant="hero-cover"] .cms-slot-inner { min-height: 240px; }
}

/* ---------- 响应式 ---------- */
@media (max-width: 960px) {
  .grid-4 { grid-template-columns: repeat(2, 1fr); }
  .grid-3 { grid-template-columns: repeat(2, 1fr); }
  .footer-grid { grid-template-columns: 1fr 1fr; }
  .contact-grid { grid-template-columns: 1fr; }
  .product-detail .pd-top { grid-template-columns: 1fr; }
}
@media (max-width: 720px) {
  .nav-toggle { display: block; }
  .site-nav { display: none; position: absolute; top: var(--cms-header-h); left: 0; right: 0; background: var(--cms-header-bg); padding: 10px var(--cms-gutter) 18px; box-shadow: var(--cms-shadow-pop); }
  .site-nav.open { display: block; }
  /* 窄屏下拉面板改成竖排：一级竖着排，下级在它下面缩进一块（见上面 (hover: none) 那组规则） */
  .nav-root { flex-direction: column; align-items: stretch; gap: 2px; }
  .nav-link { padding: 10px 12px; }
  .nav-item > .nav-sub-toggle { top: 8px; }
  .nav-tel { display: none; }
  .grid-4, .grid-3 { grid-template-columns: 1fr; }
  .news-thumb { width: 110px; }
  .form-row { grid-template-columns: 1fr; }
  .footer-grid { grid-template-columns: 1fr; }
}

/* 窄屏下的版式补丁（放在最后一条：与上面那条同特异性，靠源码顺序覆盖 top: var(--cms-header-h)）
   —— 居中与顶栏两档的 .nav-wrap 高度是 auto，那条按页头高度算的偏移会留下空隙或压住内容。 */
@media (max-width: 720px) {
  body[data-header="center"] .nav-wrap { padding: 12px 0 8px; }
  body[data-header="center"] .site-nav { top: 100%; }
  /* 顶栏档在桌面把 sticky 挪到了站名行，窄屏汉堡面板要挂在整块页头上，所以这里补一层定位参照 */
  body[data-header="topbar"] .site-header { position: relative; }
  /* 窄屏下导航收进汉堡面板（.site-nav 绝对定位到页头下方），细条里就没内容了；
     整条 display:none 会连面板一起藏掉（面板 DOM 住在这条带子里），所以只压平它自带的留白与分隔线。 */
  body[data-header="topbar"] .nav-band { padding: 0; border-bottom: 0; }
  body[data-header="topbar"] .site-nav { top: 100%; }
}

/* ========== 装修优化第二批：七个新组件（2026-10-04） ==========
   全部走 :root 令牌，不写裸色值 —— 换主题时它们跟着换。
   命名与 render.php 的 cms_node_* 输出结构一一对应。 */

/* N1 分隔标题：装饰线三种形态靠 data-rule 分派，不额外加类 */
.cms-section-title { margin: var(--cms-space-section) 0; }
.cms-sect-title { font-family: var(--cms-heading-font); color: var(--cms-heading); margin: 0; line-height: var(--cms-lh-body); }
.cms-sect-sub { margin: 6px 0 0; color: var(--cms-text-muted); font-size: var(--cms-fs-meta); }
.cms-sect-rule { display: block; margin: 14px auto 0; width: 56px; height: 2px; background: var(--cms-brand); border-radius: 2px; }
.cms-section-title[data-rule="pill"] .cms-sect-rule { width: 28px; height: 4px; border-radius: 4px; background: var(--cms-brand-bright); }
.cms-section-title[data-rule="none"] .cms-sect-rule { display: none; }
.cms-section-title[style*="left"] .cms-sect-rule,
.cms-section-title[style*="right"] .cms-sect-rule { margin-left: 0; margin-right: 0; }

/* N2 统计数字：大号数值 + 单位 + 说明。单位用品牌色，形成层次 */
.cms-stat { padding: var(--cms-space-card) 0; }
.cms-stat-value { display: block; font-family: var(--cms-heading-font); font-size: var(--cms-fs-hero);
  font-weight: 800; line-height: 1.1; color: var(--cms-brand); letter-spacing: -.5px; }
.cms-stat-unit { font-size: var(--cms-fs-section); font-weight: 500; margin-left: 2px; color: var(--cms-brand-bright); }
.cms-stat-label { display: block; margin-top: 6px; font-size: var(--cms-fs-meta); color: var(--cms-text-muted); }

/* N3 特性图标：图标圆底 + 标题 + 说明 */
.cms-feature { text-align: inherit; }
.cms-feature-icon-wrap { display: inline-flex; align-items: center; justify-content: center;
  width: 52px; height: 52px; margin-bottom: 14px; border-radius: var(--cms-radius-lg);
  background: var(--cms-brand-soft); color: var(--cms-brand); }
.cms-feature-icon { width: 26px; height: 26px; }
.cms-feature-title { margin: 0; font-family: var(--cms-heading-font); font-size: var(--cms-fs-item);
  color: var(--cms-heading); line-height: var(--cms-lh-body); }
.cms-feature-text { margin-top: 6px; color: var(--cms-text-body); font-size: var(--cms-fs-body); }

/* N4 图片组：列数由内联的 --cms-gallery-cols 决定，手机一律 2 列 */
.cms-gallery { display: grid; grid-template-columns: repeat(var(--cms-gallery-cols, 3), minmax(0, 1fr)); gap: var(--cms-space-grid); }
.cms-gallery-cell { display: block; overflow: hidden; border-radius: var(--cms-radius-lg);
  border: var(--cms-border-width) solid var(--cms-line-card); background: var(--cms-surface-alt); }
.cms-gallery-cell img { display: block; width: 100%; height: auto; }
@media (max-width: 720px) { .cms-gallery { grid-template-columns: repeat(2, minmax(0, 1fr)); } }

/* N5 时间轴：左侧竖线 + 节点圆点。手机端竖线收到内容左边 */
.cms-timeline { margin: var(--cms-space-section) 0; }
.cms-timeline-list { margin: 0; padding: 0; list-style: none; }
.cms-timeline-item { position: relative; padding: 0 0 var(--cms-space-list-row) 26px; }
.cms-timeline-item::before { content: ''; position: absolute; left: 5px; top: 8px; bottom: 0;
  width: 2px; background: var(--cms-line-card); }
.cms-timeline-item:last-child::before { display: none; }
.cms-timeline-item::after { content: ''; position: absolute; left: 0; top: 7px;
  width: 12px; height: 12px; border-radius: 50%;
  background: var(--cms-brand); box-shadow: 0 0 0 3px var(--cms-brand-soft); }
.cms-timeline-time { display: block; font-size: var(--cms-fs-meta); font-weight: 500;
  color: var(--cms-brand); letter-spacing: .3px; }
.cms-timeline-title { margin: 2px 0 0; font-family: var(--cms-heading-font);
  font-size: var(--cms-fs-item); color: var(--cms-heading); }
.cms-timeline-text { margin-top: 4px; color: var(--cms-text-body); font-size: var(--cms-fs-body); }

/* N6 评分：星星靠 data-value 上色，空星用弱化色而不是描边 */
.cms-rating { padding: var(--cms-space-card) 0; }
.cms-rating-stars { display: inline-flex; gap: 2px; font-size: var(--cms-fs-item); line-height: 1; }
.cms-rating-star { color: var(--cms-line-card); }
.cms-rating-star.is-on { color: #f0a020; }
.cms-rating-meta { display: block; margin-top: 6px; font-size: var(--cms-fs-meta); color: var(--cms-text-muted); }

/* N7 视频：宽高比固定，加载时页面高度稳定 */
.cms-video { margin: var(--cms-space-section) 0; }
.cms-video-el { display: block; width: 100%; height: auto; border-radius: var(--cms-radius-lg);
  background: var(--cms-surface-dim); }
.cms-video-caption { margin: 8px 0 0; font-size: var(--cms-fs-meta); color: var(--cms-text-muted); text-align: center; }
.cms-video-empty { margin: 0; padding: var(--cms-space-card); text-align: center;
  font-size: var(--cms-fs-meta); color: var(--cms-text-ghost);
  border: 1px dashed var(--cms-line-card); border-radius: var(--cms-radius-lg); }

/* 外观预览条（第五批）：只有管理员在预览态才渲染，公众页面连这条 DOM 都没有。
   用醒目但不刺眼的暖色 —— 它要能被一眼看见，又不能让运营以为站点就这样上线了。 */
.prev-bar {
  background: #fff3d6; color: #6b4a06; font-size: 13px;
  border-bottom: 1px solid #f0d9a8;
}
.prev-bar .container { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; padding: 8px 0; }
.prev-bar strong { color: #4a3206; }
.prev-bar a {
  margin-left: auto; color: #8a5b00; text-decoration: underline;
  font-weight: 500; white-space: nowrap;
}
.prev-bar a:hover { color: #5c3d00; }
