@charset "utf-8";
/* ==============================================================================
   AI双获客 · 共用样式层  base.css
   建立：2026-09-16  |  目的：全站「地基」—— 设计令牌 + 全局基础 + 移动端适配
   ------------------------------------------------------------------------------
   【挂载】<link rel="stylesheet" href="/static/base.css">
           位置：模板 <head> 内、模板自带 <style> **之后**（靠后加载才能盖住它）
           路由：/static/ → geo_saas/assets/（app.py:572 已支持，零架构改动）

   【断点约定】只用两个（= 现有 21/18 个模板的事实标准）
           820px —— 手机 / 平板界线
           520px —— 手机竖屏

   【★ 分层策略（重要，别改）】
     ① 设计令牌放 @layer base ⇒ **低优先级**
        原因：studio.html 是**暗色主题**模板（--bg:#0f172a / --ink:#e2e8f0），
              它自带的 :root 必须能盖住这里的亮色默认值，否则整页会变白。
        未分层的样式优先级 > 分层样式 ⇒ 模板的 :root 自动赢。
     ② 修复类规则（全局基础 / 移动端）**不分层** ⇒ 高优先级
        原因：要能盖住 27 个模板各自 @media 里的 `.main-nav{flex-wrap:nowrap;overflow-x:auto}`。
     ③ 降级：不支持 @layer 的老浏览器会整块忽略 ①（令牌失效），
        但 ② 仍生效 ⇒ 不会"越修越坏"。

   【设计原则】只写「全站通治」的规则，不写任何页面特有样式。
   ============================================================================== */

/* ------------------------------------------------------------------------------
   1. 设计令牌
   值 = 实测统计出的**事实标准**（11~14 个模板已一致沿用），故对多数页面零观感变化。
   ------------------------------------------------------------------------------ */
@layer base {
  :root {
    /* 色 —— 主色/强调（--brand 13 模板一致） */
    --brand:    #2563eb;
    --brand-h:  #1d4ed8;
    --brand-d:  #1e40af;
    --brand-bg: #eff6ff;
    /* 色 —— 文字/线条/底 */
    --ink:      #1c2430;
    --mut:      #64748b;
    --line:     #e6eaf0;
    --bg:       #f4f6f9;
    --card:     #ffffff;
    /* 色 —— 语义 */
    --ok:       #059669;  --ok-bg:     #ecfdf5;
    --warn:     #d97706;  --warn-bg:   #fffbeb;
    --danger:   #dc2626;  --danger-bg: #fef2f2;
    /* 圆角（原 22 种取值收敛为 4 档） */
    --r-sm: 8px;  --r-md: 12px;  --r-lg: 16px;  --r-pill: 999px;
    /* 阴影 */
    --sh-1: 0 1px 2px rgba(15,23,42,.04), 0 2px 10px rgba(15,23,42,.05);
    --sh-2: 0 4px 14px rgba(15,23,42,.08), 0 10px 28px rgba(15,23,42,.10);
    /* 动效 */
    --tr: .15s ease;
    /* 字体栈（原 4 种写法，统一为这一种；本批**不强制**应用到 body，见 §2） */
    --font: -apple-system, BlinkMacSystemFont, "Segoe UI", "Noto Sans SC",
            "PingFang SC", "Microsoft YaHei", sans-serif;
  }
}

/* ------------------------------------------------------------------------------
   2. 全局基础（不分层 = 高优先级，只做低风险「兜底」）
   ------------------------------------------------------------------------------ */
/* box-sizing：30/30 模板已声明 border-box，此处固化为全站约定 */
*, *::before, *::after { box-sizing: border-box; }

/* 移动端字号自动放大（iOS 横屏）防护 */
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }

/* ★ 长串（URL / 英文 / 订单号）不撑破容器
   —— 治 /baike（参考资料里的长 URL，实测溢出 64px）
        /deploy（实测溢出 74px）
   用 anywhere 而非 break-word：前者参与 min-content 计算，
   能让 flex/grid 子项正确收缩。 */
body { overflow-wrap: anywhere; }

/* 媒体不溢出 */
img, video, canvas { max-width: 100%; }

/* ------------------------------------------------------------------------------
   2.5 主导航组件（2026-10-23 · 老王拍板「乙 · 一次收编」）

   【为什么要这一段】
     导航的 **HTML 早已单点**（`db.py: nav_html()` → `__NAV__`），**样式却不是**：
     24 个后台模板各拷了一份 `.main-nav` 样式块 —— 实测 **477 个规则块 / 47,322 字节 / ≈1,500 行**，
     已经漂出：两版圆角、一版缺 `.drop.open`、三版缺子项高亮、`min-width` 170/200、
     `z-index` 40/60/99、`drop-menu` 一页 `display:block`。
     ⇒ 改一次页头要改 24 处，且**没有任何判据守得住**（`_verify_sitewide` 只看 base.css 自己）。

   【本段的身份】页头导航的**唯一权威**。
     模板里那些拷贝**已在本批全部删除**（只保留 3 类页面特化，见 §2.5.5）。
     **以后改导航 ＝ 只改这里。**

   【布局口径】老王 2026-10-23 定：
     ① **拼接卡**：页头（上圆下直）＋ 导航（上直下圆）＝ 连成一张卡。
        13 页原本就是这样，另外 8 页「浮条」向它对（浮条 = 导航 `margin-top:-8px` 压在页头下沿）。
     ② **电脑版与手机版分开写**：本节 = **桌面端（>820px）**；
        手机端在 §3.1（换行 + 紧凑 + 字号降档），两段互不干扰。

   【取值依据】全部取 24 页的**事实众数**，不是新设计：
     `background:#fff` 24/24 · `padding:10px 14px` 24/24 · `gap:6px` 24/24 ·
     `a` 13px / 8px 13px / 圆角 10px 24/24 · `drop-menu` min-width 200 23/24 …
   ------------------------------------------------------------------------------ */

/* ============ 2.5.1 条本体（桌面端） ============ */
.main-nav {
  background: #fff;
  border-radius: 14px;                        /* 默认＝独立卡；紧跟页头时由 §2.5.4 改成拼接 */
  box-shadow: 0 2px 10px rgba(0,0,0,.05);
  padding: 10px 14px;
  margin: 0 0 20px;
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  align-items: center;
}

/* ============ 2.5.2 一级入口 ============ */
.main-nav a {
  font-size: 13px; font-weight: 600; color: #475569;
  padding: 8px 13px; border-radius: 10px;
  text-decoration: none;
}
.main-nav a:hover { background: #f1f5f9; }
.main-nav a.on    { background: #2563eb; color: #fff; }

.main-nav .sep { width: 1px; height: 20px; background: #e2e8f0; margin: 0 4px; }

.main-nav .group   { display: flex; align-items: center; gap: 4px;
                     font-size: 13px; color: #94a3b8; padding: 8px 6px; font-weight: 700; }
.main-nav .group a { font-weight: 600; }
.main-nav .user    { margin-left: auto; color: #2563eb; font-weight: 700; }

/* ============ 2.5.3 下拉（🏠 我的企业 / ⚙️ 后台管理） ============ */
.main-nav .drop { position: relative; }

.main-nav .drop-sum {
  font-size: 13px; font-weight: 600; color: #475569;
  padding: 8px 13px; border-radius: 10px;
  cursor: pointer; list-style: none; user-select: none;
}
.main-nav .drop-sum::-webkit-details-marker { display: none; }
.main-nav .drop-sum::after { content: "▾"; font-size: 10px; margin-left: 4px; opacity: .7; }
.main-nav .drop-sum.on { background: #2563eb; color: #fff; }

.main-nav .drop-menu {
  display: none;
  position: absolute; top: 100%; margin-top: 6px; left: 0;
  background: #fff; border: 1px solid #e2e8f0; border-radius: 12px;
  box-shadow: 0 8px 24px rgba(15,23,42,.12);
  padding: 6px; min-width: 200px; z-index: 40;
  flex-direction: column; gap: 2px;
}
/* ★三个打开出口，缺一条就有一类设备点不开：
     hover  = 桌面鼠标
     focus-within = 键盘 Tab / 老式触屏的模拟焦点
     .open  = **触屏点击**（drop_js 给 .drop 加这个类）—— 手机没有 hover，全靠它 */
.main-nav .drop:hover .drop-menu,
.main-nav .drop:focus-within .drop-menu,
.main-nav .drop.open .drop-menu { display: flex; }

.main-nav .drop-menu a {
  padding: 9px 14px; border-radius: 8px; font-size: 13px; white-space: nowrap;
}
.main-nav .drop-menu a:hover { background: #f1f5f9; }
.main-nav .drop-menu a.on    { background: #eff6ff; color: #2563eb; }

/* ============ 2.5.4 ★拼接卡（老王定 ①）============
   有页头的页面：页头改「上圆下直」、导航改「上直下圆」、导航上边距归零 ⇒ 两块连成一张卡。
   ★两条排除，缺一条就出事：
     · `.hero`    —— 官网产物 `output/<slug>/site.html` 的正文，动它＝改坏老板的官网
     · `.hd-flat` —— studio 的暗色单行页头（零内边距）。它靠 `.fx-top` 的暗色底自成一体，
                     硬拼会在暗底上露出两个亮圆角 ⇒ 让它留在 §2.5.1 的独立卡形态。
   ★没有页头的页面自然不吃这条 ⇒ 保持独立全圆卡，那正是它们该有的样子（/result、/geo_result）。
   ★`/points` 的导航在 `<header>` **之前**（全站唯一），也吃不到这条 —— 保持独立卡，正确。 */
header:not(.hero):not(.hd-flat) { border-radius: 16px 16px 0 0; }
header:not(.hero):not(.hd-flat) + .main-nav {
  border-radius: 0 0 16px 16px;
  margin-top: 0;
}

/* ============ 2.5.5 `.fx-top` 包裹层：导航贴住包裹层底部 ============
   `.fx-top` 是「页头 + 导航」粘成一体的 sticky 容器（它自己 `padding-bottom:16px` 负责
   与下方内容的留白）。故里面的导航必须 `margin:0`，否则会**多出一截 20px 的松缝**。
   ★这条在收编前是 14 个模板各写一遍（`margin:0` 或 `margin-bottom:0`），实测**无一例外**
     —— 属通用规律，不是页面特化，故收进本组件，模板里的同名规则一并删除。 */
.fx-top .main-nav { margin: 0; }

/* ============ 2.5.5b ★导航吸顶（2026-10-27 老王「有几个页导航没固定，随屏幕翻上去就没了」）============
   病根：吸顶是**每个模板各写一份**（14 份都在 `.fx-top` 里写 position:sticky / top:0 / z-index:50），
     另有 **12 个有导航的页面根本没包 `.fx-top`** ⇒ 一滚就没：
     backup / comp_rip / console / deploy / geo_result / help / points /
     prod_images / proposals / result / result_video / terms。
   修法：规则下沉到组件层，一处通治 ——
     · 默认：`.main-nav` 自己 sticky 贴顶（覆盖那 12 个裸导航页，模板零改动）；
     · 有 `.fx-top` 的页面：容器已负责吸顶，内层 nav 强制 static
       （双层 sticky 会互相拉扯，滚动时抖）。
   ⚠️ 两个前提已核对（不核对会静默失效）：
     ① 祖先不能有 `overflow`（hidden/auto 都会让 sticky 哑掉）—— 实测 `html`/`body`/`.wrap` 都没有；
     ② 官网产物 `output/<slug>/site.html` **不含** `.main-nav`（3 份全扫，0 命中）
        ⇒ 改这里动不到老板对外的网站。 */
.main-nav {
  position: sticky;
  top: 0;
  z-index: 50;
}
.fx-top .main-nav {
  position: static;      /* 由 `.fx-top` 容器吸顶，内层不再重复吸 */
  z-index: auto;
}

/* ============ 2.5.6 暗色页的导航换底（body.dark-nav）============
   用于暗色主题页面（`/result_video` 成片播放页，背景 `#0f172a`）。
   白底导航放到暗色页上像贴了一张白纸，故给一个**修饰类**：页面 `<body class="dark-nav">`。
   ★颜色全部取自该页既有配色（#111c33 / #1e293b / #cbd5e1），**不新造色**。
   ★模板只加一个 class 名，不写任何 `.main-nav` 规则 —— 判据盯的就是这条。 */
body.dark-nav .main-nav {
  background: #111c33;
  border: 1px solid #1e293b;
  box-shadow: none;
}
body.dark-nav .main-nav a,
body.dark-nav .main-nav .drop-sum,
body.dark-nav .main-nav .group { color: #cbd5e1; }
body.dark-nav .main-nav a:hover,
body.dark-nav .main-nav .drop-menu a:hover { background: #1e293b; }
body.dark-nav .main-nav a.on,
body.dark-nav .main-nav .drop-sum.on { background: #2563eb; color: #fff; }
body.dark-nav .main-nav .sep { background: #1e293b; }
body.dark-nav .main-nav .drop-menu {
  background: #111c33;
  border-color: #1e293b;
  box-shadow: 0 8px 24px rgba(0,0,0,.5);
}
body.dark-nav .main-nav .drop-menu a { color: #cbd5e1; }
body.dark-nav .main-nav .drop-menu a.on { background: #17294d; color: #93c5fd; }
/* 2026-10-29：原 `body.dark-nav .main-nav::after`（暗色页横滚渐隐条底色）随 §3.1 横滚一起删除
   —— 伪元素的 `content` 定义已撤，留着这条只是死代码，会让人以为右侧还有渐隐条。 */

/* ============ 2.5.7 刻意留在模板里的特化（不是漏删） ============
   · `body.mode-ai .main-nav …`（studio 紫色主题，8 条）—— 换底色，不是重复；
     它们依赖本组件的基础规则，删了就会在紫色主题下露出白底导航
   · 各页 `header` 的渐变 / 内边距 / 字号 —— 那是页头，不是导航
   ⇒ 判据 `tests/_verify_nav_consistency_20261023.py` 会盯住「模板里不许再出现 nav 拷贝」：
      除 `body.mode-…` 与 `.fx-top .main-nav` 之外，多一条都会红。 */

/* ------------------------------------------------------------------------------
   3. 移动端底座（≤820px）
   ------------------------------------------------------------------------------ */
@media (max-width: 820px) {

  /* ---- 3.1 ★ 主导航：一行细条（2026-10-29 三次修订）
     演进三口：
       · 10-27「8 项导航单行横滚」：`nowrap` + `overflow-x:auto` + `overflow-y:hidden`
         + 右侧 `::after` 渐隐条 —— 目标是让 8 项只占 ~40px。
       · 10-29 二次修订：8 项整体撤掉，细条只剩「品牌名 + 后台管理▾ + 用户名▾」，
         于是把横滚拆了、改成 `flex-wrap: wrap`。结果手机上三项加起来比屏宽宽一点点
         ⇒ 用户区被挤到**第二行**，导航条凭空高一倍（首屏更挤）。
       · 10-29 三次修订（本版）：**要一行，但不要横滚**。做法是让三项里唯一"可让"的
         品牌名去让 —— `flex: 1 1 auto` + `min-width: 0` + 省略号，其余项 `0 0 auto`
         一格不让。空间够就整句显示，不够就截断，**永不换行、永不溢出屏**。

     ⚠️ **必须 `overflow: visible`**：`overflow-x:auto`（或任何非 visible 值）会让另一轴
     的 `visible` 按 `auto` 处理 —— `.ud-sum` 的下拉面板是 `.main-nav` 的绝对定位后代，
     于是被容器裁掉：**点得开、看不见**，用户只会说「点了没反应」。这是 10-27 那版的病根。
     ⇒ 判断标准是「**一行且不裁**」：`nowrap` 可以，`overflow-x:auto` 绝不行。
     ⚠️ 本文件是 nav 样式的**唯一权威**（§2.5 桌面 + §3.1 手机）：它的 `<link>`
     位于各模板内联 `<style>` **之后**，同特异性下以本文件为准 ——
     所以在模板里改 `.main-nav` 不会生效，必须改这里。 */
  .main-nav {
    flex-wrap: nowrap;              /* ★ 一行到底：细条只有 3 项，不吃第二行 */
    overflow: visible;              /* ★ 不许改：改成 auto/hidden 会裁掉下拉面板 */
    padding: 5px 9px;
  }
  /* 品牌名＝**不受压**的那一项：`0 0 auto` 一格不让。
     ★上一版写成 `flex: 1 1 auto`（可缩）是错的 —— 用户名注册填的是**公司全名**
     （实测 11~16 字），`.ud-sum` 又会吃满 `max-width`，于是品牌名被压到 20 几像素、
     只剩一个「知」字。现在反过来：**宁让用户名截断，也不让品牌名缺字**。
     `min-width:0` 保留只为 ellipsis 生效（真到极窄屏它仍然能靠省略号收尾，而不是溢出）。 */
  .main-nav > a.brand {
    flex: 0 0 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  .main-nav > a,
  .main-nav .drop-sum,
  .main-nav .ud-sum {
    white-space: nowrap;          /* ★ 治「竖排单字」 */
    font-size: 11.5px;
    padding: 5px 8px;
    border-radius: 7px;
    flex: 0 0 auto;               /* ★ 不许被压扁 */
  }
  /* 长企业名截断 —— 用户名框是这排里**唯一允许收窄**的东西。
     `56vw` 太大（375px 屏＝210px，等于把品牌名和后台管理一起挤没了），收到 `40vw`：
     375px 下上限 150px ≈ 「👤 贵州知跃机制…」，够认出是哪家企业；要看全名点开下拉。
     ★`flex: 0 1 auto` ＋ `min-width: 0`：375px 用不到收缩（总需求约 302px < 可用 333px），
     但 320px 一类极窄屏必须能继续缩 —— 缩了是省略号，不缩就是**溢出屏幕**（比缺字更糟）。 */
  .main-nav .ud-sum {
    flex: 0 1 auto;
    min-width: 0;
    max-width: 40vw;
    overflow: hidden;
    text-overflow: ellipsis;
  }
  .main-nav .sep { display: none; }        /* 小屏下竖分隔线纯占位 */
  .main-nav .drop-menu { max-width: calc(100vw - 24px); }  /* 下拉不越界 */

  /* 用户区靠右（品牌名 `flex:0 0 auto` 之后剩的空间由 `margin-left:auto` 吃掉）
     ★`flex: 0 1 auto`：允许**整体收窄**，好让里面的 `.ud-sum` 有空间可缩（见下条） */
  .main-nav .user-drop {
    margin-left: auto !important;
    flex: 0 1 auto;
    min-width: 0;
    display: flex;
  }
  /* 「⚙️ 后台管理」的 `.drop` 是**外层容器**，`0 0 auto` 得给它、不能只给里面的 `.drop-sum`
     —— 否则空间紧张时被压的是外层，文字挤成两行，`.drop-sum` 那几条 `nowrap` 白设。 */
  .main-nav .drop { flex: 0 0 auto; }

  /* ---- 3.2 内容留白收窄（小屏寸土寸金） */
  .wrap { padding-left: 12px; padding-right: 12px; }

  /* ---- 3.3 ★ 表格横滚
     治 /assets 实测溢出 19px（表格直接躺在 .card 里，没有横滚容器）。
     有 .tbl-wrap 包裹的页（如 /console）本就是横滚，此处是双保险。 */
  .tbl-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }

  /* ---- 3.4 ★ 页头小字：移动端隐藏 ----
     问题（375×812 实测）：页头 <h1>+<p> 合计 35~180px，其中小字本身占 36~110px；
       再叠加「换行后的主导航」120~154px ⇒ 顶端两块 = 189~334px = **屏高 23%~41%**，
       首屏看不到任何操作按钮（最差的 /prod_images 到 41%）。
     修法：一处通治 —— 24 个模板都是 `<header><h1>…</h1><p>小字</p></header>` 结构，
       文案**保留在模板里**（桌面端照旧显示），只在手机上藏。
     ⚠️ **必须排除 `.hero`**：官网产物 `output/<slug>/site.html` 里是
       `<header class="hero"><p class="sub">副标题</p>`，且**同样引用了本文件**
       —— 那是官网正文而非「页头小字」，隐藏它 = 改坏老板的官网。
     ⚠️ 收益**不是统一值**（别按一个数估）：实测 /publish /points /media_kit 省 60~63px；
       /sites /geo /effects /monitor /help /assets /baike 省 42~44px；/kb 为 0（header 里没有 <p>）。 */
  header:not(.hero) p { display: none; }

  /* ---- 3.5 ★ 页头收紧（2026-10-16 · 全站通治，原只在 /my_site 一页生效）----
     问题：22 个模板的页头是 `<header>` 渐变条，基础 padding 20px/22px 14px ＋ h1 20px；
       叠加换行后的主导航，顶端两块仍占掉手机首屏的大头。
     修法（只压这三处，不改配色/圆角/结构）：
       页头内边距 → 12px/14px 9px ｜ 页头标题 20 → 17px ｜ `.fx-top` 包裹层下留白 16 → 8px。
     ⚠️ **必须排除 `.hero`**：官网产物 `output/<slug>/site.html` 里是
       `<header class="hero">`（padding 64/56、标题 clamp 字号）—— 那是官网**正文**，
       压它 = 改坏老板的官网。
     ⚠️ **必须排除 `.hd-flat`**：studio.html 的页头是**零内边距的单行 flex**（h1 + 一个链接），
       给它补内边距只会**变高**（越修越坏）⇒ 该模板已给自己的 `<header>` 打上 `.hd-flat`。 */
  header:not(.hero):not(.hd-flat) { padding: 12px 14px 9px; }
  header:not(.hero) h1 { font-size: 17px; line-height: 1.3; }
  .fx-top { padding-bottom: 8px; }
}

/* ------------------------------------------------------------------------------
   4. 窄屏微调（≤520px）
   ------------------------------------------------------------------------------ */
@media (max-width: 520px) {
  .main-nav > a,
  .main-nav .drop-sum,
  .main-nav .ud-sum { font-size: 12px; padding: 6px 8px; }

  /* ---- 4.1 ★品牌名在手机上只留主标 ----
     375px 实测：品牌名 14 字（≈130px）＋「⚙️ 后台管理▾」（≈90px）＋用户名按钮
     （企业全名，最长 16 字）三者相加远超屏宽，装不下 ⇒ 上一版把品牌名挤成一个「知」字。
     修法＝分层显示：主标「知跃机制」始终在，副标「· AI双获客」手机上不显示。
     ⚠️ 是 `display:none` 而非删文案 —— HTML 里品牌名始终完整，判据/搜素/读屏都还认得出。
     ⚠️ 名字由 `db.nav_html` 产出（`<span class="bn-sub">`），类名改了两边要一起改。 */
  .main-nav .brand .bn-sub { display: none; }

  /* 卡片圆角收到 --r-md，小屏下 16px 显得过圆
     （带 fallback：老浏览器不支持 @layer 时令牌未定义，声明自动失效而非报错） */
  .card { border-radius: var(--r-md, 12px); }
}
