/* ============================================================
   股票基础信息查询 — 浅色主题样式
   设计原则：信息密度适中、卡片分区清晰、窄屏不破版
   ============================================================ */

:root {
  --bg: #f6f8fb;
  --card-bg: #ffffff;
  --border: #e2e8f0;
  --border-strong: #cbd5e1;
  --text: #0f172a;
  --text-sub: #475569;
  --text-mute: #94a3b8;
  --primary: #2563eb;
  --primary-weak: #eff6ff;
  --danger: #dc2626;
  --danger-weak: #fef2f2;
  --warning: #b45309;
  --warning-weak: #fffbeb;
  --success: #15803d;
  --success-weak: #f0fdf4;
  --radius: 12px;
  --radius-sm: 8px;
  --shadow-sm: 0 1px 2px rgba(15, 23, 42, 0.06);
  --shadow-md: 0 4px 16px rgba(15, 23, 42, 0.08);
  --font: "Microsoft YaHei", "PingFang SC", "Hiragino Sans GB", -apple-system,
    BlinkMacSystemFont, "Segoe UI", sans-serif;
}

* {
  box-sizing: border-box;
}

/*
 * 全局兜底：带 hidden 属性的元素必须真的不显示。
 *
 * 为什么必须显式写这一条：UA 样式表里的 `[hidden] { display: none }` 属于
 * **浏览器默认样式**，任何作者样式（哪怕只是一条 `.chart-grid { display: grid }`）
 * 都会把它压过去。本项目此前为 `.result-area` / `.trend-body` / `.modal` 等
 * 逐个补了 `[hidden]` 规则，却漏了 `.chart-grid` —— 而 `#chart-skeleton` 与
 * `#chart-body` 恰好都用这个类，于是 JS 设 `hidden = true` 之后骨架屏仍以
 * grid 布局留在页面上：用户看到「下方 6 张图正常、上方还有 6 张载入中」。
 * 与其继续逐个类去补，这里统一兜底，新增容器不会再踩同一个坑。
 */
[hidden] {
  display: none !important;
}

html,
body {
  margin: 0;
  padding: 0;
}

body {
  background: var(--bg);
  color: var(--text);
  font-family: var(--font);
  font-size: 14px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

/* ---------- 顶部 ---------- */

.app-header {
  background: var(--card-bg);
  border-bottom: 1px solid var(--border);
  box-shadow: var(--shadow-sm);
  position: sticky;
  top: 0;
  z-index: 20;
}

.header-inner {
  max-width: 1280px;
  margin: 0 auto;
  padding: 18px 20px 14px;
}

/* R45：账号入口要固定到顶栏**最右侧**，因此 .brand 变成一行 flex：
       左 = h1（标题 + 两个胶囊入口 + 区块导航），右 = 账号入口（margin-left:auto）。
       入口默认 hidden（服务不可用时保持隐藏），此时 flex 行里只剩 h1，
       布局与改动前逐像素一致，不影响任何既有视觉。

       ⚠️ R45 修正：`.brand` 是 `.header-inner`（flex, wrap）的子项，此前没有自己的
       flex 规则，于是按默认的 `flex: 0 1 auto` **收缩到内容宽度**（实测 915px）。
       `margin-left: auto` 只能把入口推到这 915px 的右缘 —— 视口越宽、离内容容器
       右缘越远（1440/1920 下差 325px），看上去根本不在「页面的最右侧」。
       与 R24 查询栏那条修复是同一个坑（见 `.header-inner > .query-bar`）：让它
       独占一行并撑满容器后，入口右缘才与查询栏 / 内容卡片严格对齐。
       港美股页是同款问题、同款处理（见 css/hkus.css 的 .hk-header-top）。 */
.brand {
  display: flex;
  align-items: flex-start;
  flex: 1 0 100%;
  min-width: 0;
  gap: 10px;
}

.brand > h1 {
  flex: 1 1 auto;
  /* 窄屏时允许收缩，否则区块导航会把入口挤出视口 */
  min-width: 0;
}

.brand > .account-entry {
  flex: 0 0 auto;
  margin-left: auto;
  /* 与 21px 标题的文字视觉对齐（胶囊本身只有 ~24px 高） */
  margin-top: 2px;
}

.brand h1 {
  margin: 0;
  font-size: 21px;
  font-weight: 700;
  letter-spacing: 0.5px;
}

.brand-sub {
  margin: 2px 0 14px;
  color: var(--text-mute);
  font-size: 12.5px;
}

.query-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: 12px;
}

.field {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.field label {
  font-size: 12px;
  color: var(--text-sub);
  font-weight: 600;
}

.field input,
.field select {
  height: 38px;
  padding: 0 12px;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background: #fff;
  color: var(--text);
  font-family: inherit;
  font-size: 14px;
  transition: border-color 0.15s, box-shadow 0.15s;
}

.field input {
  width: 230px;
}

.field input:focus,
.field select:focus {
  outline: none;
  border-color: var(--primary);
  box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.12);
}

.field input[aria-invalid="true"] {
  border-color: var(--danger);
}

.field-error {
  margin: 0;
  color: var(--danger);
  font-size: 12px;
}

/* 只读字段的说明文字（R2 的「固定近 10 年」提示） */
.field-hint {
  margin: 0;
  color: var(--text-mute);
  font-size: 11.5px;
  line-height: 1.5;
}

/* disabled 的下拉框降低视觉权重，明确「不可改」而非「忘了做」 */
.field select:disabled {
  background: #f8fafc;
  color: var(--text-mute);
  cursor: not-allowed;
}

.btn {
  height: 38px;
  padding: 0 20px;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  font-family: inherit;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s, color 0.15s;
}

.btn-primary {
  background: var(--primary);
  color: #fff;
}

.btn-primary:hover:not(:disabled) {
  background: #1d4ed8;
}

.btn:disabled {
  cursor: not-allowed;
  opacity: 0.6;
}

.btn-ghost {
  height: 30px;
  padding: 0 12px;
  background: #fff;
  border-color: var(--border-strong);
  color: var(--text-sub);
  font-size: 12.5px;
  font-weight: 500;
}

.btn-ghost:hover {
  border-color: var(--primary);
  color: var(--primary);
}

.presets {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 12px;
}

.preset-chip {
  padding: 4px 12px;
  border: 1px solid var(--border-strong);
  border-radius: 999px;
  background: #fff;
  color: var(--text-sub);
  font-family: inherit;
  font-size: 12.5px;
  cursor: pointer;
  transition: all 0.15s;
}

.preset-chip:hover {
  border-color: var(--primary);
  color: var(--primary);
  background: var(--primary-weak);
}

.preset-chip.is-active {
  border-color: var(--primary);
  background: var(--primary-weak);
  color: var(--primary);
  font-weight: 600;
}

.notice-bar {
  max-width: 1280px;
  margin: 0 auto;
  padding: 8px 20px 12px;
  color: var(--warning);
  background: var(--warning-weak);
  border-top: 1px solid #fde68a;
  font-size: 12.5px;
}

.notice-bar:not([hidden]) {
  display: block;
}

/* ---------- 最近搜索 R1 ---------- */

/*
 * 布局决策：用 grid + repeat(auto-fill, minmax(120px, 1fr)) 而非 flex，
 * 因为 grid 的列宽由容器宽度自动分配（auto-fill + 1fr），
 * 天然满足「一排放多个、数量按网页宽度自动分配」，无需 JS 计算列数；
 * flex-wrap 虽然也能换行，但每项宽度由内容长度决定，视觉上参差不齐。
 */
.recent {
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px dashed var(--border);
}

.recent-head {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 8px;
}

.recent-title {
  margin: 0;
  font-size: 13px;
  font-weight: 700;
  color: var(--text-sub);
}

.recent-count {
  color: var(--text-mute);
  font-size: 12px;
}

.recent-list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
  gap: 8px;
}

.recent-empty {
  grid-column: 1 / -1;
  margin: 0;
  color: var(--text-mute);
  font-size: 12.5px;
}

.recent-item {
  display: flex;
  align-items: stretch;
  min-width: 0;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background: #fff;
  overflow: hidden;
  transition: border-color 0.15s, background 0.15s;
}

.recent-item:hover {
  border-color: var(--primary);
  background: var(--primary-weak);
}

.recent-item.is-active {
  border-color: var(--primary);
  background: var(--primary-weak);
}

.recent-main {
  flex: 1 1 auto;
  min-width: 0;
  padding: 5px 4px 5px 9px;
  border: 0;
  background: transparent;
  font-family: inherit;
  text-align: left;
  cursor: pointer;
  display: flex;
  flex-direction: column;
  gap: 1px;
}

.recent-name {
  color: var(--text);
  font-size: 12.5px;
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.recent-code {
  color: var(--text-mute);
  font-size: 11px;
  font-variant-numeric: tabular-nums;
}

.recent-del {
  flex: 0 0 auto;
  width: 22px;
  border: 0;
  border-left: 1px solid var(--border);
  background: transparent;
  color: var(--text-mute);
  font-size: 13px;
  line-height: 1;
  cursor: pointer;
  transition: background 0.15s, color 0.15s;
}

.recent-del:hover {
  background: var(--danger-weak);
  color: var(--danger);
}

/* 窄屏下每项改为更紧凑的两列，避免出现 1 列超宽 */
@media (max-width: 768px) {
  .recent-list {
    grid-template-columns: repeat(auto-fill, minmax(104px, 1fr));
    gap: 6px;
  }
}

/* ---------- 右侧锚点导航 R8 ---------- */

/*
 * 定位在视口右侧、垂直居中，宽度仅 34px（收起态），不遮挡内容：
 * .app-main 最大宽 1280px 且居中，两侧留白在 ≥1400px 视口下 ≥60px，足够容纳。
 * 用 fixed 而非 sticky，保证任意滚动位置都可点击。
 */
.anchor-nav {
  position: fixed;
  right: 10px;
  top: 50%;
  transform: translateY(-50%);
  z-index: 30;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  padding: 5px 4px;
  background: rgba(255, 255, 255, 0.94);
  border: 1px solid var(--border);
  border-radius: 999px;
  box-shadow: var(--shadow-md);
  backdrop-filter: blur(4px);
}

.anchor-item {
  position: relative;
  min-width: 26px;
  height: 24px;
  padding: 0 7px;
  border: 0;
  border-radius: 12px;
  background: transparent;
  color: var(--text-mute);
  font-family: inherit;
  font-size: 11.5px;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  transition: background 0.15s, color 0.15s;
}

.anchor-item:hover {
  background: var(--primary-weak);
  color: var(--primary);
}

.anchor-dot {
  width: 5px;
  height: 5px;
  flex: none;
  border-radius: 50%;
  background: currentColor;
  opacity: 0.55;
  pointer-events: none;
}

.anchor-item.is-active .anchor-dot {
  opacity: 1;
}

.anchor-top {
  margin-bottom: 3px;
  border-bottom: 1px solid var(--border);
  border-radius: 0;
  height: 24px;
}

.anchor-top .anchor-dot {
  display: none;
}

/*
 * R11：锚点文字常显（用户反馈「右侧节点写字要不然看不到具体节点」）。
 * 原实现是 26px 圆形按钮 + hover 才浮出标签，导致节点名称默认不可见；
 * 现在改为直接显示文字标签，与左侧内容一同可读。
 * hover 时加浅底色做反馈，不再依赖浮层。
 */
.anchor-label {
  position: static;
  margin-left: 0;
  padding: 0;
  white-space: nowrap;
  background: none;
  color: inherit;
  font-size: 11.5px;
  opacity: 1;
  pointer-events: none;
  transform: none;
  transition: none;
  z-index: auto;
}

/* 圆点为装饰性标识，文字为主体（已在 .anchor-dot 定义，此处不重复） */

.anchor-item:hover {
  background: var(--primary-weak);
  color: var(--primary);
}

.anchor-item:hover .anchor-label,
.anchor-item:focus-visible .anchor-label {
  opacity: 1;
  transform: none;
}

/* 选中态：实心药丸 + 白字，文字仍然清晰 */
.anchor-item.is-active {
  background: var(--primary);
  color: #fff;
  font-weight: 600;
}

/* 窄屏：隐藏锚点条，避免遮挡窄内容区 */
@media (max-width: 768px) {
  .anchor-nav {
    display: none;
  }
}

/* ---------- 主体 ---------- */

.app-main {
  max-width: 1280px;
  margin: 0 auto;
  padding: 20px;
}

.placeholder {
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 56px 24px;
  text-align: center;
  box-shadow: var(--shadow-sm);
}

.placeholder h2 {
  margin: 0 0 10px;
  font-size: 17px;
}

.placeholder p {
  margin: 4px 0;
  color: var(--text-sub);
}

.placeholder-tip {
  margin-top: 12px !important;
  color: var(--text-mute) !important;
  font-size: 12.5px;
}

.result-area {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.result-area[hidden] {
  display: none;
}

/* ---------- 卡片 ---------- */

.card {
  background: var(--card-bg);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 18px 20px;
  box-shadow: var(--shadow-sm);
}

.card-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 14px;
}

.card-header h2 {
  margin: 0;
  font-size: 16px;
  font-weight: 700;
  position: relative;
  padding-left: 10px;
}

.card-header h2::before {
  content: "";
  position: absolute;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
  width: 3px;
  height: 15px;
  background: var(--primary);
  border-radius: 2px;
}

.badge {
  padding: 2px 9px;
  border-radius: 999px;
  background: var(--warning-weak);
  border: 1px solid #fde68a;
  color: var(--warning);
  font-size: 11.5px;
  font-weight: 600;
  white-space: nowrap;
}

/* ---------- 概览条 ---------- */

.overview-body {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 10px 22px;
}

.overview-name {
  font-size: 20px;
  font-weight: 700;
}

.overview-code {
  color: var(--text-mute);
  font-size: 13px;
}

.overview-price {
  font-size: 22px;
  font-weight: 700;
  color: var(--primary);
}

.overview-change {
  font-size: 13.5px;
  font-weight: 600;
}

.overview-change.is-up {
  color: var(--danger);
}

.overview-change.is-down {
  color: var(--success);
}

.overview-meta {
  color: var(--text-mute);
  font-size: 12.5px;
}

/* R36：行情头右侧的「同花顺 F10 / AI F10」外链 */
.overview-links {
  display: inline-flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 10px;
}

.overview-link {
  display: inline-block;
  color: var(--primary);
  font-size: 12.5px;
  font-weight: 600;
  line-height: 1.5;
  padding: 2px 9px;
  border: 1px solid var(--primary);
  border-radius: 999px;
  text-decoration: none;
  white-space: nowrap;
}

.overview-link:hover {
  background: var(--primary-weak);
}

/* ---------- 指标网格 ---------- */

.metric-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(168px, 1fr));
  gap: 12px;
}

.metric-item {
  padding: 11px 13px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: #fbfcfe;
}

.metric-item.is-unavailable {
  background: #fafafa;
  border-style: dashed;
}

.metric-label {
  display: block;
  color: var(--text-mute);
  font-size: 12px;
  margin-bottom: 3px;
}

.metric-value {
  display: block;
  font-size: 15.5px;
  font-weight: 700;
  color: var(--text);
  word-break: break-all;
}

.metric-value.is-empty {
  color: var(--text-mute);
  font-weight: 500;
}

.metric-note {
  display: block;
  margin-top: 2px;
  color: var(--text-mute);
  font-size: 11.5px;
}

/* R36 / R38：指标值内的可点击外链（所属行业 / 细分行业 / 行业人气排名）
   要求：**静态外观与普通指标文字完全一致** —— 变成链接后不能变色、不能常驻下划线，
   只在鼠标悬停时用下划线提示「这里可以点」。 */
.metric-link {
  color: inherit;
  text-decoration: none;
  cursor: pointer;
}

.metric-link:hover {
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 2px;
  text-decoration-thickness: 1px;
}

/* ---------- 区块小标题 ---------- */

.section-sub {
  margin: 18px 0 10px;
  font-size: 13.5px;
  font-weight: 700;
  color: var(--text-sub);
  padding-bottom: 6px;
  border-bottom: 1px solid var(--border);
}

.section-sub:first-child {
  margin-top: 0;
}

/* ---------- 描述列表 ---------- */

.desc-list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
  gap: 10px 18px;
  margin: 0;
}

.desc-item {
  display: flex;
  gap: 8px;
  min-width: 0;
}

.desc-label {
  flex: 0 0 88px;
  color: var(--text-mute);
  font-size: 12.5px;
}

.desc-value {
  flex: 1;
  min-width: 0;
  color: var(--text);
  word-break: break-word;
}

.desc-value.is-empty {
  color: var(--text-mute);
}

/* ---------- 段落文本 ---------- */

.para {
  margin: 0 0 8px;
  color: var(--text-sub);
  line-height: 1.75;
  word-break: break-word;
}

.para:last-child {
  margin-bottom: 0;
}

/* ---------- 表格 ---------- */

.table-wrap {
  width: 100%;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

.data-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 13px;
  min-width: 640px;
}

.data-table th,
.data-table td {
  padding: 9px 10px;
  text-align: left;
  border-bottom: 1px solid var(--border);
  white-space: nowrap;
}

.data-table th {
  background: #f8fafc;
  color: var(--text-sub);
  font-weight: 600;
  font-size: 12.5px;
  position: sticky;
  top: 0;
}

.data-table tbody tr:hover {
  background: #fafbff;
}

.data-table td.num {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.data-table .cell-wrap {
  white-space: normal;
  min-width: 180px;
  max-width: 320px;
}

/* ---------- R2 分红表：全部单元格居中 ---------- */

/*
 * 分红表按「年份 → 一行」阅读，横向扫视时年份列是主要锚点，
 * 居中对齐能让「有分红 / 未分红」两种行的年份落在同一条视觉轴上，比左对齐更容易对齐比较。
 * 只作用于 .table-center，绝不影响股东表（R5 要求左对齐）。
 */
.data-table.table-center th,
.data-table.table-center td {
  text-align: center;
}

.data-table.table-center td.cell-wrap {
  text-align: center;
}

/* 未分红年份行：整行淡化，一眼与有数据的行区分开 */
.data-table tr.is-no-dividend td {
  color: var(--text-mute);
  background: #fcfcfd;
}

.tag-none {
  display: inline-block;
  padding: 1px 8px;
  border-radius: 4px;
  background: #f1f5f9;
  border: 1px solid var(--border);
  color: var(--text-mute);
  font-size: 11.5px;
  font-weight: 600;
}

/* 同一年多条分红时的次序标记（中期分红 / 第二次派息） */
.tag-sub {
  display: inline-block;
  margin-left: 4px;
  padding: 0 5px;
  border-radius: 3px;
  background: var(--primary-weak);
  border: 1px solid #bfdbfe;
  color: var(--primary);
  font-size: 11px;
  font-weight: 600;
  vertical-align: middle;
}

/* ---------- R5 股东表：全部数据单元格左对齐 ---------- */

/*
 * 股东表以「股东名称」为主键阅读，名称列必须左对齐；
 * 若数值列右对齐，整行的视觉起点忽左忽右，读行时容易串行。
 * 用 .table-left 局部覆盖，保留 tabular-nums 便于同列数字对齐比较。
 */
.data-table.table-left th,
.data-table.table-left td,
.data-table.table-left td.num {
  text-align: left;
}

.data-table.table-left td.num {
  font-variant-numeric: tabular-nums;
}

/* R4：合计行（tfoot）—— 与表体区分开，同时不覆盖 .table-left 的左对齐 */
.data-table tfoot td {
  background: #f8fafc;
  border-top: 2px solid var(--border-strong);
  border-bottom: 0;
  color: var(--text);
  font-weight: 700;
  font-size: 12.5px;
}

/* ---------- R3 控股股东：单行不换行 ---------- */

/*
 * 控股股东名称可能很长（如「中国贵州茅台酒厂(集团)有限责任公司」，18 字），
 * 默认 desc-list 是 260px 起步的双列网格，很容易折成 3 行、把卡片撑得很高。
 * 这里给「控股股东」这一项单独用 nowrap + ellipsis + title，
 * hover 时通过 title 属性查看完整名称，视觉上恒为一行。
 */
.desc-item.is-nowrap .desc-value {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  word-break: normal;
}

/* ---------- ETF 专属排版 R9 ---------- */

.badge-etf {
  background: var(--primary-weak);
  border-color: #bfdbfe;
  color: var(--primary);
  margin-right: 6px;
  vertical-align: middle;
}

/* ETF 卡片左侧用主色描边，与个股卡片形成视觉区分 */
.etf-card {
  border-left: 3px solid var(--primary);
}

.badge-warn {
  background: var(--warning-weak);
  border-color: #fde68a;
  color: var(--warning);
}

/* 概览条上的净值展示（ETF 无股价，改用单位净值 + 涨跌幅） */
.overview-nav {
  color: var(--primary);
}

/* ETF 重仓股「较上期变动」的涨跌语义色 */
.tag-change-up {
  color: var(--danger);
  font-weight: 600;
}

.tag-change-down {
  color: var(--success);
  font-weight: 600;
}

.tag-change-flat {
  color: var(--text-mute);
}

/* ETF 收益率网格 */
.etf-returns {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(132px, 1fr));
  gap: 10px;
}

/* 「ETF 无此数据」块内的补充说明文字 */
.state-detail-inline {
  margin: 0 !important;
  color: var(--text-mute);
  font-size: 12px;
  line-height: 1.7;
}

/* desc-item 内的行内补充说明（规模日期等） */
.desc-note-inline {
  flex: 0 0 auto;
  align-self: baseline;
  color: var(--text-mute);
  font-size: 11.5px;
}

/* ---------- 爱问财嵌入卡片 R7 ---------- */

.app-section {
  max-width: 1280px;
  margin: 0 auto;
  padding: 0 20px;
}

.iwencai-hint {
  margin: 0 0 10px;
  color: var(--text-sub);
  font-size: 12.5px;
  line-height: 1.7;
}

.iwencai-query {
  display: inline-block;
  margin-top: 2px;
  padding: 2px 8px;
  border-radius: 4px;
  background: #f1f5f9;
  border: 1px solid var(--border);
  color: var(--text);
  font-family: ui-monospace, SFMono-Regular, Consolas, monospace;
  font-size: 11.5px;
  word-break: break-all;
}

.iwencai-frame-wrap {
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  overflow: hidden;
  background: #fafbfd;
}

.iwencai-frame {
  display: block;
  width: 100%;
  height: 460px;
  border: 0;
  background: #fff;
}

/* 收起态：只保留卡片头与提示，iframe 不占位（配合 loading=lazy 进一步省流量） */
.iwencai-card.is-collapsed .iwencai-frame-wrap,
.iwencai-card.is-collapsed .iwencai-query {
  display: none;
}

.card-header-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

.btn-link {
  display: inline-flex;
  align-items: center;
  height: 30px;
  text-decoration: none;
}

.tag-preplan {
  padding: 1px 7px;
  border-radius: 4px;
  background: var(--warning-weak);
  border: 1px solid #fde68a;
  color: var(--warning);
  font-size: 11.5px;
  font-weight: 600;
}

.tag-done {
  padding: 1px 7px;
  border-radius: 4px;
  background: var(--success-weak);
  border: 1px solid #bbf7d0;
  color: var(--success);
  font-size: 11.5px;
  font-weight: 600;
}

.table-footnote {
  margin: 10px 0 0;
  color: var(--text-mute);
  font-size: 12px;
}

/* ---------- 图表 ---------- */

/*
  R33：六图看板固定「2 行 3 列」。
  用 repeat(3, minmax(0,1fr)) 而非 auto-fit：auto-fit 在宽屏会挤成 4~5 列，
  破坏用户要求的 2×3 整齐排版；minmax(0,1fr) 保证子项不会因内容撑破列宽。
  窄屏在下面两个断点降为 2 列 / 1 列。
*/
.chart-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 18px;
}

.chart-panel {
  min-width: 0;
}

.chart-panel-title {
  margin: 0 0 8px;
  font-size: 13.5px;
  font-weight: 700;
  color: var(--text-sub);
}

.chart-container {
  width: 100%;
  height: 280px;
}

/*
  每张图下方的【使用说明】文字块（用户要求：图表下方紧跟对应说明）。
  与图之间用一条虚线分隔，视觉上「图 → 说明」是同一组，不会被误读成下一张图的一部分。
*/
.chart-note {
  margin: 10px 0 0;
  padding-top: 8px;
  border-top: 1px dashed var(--border);
  color: var(--text-mute);
  font-size: 12.5px;
  line-height: 1.7;
}

.chart-note-label {
  display: inline-block;
  margin-right: 6px;
  padding: 0 6px;
  border-radius: 4px;
  background: #eef4ff;
  color: #2f6fed;
  font-size: 11.5px;
  font-weight: 700;
  line-height: 18px;
  vertical-align: 1px;
}

/* R59：图内不再画小字副标题，「数据来源」改排在【使用说明】的**最后面**。
   占一整行（display: block），字号略小于说明正文，颜色沿用弱灰。 */
.chart-note-source {
  display: block;
  margin-top: 2px;
  color: var(--text-mute);
  font-size: 12px;
}

/* ---------- R33 可折叠股价走势图 ---------- */

.trend-card .card-header {
  align-items: center;
}

/*
 * R53：走势图标题括号里的复权口径下拉（与港美股页 .hk-adjust-select 同款外观）。
 * 它嵌在 <h2> 里，外观必须与括号里的**普通标题文字完全一致**：
 * 去掉系统外观、边框、内边距与自绘箭头，颜色/字体/字重/行高全部继承标题。
 * 可点性只用 cursor: pointer 与 title 提示表达，不额外加图形（零视觉变化）。
 */
.trend-adjust-select {
  appearance: none;
  -webkit-appearance: none;
  border: 0;
  margin: 0;
  padding: 0;
  background: transparent;
  color: inherit;
  font: inherit;
  font-weight: inherit;
  line-height: inherit;
  cursor: pointer;
}

.trend-adjust-select:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
  border-radius: 4px;
}

/* 「展开 / 折叠」按钮：浅色描边，不抢主标题的注意力
   R59：本类也用在 <a>（「大盘云图」入口）上 —— 用户要求它与展开按钮「样式和字体一致」，
   因此两条规则**共用同一份声明**；对 <a> 只需额外去掉下划线并继承字体即可。 */
.trend-toggle {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 12px;
  border: 1px solid var(--border-strong);
  border-radius: 999px;
  background: #fff;
  color: var(--text-sub);
  font-family: inherit;
  font-size: 12.5px;
  font-weight: 600;
  /* R59：<button> 走 UA 默认 line-height: normal，而 <a> 会继承父级行高，
     两者算出来的行高不一致（实测 normal vs 20px）—— 显式钉死，保证这枚胶囊
     不管套在 <a> 还是 <button> 上，行高都逐项相同。 */
  line-height: 1.2;
  text-decoration: none;
  cursor: pointer;
  transition: border-color .16s ease, color .16s ease, background .16s ease;
}

.trend-toggle:hover {
  border-color: #b8cdf7;
  background: #f5f8ff;
  color: #2f6fed;
}

.trend-toggle .trend-caret {
  width: 0;
  height: 0;
  border-left: 4.5px solid transparent;
  border-right: 4.5px solid transparent;
  border-top: 5px solid currentColor;
  transition: transform .18s ease;
}

.trend-toggle[aria-expanded="true"] .trend-caret {
  transform: rotate(180deg);
}

.trend-body {
  margin-top: 12px;
}

.trend-body[hidden] {
  display: none;
}

.trend-period {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  /* R51：周期按钮与提示文案整体靠右对齐（窄屏折行后仍贴容器右缘）。 */
  justify-content: flex-end;
  gap: 8px;
  margin-bottom: 8px;
}

.trend-period-btn {
  padding: 5px 14px;
  border: 1px solid var(--border-strong);
  border-radius: 6px;
  background: #fff;
  color: var(--text-sub);
  font-size: 12.5px;
  cursor: pointer;
  transition: all .16s ease;
}

.trend-period-btn:hover {
  border-color: #b8cdf7;
  color: #2f6fed;
}

.trend-period-btn.is-active {
  border-color: #2f6fed;
  background: #eef4ff;
  color: #2f6fed;
  font-weight: 700;
}

.trend-period-hint {
  margin-left: 4px;
  color: var(--text-mute);
  font-size: 12px;
}

/*
 * R34：指标参数条（MACD / KDJ）。
 * 只在展开后出现，一行放得下就一行；窄屏自动换行，不挤压图表宽度。
 */
.trend-indicators {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 14px;
  margin-bottom: 8px;
  padding: 8px 10px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: #fafbfd;
}

.trend-ind-group {
  display: flex;
  align-items: center;
  gap: 6px;
}

.trend-ind-name {
  color: var(--text-sub);
  font-size: 12.5px;
  font-weight: 700;
}

.trend-ind-field {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  color: var(--text-mute);
  font-size: 12px;
}

.trend-ind-field input {
  width: 46px;
  padding: 3px 4px;
  border: 1px solid var(--border-strong);
  border-radius: 5px;
  background: #fff;
  color: var(--text);
  font-family: var(--font);
  font-size: 12.5px;
  text-align: center;
}

.trend-ind-field input:focus {
  outline: none;
  border-color: #2f6fed;
  box-shadow: 0 0 0 2px rgba(47, 111, 237, 0.12);
}

.trend-ind-reset {
  padding: 4px 10px;
  border: 1px solid var(--border-strong);
  border-radius: 5px;
  background: #fff;
  color: var(--text-sub);
  font-family: var(--font);
  font-size: 12px;
  cursor: pointer;
}

.trend-ind-reset:hover {
  border-color: #b8cdf7;
  color: #2f6fed;
}

.trend-ind-hint {
  margin-left: auto;
  color: var(--text-mute);
  font-size: 12px;
}

/*
  R34：走势图容器高一点，才装得下「主图 + MACD + KDJ」三块子图。
  ⚠️ 必须写成 `.chart-container.trend-container`（两个类）提高优先级：
  文件下方 `@media (max-width:768px){ .chart-container{height:240px} }` 是给六张
  基本面图用的，它出现得更晚，单靠 `.trend-container` 会被它按「后写覆盖」压成 240px
  —— 那样三块子图会挤成一条缝，几乎读不出指标。
*/
.chart-container.trend-container {
  height: 520px;
}

/* 手机端：三块子图挤在 520px 里读不清，整体放低一点高度并允许横向占满 */
@media (max-width: 768px) {
  .chart-container.trend-container {
    height: 460px;
  }

  .trend-ind-hint {
    margin-left: 0;
    width: 100%;
  }
}

/* ---------- R33 恢复弹窗 ---------- */

.modal {
  position: fixed;
  inset: 0;
  z-index: 9998;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
}

.modal[hidden] {
  display: none;
}

.modal-backdrop {
  position: absolute;
  inset: 0;
  background: rgba(15, 23, 42, .38);
}

.modal-box {
  position: relative;
  width: min(560px, 100%);
  max-height: 80vh;
  overflow: auto;
  padding: 20px;
  border-radius: 12px;
  background: #fff;
  box-shadow: 0 18px 48px rgba(15, 23, 42, .22);
}

/* R60：弹窗右上角的叉号关闭按钮（账号弹窗用；用户要求把底部「关闭」按钮挪到这里）。
   id 仍是 #account-cancel，因此 account.js 里已有的关闭逻辑不用改。 */
.modal-close {
  position: absolute;
  top: 12px;
  right: 12px;
  width: 30px;
  height: 30px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  border: 1px solid transparent;
  border-radius: 8px;
  background: transparent;
  color: var(--text-mute);
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
  transition: background .15s, color .15s, border-color .15s;
}

.modal-close:hover {
  border-color: var(--border);
  background: var(--primary-weak);
  color: var(--text);
}

/* R60：账号弹窗加宽加高（用户要求）—— 注册态字段多、已登录态还有预留问题与备份列表，
   原来 560px / 80vh 会挤出滚动条。这里只放宽账号弹窗，恢复弹窗与收藏弹窗不受影响。 */
#account-modal .modal-box {
  width: min(680px, 100%);
  max-height: 92vh;
}

/* R60：「忘记密码？」挪到最右侧，右边缘与用户名输入框尾部对齐（用户要求）。 */
#account-recover-link {
  display: block;
  width: 100%;
  text-align: right;
}

.modal-title {
  margin: 0 0 10px;
  font-size: 16px;
  color: var(--text-strong, #0f172a);
}

.modal-hint {
  margin: 0 0 12px;
  color: var(--text-mute);
  font-size: 12.5px;
  line-height: 1.7;
  word-break: break-all;
}

/* ============================================================
   R45：备份列表（恢复弹窗与账号备份面板共用同一套类名）
   ------------------------------------------------------------
   用户要求「鼠标放到某个备份上时，在它后面显示一个删除按钮」。
   原来的 `<select>` 里放不了按钮，所以列表改成逐行 div：
     .backup-rows              可滚动容器（取代原来的两个下拉框类名）
     .backup-row               一行：文件名/时间 + 右侧删除按钮
     .backup-row.is-selected   当前选中行（原来由 <select> 自动维护的选中态）
   ============================================================ */
.backup-rows {
  max-height: 220px;
  overflow-y: auto;
  border: 1px solid var(--border-strong);
  border-radius: 8px;
  background: #fff;
}

.backup-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 10px;
  border-bottom: 1px solid var(--border);
  color: var(--text-sub);
  font-size: 13px;
  cursor: pointer;
}

.backup-row:last-child {
  border-bottom: none;
}

.backup-row:hover {
  background: var(--primary-weak);
}

.backup-row.is-selected {
  background: var(--primary-weak);
  color: var(--text);
  font-weight: 600;
}

.backup-row:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: -2px;
}

.backup-row-label {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* 删除按钮：默认透明，鼠标移到这一行（或按钮被键盘聚焦）时才出现 */
.backup-row-del {
  flex: 0 0 auto;
  padding: 4px 10px;
  border: 1px solid var(--border-strong);
  border-radius: 6px;
  background: transparent;
  color: var(--danger);
  font-family: inherit;
  font-size: 12.5px;
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.12s, background 0.12s, color 0.12s;
}

.backup-row:hover .backup-row-del,
.backup-row-del:focus-visible {
  opacity: 1;
}

.backup-row-del:hover {
  background: var(--danger);
  border-color: var(--danger);
  color: #fff;
}

/* 触屏设备没有 hover：「鼠标移上去才出现」会变成永远不出现，
   因此这里常显删除按钮（手机上也要能手动清理）。 */
@media (hover: none) {
  .backup-row-del {
    opacity: 1;
  }
}

.modal-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 16px;
}

/* 中等宽度（平板 / 窄窗口）：2×3 降为 3 行 2 列，避免每格过窄看不清坐标轴 */
@media (max-width: 1100px) {
  .chart-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

.chart-container.chart-fallback {
  height: auto;
  min-height: 140px;
}

.fallback-box {
  padding: 16px;
  border: 1px dashed var(--border-strong);
  border-radius: var(--radius-sm);
  background: #fafbfd;
}

.fallback-tip {
  margin: 0 0 10px;
  color: var(--text-sub);
  font-size: 12.5px;
}

.fallback-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 12.5px;
  max-height: 200px;
}

.fallback-table th,
.fallback-table td {
  padding: 5px 8px;
  border-bottom: 1px solid var(--border);
  text-align: left;
}

.fallback-table td:last-child {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

/* ---------- 骨架屏 ---------- */

.skeleton-list {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.skeleton-list[hidden] {
  display: none;
}

.skeleton-line,
.skeleton-box {
  background: linear-gradient(90deg, #eef2f7 25%, #f8fafc 37%, #eef2f7 63%);
  background-size: 400% 100%;
  animation: skeleton-loading 1.3s ease-in-out infinite;
  border-radius: 6px;
}

.skeleton-line {
  height: 16px;
}

.skeleton-box {
  height: 76px;
}

.skeleton-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(168px, 1fr));
  gap: 12px;
}

@keyframes skeleton-loading {
  0% {
    background-position: 100% 50%;
  }
  100% {
    background-position: 0 50%;
  }
}

/* ---------- 状态提示 ---------- */

.module-body[hidden] {
  display: none;
}

.state-box {
  padding: 20px 16px;
  border-radius: var(--radius-sm);
  text-align: center;
  border: 1px solid transparent;
}

.state-box p {
  margin: 0 0 10px;
  font-size: 13.5px;
}

.state-box.is-empty {
  background: #fafbfd;
  border-color: var(--border);
  color: var(--text-mute);
}

.state-box.is-error {
  background: var(--danger-weak);
  border-color: #fecaca;
  color: var(--danger);
  text-align: left;
}

.state-box.is-error .state-title {
  display: block;
  font-weight: 700;
  margin-bottom: 4px;
}

.state-box.is-error .state-detail {
  display: block;
  color: #991b1b;
  font-size: 12.5px;
  margin-bottom: 12px;
  word-break: break-word;
}

.state-box.is-error .btn {
  background: #fff;
  border-color: #fca5a5;
  color: var(--danger);
}

.state-box.is-error .btn:hover {
  border-color: var(--danger);
}

/* ---------- P0：浏览器环境受限（UA 被数据源封禁） ---------- */

/*
 * ⚠️ 必须与 is-empty（灰）明显区分：
 * 「暂无数据」= 数据源确实没有这项数据；
 * 「环境受限」= 数据源有，但拒绝了当前浏览器（User-Agent 被封禁），重试无用。
 * 两者处置完全不同（换浏览器 vs 无需处理），混用会让用户误判。
 * 用琥珀色 + 虚线边框表达「可行动但受限」，而非红色的「出错」。
 */
.state-box.is-blocked {
  background: var(--warning-weak);
  border-color: #fde68a;
  color: var(--warning);
  text-align: left;
}

.state-box.is-blocked p {
  margin: 0 0 6px;
  color: var(--warning);
  font-size: 13.5px;
}

.state-box.is-blocked p:last-child {
  margin-bottom: 0;
}

/* ---------- 页脚 ---------- */

.app-footer {
  max-width: 1280px;
  margin: 0 auto;
  padding: 16px 20px 28px;
}

.app-footer p {
  margin: 0;
  color: var(--text-mute);
  font-size: 12px;
  text-align: center;
}

/* ---------- 窄屏适配 ---------- */

@media (max-width: 768px) {
  .header-inner,
  .app-main,
  .app-footer,
  .notice-bar {
    padding-left: 14px;
    padding-right: 14px;
  }

  .brand h1 {
    font-size: 18px;
  }

  .query-bar {
    flex-direction: column;
    align-items: stretch;
  }

  .field input,
  .field select {
    width: 100%;
  }

  .btn {
    width: 100%;
  }

  .card {
    padding: 15px 14px;
  }

  .chart-grid {
    grid-template-columns: 1fr;
  }

  .chart-container {
    height: 240px;
  }

  .desc-list {
    grid-template-columns: 1fr;
  }

  .metric-grid {
    grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
    gap: 10px;
  }

  .overview-price {
    font-size: 19px;
  }
}

@media (max-width: 420px) {
  .metric-grid {
    grid-template-columns: 1fr 1fr;
  }

  .card-header {
    flex-wrap: wrap;
  }
}
/* ============================================================
   R11-1 可比公司
   ============================================================ */
.peers-block {
  margin-top: 18px;
  padding-top: 16px;
  border-top: 1px dashed var(--border);
}

.peers-header {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 10px;
}

.peers-hint {
  font-size: 12px;
  color: var(--text-mute);
}

.peers-group {
  margin-top: 12px;
}

.peers-group-title {
  display: flex;
  align-items: baseline;
  gap: 6px;
  margin-bottom: 7px;
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
}

.peers-count {
  font-size: 12px;
  font-weight: 400;
  color: var(--text-mute);
}

/* 公司名链接：橙色下划线，区别于普通文本 */
.peer-link {
  display: inline-block;
  margin: 0 8px 6px 0;
  padding: 2px 4px;
  color: var(--primary);
  text-decoration: underline;
  text-decoration-color: var(--primary);
  text-underline-offset: 3px;
  border-radius: 3px;
  cursor: pointer;
  transition: background 0.15s;
}

.peer-link:hover {
  background: var(--primary-weak);
}

/* 非 A 股主体：不可点击，灰显并给出原因 */
.peer-link.is-disabled {
  color: var(--text-mute);
  text-decoration: none;
  cursor: not-allowed;
  border-bottom: 1px dotted var(--text-mute);
}

.peer-link:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 1px;
}

.peers-more {
  margin-top: 8px;
  font-size: 12px;
  color: var(--text-mute);
}

/* ============================================================
   R11-2 爱问财账号信息区
   ============================================================ */
.iwencai-login {
  margin: 12px 0;
  padding: 12px 14px;
  background: var(--bg-subtle, #f8fafc);
  border: 1px solid var(--border);
  border-radius: 8px;
}

.iwencai-login-head {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 10px;
}

.iwencai-login-title {
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
}

.iwencai-login-note {
  font-size: 12px;
  color: var(--text-mute);
}

.iwencai-login-fields {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  align-items: flex-end;
}

.iwencai-field {
  display: flex;
  flex-direction: column;
  gap: 4px;
  min-width: 200px;
  flex: 1 1 200px;
}

.iwencai-field-label {
  font-size: 12px;
  color: var(--text-mute);
}

.iwencai-field input {
  padding: 6px 10px;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: #fff;
  color: var(--text);
  font-family: inherit;
  font-size: 13px;
}

.iwencai-field input:focus {
  outline: 2px solid var(--primary);
  outline-offset: -1px;
  border-color: var(--primary);
}

.iwencai-field-actions {
  flex-direction: row;
  align-items: center;
  gap: 8px;
  flex: 0 0 auto;
  min-width: 0;
}

.iwencai-login-tip {
  margin: 10px 0 0;
  padding: 8px 10px;
  background: #fffbeb;
  border: 1px solid #fde68a;
  border-radius: 6px;
  font-size: 12px;
  line-height: 1.6;
  color: #78350f;
}

.iwencai-login-tip strong {
  color: #92400e;
}

/* ============================================================
   R12 选股条件记录
   ============================================================ */
.pick-conditions {
  margin-top: 12px;
  padding: 14px;
  background: var(--bg-subtle, #f8fafc);
  border: 1px solid var(--border);
  border-radius: 8px;
}

.pick-conditions-head {
  display: flex;
  align-items: baseline;
  gap: 8px;
  margin-bottom: 8px;
}

.pick-label,
.pick-history-label {
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
}

.pick-count {
  font-size: 12px;
  color: var(--text-mute);
}

.pick-row {
  display: flex;
  gap: 8px;
  align-items: center;
  flex-wrap: wrap;
}

.pick-row input {
  flex: 1 1 260px;
  min-width: 200px;
  padding: 7px 10px;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: #fff;
  color: var(--text);
  font-family: inherit;
  font-size: 13px;
}

.pick-row input:focus {
  outline: 2px solid var(--primary);
  outline-offset: -1px;
  border-color: var(--primary);
}

.pick-history {
  display: flex;
  gap: 8px;
  align-items: center;
  flex-wrap: wrap;
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px dashed var(--border);
}

.pick-select {
  flex: 1 1 240px;
  min-width: 180px;
  max-width: 100%;
  padding: 6px 8px;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: #fff;
  color: var(--text);
  font-family: inherit;
  font-size: 13px;
  /* 下拉项过长时横向滚动，避免撑破卡片 */
  max-width: 100%;
}

.pick-tip {
  margin: 10px 0 0;
  font-size: 12px;
  line-height: 1.6;
  color: var(--text-mute);
}

/* ============================================================
   R14 布局：左侧人气榜 + 紧凑顶部 + 锚点两字一行
   ============================================================ */

/* 顶部：标题与副标题合并为一行，减少纵向占用 */
.brand h1 {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 10px;
}

.brand-sub {
  font-size: 13px;
  font-weight: 400;
  color: var(--text-mute);
  white-space: nowrap;
}

/*
  R37：港股 / 美股查询入口。
  港美股的分红数据东财没有开放接口（报表配置不存在），无法并进本页，
  因此做成独立页面 hkus.html，从这里跳转。样式上做成一个浅底 chip，
  跟在标题后面，与右侧的区块导航区分开（后者是无边框的纯文字链）。
*/
.hkus-entry {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 2px 10px;
  border: 1px solid var(--primary);
  border-radius: 999px;
  background: var(--primary-weak);
  color: var(--primary);
  font-size: 12.5px;
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
  transition: background 0.15s, color 0.15s;
}

.hkus-entry:hover {
  background: var(--primary);
  color: #fff;
}

/* ============================================================
   R40：账号入口与账号弹窗
   ------------------------------------------------------------
   入口在 A 股页沿用 .hkus-entry 的胶囊外观（与「港股/美股」「浏览器扩展」并排），
   但它是 <button>：浏览器会带默认背景、边框与字体，这里补齐重置，
   保证三种入口在视觉上完全一致。
   ============================================================ */
.account-entry {
  font-family: inherit;
  cursor: pointer;
  line-height: 1.4;
}

.account-tabs {
  display: flex;
  gap: 4px;
  margin-bottom: 14px;
  border-bottom: 1px solid var(--border);
}

.account-tab {
  padding: 7px 14px;
  border: 1px solid transparent;
  border-bottom: 2px solid transparent;
  border-radius: 8px 8px 0 0;
  background: transparent;
  color: var(--text-mute);
  font-family: inherit;
  font-size: 13.5px;
  cursor: pointer;
}

.account-tab.is-active {
  color: var(--primary);
  border-color: var(--border);
  border-bottom-color: var(--primary);
  background: var(--card-bg);
  font-weight: 600;
}

.account-field {
  display: block;
  margin-bottom: 12px;
}

.account-label {
  display: block;
  margin-bottom: 5px;
  font-size: 12.5px;
  color: var(--text-sub);
}

.account-input {
  width: 100%;
  padding: 9px 11px;
  border: 1px solid var(--border-strong);
  border-radius: 8px;
  background: #fff;
  color: var(--text);
  font-family: inherit;
  font-size: 14px;
  box-sizing: border-box;
}

.account-input:focus {
  outline: none;
  border-color: var(--primary);
  box-shadow: 0 0 0 3px var(--primary-weak);
}

.account-error {
  margin: 4px 0 0;
  padding: 8px 10px;
  border-radius: 8px;
  background: var(--danger-weak);
  color: var(--danger);
  font-size: 12.5px;
  line-height: 1.6;
}

/*
 * R57：错误槽「常驻占位」，修「点登录报错时登录按钮往下跳」。
 * 现象：提示「密码不正确 / 该用户名还未注册」时这个 <p> 从 display:none 变成块级，
 *   弹窗长高 40px（8+20+8 的一行文案 + 4px 上边距），而 .modal 是垂直居中，
 *   于是按钮行被顶下 20px —— 用户看到的就是「登录按钮错位」。
 * 修法：空态也占住**一行文案的高度**（40px = 4px 上边距 + 36px 盒子，与有文案时同高），
 *   显隐改用 visibility（空态看不见但仍然占位），因此报错前后布局零位移。
 * 注意：这里用 id 选择器 + !important 是为了压过上面那条兜底的
 *   `[hidden] { display: none !important }`（id 特异性 1-0-0 > 属性选择器 0-1-0），
 *   也就是说这两个提示节点的显隐从此由「文案是否为空」决定，不再用 hidden 属性。
 */
#account-error,
#account-recover-error {
  display: block !important;
  min-height: 36px;
  visibility: hidden;
}

#account-error:not(:empty),
#account-recover-error:not(:empty) {
  visibility: visible;
}

.account-current {
  margin: 4px 0 0;
  padding: 10px 12px;
  border-radius: 8px;
  background: var(--primary-weak);
  color: var(--text-sub);
  font-size: 13px;
}

.account-tip {
  margin: 14px 0 0;
  color: var(--text-mute);
  font-size: 12px;
  line-height: 1.7;
}

.account-tip code,
.account-current code {
  padding: 1px 4px;
  border-radius: 4px;
  background: #eef2ff;
  font-size: 11.5px;
}

/* R42：账号「全量数据备份」面板 */
.account-backup {
  margin: 12px 0 0;
  padding: 12px;
  border-radius: 10px;
  background: #f7f9fc;
  border: 1px solid var(--border);
}

.account-backup-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  flex-wrap: wrap;
}

.account-backup-title {
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
}

.account-backup-hint {
  margin: 8px 0 0;
  font-size: 12px;
  line-height: 1.7;
  color: var(--text-mute);
}

.account-backup-msg {
  margin: 8px 0 0;
  font-size: 12.5px;
  line-height: 1.6;
  color: var(--text-sub);
}

.account-backup-msg.is-error {
  color: var(--danger, #dc2626);
}

.account-backup-list {
  margin: 10px 0 0;
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

/* R45：快照列表占满整行（面板本身是 flex 行，按钮落在列表下方） */
.account-backup-list .backup-rows {
  flex: 1 1 100%;
  min-width: 0;
}

/* R44：账号「预留问题 / 找回密码」 */
.account-link {
  display: inline-block;
  margin: 2px 0 0;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--primary);
  font-family: inherit;
  font-size: 12.5px;
  cursor: pointer;
}

.account-link:hover {
  text-decoration: underline;
}

.account-recover {
  margin: 10px 0 0;
  padding: 12px;
  border-radius: 10px;
  background: #f7f9fc;
  border: 1px solid var(--border);
}

.account-recover-hint {
  margin: 0 0 10px;
  font-size: 12.5px;
  line-height: 1.7;
  color: var(--text-mute);
}

.account-recover-question {
  margin: 0 0 12px;
  padding: 10px 12px;
  border-radius: 8px;
  background: var(--primary-weak);
  color: var(--text);
  font-size: 13.5px;
  font-weight: 600;
  line-height: 1.6;
  word-break: break-word;
}

.account-security {
  margin: 12px 0 0;
  padding: 12px;
  border-radius: 10px;
  background: #f7f9fc;
  border: 1px solid var(--border);
}

/*
 * R56：注册表单里的「预留问题 + 答案」分组。
 * 只是给两个 .account-field 套一层浅底容器，视觉上相当于缩进一小块；
 * 里面每个字段的样式仍由 .account-field / .account-input 提供，不新开一套。
 */
.account-register-security {
  margin: 0 0 12px;
  padding: 10px 12px 2px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: #f7f9fc;
}

.account-register-hint {
  margin: 0 0 10px;
  font-size: 11.5px;
  line-height: 1.7;
  color: var(--text-mute);
}

.account-security-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  flex-wrap: wrap;
}

.account-security-title {
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
}

.account-security-status {
  margin: 8px 0 0;
  font-size: 12.5px;
  line-height: 1.7;
  color: var(--text-sub);
  word-break: break-word;
}

.account-security-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
}

.account-security-msg {
  margin: 8px 0 0;
  font-size: 12.5px;
  line-height: 1.6;
  color: var(--text-sub);
}

.account-security-msg.is-error {
  color: var(--danger, #dc2626);
}

/* 头部内容区改为「左：查询栏 / 右：人气榜」的横向布局 */
.header-inner {
  display: flex;
  align-items: flex-start;
  gap: 18px;
  flex-wrap: wrap;
}

.header-main {
  flex: 1 1 420px;
  min-width: 0;
}

/* 查询栏：允许换行，最近搜索占剩余空间 */
.query-bar {
  display: flex;
  align-items: flex-end;
  gap: 10px;
  flex-wrap: wrap;
}

.query-bar .field {
  flex: 0 0 auto;
}

/*
 * R49：查询栏的错误提示独占一行，排在**查询行下方**。
 *
 * 它原本是 .field-code 里的流内元素（label → input → 错误），出错时把那个 field
 * 撑高一个提示行；而本查询栏是 `align-items: flex-end` 的 flex 行，行底由最高的
 * 兄弟项决定，于是输入框被整体顶高（实测约 21px），与「分红年数」下拉、查询按钮
 * 上下错开 —— 用户反馈的「输入框会上移错位」。
 *
 * 现在它在 DOM 里是 .query-bar 的最后一个子元素（见 index-modular.html 的 R49 注释），
 * `flex-basis: 100%` 保证它一定换到新的一行；第一行的控件几何位置因此与提示是否
 * 出现完全无关（零位移），提示只向下长。
 * ⚠️ 别再把它挪回某个 .field 内部 —— 那正是这个 bug 的成因。
 */
.query-bar > .field-error {
  flex: 1 0 100%;
  margin: 0;
}

/* 年数下拉不需要长提示，压缩宽度 */
.field-years {
  min-width: 0;
}

.field-years .field-hint {
  font-size: 11px;
}

/* 最近搜索移到查询按钮后：横向紧凑 chip 排列 */
.recent-inline {
  flex: 1 1 320px;
  min-width: 240px;
  margin: 0;
  padding: 6px 10px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--bg-subtle, #f8fafc);
}

.recent-inline .recent-head {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 4px;
}

.recent-inline .recent-title {
  font-size: 12px;
  color: var(--text-mute);
  font-weight: 500;
}

.recent-inline .recent-list {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 6px;
  max-height: 56px;
  overflow-y: auto;
}

.recent-inline .recent-empty {
  margin: 0;
  font-size: 12px;
}

/* 左侧人气榜：竖排 */
/* R18：移除 position:sticky —— 本元素位于 .app-header（本身已 sticky）内部，
   嵌套 sticky 会让 header 高度被撑到内容全高（实测 4826px），
   在页面上表现为查询栏与结果区之间出现巨大空隙。 */
.hot-rail {
  flex: 0 0 168px;
  width: 168px;
  padding: 10px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--bg-subtle, #f8fafc);
}

.hot-rail-head {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin-bottom: 8px;
  padding-bottom: 6px;
  border-bottom: 1px dashed var(--border);
}

.hot-rail-title {
  margin: 0;
  font-size: 13px;
  font-weight: 600;
}

.hot-rail-meta {
  font-size: 11px;
  color: var(--text-mute);
}

.hot-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.hot-empty {
  font-size: 11.5px;
  color: var(--text-mute);
  line-height: 1.5;
  padding: 4px 2px;
}

.hot-btn {
  display: flex;
  align-items: center;
  gap: 6px;
  width: 100%;
  padding: 4px 5px;
  border: 0;
  border-radius: 5px;
  background: transparent;
  color: var(--text);
  font-family: inherit;
  font-size: 12px;
  cursor: pointer;
  text-align: left;
  transition: background 0.15s;
}

.hot-btn:hover {
  background: var(--primary-weak);
}

.hot-rank {
  flex: none;
  width: 16px;
  height: 16px;
  border-radius: 3px;
  font-size: 10.5px;
  font-weight: 600;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: #e2e8f0;
  color: #475569;
}

/* 前三名用不同底色突出（红/橙/蓝，符合热度语义） */
.hot-rank-top.hot-rank { background: #fee2e2; color: #b91c1c; }
.hot-rank-rest { }

.hot-name {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* R15：人气榜已按用户要求去掉 6 位代码显示（hot-code 样式随之移除） */
.hot-rail-foot {
  margin: 8px 0 0;
  padding-top: 6px;
  border-top: 1px dashed var(--border);
  font-size: 11px;
  color: var(--text-mute);
  text-align: center;
}

/* 窄屏：人气榜移回顶部横向 */
@media (max-width: 900px) {
  .hot-rail {
    flex: 1 1 100%;
    width: 100%;
  }
  .hot-list {
    flex-direction: row;
    flex-wrap: wrap;
  }
  .hot-btn {
    width: auto;
  }
}

/* ============================================================
   R14 锚点：两字一行 + 回顶标红
   ============================================================ */

/* 限制宽度并允许换行 → 「公司概况」这类四字标签折成两行 */
.anchor-item {
  width: 34px;
  min-width: 34px;
  height: auto;
  min-height: 22px;
  padding: 2px 4px;
  border-radius: 6px;
  align-items: flex-start;
  justify-content: center;
  line-height: 1.25;
}

.anchor-label {
  white-space: normal;      /* 允许换行：两字一行 */
  word-break: break-all;
  text-align: center;
  font-size: 11px;
}

/* 回顶：红底白字，醒目 */
.anchor-top {
  margin-bottom: 4px;
  padding-bottom: 5px;
  border-bottom: 1px solid var(--border);
  border-radius: 0;
  width: 34px;
  background: #dc2626;
  color: #fff;
  font-weight: 600;
}

.anchor-top:hover {
  background: #b91c1c;
  color: #fff;
}

.anchor-top .anchor-label {
  color: #fff;
  font-weight: 600;
}

/* ============================================================
   R15：锚点滚动定位修正
   app-header 是 position:sticky(top:0)，会遮住被滚动到顶部的区块标题。
   统一用 scroll-margin-top 预留高度，JS 侧 scrollIntoView 不再手算偏移。
   ============================================================ */
/* R20：--anchor-offset 由 JS(syncAnchorOffset) 按 header 实测高度写入，
   未写入时回退 96px，保证纯 CSS 环境下也不会退化。 */
.app-main {
  /* 预留 sticky header 高度 + 一点呼吸间距 */
  scroll-margin-top: var(--anchor-offset, 96px);
}

.app-main section[data-anchor],
.app-main .card {
  scroll-margin-top: var(--anchor-offset, 96px);
}

/* 条件选股原在 <main> 之外，现已并入主内容流，统一同样处理 */
#iwencai-section {
  scroll-margin-top: var(--anchor-offset, 96px);
}

/* ============================================================
   R16：人气榜刷新按钮 + 热度值
   ============================================================ */
.hot-rail-head-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 6px;
}

.hot-refresh {
  flex: none;
  padding: 2px 8px;
  border: 1px solid var(--border);
  border-radius: 4px;
  background: #fff;
  color: var(--text-mute);
  font-family: inherit;
  font-size: 11px;
  line-height: 1.4;
  cursor: pointer;
  transition: background 0.15s, color 0.15s, border-color 0.15s;
}

.hot-refresh:hover:not(:disabled) {
  background: var(--primary-weak);
  color: var(--primary);
  border-color: var(--primary);
}

.hot-refresh:disabled {
  opacity: 0.6;
  cursor: progress;
}

/* 热度值：弱化显示，不与股票名抢焦点 */
.hot-heat {
  flex: none;
  font-size: 10.5px;
  color: var(--text-mute);
  font-variant-numeric: tabular-nums;
}

.hot-rail-foot {
  line-height: 1.5;
}

/* ============================================================
   R17：顶部锚点链接（样式沿用 .brand-sub，仅加可交互反馈）
   ============================================================ */
.brand-link {
  color: inherit;
  text-decoration: none;
  cursor: pointer;
  border-bottom: 1px solid transparent;
  transition: color 0.15s, border-color 0.15s;
}

.brand-link:hover {
  color: var(--primary);
  border-bottom-color: var(--primary);
}

.brand-link:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
  border-radius: 2px;
}

.brand-sep {
  margin: 0 3px;
  opacity: 0.6;
}

/* 股票代码输入框收窄（原 flex:0 0 auto 会撑满） */
.query-bar .field:not(.field-years) {
  flex: 0 0 auto;
}

.query-bar .field input#code-input {
  width: 168px;
  max-width: 168px;
}

/* 人气榜：标题与条目文字居中（R17 用户要求） */
.hot-rail-title {
  text-align: center;
}

/* 条目：排名+名称+热度 整体居中 */
.hot-btn {
  justify-content: center;
  text-align: center;
}

.hot-name {
  text-align: center;
  /* 名称居中后仍需保留省略号能力 */
  flex: 0 1 auto;
}

.hot-rank,
.hot-heat {
  text-align: center;
}

/* ============================================================
   R18：查询区与最近搜索视觉对齐（同款底色 + 等高）
   ============================================================ */

/* 给「股票代码 / 分红年数 / 查询」这一段包上与最近搜索一致的底色，
   消除用户截图里「前面没背景、后面有背景」的不一致 */
.query-bar {
  padding: 6px 10px;
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--bg-subtle, #f8fafc);
  /* 与下方 .recent-inline 保持相同内边距，使两组视觉等高 */
}

/* 标签与控件垂直居中，避免上沿不齐 */
.query-bar .field {
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.query-bar .field > label {
  font-size: 12px;
  line-height: 1.4;
  margin-bottom: 3px;
}

/* 查询按钮与下拉框、输入框同高 */
.query-bar .btn-primary {
  align-self: flex-end;
}

/* 两组容器高度对齐：recent-inline 与 query-bar 均为两行结构（标签+控件） */
.recent-inline {
  display: flex;
  flex-direction: column;
  justify-content: center;
}

/* ============================================================
   R18：人气榜第二排显示今日涨跌幅（红涨绿跌）
   ============================================================ */
.hot-main {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: center;   /* 与上方标题「居中」要求保持一致 */
  gap: 1px;
}

.hot-name {
  text-align: center;
}

.hot-chg {
  font-size: 10.5px;
  line-height: 1.2;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* A 股口径：红涨绿跌 */
.hot-chg.is-up { color: #dc2626; }    /* 红 */
.hot-chg.is-down { color: #15803d; }  /* 绿 */
.hot-chg.is-flat { color: var(--text-mute); }

/* ============================================================
   R18：人气榜底部说明（用户要求从逗号处换行成两行）
   ============================================================ */
.hot-rail-foot {
  /* 从「，」处断行：第一行「数据来自同花顺」，第二行「每30分钟自动更新」 */
  max-width: 132px;
  margin-left: auto;
  margin-right: auto;
  text-align: center;
  word-break: normal;
  overflow-wrap: break-word;
  line-height: 1.6;
}

/* ============================================================
   R18：右侧锚点 —— 两字一行（不要一字一行）
   ============================================================ */

/* 关键：不能用 word-break: break-all（会逐字断行），
   改用 overflow-wrap: anywhere 只在必要时断词，
   并把标签宽度固定为 2 个汉字宽 → 「公司概况」折成 2+2 两行，
   而非4 个字各占一行 */
.anchor-item {
  width: 32px;
  min-width: 32px;
}

.anchor-label {
  white-space: normal;
  /* 两个 11px 汉字 ≈ 22px；用固定 px 而非 2em，
     因为 2em 会随各自字体大小算出不同值，实测只有 15px 导致一字一行 */
  width: 22px;
  /* break-all 会逐字断行（4 个字各占一行），必须用 normal */
  word-break: normal;
  overflow-wrap: anywhere;
  line-height: 1.3;
  letter-spacing: 0;
}

/* 圆点与文字两行并存时仍保持顶部对齐 */
.anchor-item {
  align-items: flex-start;
}

.anchor-dot {
  margin-top: 3px;
}

/* ============================================================
   R18 补充：两组容器真正等高
   实测：输入框/下拉/按钮均38px（已一致），
   但 .query-bar 高 178px、.recent-inline 仅 92px。
   原因是 query-bar 内多了一组「标签+控件」且 align-items:flex-end 产生额外行距。
   ============================================================ */

/* 让两组的总高度都由「标签行 + 控件行」决定，多余间距由内边距统一 */
.query-bar {
  align-items: stretch;
  min-height: 56px;
}

.query-bar .field {
  justify-content: flex-start;
}

.query-bar .field > label {
  margin-bottom: 4px;
}

/* 查询按钮与控件底边对齐（不再 align-self:flex-end，避免拉高容器） */
.query-bar .btn-primary {
  align-self: flex-end;
  height: 38px;
}

.recent-inline {
  min-height: 56px;
}

/* ============================================================
   R18 修正（放在文件末尾以覆盖前面重复定义）
   实测问题：标签宽仅 15px（2em 在 11px 字号下偏小）→「公司概况」仍一字一行
   ============================================================ */

/* 固定 22px = 两个 11px 汉字实宽，保证 4 字标签折成 2+2 两行 */
.anchor-label {
  width: 22px;
  word-break: normal;        /* 禁用逐字断行 */
  overflow-wrap: anywhere;
  white-space: normal;
}

/* 查询区与最近搜索等高：统一内边距与最小高度 */
.query-bar {
  align-items: center;
  min-height: 62px;
  padding: 8px 12px;
}

.query-bar .field {
  justify-content: center;
  gap: 0;
}

.query-bar .field > label {
  margin-bottom: 3px;
  font-size: 12px;
  line-height: 1.3;
}

.recent-inline {
  min-height: 62px;
  padding: 8px 12px;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

/* ============================================================
   R18 修正（放在文件末尾以覆盖前面重复定义）
   实测问题：标签宽仅 15px（2em 在 11px 字号下偏小）→「公司概况」仍一字一行
   ============================================================ */

/* 固定 22px = 两个 11px 汉字实宽，保证 4 字标签折成 2+2 两行 */
.anchor-label {
  width: 22px;
  word-break: normal;        /* 禁用逐字断行 */
  overflow-wrap: anywhere;
  white-space: normal;
}

/* 查询区与最近搜索等高：统一内边距与最小高度 */
.query-bar {
  align-items: center;
  min-height: 62px;
  padding: 8px 12px;
}

.query-bar .field {
  justify-content: center;
  gap: 0;
}

.query-bar .field > label {
  margin-bottom: 3px;
  font-size: 12px;
  line-height: 1.3;
}

.recent-inline {
  min-height: 62px;
  padding: 8px 12px;
  display: flex;
  flex-direction: column;
  justify-content: center;
}

/* ============================================================
   R18 修正②：.anchor-item 是 flex 容器，label 会被 flex-shrink 压缩
   （实测设width:22px 实际只有 15px）。禁用收缩 + 提高优先级。
   ============================================================ */
.anchor-item {
  width: 34px;
  min-width: 34px;
  max-width: 34px;
}

.anchor-label {
  flex: none !important;      /* 关键：不被 flex 压缩 */
  width: 22px !important;
  min-width: 22px !important;
  word-break: normal !important;
  overflow-wrap: anywhere;
  white-space: normal;
}

/* ============================================================
   R18 修正②：.anchor-item 是 flex 容器，label 会被 flex-shrink 压缩
   （实测设width:22px 实际只有 15px）。禁用收缩 + 提高优先级。
   ============================================================ */
.anchor-item {
  width: 34px;
  min-width: 34px;
  max-width: 34px;
}

.anchor-label {
  flex: none !important;      /* 关键：不被 flex 压缩 */
  width: 22px !important;
  min-width: 22px !important;
  word-break: normal !important;
  overflow-wrap: anywhere;
  white-space: normal;
}

/* ============================================================
   R18 修正③：顶部两组真正等高
   .query-bar（表单，横向）与 .recent-inline（纵向两行）结构不同，
   让它们作为 flex 子项stretch 到同一行高度，而不是各自按内容收缩。
   ============================================================ */

/* .query-bar 本身是 form，需让其内部（.header-main 的 flex 行）等高 */
.header-main {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

/* 查询栏与最近搜索并排成一行，且等高 */
.query-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: stretch;   /* 关键：子项拉伸等高 */
}

/* 最近搜索作为 query-bar 的同级块级元素参与同一 flex 行 */
.query-bar > .recent-inline {
  align-self: stretch;
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-height: auto;
}

/* 查询区内部：标签在上、控件在下，两块整体垂直居中 */
.query-bar > .field {
  display: flex;
  flex-direction: column;
  justify-content: center;
}

/* ============================================================
   R18 修正③：顶部两组真正等高
   .query-bar（表单，横向）与 .recent-inline（纵向两行）结构不同，
   让它们作为 flex 子项stretch 到同一行高度，而不是各自按内容收缩。
   ============================================================ */

/* .query-bar 本身是 form，需让其内部（.header-main 的 flex 行）等高 */
.header-main {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

/* 查询栏与最近搜索并排成一行，且等高 */
.query-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: stretch;   /* 关键：子项拉伸等高 */
}

/* 最近搜索作为 query-bar 的同级块级元素参与同一 flex 行 */
.query-bar > .recent-inline {
  align-self: stretch;
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-height: auto;
}

/* 查询区内部：标签在上、控件在下，两块整体垂直居中 */
.query-bar > .field {
  display: flex;
  flex-direction: column;
  justify-content: center;
}

/* ============================================================
   R19：最近搜索只保留一行
   用户反馈出现纵向滚动条（超出部分需滚动才能看到）。
   改为单行不换行 + 超出隐藏，横向可滚动查看其余记录。
   ============================================================ */
.recent-inline .recent-list {
  flex-wrap: nowrap;              /* 不换行 → 恒定一行 */
  overflow-x: auto;              /* 横向滚动查看其余 */
  overflow-y: hidden;            /* 关键：去掉纵向滚动条 */
  max-height: none;              /* 取消原 max-height 限制 */
  scrollbar-width: thin;
  -webkit-overflow-scrolling: touch;
}

.recent-inline .recent-list::-webkit-scrollbar {
  height: 4px;
}

.recent-inline .recent-list::-webkit-scrollbar-thumb {
  background: var(--border);
  border-radius: 2px;
}

.recent-inline .recent-item {
  flex: none;                    /* 防止被压缩 */
}

/* 空态提示在单行下不应撑高 */
.recent-inline .recent-empty {
  flex: none;
  margin: 0;
  line-height: 1.6;
}

/* ============================================================
   R19：人气榜条目三列布局（序号 / 名称+涨跌幅 / 热度）
   用户反馈：涨跌幅挤在中间，应紧跟名称；
            且整个列表左侧对齐，与右侧锚点风格不一致。
   ============================================================ */

/* 名称与涨跌幅在同一行紧邻，不再是「名称在上、涨跌幅在下」 */
.hot-main {
  display: flex;
  flex-direction: row;        /* 改为横向：名称紧跟涨跌幅 */
  align-items: baseline;
  gap: 4px;
  justify-content: center;
  flex: 0 1 auto;
  min-width: 0;
}

.hot-name {
  flex: none;
}

.hot-chg {
  flex: none;
}

/* 三列整体居中，但整体仍占满按钮宽度（与右侧锚点视觉对齐） */
.hot-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  padding: 4px 6px;
}

/* 热度值固定在右侧，避免随名称长度跳动 */
.hot-heat {
  flex: none;
  margin-left: auto;
  min-width: 34px;
  text-align: right;
}

/* 名称过长时省略，避免挤压热度列 */
.hot-name {
  max-width: 62px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ============================================================
   R21：查询按钮与输入框对齐
   ------------------------------------------------------------
   实测（1440px 视口）：代码输入框 / 年数下拉 均在 y=110..148，
   而按钮仅 align-self:flex-end → 落在 y=112..150，比控件低 2px，
   视觉上「按钮掉下去了」。这里让按钮与控件底边齐平（差 0.5px 内）。
   ============================================================ */
.query-bar .btn-primary {
  align-self: flex-end;
  height: 38px;
  /* 控件行在字段内垂直居中，底部留约 2px 余量；按钮贴底会低 2px，补偿回来 */
  margin-bottom: 2px;
}

/* 窄屏换行后按钮自成一行时，不再需要这个补偿 */
@media (max-width: 560px) {
  .query-bar .btn-primary {
    margin-bottom: 0;
  }
}

/* ============================================================
   R22：卡片底框对齐 / 股东合计占比标红 / 分红率列
   ============================================================ */

/*
 * 1) 爱问财条件选股卡片的底框与其它卡片对齐。
 *    实测（1440px 视口）：
 *      .result-area 内卡片      x=93  w=1240
 *      #iwencai-section 内卡片  x=113 w=1200   ← 左右各窄 20px
 *    原因：R15 把 #iwencai-section 移进 <main class="app-main"> 后，
 *          .app-main 的 padding:20px 与 .app-section 的 padding:0 20px 叠加了两次；
 *          且它作为 .app-main 的直接子元素不参与 .result-area 的 gap:16px，
 *          与上方卡片间距实测为 0。
 *    处理：去掉重复内边距 + 补 16px 上间距，与卡片间距一致。
 */
.app-section {
  max-width: 1280px;
  margin: 16px auto 0;
  padding: 0;
}

/* 2) 前十大股东合计占比 < 50%：整行标红（提示股权相对分散） */
.data-table tfoot tr.is-low-total td {
  color: var(--danger);
}

.footnote-alert {
  color: var(--danger);
}

/* 3) 分红表「分红率」列：数字对齐 + 空值淡化（与其它列的空值表现一致） */
.data-table td.payout-cell {
  font-variant-numeric: tabular-nums;
}

.data-table td.payout-cell.is-empty {
  color: var(--text-mute);
}

/* ============================================================
   R23：查询按钮与输入框严格平齐 / 右下角常驻回顶按钮 / 合计占比只标红数值
   ============================================================ */

/*
 * 1) 查询按钮与输入框平齐。
 *    实测（1440×900，最近搜索 7 条）：
 *      .query-bar        高 103.2px（行高被右侧「最近搜索」面板撑到 85.2px）
 *      #code-input       top=122.7 bottom=160.7
 *      #submit-btn       top=135.0 bottom=173.0   ← 比输入框低 12.3px
 *    原因：查询栏是 flex 行（align-items 生效值 stretch），各 .field 内容
 *          在拉高的行内居中，而按钮 align-self:flex-end 直接贴到行底。
 *    处理：按钮改用与输入框同构的 .field 容器（含一个不可见占位标签，
 *          字号/行高/下边距与真实标签完全一致），于是按钮与输入框同处
 *          「标签行 + 控件行」结构中，无论行高如何变化都严格对齐。
 *    下面同时把旧的 align-self:flex-end 与 margin-bottom:2px 归零。
 */
.query-bar .field-action {
  display: flex;
  flex-direction: column;
  justify-content: center;
  flex: 0 0 auto;
}

.query-bar .field-ghost {
  /* 与 .query-bar .field > label 完全同参，仅不可见 */
  visibility: hidden;
  font-size: 12px;
  font-weight: 600;
  line-height: 1.3;
  margin-bottom: 3px;
}

.query-bar .field-action .btn-primary {
  align-self: flex-start;
  flex: 0 0 auto;
  height: 38px;
  margin: 0;
}

/*
 * 窄屏（≤768px，与站内其它窄屏断点一致）查询栏会换行、按钮自成一行，
 * 此时占位标签只会带来一段无意义的空白，直接隐藏。
 * 断点取 768 是实测结果：769~800px 仍未换行（占位标签继续保证平齐），
 * ≤768px 换行（隐藏占位标签，按钮在自己的行内正常居中）。
 */
@media (max-width: 768px) {
  .query-bar .field-ghost {
    display: none;
  }
}

/* 2) 右下角常驻回顶按钮（fixed，任何滚动位置都可点） */
.to-top {
  position: fixed;
  right: 24px;
  bottom: 24px;
  z-index: 80;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1px;
  width: 46px;
  height: 52px;
  padding: 0;
  border: none;
  border-radius: 12px;
  background: #dc2626;
  color: #fff;
  font-family: inherit;
  font-size: 11px;
  line-height: 1.1;
  cursor: pointer;
  box-shadow: 0 6px 16px rgba(220, 38, 38, 0.32);
  transition: background 0.15s, transform 0.15s, box-shadow 0.15s;
}

.to-top:hover {
  background: #b91c1c;
  transform: translateY(-2px);
  box-shadow: 0 10px 22px rgba(220, 38, 38, 0.38);
}

.to-top:active {
  transform: translateY(0);
}

.to-top:focus-visible {
  outline: 3px solid rgba(220, 38, 38, 0.35);
  outline-offset: 2px;
}

.to-top-arrow {
  font-size: 17px;
  line-height: 1;
}

/* 小屏收成圆形，避免遮挡内容 */
@media (max-width: 560px) {
  .to-top {
    right: 14px;
    bottom: 14px;
    width: 40px;
    height: 40px;
    border-radius: 50%;
  }
  .to-top-text {
    display: none;
  }
  .to-top-arrow {
    font-size: 18px;
  }
}

/* 3) R23 修订：前十大股东合计占比 < 50% 时「只标红数值」，前面的说明文字保持常规颜色 */
.data-table tfoot tr.is-low-total td {
  color: var(--text);
}

.data-table tfoot td.is-low-value,
.data-table tfoot .low-value {
  color: var(--danger);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

/* 数值后的补充说明（如「部分股东占比缺失」）保持常规颜色，避免整行发红 */
.data-table tfoot .low-note {
  color: var(--text-sub);
  font-weight: 400;
}

/* 表尾补充说明不再整段标红（用户要求「只需要数值标红」） */
.footnote-alert {
  color: inherit;
  font-weight: 600;
}

/* ============================================================
   R24：顶部底框宽度 / 中文联想 / 剪贴板监控 / 轻提示 / 规模排版 / 移动端
   ============================================================ */

/*
 * 1) 顶部「背景底框」与下方内容底框宽度不一致（用户截图：右上角指向查询区，
 *    右下角指向内容区，两条边不齐；放大缩小时时好时坏）。
 *
 *    实测（查询 600519 后，最近搜索 7 条）：
 *      视口 1800/1600/1440  → 查询栏宽 1055.7px，内容卡片宽 1240px   ← 差 184.3px
 *      视口 1024/960/900    → 查询栏与卡片同宽（都是 945/905/845）
 *    根因：`.query-bar` 是 `.header-inner`（flex, wrap）的子项，而
 *          `.header-inner` 默认给子项 `flex: 0 1 auto` —— 查询栏宽度是
 *          **由内容撑出的 max-content（1055.7px）**，行内还有空余也不会拉伸；
 *          只有当可用宽度小于 max-content 时才会被压到「刚好等于容器宽」。
 *          于是「宽屏窄一截、窄屏又刚好齐」，缩放一下就会跳。
 *    处理：让它独占一行并撑满容器（标题在第 1 行、查询区在第 2 行，本就如此），
 *          宽度即等于 `.header-inner` 内容宽 = `.app-main` 内容宽 = 卡片宽。
 */
.header-inner > .query-bar {
  flex: 1 0 100%;
  min-width: 0;
}

/* 2) 中文名/代码联想下拉（R24） */
.field-code {
  position: relative;
}

.suggest-panel {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  z-index: 45;
  width: max(280px, 100%);
  max-height: 292px;
  overflow-y: auto;
  padding: 4px;
  border: 1px solid var(--border-strong);
  border-radius: 10px;
  background: var(--card-bg);
  box-shadow: 0 12px 28px rgba(15, 23, 42, 0.16);
}

.suggest-panel[hidden] {
  display: none;
}

.suggest-item {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 8px 10px;
  border: none;
  border-radius: 7px;
  background: transparent;
  font-family: inherit;
  font-size: 13px;
  color: var(--text);
  text-align: left;
  cursor: pointer;
}

.suggest-item:hover,
.suggest-item.is-active {
  background: var(--primary-weak, #eff6ff);
}

.suggest-code {
  flex: 0 0 auto;
  font-variant-numeric: tabular-nums;
  font-weight: 700;
  color: var(--primary);
}

.suggest-name {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.suggest-type {
  flex: 0 0 auto;
  color: var(--text-mute);
  font-size: 11.5px;
}

/* R28：在线联想不可达、改由本机内置名录匹配时的顶部说明 */
.suggest-note {
  margin: 0;
  padding: 6px 10px;
  border-bottom: 1px solid var(--border);
  color: var(--text-mute);
  font-size: 11.5px;
  line-height: 1.5;
}

/* 3) 剪贴板监控开关（R24） */
.clip-toggle {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 38px;
  padding: 0 12px;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background: #fff;
  color: var(--text-sub);
  font-family: inherit;
  font-size: 12.5px;
  white-space: nowrap;
  cursor: pointer;
  transition: border-color 0.15s, background 0.15s, color 0.15s;
}

.clip-toggle:hover {
  border-color: var(--primary);
  color: var(--primary);
}

.clip-toggle.is-on {
  border-color: #16a34a;
  background: #f0fdf4;
  color: #15803d;
}

.clip-dot {
  width: 8px;
  height: 8px;
  flex: 0 0 auto;
  border-radius: 50%;
  background: var(--text-mute);
}

.clip-toggle.is-on .clip-dot {
  background: #16a34a;
  box-shadow: 0 0 0 3px rgba(22, 163, 74, 0.18);
}

/* 4) 全局轻提示（fixed，不参与文档流，绝不引起布局跳动） */
.toast {
  position: fixed;
  top: calc(16px + env(safe-area-inset-top, 0px));
  left: 50%;
  transform: translateX(-50%);
  z-index: 120;
  max-width: min(560px, calc(100vw - 32px));
  padding: 10px 16px;
  border: 1px solid var(--border-strong);
  border-radius: 10px;
  background: var(--card-bg);
  color: var(--text);
  font-size: 13px;
  line-height: 1.5;
  box-shadow: 0 12px 30px rgba(15, 23, 42, 0.18);
}

.toast[hidden] {
  display: none;
}

.toast.is-error {
  border-color: #fecaca;
  background: #fef2f2;
  color: #b91c1c;
}

/* 5) 基金规模：金额独立不折行，规模日期另起一行小字（R24） */
.desc-item.is-stack {
  flex-wrap: wrap;
}

.desc-item.is-stack .desc-value {
  flex: 1 0 auto;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

.desc-item.is-stack .desc-note-inline {
  flex: 0 0 100%;
  margin-top: 2px;
  font-size: 11px;
  line-height: 1.4;
}

/* ============================================================
   R24：移动端适配（为打包成 App 做准备）
   ------------------------------------------------------------
   目标机型：iPhone SE(375) ~ 主流安卓(360-430) 的 WebView。
   要点：防止 iOS 聚焦缩放、点击热区 ≥ 40px、表格横向滚动、
        刘海/小白条安全区、标题栏换行不溢出。
   ============================================================ */
@media (max-width: 768px) {
  /* ① 顶部副标题（6 个跳转项）允许换行，不再 nowrap 溢出 */
  .brand-sub {
    white-space: normal;
    line-height: 1.9;
  }

  /* ② iOS 在 font-size < 16px 的输入控件聚焦时会强制放大页面，这里统一提到 16px */
  .field input,
  .field select,
  .recent-inline .recent-name,
  .recent-inline .recent-code {
    font-size: 16px;
  }

  .recent-inline .recent-name {
    font-size: 13px;
  }
  .recent-inline .recent-code {
    font-size: 12px;
  }

  /* ③ 点击热区：所有按钮至少 40px 高 */
  .btn,
  .clip-toggle,
  .hot-refresh {
    min-height: 40px;
  }

  /* ④ 卡片与页脚留白收紧，信息密度更高 */
  .card {
    padding: 14px 13px;
    border-radius: 10px;
  }

  .result-area {
    gap: 12px;
  }

  .app-main {
    padding-top: 14px;
  }

  /* ⑤ 表格：保持横向滚动（.data-table 已有 min-width:640px），
        并让滚动条更贴近手指习惯 */
  .table-wrap {
    -webkit-overflow-scrolling: touch;
    scrollbar-width: thin;
  }

  /* ⑥ 联想下拉在手机上占满输入框宽度 */
  .suggest-panel {
    width: 100%;
    max-height: 46vh;
  }
}

/* ⑦ 安全区：底部小白条 / 刘海屏（打包成 App 后必需，浏览器里 env() 为 0 不影响） */
.app-footer {
  padding-bottom: calc(18px + env(safe-area-inset-bottom, 0px));
}

@media (max-width: 560px) {
  .to-top {
    bottom: calc(14px + env(safe-area-inset-bottom, 0px));
  }

  /* 手机上超长的「区间累计/分红次数」等数字列改为两列更省空间 */
  .metric-grid {
    grid-template-columns: repeat(auto-fill, minmax(132px, 1fr));
  }

  .metric-value {
    font-size: 17px;
  }

  .card-header h2 {
    font-size: 15px;
  }

  .brand h1 {
    font-size: 17px;
  }
}

/* ============================================================
   R25：季度营业额 / 资产负债率 趋势图 + 股权分散提示整句标红
        + 分红表倒序（最新在最上）
   ============================================================ */

/* ① 合计占比低于 50% 时，那句结论整句标红。
    为什么是独立类而非直接改 .footnote-alert：
      R23 曾应要求把 .footnote-alert 调成 inherit（只让数值标红）；
      但「股权相对分散」这句是**结论性警示**，用户要求它出现时必须醒目标红。
      用 .footnote-alert.is-critical 精确命中这一句，其余附注维持 R23 的配色。 */
.footnote-alert.is-critical {
  color: var(--danger);
  font-weight: 600;
}

/* ============================================================
   R29：手机端兼容性修复
   ------------------------------------------------------------
   用 headless Chrome 在 320/375/390/412 四种宽度下实测（含点完查询后的
   满内容态），发现以下问题，逐条修复。前两条是**功能性缺陷**，不是外观问题。
   ============================================================ */
@media (max-width: 768px) {
  /* ① 【致命】取消顶栏吸顶。
     手机上查询表单纵向堆叠后，.app-header 实测高达 725px（iPhone 14 视口 844px 的 86%）。
     它同时是 position:sticky(top:0)，于是滚动时整块钉在顶部，
     内容区只剩底部一条缝 —— 表现就是「页面几乎滚不动、往下看不到内容」。
     桌面端 header 只有 ~150px，吸顶是合理的，因此只在窄屏取消。 */
  .app-header {
    position: static;
  }

  /* ② 【致命】「最近搜索」不再被当成 320px 高。
     .recent-inline 的 `flex: 1 1 320px` 在桌面是横向排布的**宽度**，
     但窄屏 .query-bar 改成 flex-direction:column 后，320px 变成了**高度**，
     min-width:240px 同样变 min-height —— 实测把查询栏从 ~250px 撑到 571px，
     中间一大片空白（截图里最显眼的问题）。 */
  .recent-inline {
    /* 必须是 1 1 100%（而不是 0 0 auto）：
       ⑥ 把 .query-bar 改回 row 后，flex-basis:auto 会让它以**内容宽度**展开，
       实测被撑到 493px > 390px 视口，整页出现横向滚动。 */
    flex: 1 1 100%;
    min-width: 0;
  }

  /* ③ 中文可在任意字符间断行，顶部 6 个跳转项会被拆词：
     实测「条件选股」被拆成上一行结尾的「条」+ 下一行的「件选股」。
     逐项 nowrap 后整体换行单位变成整个词，同时给足点击热区。 */
  .brand-sub {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 2px 2px;
  }

  .brand-link {
    display: inline-block;
    white-space: nowrap;
    /* 热区高度 18px → 38px（iOS/安卓推荐 ≥ 40px，此处配合行高已足够好点） */
    padding: 10px 4px;
    line-height: 1.2;
  }

  .brand-sep {
    margin: 0 1px;
  }

  /* ④ 触控热区补足：删除按钮宽度只有 22px，手指几乎点不到 */
  .recent-del {
    min-width: 36px;
    min-height: 44px;
  }

  /* ⑤ 爱问财的两个控件只有 33px 高，低于可点阈值。
       注意 #pick-input 没有类名（样式挂在 .pick-row input 上），
       因此这里按结构选，否则规则会静默不命中。 */
  .pick-row input,
  .pick-select {
    min-height: 40px;
  }

  /* ⑥ 纵向空间优化：查询栏排成「两行」——
       第一行代码框、年数各占整行（输入要宽），第二行按钮与剪贴板开关并排。
       原来 1211 行的 .query-bar{flex-direction:column} 让每个控件各占一行，
       header 无谓地高出约 54px（手机上相当于整屏的 6%）。
       注意必须先改回 row，否则下面的 calc(50%) 会被当成**高度**（同 ② 的坑）。 */
  .query-bar {
    flex-direction: row;
    flex-wrap: wrap;
    align-items: flex-end;
  }

  .field-code,
  .field-years {
    flex: 1 1 100%;
    min-width: 0;
  }

  .field-action,
  .field-clip {
    flex: 1 1 calc(50% - 6px);
    min-width: 0;
  }

  .field-clip .clip-toggle {
    width: 100%;
    justify-content: center;
  }

  /* ⑦ 表格横向滚动时给一个可见提示：右侧渐隐，暗示「还能往右拖」 */
  .table-wrap {
    position: relative;
  }

  .table-wrap::after {
    content: '';
    position: absolute;
    top: 0;
    right: 0;
    width: 22px;
    height: 100%;
    pointer-events: none;
    background: linear-gradient(to right, rgba(255, 255, 255, 0), rgba(255, 255, 255, 0.9));
  }
}

/* ============================================================
   R30：ETF「趋势图表」卡内的状态占位
   ------------------------------------------------------------
   ETF 查询时净值数据要等分红接口返回才有，中间是加载态；
   净值取不到时是空态。两者都需要在图表容器里居中显示，
   否则卡片在数据到位前就是一片空白。
   ============================================================ */
.chart-container .state-box {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-height: 220px;
  height: 100%;
}

.state-box.is-loading {
  background: #fafbfd;
  border-color: var(--border);
  color: var(--text-mute);
}

/* 空态的第二行说明：字号更小、颜色更淡，与主提示拉开层级 */
.state-box .state-hint {
  margin: 0;
  font-size: 12.5px;
  line-height: 1.7;
  color: var(--text-mute);
  max-width: 560px;
}
