/* ============================================================================
   鸣山机械官网 · 在线提交表单组件样式（全站唯一真源）
   file: static/css/ms-form.css      新增日期：2026-09-23
   ----------------------------------------------------------------------------
   使用方：只有 view/pc/form.html 与 view/m/form.html 这一个组件。
   全站所有「在线提交」入口都是它 —— 产品详情、案例详情、新闻详情、新闻列表、
   通用单页、联系我们、服务与支持。外观基准 = 服务与支持栏目的询盘表单。

   【为什么要有这个文件】
   改造前，同一个组件在 6 个位置出现 4 种长相，皮肤还散落在两处、且都不完整：
     · ms-svc.css 把皮肤锁在 .ms-sv-formcard 下 —— 只有服务与支持栏目的模板加载
       ms-svc.css，案例/新闻/联系我们/产品页拿不到。直接后果：人机验证的输入框与
       码图**上下错行**（浏览器实测 capRowDisplay:block、capGap:-331，码图被挤到
       输入框下方、左侧空出 331px），附件控件完全没有样式；
     · ms-case.css 的 .ms-cs-cta 只覆盖案例页；
     · 产品详情页另起炉灶自建 .ms-dform / .ms-mdform，字段比别处少（没有客户邮箱、
       所属行业、图纸附件），而且**没有验证码字段** —— 服务端自 2026-09-23 起是
       无条件校验人机验证的，等于产品页询盘一直提交不成功。
   本文件把皮肤收口成一处，并在 view/{pc,m}/head.html 全站加载，以上问题一并消失。

   【为什么组件要自带深色底衬 .ms-fc】
   site.css 的 .ms-card 是**白底卡**（background:#fff、文字深蓝），.ms-input 同样是
   白底深字。而服务与支持这一版表单整套控件是深色的（输入框 rgba(6,20,36,.55)、
   文字 #EAF2FA），只有放在深色底上才成立。若沿用 .ms-card，浅色页（联系我们 /
   新闻）就会出现「近白色标签压在白色卡面上」的不可读组合。
   所以组件自己带一层深色底衬，不再依赖所在页面的底色 ——
   深色页（服务与支持 / 案例）与浅色页（联系我们 / 新闻）看到的表单完全一致。

   【工程约束（都是踩过的坑）】
   1. 本文件必须在 site.css **之后**加载。head.html 里排在 ms-case.css 之后，
      靠源码顺序压过 site.css 的同权重原子类：site.css 的
      `.ms-input.is-error{background-color:hsla(0,83%,98%,.4)}` 是 (0,2,0)，
      与本文件的 `.ms-fc .ms-input` (0,2,0) 同权，后出现者胜 ——
      否则输入框一旦报错就会变成一块接近白色的底板。
   2. 颜色只用 ms-case.css 顶部 :root 的既有令牌，不新增色值。
   3. 禁止把规则写进 @media：一旦落进媒体查询，桌面端整块失效
      （本项目踩过；定位脚本里的 depth_at() 就是为此写的）。
   4. 禁止在 HTML 属性里写 `{:(...) }` 形式的三元表达式：本模板引擎对**以左括号
      开头**的 {:...} 不解析，会把原文当字符串输出到页面上（改造前
      data-ms-variant 与 type 两个属性就是这么漏出去的，全站每页 2 处）。
      需要条件属性一律用 {if}{else/}{/if}，或改用 `{$var|default=xx}`。
   ========================================================================== */

/* ---------- 组件根：自带深色底衬，脱离页面底色 ---------- */
.ms-fc {
  /* 必须 hidden：内部卡头是整块实心色，不裁会把直角顶出圆角 */
  overflow: hidden;
  border-radius: .625rem;                     /* 与原 .ms-card 的 10px 保持一致 */
  background: #132134;                        /* = rgba(255,255,255,.045) 叠在深蓝页底上的实测等效色 */
  border: 1px solid var(--ms-line, rgba(122, 168, 214, .17));
  box-shadow: var(--ms-sh-2, 0 18px 40px -22px rgba(0, 0, 0, .85));
}
/* 卡头（深色带）。site.css 的 bg-ink-900 已经给了同色，这里兜底，
   保证即使某个页面没加载 site.css 也不会变成白底黑字。 */
.ms-fc > .bg-ink-900 { background: var(--ms-ink-900, #0B1E33); }

/* ---------- 输入控件：白底原子类 → 深色 ---------- */
.ms-fc .ms-input {
  background-color: rgba(6, 20, 36, .55);
  border-color: var(--ms-line, rgba(122, 168, 214, .17));
  color: var(--ms-text, #EAF2FA);
}
.ms-fc .ms-input::placeholder { color: rgba(234, 242, 250, .34); }
.ms-fc .ms-input:hover { border-color: var(--ms-line-strong, rgba(122, 168, 214, .34)); }
.ms-fc .ms-input:focus,
.ms-fc .ms-input.is-error:focus {
  border-color: var(--ms-link, #8FC4EC);
  outline: none;
  box-shadow: 0 0 0 3px rgba(143, 196, 236, .14);
}
/* 下拉展开项走浏览器原生弹层、不带页面背景，必须显式给深色，否则白底白字 */
.ms-fc .ms-input option { background: var(--ms-ink-900, #0B1E33); color: #EAF2FA; }
/* 报错态：site.css 的 .ms-input.is-error 会把底色刷成近白，这里压回深色 */
.ms-fc .ms-input.is-error {
  background-color: rgba(6, 20, 36, .55);
  border-color: var(--ms-accent-soft, #F2B7BC);
}
/* 标签与错误文案：site.css 里是按白底页选的深蓝字 / 纯红字，深底上读不出来。
   品牌红 #C81E2D 在深底上只有 2.97:1，必须换成 --ms-accent-soft（10.0:1）。 */
.ms-fc .ms-label { color: var(--ms-text-soft, rgba(234, 242, 250, .78)); }
.ms-fc .ms-label .req { color: var(--ms-accent-soft, #F2B7BC); }
.ms-fc .ms-err.is-show { color: var(--ms-accent-soft, #F2B7BC); }

/* ---------- 图纸 / 技术附件 ---------- */
.ms-file {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 9px 12px;
  border: 1px dashed var(--ms-line-strong, rgba(122, 168, 214, .34));
  border-radius: var(--ms-r-sm, 8px);
  background: rgba(6, 20, 36, .42);
}
.ms-file input[type=file] {
  flex: 1;
  min-width: 0;
  font-size: 12.5px;
  color: var(--ms-text-dim, rgba(234, 242, 250, .62));
}
.ms-file input[type=file]::file-selector-button {
  margin-right: 10px;
  height: 28px;
  padding: 0 12px;
  border: 1px solid var(--ms-line-strong, rgba(122, 168, 214, .34));
  border-radius: 6px;
  background: rgba(255, 255, 255, .05);
  color: var(--ms-text, #EAF2FA);
  font-size: 12.5px;
  font-weight: 600;
  cursor: pointer;
}
.ms-file__tip {
  margin: 6px 0 0;
  font-size: 11.5px;
  line-height: 1.7;
  color: var(--ms-text-faint, rgba(234, 242, 250, .5));
}

/* ---------- 人机验证：全站统一「输入框 + 码图」同一行 ----------
   码图由 GD 生成、底色是浅色（#F5F7FA），在深色卡面上是一块正常的高对比白板；
   输入框仍走深色。两者同一行、间距 9px，与设计规范一致。
   注意：这两个类**故意不锁在 .ms-fc 内** —— 它们是唯一需要在任何背景下都成立的
   排版规则（同排、固定 104×40），组件已经被 .ms-fc 包住，不需要再收窄。 */
.ms-caprow { display: flex; align-items: center; gap: 9px; }
.ms-caprow .ms-input { flex: 1; min-width: 0; letter-spacing: .18em; text-transform: uppercase; }
.ms-capimg {
  flex: 0 0 auto;
  width: 104px;
  height: 40px;
  border: 1px solid rgba(122, 168, 214, .34);
  border-radius: 7px;
  background: #F5F7FA;
  cursor: pointer;
  object-fit: cover;
}

/* ---------- 隐私承诺 ---------- */
.ms-formnote {
  margin: 12px 0 0;
  text-align: center;
  color: var(--ms-text-faint, rgba(234, 242, 250, .5));
}

/* ---------- 提交结果提示条 ----------
   site.js 会给它写 `bg-emerald-50 text-emerald-700 border-emerald-200` 这类
   **浅色**底 + 深色字，在深色卡面上是一块突兀的白斑。
   用同名工具类提权覆盖成半透深色调（只改颜色，尺寸/圆角沿用 site.js 给的）。 */
.ms-fc [data-ms-form-msg] { border-radius: 8px; }
.ms-fc [data-ms-form-msg].bg-emerald-50 {
  background: rgba(22, 163, 74, .16);
  border-color: rgba(22, 163, 74, .38);
  color: #9BE3B4;
}
.ms-fc [data-ms-form-msg].bg-brand-50 {
  background: rgba(200, 30, 45, .18);
  border-color: rgba(200, 30, 45, .38);
  color: var(--ms-accent-soft, #F2B7BC);
}

/* ============================================================================
   Phase W 新增：手机/座机切换、省-市-县三级联动、非国内自填、字数与频次提示
   ----------------------------------------------------------------------------
   ⚠⚠ 这里有一个**必踩的坑**，写之前先看清楚：
     下面给 `.ms-phonepane` / `.ms-region3` / `.ms-region-overseas` 设了
     display:flex / grid。而这三块靠 HTML 的 `hidden` 属性做显隐切换，
     `hidden` 的默认样式是 UA 样式表里的 `[hidden]{display:none}`，
     权重只有 (0,1,0) —— **任何**给同一元素写的 display 都会把它压掉，
     结果是「隐藏的面板其实一直显示着」，而且完全不报错。
     所以必须显式补一条 [hidden] 规则，并用 !important 兜住
     （否则就要靠源码顺序取胜，属于一改就坏的脆弱写法）。

     ⚠ 注意**不要**偷懒写成 `.ms-phonepane{display:none}` 再在别处打开：
     默认可见的「手机」面板与「国内三级」面板都没有 hidden 属性，
     那样写会把它们一起藏掉（这类错误在 HTML 里完全看不出来）。
   ========================================================================== */
.ms-phonerow[hidden],
.ms-phonepane[hidden],
.ms-region3[hidden],
.ms-region-overseas[hidden] { display: none !important; }

/* ---------- 手机 / 座机 单选 ---------- */
.ms-phonerow {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 9px;
}
.ms-radio {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  height: 34px;
  padding: 0 13px;
  border: 1px solid var(--ms-line, rgba(122, 168, 214, .17));
  border-radius: 9999px;
  font-size: 13px;
  font-weight: 600;
  line-height: 1;
  color: var(--ms-text-dim, rgba(234, 242, 250, .62));
  cursor: pointer;
  transition: color 180ms ease, border-color 180ms ease, background-color 180ms ease;
  /* 触控友好：移动端整块可点，不需要精确戳中那个小圆点 */
  user-select: none;
}
.ms-radio:hover { color: var(--ms-text, #EAF2FA); border-color: var(--ms-line-strong, rgba(122, 168, 214, .34)); }
.ms-radio input[type=radio] {
  flex: 0 0 auto;
  width: 15px;
  height: 15px;
  margin: 0;
  accent-color: var(--ms-brand, #C81E2D);   /* 原生控件染色，无需自绘 */
  cursor: pointer;
}
/* 选中态：:has 已在 Chromium 105+/Safari 15.4+/Firefox 121+ 全量支持，
   页面本身用了 IntersectionObserver/MutationObserver，目标浏览器基线一致。 */
.ms-radio:has(input:checked) {
  color: #fff;
  border-color: var(--ms-brand, #C81E2D);
  background: rgba(200, 30, 45, .18);
}

/* ---------- 座机：区号 - 号码 ---------- */
.ms-phonelintwo {
  display: flex;
  align-items: center;
  gap: 8px;
}
.ms-phonelintwo .ms-input { min-width: 0; }
/* 区号框宽度固定，号码框吃掉剩余空间 —— 座机号码比区号长得多。
   Phase Y：区号从「裸 input + datalist」换成自绘选择器，外层多了一层
   .ms-ac（position:relative 的定位容器）。flex 宽度要挂在容器上，
   挂在里面的 input 上是没用的（wrapper 默认宽度按内容撑）。 */
.ms-phonelintwo .ms-ac { flex: 0 0 118px; min-width: 0; position: relative; }
.ms-phonelintwo .ms-ac .ms-input { width: 100%; text-align: left; }
.ms-phonelintwo input[name="phone_no"] { flex: 1 1 auto; }
.ms-phonesep {
  flex: 0 0 auto;
  font-size: 15px;
  font-weight: 700;
  color: var(--ms-text-dim, rgba(234, 242, 250, .62));
}

/* ---------- 所在地区：省 / 市 / 区县 ----------
   Phase Y 修正（客户 2026-09-23 报障：「选完省市后，区县掉到第二行」）：

   旧写法是 auto-fit + minmax(132px,1fr) —— 本意是「宽屏一行三个、窄屏自动掉行」。
   但实测手机端（390px 视口，表单 p-4 内边距后可用宽 358px）：
       132 × 3 列 + 2 × 8 gap = 412px > 358px  →  只能放 2 列  →  第三个必换行。
   这不是「自动适配」，是**必然掉行**，而且宽屏（PC 的窄侧栏同样只有 ~360px）也一样。

   改法：恒定三列 + minmax(0,1fr)。minmax 的下界写 0 而不是某个像素值，
   否则列宽下界会撑破容器；配合把占位文案从「请选择省 / 直辖市」（9 字）
   缩到「请选择省份」（5 字），100px 出头的单元格也不会截断。
   ⚠ 本文件禁止用 @media（见文件头第 3 条），所以只能靠「恒三列 + 短文案」这条路。 */
.ms-region3 {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 6px;
  margin-top: 9px;
}
/* 三列之后每格只有 ~110px：横向内边距压到最小，右侧留 20px 给原生下拉箭头，
   否则箭头会压在「区县」两个字上面。 */
.ms-region3 .ms-input {
  min-width: 0;
  padding-left: 6px;
  padding-right: 20px;
  font-size: 12.5px;
  text-overflow: ellipsis;
}
.ms-region-overseas { margin-top: 9px; }
/* country 下拉与三级下拉之间留出呼吸，避免看起来像一个控件组 */
.ms-fc select[data-ms-country] { margin-bottom: 0; }

/* ---------- 需求描述字数提示 ---------- */
.ms-charhint {
  margin: 5px 0 0;
  text-align: right;
  font-size: 11.5px;
  font-variant-numeric: tabular-nums;
  color: var(--ms-text-faint, rgba(234, 242, 250, .5));
}
.ms-charhint.is-near { color: var(--ms-accent-soft, #F2B7BC); }
/* Phase Y：需求描述改成「15 ~ 1000 字」后，字数提示要能表达「还差多少」
   （低于下限 = 红），而不只是「快满了」 */
.ms-charhint.is-short { color: var(--ms-accent-soft, #F2B7BC); }
.ms-charhint.is-over { color: var(--ms-accent-soft, #F2B7BC); font-weight: 700; }
/* 字段级字数要求提示（称呼 / 公司名称 / 需求描述下方那行小字） */
.ms-lenhint {
  margin: 5px 0 0;
  font-size: 11.5px;
  line-height: 1.7;
  color: var(--ms-text-faint, rgba(234, 242, 250, .5));
}

/* ---------- 提交频次与时间限制说明 ---------- */
.ms-formlimit {
  margin: 10px 0 0;
  text-align: center;
  line-height: 1.75;
  color: var(--ms-text-faint, rgba(234, 242, 250, .5));
}
.ms-formlimit b {
  font-weight: 700;
  color: var(--ms-text-dim, rgba(234, 242, 250, .62));
}

/* ============================================================================
   Phase Y 新增：区号选择器（自绘下拉，取代原生 datalist）
   ----------------------------------------------------------------------------
   客户 2026-09-23 报障：
     「手机端的区号，不容易显示出来；PC 端必须把已输入的区号删掉，且鼠标要
       指向选择框的一个符号，才能弹出来」

   根因：原实现 `<input list="ms-areacodes">` + `<datalist>`。
   datalist 的两个硬伤都是浏览器行为，改 CSS/JS 参数救不回来：
     ① 只要输入框里已有字符，浏览器就把候选**前缀过滤**成「看起来没弹出」；
     ② 触屏端只有点中框内最右侧那个极小的三角才展开，命中率极低。

   所以改为自绘面板。两个关键设计：

   【1】面板挂在 <body> 上、用 position:fixed
     表单卡片 .ms-fc 是 overflow:hidden；表单还可能被外层 sticky 侧栏、
     带 transform 的容器包着。绝对定位的面板会被**任意一层**祖先裁掉或
     盖住，而且这类问题在 HTML 里完全看不出来。
     挂 body + fixed 一次性绕开所有裁剪与层叠上下文，代价只是滚动/缩放时
     重算一次位置（见 site.js 的 acPlace）。

   【2】点击/聚焦 = 全量弹出，输入才过滤
     这正是客户的核心诉求：不再需要「先删掉已输入的内容」。

   ⚠ 面板在 .ms-fc 之外，所以这里**不能**用 `.ms-fc xxx` 前缀选择器；
     颜色令牌来自 ms-case.css 顶部的 :root，全局可用，仍带 fallback。
   ⚠ [hidden] 必须用 !important 兜住，理由同文件前面 156-179 行那段说明。
   ========================================================================== */
.ms-ac { position: relative; }
/* 右侧给展开按钮让出 30px，否则文字会压在箭头上 */
.ms-ac .ms-input { padding-right: 30px; }
.ms-ac__btn {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  width: 30px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 0;
  background: transparent;
  cursor: pointer;
  color: var(--ms-text-dim, rgba(234, 242, 250, .62));
}
.ms-ac__btn:hover { color: var(--ms-text, #EAF2FA); }
.ms-ac__btn svg {
  width: 14px;
  height: 14px;
  transition: transform .15s ease;
}
.ms-ac.is-open .ms-ac__btn { color: var(--ms-text, #EAF2FA); }
.ms-ac.is-open .ms-ac__btn svg { transform: rotate(180deg); }

.ms-ac__panel {
  position: fixed;
  z-index: 9999;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  border-radius: 10px;
  background: #0F1F33;
  border: 1px solid var(--ms-line-strong, rgba(122, 168, 214, .34));
  box-shadow: 0 22px 48px -18px rgba(0, 0, 0, .9);
}
.ms-ac__panel[hidden] { display: none !important; }
.ms-ac__hd {
  flex: 0 0 auto;
  padding: 8px 12px;
  font-size: 11.5px;
  line-height: 1.6;
  color: var(--ms-text-faint, rgba(234, 242, 250, .5));
  border-bottom: 1px solid var(--ms-line, rgba(122, 168, 214, .17));
}
.ms-ac__list {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  padding: 4px;
}
.ms-ac__it {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 40px;              /* 触屏友好：≥40px 命中区 */
  padding: 7px 10px;
  border-radius: 6px;
  cursor: pointer;
  font-size: 13px;
  color: var(--ms-text, #EAF2FA);
}
.ms-ac__it b {
  flex: 0 0 auto;
  min-width: 46px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  color: var(--ms-accent-soft, #F2B7BC);
}
.ms-ac__it span {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--ms-text-soft, rgba(234, 242, 250, .78));
}
.ms-ac__it.is-on,
.ms-ac__it:hover { background: rgba(200, 30, 45, .18); }
.ms-ac__none {
  padding: 12px;
  font-size: 12.5px;
  line-height: 1.7;
  color: var(--ms-text-faint, rgba(234, 242, 250, .5));
}
