/* ============================================================================
 * custom.css —— 我们的自定义样式（唯一允许我们改的样式文件）
 *
 * 分界线：
 *   assets/client/index-C191fWPP.css   客户给的样式表，原样加载，**不要改**
 *   assets/custom.css                  这个文件 —— 所有我们自己的东西
 *
 * 规则：需要覆盖客户的东西时，**不要回去改客户那份**，在这里写同选择器的规则。
 * 本文件在客户样式表**之后**加载，同权重下后写的胜出，所以覆盖是可靠的；
 * 一旦客户升级样式表，先回来看这里哪些「靠后加载取胜」的规则还成立。
 *
 * 目录：
 *   一、自托管字体（覆盖客户的 CDN 地址）
 *   二、中文字体回退
 *   三、字号 token —— 数值取自客户的静态站点
 *   四、客户编译产物里没有的工具类（我们模板用到了）
 *   五、登录态让开 WP 工具条
 *   六、Fluent Forms 皮肤（WP 独有，客户那边没有表单）
 *   七、导航 Logo 与移动端菜单
 *   八、合作媒体页（客户没有这个页面）
 *   九、首页动画：客户用 JS 动画库表达、CSS 写不出来的那几处
 * ========================================================================= */

/* ─────────────────────────────────────────────────────────────
 * 一、自托管字体
 *
 * 客户样式表里 Mazzard H 指向 db.onlinewebfonts.com。两个问题：
 *   1. 目标用户在中国大陆，那个域名经常连不上或极慢，页面会卡在字体加载上；
 *   2. 第三方地址随时可能失效，上线就是隐患。
 * 所以下载下来放进 assets/fonts/ 自托管。
 *
 * 这里是**同 family + 同 weight** 的重复声明，靠「本文件后加载」覆盖掉客户的
 * 那两条 —— 浏览器对同描述符的 @font-face 取后出现的那条，所以不会去请求 CDN。
 * 实测：Network 面板里没有 db.onlinewebfonts.com 的请求。
 *
 * ⚠ 前提是本文件排在客户样式表之后（见 functions.php 的入队依赖）。
 * ───────────────────────────────────────────────────────────── */
@font-face {
  font-family: "Mazzard H";
  src: url(fonts/mazzard-h-400.woff2) format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Mazzard H";
  src: url(fonts/mazzard-h-500.woff2) format("woff2");
  font-weight: 500;
  font-style: normal;
  font-display: swap;
}

/* ─────────────────────────────────────────────────────────────
 * 二、中文字体回退
 *
 * Mazzard H 是**纯拉丁字体** —— 文件只有 26KB，不含任何汉字。所以中文会落到
 * 浏览器默认的 sans-serif 上，和拉丁字母**不是同一套字**：同一行里「慧联制造」
 * 和「HuiLink」字形、字重、x-height 都不一样，看起来就是「一块大一块小」。
 *
 * 按中文平台的常见优先级补回退链：
 *   PingFang SC       macOS / iOS
 *   Microsoft YaHei   Windows
 *   思源 / Noto       部分 Linux 与安卓
 * 刻意不下载中文字体文件：一套中文字重 2–5MB，而这个站的目标用户在境内，
 * 首屏代价太大，回退链里的都是各平台自带的系统字体。
 * ───────────────────────────────────────────────────────────── */
html, body, * {
  font-family: "Mazzard H", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei",
               "Source Han Sans SC", "Noto Sans CJK SC", "WenQuanYi Micro Hei", sans-serif;
}

/* ─────────────────────────────────────────────────────────────
 * 三、字号 token —— 数值 = 客户静态站点里的原值
 *
 * 模板里 97 处写的是 var(--fs-*)，不是裸数值，所以全站字号在这一个地方收口。
 * **下面每个值都从客户静态站的 HTML 里量出来，不要再凭感觉调。**
 *
 * 取值依据（客户 React 源码里那组常量 J，以及 94 个静态页面的实测分布）：
 *
 *   --fs-hero    首页首屏 h1        静态站 clamp(22px, 3.4vw, 48px)   （J.displayLong，仅首页用）
 *   --fs-h1      内页 / 详情页 h1    静态站 clamp(36px, 4.6vw, 72px)   （J.display，94 个页面里 92 个用这个）
 *   --fs-h2      区块标题           静态站 clamp(30px, 3.6vw, 56px)   （J.sectionTitle，14 处）
 *   --fs-h3      卡片标题           静态站 clamp(16px, 1.7vw, 24px)   （h3 里 10 处用这个，占多数）
 *   --fs-body    正文               静态站 clamp(16px, 1.25vw, 20px)  （J.body，110 处）
 *   --fs-meta    辅助文字 / 标签     静态站是**固定 15px**（出现 208 次，最多的一档）
 *   --fs-display 统计数字           静态站 clamp(26px, 2.4vw, 38px)   （首页 12,000㎡ / 200+ 那排）
 *
 * 下面这五个是首页专用档位。客户的 React 源码里同样有三档具名常量、两档是就地
 * 写的字面量 —— 数值原样搬过来，只是给了名字，免得散在模板里：
 *
 *   --fs-eyebrow   hero 上方小标题    静态站 clamp(16px, 1.15vw, 20px)   （J.eyebrow）
 *   --fs-cta       大按钮文字         静态站 clamp(16px, 1.2vw, 19px)    （J.cta）
 *   --fs-chip      hero 地点/日期条   静态站 clamp(14px, 1vw, 17px)      （首页字面量）
 *   --fs-tiny      价值卡要点         静态站 clamp(12px, 1vw, 15px)      （首页字面量）
 *   --fs-tiny-cta  价值卡按钮         静态站 clamp(13px, 1.1vw, 16px)    （首页字面量）
 *
 * 历史说明：这一组值在 2026-10 之前被我们**整体收小过**（区块标题 56 → 30、
 * 正文 20 → 17），依据是客户一句「字体太大」，当时还写进了 DESIGN.md。
 * 2026-10-12 用户明确：以客户静态站为准，那份收缩作废。所以现在这里是原值。
 * 真要再动，先把整站和客户静态页并排比一遍，别再只凭一句口头反馈改。
 * ───────────────────────────────────────────────────────────── */
:root {
  --fs-hero:      clamp(22px, 3.4vw,  48px);
  --fs-h1:        clamp(36px, 4.6vw,  72px);
  --fs-h2:        clamp(30px, 3.6vw,  56px);
  --fs-h3:        clamp(16px, 1.7vw,  24px);
  --fs-body:      clamp(16px, 1.25vw, 20px);
  --fs-meta:      15px;
  --fs-display:   clamp(26px, 2.4vw,  38px);

  --fs-eyebrow:   clamp(16px, 1.15vw, 20px);
  --fs-cta:       clamp(16px, 1.2vw,  19px);
  --fs-chip:      clamp(14px, 1vw,    17px);
  --fs-tiny:      clamp(12px, 1vw,    15px);
  --fs-tiny-cta:  clamp(13px, 1.1vw,  16px);
}

/* ─────────────────────────────────────────────────────────────
 * 四、客户编译产物里没有的工具类
 *
 * 背景：客户的样式表是从 React 站**编译出来的产物**，只包含那一刻用到过的类。
 * 我们后来在 WP 里新写模板，随手用了一些当时没有的类（lg:grid-cols-[260px_1fr]
 * 之类）—— 它们在产物里根本不存在，表现是布局静默失效（筛选栏撑满整行、
 * 两栏变一栏），不报错、很难查。
 *
 * 这里只补实际用到的那几个，写法照 Tailwind 的产出对齐。
 * 新加类之前先 grep 一下 assets/client/index-C191fWPP.css 有没有，没有才加到这里。
 *
 * 注意：**不要**在这里改客户的字号体系。客户样式表里那些组件类
 * （.accordion-heading / .accordion-card h3 / .text-2xl …）自带正确的字号，
 * 以前这里有一组把它们「收小」的覆盖规则，2026-10-12 已按「以客户为准」删除。
 * ───────────────────────────────────────────────────────────── */

/* 任意值网格列 —— Tailwind 产物里不会有，必须手写 */
.md\:grid-cols-\[1fr_320px\] { grid-template-columns: 1fr 320px; }   /* 详情页：正文 + 侧栏 */
.md\:grid-cols-\[120px_180px_1fr\] { grid-template-columns: 120px 180px 1fr; }  /* 日历：时间 / 类型 / 标题 */

/* 断点工具类 */
@media (min-width: 1024px) {
  .lg\:sticky { position: sticky; }
  .lg\:top-28 { top: 7rem; }
}
@media (min-width: 768px) {
  .md\:p-8 { padding: 2rem; }
}

/* 尺寸 / 定位 */
.h-20 { height: 5rem; }
.w-20 { width: 5rem; }
.top-1\/2 { top: 50%; }
.left-3 { left: 0.75rem; }
.right-3 { right: 0.75rem; }
.-translate-y-1\/2 { transform: translateY(-50%); }
.text-4xl { font-size: 2.25rem; line-height: 2.5rem; }

/* 新闻正文排版：正文由编辑器输出，产出的 <p> 不带样式 */
.ainanjing-article > p:not([class]) { color: rgb(26, 11, 84); line-height: 1.8; }

/* ─────────────────────────────────────────────────────────────
 * 五、登录态：让开 WordPress 顶部工具条（admin bar）
 *
 * 现象：管理员登录后 #wpadminbar 和固定导航叠在一起，导航顶部 16px 被压住
 * （圆角被切、Logo 上沿被盖）。实测 2026-10-09：
 *   #wpadminbar   fixed / top 0 / 高 32px / z-index 99999
 *   导航外层 div   fixed / top 16px / 高 77.5px / z-index 50
 * 高度和层级都压不过它，只能把导航整体挪下去。
 *
 * WP 自己给 <html> 加了 margin-top:32px（"bump"），那招只推移文档流，
 * 对 position:fixed 的导航完全无效 —— 所以这里必须单独处理。
 *
 * 高度取 WP 的 CSS 变量 --wp-admin--admin-bar--height（7.1 起定义在 html 上，
 * ≤782px 自动变 46px），不手写 32/46 两个魔数。变量只在工具条显示时存在，
 * 所以整条规则挂在 body.admin-bar 下：未登录时它不生效，导航仍是 top:1rem。
 *
 * 已知边界：≤600px 时 WP 把工具条改成 position:absolute（滚动即消失），
 * 而导航的让位会一直留着，表现为滚动后导航上方露出一条内容。
 * 「登录态 + 手机」是少见组合，不值得为它给 custom.js 加滚动分支。
 * ───────────────────────────────────────────────────────────── */
body.admin-bar [data-nav-shell] {
  top: calc(1rem + var(--wp-admin--admin-bar--height, 32px));
}

/* ─────────────────────────────────────────────────────────────
 * 六、Fluent Forms 皮肤
 *
 * 四个前台表单（/contact、/visit、/exhibit/booth、/media/register）由
 * Fluent Forms 渲染，它输出的是一套自己的 class（ff-el-group /
 * ff-el-input--label / ff-el-form-control / ff-btn-submit…）。这一节把它们
 * 压回本站的表单外观 —— 对着 fluentform 的实际输出写的，不是照猜：
 *
 *   <div class="fluentform ff-default fluentform_wrapper_3 ainanjing-form …">
 *     <form class="frm-fluent-form … ff-el-form-top">
 *       <fieldset>                    ← 每页一次，字段和提交按钮都在这层
 *         <legend class="ff_screen_reader_title" style="…height:0…">  ← 内联隐藏
 *         <div class="ff-el-group">
 *           <div class="ff-el-input--label ff-el-is-required asterisk-right"><label>…</label></div>
 *           <div class="ff-el-input--content"><input class="ff-el-form-control"></div>
 *         </div>
 *         <div class="ff-el-group ff-text-left ff_submit_btn_wrapper"><button class="ff-btn ff-btn-submit">…</button></div>
 *       </fieldset>
 *     </form>
 *   </div>
 *
 * ── 这一节不是「覆盖 Fluent Forms 的皮肤」，它就是唯一的皮肤 ──────
 *
 * 实测 2026-10-09：这些页面上 Fluent Forms 的两张样式表
 * （fluent-forms-public.css / fluentform-public-default.css）**根本没有加载** ——
 * 页面里只有 fonts / 客户样式表 / custom.css / TranslatePress 四张。
 *
 * 原因是它的加载方式：FF 靠「文章正文里有没有 fluentform 短代码」来决定要不要
 * 入队样式（maybeLoadFluentFormStyles），而我们的表单是模板里 do_shortcode()
 * 调的，正文里没有那个短代码 —— 它检测不到。renderForm() 里还有一次兜底入队，
 * 但那次发生在 wp_head 之后，WordPress 不会再打印。
 *
 * 所以输入框、标签、按钮、错误提示、成功卡片的外观**全部**由这一节负责，
 * 没有第二处兜着。改动前先确认没有 FF 的规则在跟它叠加。
 *
 * 那为什么选择器还要带 .fluentform.ff-default 这一层？两个理由：
 *   1. 万一以后表单改成写进正文（或 FF 改了加载策略），它的样式表就会真的加载。
 *      带上这一层，权重稳定高过它那套 .fluentform .ff-el-*，与加载顺序无关 ——
 *      不会出现「某天突然变样」这种最难查的问题。
 *   2. 客户的样式表是编译产物、里面没有的类会静默失效（见第四节），
 *      所以这里的每个值都写死或引用确定存在的变量，不指望任何现成的组件类。
 *
 * 顺带：FF 的皮肤表里定义了 --fluentform-danger / --fluentform-primary 等变量，
 * 现在这个页面没有它，变量是空的。下面照样重映射一遍 —— 一是无害，二是万一
 * 上面第 1 条发生，布局表里那 13 处引用能拿到正确的颜色。
 * ───────────────────────────────────────────────────────────── */

.fluentform.ff-default {
  --nj-ink:      rgb(26, 11, 84);
  --nj-muted:    rgb(131, 121, 158);
  --nj-line:     rgba(26, 11, 84, 0.12);
  --nj-surface:  rgb(249, 249, 249);
  --nj-required: rgb(200, 111, 255);
  --nj-danger:   rgb(196, 43, 67);
  --nj-focus:    rgba(26, 11, 84, 0.28);

  /* Fluent Forms 自己的变量也重映射一遍：错误提示色、下拉加载态那几处它内部在用 */
  --fluentform-primary:       rgb(28, 78, 255);
  --fluentform-secondary:     rgb(26, 11, 84);
  --fluentform-danger:        rgb(196, 43, 67);
  --fluentform-border-color:  rgba(26, 11, 84, 0.12);
  --fluentform-border-radius: var(--radius-control);
}

/* ── 字段块 ───────────────────────────────────────────────────
 * 间距对应设计稿的 space-y-5（20px）。Fluent Forms 布局表里对
 * .ff-el-group 有 20px 和 0 两条规则，哪条生效取决于源码顺序 ——
 * 显式写死，免得它哪天改动就让整页间距静默错位。 */
.fluentform.ff-default .ff-el-group {
  margin-bottom: 20px;
}

/* ── 标签 ─────────────────────────────────────────────────────
 * 设计稿：<span class="text-sm font-medium"> + space-y-2（8px）。
 * Fluent Forms 默认是 inline-block + 5px，要改。 */
.fluentform.ff-default .ff-el-input--label {
  display: block;
  margin-bottom: 8px;
}
.fluentform.ff-default .ff-el-input--label > label {
  font-size: 14px;
  font-weight: 500;
  line-height: 1.4;
  color: var(--nj-ink);
}

/* ── 必填星号 ─────────────────────────────────────────────────
 * Fluent Forms 用纯 CSS 的 ::after 生成，颜色取自 --fluentform-danger，
 * 但那个变量同时管着**错误提示**的颜色（设计稿里错误是红的）。
 * 所以变量保持红，星号单独用更高权重改紫。 */
.fluentform.ff-default .ff-el-input--label.ff-el-is-required.asterisk-right > label:after {
  content: " *";
  margin-left: 3px;
  color: var(--nj-required);
}
.fluentform.ff-default .ff-el-input--label.ff-el-is-required.asterisk-left > label:before {
  content: "* ";
  margin-right: 3px;
  color: var(--nj-required);
}

/* ── 输入框 / 下拉 / 多行文本 ─────────────────────────────────
 * 对应模板里原来那两个变量：
 *   class "w-full rounded-control px-4 py-3 text-sm outline-none border transition-colors"
 *   style "background:rgb(249,249,249);border-color:rgba(26,11,84,.12);color:rgb(26,11,84)" */
.fluentform.ff-default .ff-el-form-control {
  width: 100%;
  background: var(--nj-surface);
  border: 1px solid var(--nj-line);
  border-radius: var(--radius-control);
  color: var(--nj-ink);
  font-family: inherit;
  font-size: 14px;
  line-height: 1.5;
  padding: 0.75rem 1rem;
  outline: none;
  box-shadow: none;
  transition: border-color .2s ease;
}
/* 下拉保持浏览器原生外观（设计稿就是这么用的），不用自己画箭头 */
.fluentform.ff-default select.ff-el-form-control {
  padding-right: 1rem;
}
.fluentform.ff-default .ff-el-form-control:focus {
  border-color: var(--nj-focus);
}
.fluentform.ff-default .ff-el-form-control::placeholder {
  color: var(--nj-muted);
  opacity: 1;
}

/* ── 校验错误 ─────────────────────────────────────────────────
 * Fluent Forms 给字段块加 .ff-el-is-error，并在 .ff-el-input--content 里
 * 插一个 <div class="error text-danger">。设计稿是一条浅红底的通告条。 */
.fluentform.ff-default .ff-el-is-error .ff-el-form-control {
  border-color: var(--nj-danger);
}
.fluentform.ff-default .ff-el-is-error .ff-el-input--content .text-danger {
  margin-top: 8px;
  padding: 0.75rem 1rem;
  border-radius: var(--radius-control);
  background: rgba(196, 43, 67, 0.08);
  color: var(--nj-danger);
  font-size: 14px;
  line-height: 1.5;
}

/* ── 提交按钮 ─────────────────────────────────────────────────
 * Fluent Forms 输出的是裸 <button class="ff-btn ff-btn-submit ff_btn_no_style">
 * （button_style=no_style，所以它不会往页面里塞自己那段按钮样式）。
 * 设计稿的按钮是「外层 1px 渐变底 + 内层白字」两层结构；这里只有一层，
 * 把渐变直接画在按钮上，视觉等价。 */
.fluentform.ff-default .ff_submit_btn_wrapper {
  margin-bottom: 0;
  /* 显式左对齐：FF 的布局表里有 .ff_submit_btn_wrapper{text-align:right}，
     现在那张表没加载，但写死更稳（见本节头部说明）。 */
  text-align: left;
}
.fluentform.ff-default .ff-btn-submit {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: var(--radius-control);
  background-image: linear-gradient(90deg, rgb(28, 78, 255), rgb(172, 36, 255) 50%, rgb(254, 136, 27));
  color: #fff;
  font-family: inherit;
  font-size: var(--fs-body);
  font-weight: 500;
  line-height: 1.2;
  padding: 0.75rem 1.75rem;
  white-space: nowrap;
  cursor: pointer;
  transition: opacity .3s ease;
}
.fluentform.ff-default .ff-btn-submit:hover,
.fluentform.ff-default .ff-btn-submit:focus-visible {
  opacity: .9;
}
.fluentform.ff-default .ff-btn-submit:disabled {
  opacity: .6;
  cursor: default;
}
/* Fluent Forms 提交时会在按钮上叠一层白色进度条，跟设计稿不符 */
.fluentform.ff-default .ff-btn.ff-working:after {
  display: none;
}

/* ── 成功卡片 ─────────────────────────────────────────────────
 * 提交成功后 Fluent Forms 把 confirmation 里那段 HTML 塞进它自己新建的
 * div.ff-message-success（接在表单后面），并把表单隐藏。
 * 它自带边框/内边距/阴影，先拆掉，再让 .nj-form-done 自己成一整张卡片。 */
.fluentform.ff-default .ff-message-success {
  margin-top: 0;
  padding: 0;
  border: 0;
  box-shadow: none;
}
.nj-form-done {
  border-radius: var(--radius-card);
  background: #fff;
  padding: 2.5rem;
  text-align: center;
  box-shadow: 0 1px 29px #3f4a7e1a;
  color: var(--nj-ink);
}
.nj-form-done__title {
  margin: 0;
  font-size: var(--fs-h2);
  font-weight: 500;
  color: var(--nj-ink);
}
.nj-form-done__note {
  margin: 1rem 0 0;
  color: var(--nj-muted);
  font-size: var(--fs-body);
  line-height: 1.7;
}
.nj-form-done__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin-top: 1.25rem;
  border-radius: var(--radius-control);
  background-image: linear-gradient(90deg, rgb(28, 78, 255), rgb(172, 36, 255) 50%, rgb(254, 136, 27));
  color: #fff;
  font-size: var(--fs-body);
  font-weight: 500;
  padding: 0.75rem 1.75rem;
  text-decoration: none;
  transition: opacity .3s ease;
}
.nj-form-done__btn:hover {
  opacity: .9;
}

/* ── 同意声明行（展位申请页，2026-10-16 客户设计稿） ───────────
 * 设计稿在提交按钮**上方**，也就是 fieldset 内部；标记由模板经
 * ainanjing_render_form() 的 $note 参数塞进去（见 inc/helpers.php）。
 * 这里只管外观：灰字 14px（设计稿 text-sm），结尾那个「隐私政策」是下划线
 * 链接、颜色跟着正文走 —— 跟客户原始静态站 dist/zh/exhibit/booth 一致。 */
.nj-form-consent {
  margin: 0 0 20px;
  font-size: 14px;
  line-height: 1.7;
  color: rgb(131, 121, 158);
}
.nj-form-consent a {
  color: inherit;
  text-decoration: underline;
}

/* ── 两列表单：联系页 / 展位申请页 ─────────────────────────────
 * 设计稿把前几个字段并成两列 ——
 *   联系页：<div class="grid sm:grid-cols-2 gap-5"> 只包住前四个字段，
 *           关注方向 / 补充说明 / 提交按钮在网格外；
 *   展位页：公司名称|联系人、电子邮箱|联系电话 两行，意向展位类型占左半格，
 *           补充说明 / 同意声明 / 提交按钮通栏。
 * Fluent Forms 把字段直接铺在 fieldset 里，所以网格画在 fieldset 上 ——
 * 比数 :nth-child 稳，因为 fieldset 里还夹着隐藏 input 和蜜罐字段。
 *
 * 通栏有两条路，都写在这里：
 *   .nj-span-2     联系页用。类由插件字段定义里的 container_class 挂上去，
 *                  所以改了定义得去后台点一次「创建 / 修复表单」才会进库。
 *   :has(textarea) 展位页用。纯主题内的选择器，不依赖那次后台同步 ——
 *                  客户站上少点一步也不会静默变成半宽。 */
@media (min-width: 640px) {
  .ainanjing-form-contact .frm-fluent-form fieldset,
  .ainanjing-form-exhibit-booth .frm-fluent-form fieldset {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 20px;
    align-items: start;
  }
  /* legend 是给读屏用的表单标题，Fluent Forms 用内联样式把它压成 0×0 但仍是
     display:block —— 那会占掉一个网格格。absolute 让它脱离网格流，
     同时留在无障碍树里（比 display:none 正确）。 */
  .ainanjing-form-contact .frm-fluent-form fieldset > legend,
  .ainanjing-form-exhibit-booth .frm-fluent-form fieldset > legend {
    position: absolute;
  }
  /* 间距交给 grid 的 gap。⚠ 选择器必须写成 .fluentform.ff-default.ainanjing-form-contact
     四个类 —— 上面那条 .fluentform.ff-default .ff-el-group 是三个类，
     只写 .ainanjing-form-contact .ff-el-group 会压不过它，20px 外边距和 20px
     gap 会叠成 40px 行距（这个坑踩过，实测行距 119px 而设计是 99px）。
     同意声明同一条道理：它的 20px 下外边距也得在这里让位给 gap。 */
  .fluentform.ff-default.ainanjing-form-contact .ff-el-group,
  .fluentform.ff-default.ainanjing-form-exhibit-booth .ff-el-group,
  .fluentform.ff-default.ainanjing-form-exhibit-booth .nj-form-consent {
    margin-bottom: 0;
  }
  .fluentform.ff-default.ainanjing-form-contact .ff-el-group.nj-span-2,
  .fluentform.ff-default.ainanjing-form-contact .ff_submit_btn_wrapper,
  .fluentform.ff-default.ainanjing-form-exhibit-booth .ff-el-group:has(> .ff-el-input--content > textarea),
  .fluentform.ff-default.ainanjing-form-exhibit-booth .nj-form-consent,
  .fluentform.ff-default.ainanjing-form-exhibit-booth .ff_submit_btn_wrapper {
    grid-column: 1 / -1;
  }
}

/* ─────────────────────────────────────────────────────────────
 * 七、导航：品牌 Logo 与移动端菜单（2027 换标时加）
 * ───────────────────────────────────────────────────────────── */

/* 品牌锁定组合：方形图标 + 右侧两行文字。
   2026-10-16 客户要求把文字从图里拆出来（结构见 helpers.php 的
   ainanjing_brand_lockup）。原来那张 4:1 横版 SVG 把三行字烘焙在图里，
   按 48px 的图高算中文副标题实际只有 5.2px（26/240 × 48），既看不清、
   翻译插件也抓不到。拆开后图标和文字是独立元素，字号各自可控。
   ⚠ 导航那一份的尺寸连同响应式断点必须收在**一个类**里，不能像其它条目那样拆成 Tailwind 工具类：
   ⚠ 尺寸连同响应式断点必须收在**一个类**里，不能像其它条目那样拆成 Tailwind 工具类：
   custom.js 的滚动收缩是按列表**增删**类，md: 那档一旦写进表里，
   收缩时旧高度被移除、md 那档却还在，会在 ≥768px 静默压住新值 = 收缩失效。
   滚动前后由 custom.js 在 .nav-logo / .nav-logo--compact 之间整类切换。
   所以这里的尺寸一律按 .nav-logo / .nav-logo--compact 这对类写，别挪回模板。 */
.brand-lockup {
  display: inline-flex;
  align-items: center;
}
.brand-lockup .brand-mark {
  display: block;
  width: auto;
  object-fit: contain;
  object-position: left;
}
.brand-text {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
.brand-name {
  font-weight: 700;
  line-height: 1.15;
  white-space: nowrap;
}
.brand-sub {
  font-weight: 400;
  line-height: 1.25;
  white-space: nowrap;
}

/* 导航：未滚动 / 已滚动（由 custom.js 整类切换） */
.nav-logo { gap: 0.5rem; }
.nav-logo .brand-mark { height: 2.5rem; }
.nav-logo .brand-name { font-size: 12px; color: #0a0b0d; letter-spacing: 0.01em; }
.nav-logo .brand-sub  { font-size: 8px;  color: #0a0b0d; }
.nav-logo--compact { gap: 0.4rem; }
.nav-logo--compact .brand-mark { height: 2.125rem; }
.nav-logo--compact .brand-name { font-size: 11px; }
.nav-logo--compact .brand-sub  { font-size: 7.5px; }

@media (min-width: 768px) {
  .nav-logo .brand-mark { height: 3rem; }
  .nav-logo .brand-name { font-size: 14px; }
  .nav-logo .brand-sub  { font-size: 8.5px; }
  .nav-logo--compact .brand-mark { height: 2.5rem; }
  .nav-logo--compact .brand-name { font-size: 12.5px; }
  .nav-logo--compact .brand-sub  { font-size: 8px; }
}

/* 客户传了自定义 Logo 就整份用客户的图，只加个上限防超宽图撑破导航 */
.brand-lockup--custom .brand-mark { height: 3rem; max-width: 220px; }
.nav-logo--compact.brand-lockup--custom .brand-mark { height: 2.5rem; max-width: 180px; }

/* 页脚：外面套着白卡片（深底上不能直接用近黑的字），所以文字仍是深色 */
.footer-lockup { gap: 0.7rem; }
.footer-lockup .brand-mark { height: 2.75rem; }
.footer-lockup .brand-name { font-size: 17px; color: #0a0b0d; letter-spacing: 0.01em; }
.footer-lockup .brand-sub  { font-size: 9px;  color: #4e5969; }

/* 移动端菜单：一级项一组，组间一条细分隔线。
   线画在组的**上边**（相邻兄弟选择器），第一个分组天然没有线。
   不要改成 :last-of-type —— 面板底部那行「语言切换 + 展位预订」也是 div，
   会把 last-of-type 抢走，最后一条分隔线就永远去不掉。 */
.nav-mobile-group { padding: 0.75rem 0; }
.nav-mobile-group + .nav-mobile-group { border-top: 1px solid rgba(26, 11, 84, 0.08); }

/* ─────────────────────────────────────────────────────────────
 * 八、合作媒体页（/media/press）
 *
 * 版式参照 fairplus.cn/media-partners/：按类别分节，每节一个 logo 网格。
 * 网格这一层没法用现成的工具类表达 —— auto-fill / minmax / aspect-ratio
 * 都不在客户的编译产物里 —— 所以写在这里。
 * 字号仍按主题的规矩在模板里内联 font-size:var(--fs-x)。
 * ───────────────────────────────────────────────────────────── */

.media-partner-section { margin-bottom: 3rem; }
.media-partner-section:last-of-type { margin-bottom: 0; }
.media-partner-section-title { margin-bottom: 1.25rem; }
.media-partner-section-note {
  font-size: var(--fs-meta);
  font-weight: 400;
  color: rgb(131, 121, 158);
  margin-left: 0.5em;
}

/* 每格最小 140px，宽度富余就多排几列 —— 和 fairplus 一致 */
.media-partner-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap: 1.25rem;
}
.media-partner-item { text-align: center; }

.media-partner-logo {
  background: #fff;
  border: 1px solid rgba(26, 11, 84, 0.1);
  border-radius: var(--radius-control);
  padding: 1rem;
  aspect-ratio: 16 / 9;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: border-color 0.2s ease, box-shadow 0.2s ease, transform 0.2s ease;
}
.media-partner-logo img { max-width: 100%; max-height: 100%; object-fit: contain; }
.media-partner-link {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
}

/* 没传 Logo 时的文字占位：用媒体名顶着，不塞随机图 */
.media-partner-logo-text {
  font-size: var(--fs-meta);
  line-height: 1.35;
  color: rgb(131, 121, 158);
  word-break: break-word;
}

/* hover 抬升**所有条目都有**（和 fairplus 一致）—— 它是「这块是活的」的视觉反馈，
   和「能不能点」是两回事：能不能点只由手型和是否真的包了 <a> 决定。 */
.media-partner-logo:hover {
  border-color: rgb(28, 78, 255);
  box-shadow: 0 10px 24px rgba(63, 74, 126, 0.12);
  transform: translateY(-2px);
}
/* 手型只给有链接的 —— 它才是「这里能点」的暗示 */
.media-partner-item--linked { cursor: pointer; }
@media (prefers-reduced-motion: reduce) {
  .media-partner-logo { transition: none; }
  .media-partner-logo:hover { transform: none; }
}

.media-partner-name {
  font-size: var(--fs-meta);
  color: rgb(26, 11, 84);
  margin-top: 0.625rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.media-partner-name a { color: inherit; text-decoration: none; transition: color 0.2s ease; }
.media-partner-item--linked .media-partner-name a:hover { color: rgb(28, 78, 255); }

/* ─────────────────────────────────────────────────────────────
 * 九、首页动画：客户用 JS 动画库表达、CSS 写不出来的那几处
 *
 * 客户原站用 framer-motion，参数（时长、关键帧、缓动）都写在这两段里，
 * 逐项照抄。其余动画（滚动进场 .reveal、统计数字递增、价值卡悬停展开）
 * 客户样式表里本来就有现成的类/内联值，由 custom.js 切换，不在这里重复定义。
 *
 * ⚠ 两处刻意的不精确，写在这里免得以后被当成 bug 查：
 *   1. framer-motion 的 times:[0,.4,1] 是「关键帧时间点」，CSS 这边用百分比表达，
 *      缓动只能**逐段**给（写进关键帧里的 animation-timing-function）。
 *      客户对 clipPath 的两段分别用 easeIn / cubic-bezier(.16,1,.3,1)，
 *      对 filter 和 opacity 两段用 easeInOut —— 这里统一取 clipPath 那组，
 *      观感一致，逐属性映射需要 JS 驱动。
 *   2. whileHover 的弹簧（stiffness 340 / damping 24）没法用 CSS 表达，
 *      用一条短缓动近似。缩放幅度 1.07 是原值。
 * ───────────────────────────────────────────────────────────── */

/* ── 展商 Logo 云的「波浪」 ───────────────────────────────────
 * 客户 Ys 组件：每个 logo 延迟 index*0.045s，在 0.92s 内做
 *   clipPath  inset(0 0% 0 0) → inset(0 100% 0 0) → inset(0 0% 0 0)
 *   filter    blur(0px)       → blur(8px)         → blur(0px)
 *   opacity   1               → 0.2               → 1
 * 也就是「从左往右擦掉再擦回来」。换页动画，也每 4.6s 无条件跑一次。
 * custom.js 负责加 .is-waving 和写 animation-delay。 */
@keyframes nj-logo-wave {
  0% {
    clip-path: inset(0 0% 0 0);
    filter: blur(0px);
    opacity: 1;
    animation-timing-function: ease-in;
  }
  40% {
    clip-path: inset(0 100% 0 0);
    filter: blur(8px);
    opacity: 0.2;
    animation-timing-function: cubic-bezier(0.16, 1, 0.3, 1);
  }
  100% {
    clip-path: inset(0 0% 0 0);
    filter: blur(0px);
    opacity: 1;
  }
}
.exhibitor-cloud [data-logo-index].is-waving {
  animation: nj-logo-wave 0.92s both;
}

/* ── 展商 Logo 的悬停缩放 ─────────────────────────────────────
 * 客户 whileHover: scale 1.07（弹簧）。这里用短缓动近似。 */
.exhibitor-cloud [data-logo-index] {
  transition: transform 0.25s cubic-bezier(0.16, 1, 0.3, 1);
}
.exhibitor-cloud [data-logo-index]:hover {
  transform: scale(1.07);
}

/* 无障碍：两个都要能被 prefers-reduced-motion 关掉。
   （custom.js 里也已经跳过波浪，这里是双保险 —— 用户可能在页面打开后改系统设置。） */
@media (prefers-reduced-motion: reduce) {
  .exhibitor-cloud [data-logo-index].is-waving { animation: none; }
  .exhibitor-cloud [data-logo-index] { transition: none; }
  .exhibitor-cloud [data-logo-index]:hover { transform: none; }
}

/* ─────────────────────────────────────────────────────────────
 * 九、2026-10-16 客户反馈的首页改动
 *
 * ⚠ 这一节**全是客户主动要求的偏离**，做完之后首页和客户静态站不再逐字一致。
 * tools/parity-check.py 里对应地记成 KNOWN_GAPS（带出处），不是漂移。
 * 客户那份基座 assets/client/*.css 仍然一个字节没动。
 * ───────────────────────────────────────────────────────────── */

/* ── 首屏文字放大 1.25 倍（客户：「Hero 区域整体文字需要放大，按钮不放大」）──
 * 数值 = 原来各 token 的 clamp 三项各 × 1.25。
 *
 * 为什么要 !important：客户标记里这些字号是**内联**写的
 * （style="font-size:var(--fs-hero)…"，见 front-page.php 首屏那一段），
 * 内联声明压得过任何普通样式表规则 —— 不加 !important 这几条完全不生效
 * （第一版就是这么写的，改完字号一点没动）。这正是 !important 该出场的场合。
 *
 * ⚠ 也别图省事去改 --fs-* 那几个 token：它们是全站共用的，其中 --fs-eyebrow
 * 还被首屏「了解更多」那个按钮用着，一改按钮跟着变大 —— 正好是客户说不要的。
 * 所以这里只点名首屏里的四个**文字**元素，用标签和现成的类选，模板不加钩子：
 *   h1                 首屏唯一的 h1
 *   p                  首屏唯一的段落
 *   .gradient-text-b   眉标那个 span
 *   .rounded-chip      日期 / 地点胶囊
 * 两个按钮都是 <a>，一个都沾不上。作用域只有 .hero-boost 这一个 section。 */
.hero-boost h1 {
  font-size: clamp(28px, 4.25vw, 60px) !important;
}
.hero-boost p {
  font-size: clamp(20px, 1.5625vw, 25px) !important;
}
.hero-boost .gradient-text-b {
  font-size: clamp(20px, 1.44vw, 25px) !important;
}
.hero-boost .rounded-chip {
  font-size: clamp(17px, 1.25vw, 21px) !important;
}

/* ── 合作媒体跑马灯（2026-10-16 客户新增板块）──────────────────────
 * 结构（在 front-page.php 里输出）：
 *   .media-marquee            可视窗口，overflow:hidden
 *     .media-marquee-track    真正在动的轨道，里面是两组一模一样的内容
 *       .media-marquee-set    一组卡片
 *
 * 为什么是两组：位移 -50%（正好等于一组的宽度）之后，第二组落回第一组
 * 原来的位置 —— 这就是无缝循环。只放一组的话，滚到头会「唰」地弹回去。
 *
 * 方向：
 *   --rightward   translateX(-50%) → 0     内容往右走（第一行：大众媒体）
 *   --leftward    translateX(0) → -50%     内容往左走（第二行：行业媒体）
 * 时长由 PHP 按卡片数算好、写成行内自定义属性 --marquee-duration，
 * 好让两行的**线速度**接近，不至于一行飞快一行爬。 */
.media-marquee {
  overflow: hidden;
  width: 100%;
}
.media-marquee + .media-marquee { margin-top: 1.25rem; }
.media-marquee-track {
  display: flex;
  width: max-content;
  animation: nj-marquee-rightward var(--marquee-duration, 60s) linear infinite;
  will-change: transform;
}
.media-marquee--leftward .media-marquee-track { animation-name: nj-marquee-leftward; }
.media-marquee-set {
  display: flex;
  flex: none;
  gap: 1.25rem;
  /* 组与组之间也要有间隔，否则接缝处两张卡片会贴在一起 */
  padding-right: 1.25rem;
}

@keyframes nj-marquee-rightward {
  from { transform: translateX(-50%); }
  to   { transform: translateX(0); }
}
@keyframes nj-marquee-leftward {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}

/* 单张卡片：白底圆角 + 弱阴影，上面 logo 下面名字 */
.media-marquee-card {
  display: flex;
  flex: none;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.6rem;
  width: 200px;
  height: 104px;
  padding: 0.9rem 1rem;
  background: #ffffff;
  border: 1px solid rgba(26, 11, 84, 0.08);
  border-radius: 14px;
  /* ⚠ 影子必须收得很紧，不能用站里别处那种 0 1px 29px 的大范围阴影。
     一排 17~19 张卡片挨着，29px 的光晕会在卡片之间的空隙里连成一条灰带，
     远看就是「每一行都有一层背景色」—— 客户 2026-10-16 就是这么反馈的。
     实测那一层各元素的 background-color 全是透明，色带纯粹是阴影叠出来的。
     所以这里靠描边立住卡片，阴影只留一点点。 */
  box-shadow: 0 1px 2px rgba(63, 74, 126, 0.06);
  text-decoration: none;
  transition: transform 0.25s cubic-bezier(0.16, 1, 0.3, 1), box-shadow 0.25s ease;
}
a.media-marquee-card:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 10px rgba(63, 74, 126, 0.1);
}
.media-marquee-logo {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 46px;
}
.media-marquee-logo img {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
}
.media-marquee-name {
  max-width: 100%;
  overflow: hidden;
  font-size: 13px;
  line-height: 1.2;
  color: rgb(26, 11, 84);
  white-space: nowrap;
  text-overflow: ellipsis;
}

/* 鼠标停在某一排上就暂停 —— 不然想点某一家的时候它一直在跑。
   参考站的跑马灯也是这个行为。 */
.media-marquee:hover .media-marquee-track { animation-play-state: paused; }

@media (prefers-reduced-motion: reduce) {
  .media-marquee-track { animation: none; }
}

/* ── 页脚四栏（2026-10-16 客户要求）─────────────────────────────
 * 从左到右：logo+文字 / 主办单位 / 快速导航 / 联系我们。
 *
 * ⚠ 这里**不能**写 md:grid-cols-5：客户那份编译好的 Tailwind 里 md 档只有
 * grid-cols-1~4（他们自己的站没用到 5），类名不存在时不是报错，而是整条规则
 * 不生效 —— 四栏会静默退化成两列。第一版就是这么写的，实测确认过。
 * 所以按主题一贯的做法，用一个语义类写在这里。
 *
 * 网格是 5 份：logo 那栏占 2 份（简介和展期需要宽度），其余三栏各 1 份，
 * 视觉上正好四栏。 */
.footer-grid {
  display: grid;
  gap: 2.5rem;
}
@media (min-width: 768px) {
  .footer-grid {
    /* 四份按比例分，不是等分：
       logo 那栏 1.6（简介 + 展期要宽度），联系我们 1.4（要放得下整条邮箱，
       等宽时 ainnanjing@messenanjing.cn 正好被挤到折行、还被断在词中间），
       中间两栏 1 就够（最长的「德国斯图加特展览集团」在 1fr 里放得下）。 */
    grid-template-columns: 1.6fr 1fr 1fr 1.4fr;
  }
}

/* ─────────────────────────────────────────────────────────────
 * 十、联系我们页的分栏（2026-10-16 整页对齐客户静态站的 /contact）
 * ───────────────────────────────────────────────────────────── */

/* 联系人分栏。
 * 客户设计稿是「展位联系 2 人 + 媒体与参观 1 人」，标记里写死的是
 * lg:grid-cols-3 加第一组 lg:col-span-2。我们这边人数会变，所以不写死：
 *   外层列数 = 联系人总数      → 模板写成 --contact-cols
 *   每组跨的列数 = 本组人数     → 模板写成 --contact-span
 * 客户的 2+1 就是 3 列 + 跨 2 列，和这边算出来的完全一致；
 * 以后加人、改分组名字，版式自己跟着走。
 *
 * 用变量是因为这两个数**得算出来**，Tailwind 的工具类是固定的几档，表达不了。
 * 同理，lg:col-span-2 那种档位只在客户那棵写死的树里成立。
 *
 * ⚠ 组内的卡片列数也跟着 --contact-span 走：跨 1 列时（lg 下）内部就是单列，
 * 这正是客户标记里第二个分组写 `lg:grid-cols-1` 的原因。 */
.contact-groups {
  display: grid;
  gap: 2.5rem 1rem;   /* = gap-y-10 gap-x-4 */
}
.contact-group-cards {
  display: grid;
  gap: 1rem;          /* = gap-4 */
}
@media (min-width: 640px) {
  .contact-group-cards {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}
@media (min-width: 1024px) {
  .contact-groups {
    grid-template-columns: repeat(var(--contact-cols, 3), minmax(0, 1fr));
  }
  .contact-groups > .contact-group {
    grid-column: span var(--contact-span, 1);
  }
  .contact-group-cards {
    grid-template-columns: repeat(var(--contact-span, 1), minmax(0, 1fr));
  }
}

/* ─────────────────────────────────────────────────────────────
 * 十一、页面 Hero：全宽背景图 + 便利贴面板
 *      （2026-10-16 客户要求，除首页外每个页面都用）
 *
 * 照客户线上站那一版 page-hero 改的：
 *   客户原值                        这里
 *   max-w-xl (576px)                .hero-panel__card 的 max-width
 *   bg-ploy-background-primary/94   白 94%，一眼能看见底下的图
 *   backdrop-blur                   同一手，模糊背景图
 *   border + shadow-xl              同
 *   p-6 md:p-10                     用 clamp 平滑过渡
 *
 * 结构在 parts/hero.php，那里只留结构，值全在这 —— 因为这几个值都不在客户
 * 编译好的样式表里，写成 Tailwind 类名不会有任何规则生效。
 * ───────────────────────────────────────────────────────────── */

.hero-panel__card {
  width: 100%;
  max-width: 576px;
  padding: clamp(24px, 2.6vw, 40px);
  background: rgba(255, 255, 255, 0.94);
  border: 1px solid rgba(26, 11, 84, 0.08);
  box-shadow: 0 20px 25px -5px rgba(10, 5, 20, 0.12), 0 8px 10px -6px rgba(10, 5, 20, 0.1);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
}

/* 面板里那行小字（eyebrow）。客户那版没有，是既有文案，做成标题上面一行弱化的小字 */
.hero-panel__eyebrow {
  margin-bottom: 0.75rem;
  font-size: var(--fs-eyebrow);
  font-weight: 500;
  letter-spacing: 0.04em;
  color: rgb(131, 121, 158);
}
.hero-panel__sub {
  margin-top: 1.5rem;
  font-size: var(--fs-body);
  line-height: 1.7;
  color: rgb(131, 121, 158);
}
.hero-panel__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem;
  margin-top: 2rem;
}

/* 次要按钮。原来是「白描边 + 白字」（面板是深色图的时候写的），
   现在面板是浅色的，白字白描边就看不见了 —— 换成深色描边深色字。 */
.hero-panel__secondary {
  color: rgb(26, 11, 84);
  border: 1px solid rgba(26, 11, 84, 0.18);
  transition: background-color 0.2s ease;
}
.hero-panel__secondary:hover {
  background: rgba(26, 11, 84, 0.05);
}

/* ─────────────────────────────────────────────────────────────
 * 十二、组织机构页：分组 + 品牌色横幅（2026-10-16 客户设计稿）
 *
 * 客户把这一页从「4 张平铺卡」改成三个分组（主办方 / 承办方 / 合作伙伴），
 * 并把手上的照片换成一张品牌色横幅 —— 横幅里只有字标和日期。
 *
 * 值是从客户设计稿的图像里**量**出来的（逐像素扫边界，不是看截图估的），
 * 但设计稿不是 1:1 —— 它画在 1440 的画布上，卡片只有 421.5px 宽、
 * 内容左边距 123px。把这两个比值放到本站的实际布局上一算：
 *
 *     本站这一页卡片 564px ÷ 421.5 = 1.338
 *     本站内容左边距 280px ÷ 123  = 2.276   ← 对不上
 *
 * 所以设计稿不是本站布局的等比缩放，卡片宽度这一条不能直接拿来定标尺。
 * 真正可靠的锚点是**卡片里的机构名**：客户静态站那张卡是写死的 text-2xl
 * （24px），设计稿里量出来是每字 18.9px → 缩放系数 24 ÷ 18.9 = **1.27**。
 * 下面所有尺寸都按 1.27 换算。按这个系数，机构名 24px、描述 16px
 * 都和设计稿严丝合缝（实测比例偏差 < 0.5%），反过来说明锚点选对了。
 *
 * 横幅渐变的两个端点色：先在设计稿的横幅上采一圈点、按 150° 轴做线性拟合并
 * 外推到四角（紫红和绿两版算出来都是 ~150°，不是 135°），再用本站渲染出来的
 * 同位置采样做一次残差修正（第一次紫红整体偏暗 13/255，修完残差 5/255）。
 * ⚠ 设计稿的横幅上还有一层很淡的斜向丝纹（像是丝绢质感），这里**没做** ——
 *   那更像一张导出的位图，用 CSS 近似反而更容易画歪。要做的话得先拿到原图。
 *
 * 卡片的其它部分一律没动：名称 24px、描述 16px、p-10、rounded-card 全部沿用，
 * 和客户静态站那一版卡片一致。
 * ───────────────────────────────────────────────────────────── */

/* 分组之间留白；第一组不用（section 自己的 py-20 已经给足）。
   设计稿里「上一组卡片底 → 下一组标题顶」是 63px，× 1.27 ≈ 80px。 */
.org-group + .org-group {
  margin-top: 5rem;
}

/* 分组标题。设计稿里中文每字墨迹宽 24px（÷ 0.95 得字号 25.3）× 1.27 ≈ 32。
   和客户静态站里 /about 那种写死的 32px 区块标题正好是同一档。 */
.org-group-title {
  margin-bottom: 2.25rem;
  font-size: 32px;
  font-weight: 500;
  line-height: 1.2;
  letter-spacing: -0.01em;
}

/* 横幅本身。纵向居中 —— 设计稿里字标的中心落在横幅正中（偏 3px）。 */
.org-banner {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  aspect-ratio: 16 / 10;   /* 设计稿 421.5 × 268 ≈ 1.57，和原来的 aspect-[16/10] 同档 */
}

/* 紫红：主办方 + 合作伙伴 */
.org-banner--violet {
  background: linear-gradient(150deg, #8651af 0%, #4c0d1e 100%);
}
/* 绿：承办方 */
.org-banner--green {
  background: linear-gradient(150deg, #8db459 0%, #184d33 100%);
}

/* 字标。设计稿字高 16px ÷ 0.72（大写字母高度比）× 1.27 ≈ 28。
   窄屏会缩，不然 15 个字带字距在 375 的手机上会顶到边。 */
.org-banner__mark {
  font-size: clamp(16px, 2.4vw, 28px);
  font-weight: 500;
  letter-spacing: 0.12em;
  /* 不是纯白：设计稿量到字标的**亮度**只有 195/255，纯白是 244。
     按背景亮度反推，相当于白色 0.68 不透明度。（色相不可信 —— 截图是
     有损压缩的，细笔画的色度被背景平均掉了，两行字量出来都是中性灰。）*/
  color: rgba(255, 255, 255, 0.68);
}

/* 日期。设计稿里它不在字标正下方，而是贴着横幅**底部**，居中。
   （字标在正中，两者之间是一大段空 —— 这是设计稿的样子，不是漏了对齐。）
   40px 不是直接量出来的：设计稿量到的是「日期的墨迹下沿距横幅底 37px」
   （× 1.27 = 47px），而 bottom 定位的是**行盒**，行盒比墨迹高约 7px，
   所以要再往下让 8px。 */
.org-banner__date {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 2.5rem;
  text-align: center;
  font-size: clamp(12px, 1.55vw, 18px);
  letter-spacing: 0.15em;
  color: rgba(255, 255, 255, 0.5);   /* 同上一行：按亮度反推约 0.46，笔画细、
                                        实测偏暗，取 0.5 */
}
