/* ============================================================================
   tryaiapi-modern.css — V11 现代化设计系统共享壳（2026-07-04）
   适用：home-V11 / models / docs / transparency / legal 新一代公开前台页
   主题机制：tryaiapi-site.js 管理 body.ifw-theme-dark（localStorage
   infwave_public_theme），本文件所有 token 定义在 body 层以便 class 覆盖。
   设计权威源：frontend/docs/Design_Language_Statement.md §VI/§VII
   列宽规则：AI_Workspace/agents/frontend-ui.md § 数据表格列宽节奏规则
   ============================================================================ */

/* ---------- tokens ---------- */
body.ifw-public-page {
  --paper: #fbfbfd;
  --panel: #ffffff;
  --ink: #10141a;
  --mute: #5b6472;
  --faint: #8a93a1;
  --line: rgba(16, 20, 26, 0.09);
  --line-strong: rgba(16, 20, 26, 0.16);
  --accent: #ea580c;
  --accent-soft: rgba(234, 88, 12, 0.08);
  --term-bg: #14181f;
  --term-ink: #d8dee8;
  --term-mute: #7d8797;
  --term-str: #f0a36b;
  --ok: #34c759;
  --no: #e5484d;
  --shadow: 0 1px 2px rgba(16, 20, 26, 0.04);
  --shadow-lift: 0 10px 30px rgba(16, 20, 26, 0.07);
  --sans: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif;
  --mono: ui-monospace, "SF Mono", "JetBrains Mono", Menlo, Consolas, monospace;
  /* mobile nav CTA guard aliases（check_mobile_nav_cta.py REQUIRED_DECLARATIONS） */
  --ink-900: #10141a;
  --canvas: #fbfbfd;
}
body.ifw-public-page.ifw-theme-dark {
  --paper: #0b0d11;
  --panel: #11141a;
  --ink: #f0f2f6;
  --mute: #9aa3b0;
  --faint: #6b7482;
  --line: rgba(240, 242, 246, 0.09);
  --line-strong: rgba(240, 242, 246, 0.18);
  --accent: #f0762e;
  --accent-soft: rgba(240, 118, 46, 0.10);
  --term-bg: #12161d;
  --shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
  --shadow-lift: 0 10px 30px rgba(0, 0, 0, 0.4);
  --ink-900: #f0f2f6;
  --canvas: #0b0d11;
}

/* ---------- base ---------- */
body.ifw-public-page {
  margin: 0;
  font-family: var(--sans);
  background: var(--paper);
  color: var(--ink);
  font-size: 15px;
  line-height: 1.75;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
body.ifw-public-page *,
body.ifw-public-page *::before,
body.ifw-public-page *::after { box-sizing: border-box; }
body.ifw-public-page a { color: inherit; text-decoration: none; }
body.ifw-public-page img { max-width: 100%; display: block; }
body.ifw-public-page :focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 4px; }
/* UA heading-margin neutralization (round 4, owner 2026-07-04: docs SDK 卡片
   客户端标题"行高特别高"). UA default heading margins (h4 = 1.33em ≈ 20px each
   side at 15px!) are never part of this design system — they silently inflated
   .ifw-sdk-card-head to 91px for a single 15px line, and 12 rule-groups across
   docs/transparency (measured via live getComputedStyle scan) leaked them.
   Home/models/legal already declare explicit margins on every heading.
   Bare element selector ON PURPOSE (specificity 0,0,1): author rules always
   beat UA defaults regardless of specificity, but this must LOSE to any
   page-level class rule (e.g. `.ifw-step h4 { margin-bottom: 6px }`) so pages
   opt INTO spacing instead of inheriting UA noise. Do NOT "strengthen" this
   selector with a body prefix — that would override page rules' partial
   margins (the §8D specificity class of bug, in reverse).
   Guarded by check_mobile_nav_cta.py (heading-reset invariant, manifest-driven). */
h1, h2, h3, h4, h5, h6 { margin: 0; }

.ifw-shell { max-width: 1220px; margin: 0 auto; padding: 0 28px; }
/* 固定导航下的页面首屏留白（contract 要求的 ifw-nav-offset 语义） */
.ifw-nav-offset { padding-top: 108px; }

/* ---------- nav（渲染 render_public_english.nav() 输出的既有结构） ---------- */
body.ifw-public-page .ifw-nav-wrap {
  position: fixed; top: 0; left: 0; right: 0; z-index: 50;
  background: color-mix(in srgb, var(--paper) 78%, transparent);
  -webkit-backdrop-filter: saturate(180%) blur(16px);
  backdrop-filter: saturate(180%) blur(16px);
  border-bottom: 1px solid var(--line);
}
/* Round-3 sizing (owner 2026-07-04: "左轻右重、小气" — the left cluster gets one
   step heavier to balance the big dark CTA on the right): bar 54px→62px, brand
   16px→18px (glyph follows via em), links 14.5px→15.5px. .ifw-nav-offset (108px)
   stays: taller bar + round-3's 15-20% whitespace tightening cancel out. */
body.ifw-public-page .ifw-nav {
  max-width: 1220px; margin: 0 auto; padding: 0 28px; height: 62px;
  display: flex; align-items: center; gap: 28px;
}
/* Round-4 brand size (owner 2026-07-04: logo must read "视觉上大一点点" than the
   nav links; at 18px it read the same). Compare INK HEIGHT, not font-size:
   Latin caps occupy ~0.705em (measured live: 'API' ink 12.68px @18px) while
   CJK glyphs fill ~0.94em (measured: 模型市场 ink 14.5px @15.5px) — so an 18px
   Latin lockup is optically SHORTER than 15.5px CJK links (12.68 vs 14.5).
   22px puts brand caps at ~15.5px ink (+7% over the links) and the 0.75em
   glyph at 16.5px (+14%) — one visible step up, in both locales (EN links'
   Latin x-height ~11px ink is comfortably cleared). If resizing either side,
   re-derive from ink height: brandCap = fs × 0.705 vs cjkInk = fs × 0.94. */
body.ifw-public-page .ifw-brand {
  display: flex; align-items: center; gap: 7px; flex: none;
  font-size: 22px; font-weight: 700; letter-spacing: -0.01em; white-space: nowrap;
}
/* Try/[glyph]/API lockup spacing: V11 first shipped with the generic `.ifw-brand
   { gap: 7px }` applying UNIFORMLY between all three children (Try↔glyph AND
   glyph↔API), which owner flagged as "空隙有点大" (2026-07-04, second-round
   feedback) and asked to restore the V9-era rhythm instead of V11's reinvention.
   V9 (tryaiapi-public.css) never used a uniform flex gap for this lockup — it
   zeroed the gap on the lockup variant specifically and hand-tuned an
   ASYMMETRIC margin on the glyph itself (tighter on the Try side, slightly
   looser on the API side) so the glyph optically sits mid-word instead of
   looking like a 3rd separate item. Restore that exact ported values (em-based
   so it keeps scaling with .ifw-brand's own font-size, same reasoning as the
   cap-height fix below) — do not reintroduce a uniform gap for this variant. */
body.ifw-public-page .ifw-brand.ifw-brand-tryaiapi { gap: 0; }
/* 0.75em ≈ text cap-height (0.705em at this font-size) + ~1px optical overshoot
   for the pointed-apex "AI" glyph, so the mark visually matches Try/API instead
   of looming above them. Ported from tryaiapi-public.css (V9) cap-height fix —
   V11 shipped with a flat 20px (≈1.25em, ~2x cap-height) that owner flagged as
   "太大" on 2026-07-04. Keep this em-relative so it self-scales with .ifw-brand
   font-size instead of drifting back to a magic px number. See gateway-frontend.md §19b
   + §39 (V11 mobile/logo fixup incident). */
body.ifw-public-page .ifw-brand-glyph-img {
  height: 0.75em; width: auto;
  /* ported 1:1 from tryaiapi-public.css's `.ifw-brand-glyph-img { margin: 0
     0.20em 0 0.10em }` — asymmetric on purpose (V9 comment: glyph is a
     pointed-apex mark, needs slightly more breathing room on its trailing/API
     side than its leading/Try side to look optically centered). */
  margin: 0 0.20em 0 0.10em;
}
body.ifw-theme-dark .ifw-brand-glyph-img { filter: brightness(0) invert(1); }
/* Alternate lockup variant (class .ifw-brand-iwkey, non-hk deploy profile
   only — deploy_public_frontend.py's apply_profile_brand() emits this class,
   never present in hk's own HTML, so this rule cannot affect the primary
   lockup above). PORTED 1:1 from tryaiapi-public.css (V9 shell), where it
   was established and owner-verified in D-042 (commit d0e6262, 2026-06-08)
   — see ALT_LOCKUP_GLYPH_SCALE in deploy_public_frontend.py for the full
   reasoning. Gap zeroed to match the primary lockup's own spacing model
   above (the glyph's own asymmetric margin does the spacing, not flex gap).
   RECURRENCE WARNING (2026-07-14): this override was SILENTLY DROPPED when
   the V11 shell (this file) was authored from scratch on 2026-07-04 — only
   the decorative-glyph base rule above was ported, not this variant-scoped
   one — regressing this lockup's glyph back to the primary lockup's small
   decorative size until owner reported the brand mark read too small.
   check_iwkey_glyph_sizing.py asserts this rule exists at >=1.8x the base
   height; do NOT re-derive this value by eye if it goes missing again —
   restore this exact block. */
body.ifw-public-page .ifw-brand.ifw-brand-iwkey { gap: 0; }
body.ifw-public-page .ifw-brand-iwkey .ifw-brand-glyph-img {
  height: 1.5em;
  transform: translateY(2px);
}
body.ifw-public-page .ifw-brand-try, body.ifw-public-page .ifw-brand-api,
body.ifw-public-page .ifw-brand-key { line-height: 1; }
/* Non-scrolling wrapper around .ifw-nav-links: hosts the "more content"
   fade-mask overlay (in the media query below) at a FIXED position relative
   to the nav row, independent of .ifw-nav-links' own internal scroll offset
   — a pseudo-element on .ifw-nav-links itself would scroll away with the
   content instead of staying pinned at the viewport edge. flex:1 + min-width:0:
   the scroll region absorbs ALL width pressure so the brand (left) and the
   .ifw-nav-right tool group + CTA (right) stay full-size and permanently
   visible (owner 2026-07-04 second-round feedback: "导航条太宽，要往左滑才能
   看到进入控制台按钮...这个按钮很重要...没有任何提示，横向滚动条太丑" — CTA
   persistent + fade hint instead of an undiscoverable scroll-to-reveal
   control). Round 3 dropped the old margin-left:auto: links now sit LEFT,
   next to the brand ("左 = logo + 页面导航链接"). */
body.ifw-public-page .ifw-nav-scroll {
  position: relative; flex: 1 1 auto; min-width: 0;
}
body.ifw-public-page .ifw-nav-links {
  display: flex; align-items: center; gap: 28px;
  font-size: 15.5px; font-weight: 500; color: var(--mute);
  /* min-width:0 lets this shrink to fit inside .ifw-nav-scroll's own box so
     overflow-x:auto (below) can actually kick in as horizontal scroll instead
     of the browser squeezing/wrapping each child's text vertically. Without
     this, narrow viewports wrapped every 2-char CJK nav label into a vertical
     stack (owner-reported "导航条按钮变成纵向排列", 2026-07-04 first-round
     feedback). */
  min-width: 0;
}
body.ifw-public-page .ifw-nav-links > a {
  padding: 4px 0; transition: color .15s; cursor: pointer;
  /* nowrap + flex:none: prevent per-item text wrap and per-item shrink so the
     row overflows horizontally (scrollable) instead of squeezing each label
     into a multi-line stack. Pair with .ifw-nav-links min-width:0 above. */
  white-space: nowrap; flex: none;
}
body.ifw-public-page .ifw-nav-links > a:hover { color: var(--ink); }
body.ifw-public-page .ifw-nav-links > a.active { color: var(--ink); font-weight: 600; }
body.ifw-public-page .ifw-lang-switch { font-size: 13px; color: var(--faint); }
/* Right-side tool group (round 3, owner 2026-07-04: "右 = 工具组(铃铛/明暗/EN)
   + 进入控制台 CTA"). nav() (render_public_english.py) emits this container
   holding the lang switch + CTA; tryaiapi-site.js ensurePublicShellControls()
   injects its .ifw-nav-utilities (bell + theme toggle) INTO it, before the
   lang switch. flex:none: the group is the fixed right anchor — all width
   pressure must land on .ifw-nav-scroll (min-width:0), never squeeze the
   tools/CTA (same non-shrink class of bug as .ifw-nav-utilities below,
   guarded by check_mobile_nav_cta.py). margin-left:auto is defensive
   (no-op while .ifw-nav-scroll is flex:1). */
body.ifw-public-page .ifw-nav-right {
  display: flex; align-items: center; gap: 14px; flex: none; margin-left: auto;
}
body.ifw-public-page .ifw-nav-right .ifw-lang-switch:hover { color: var(--ink); }
/* CTA is emitted inside .ifw-nav-right (round 3; previously a bare .ifw-nav
   child), still NOT nested inside the scrollable .ifw-nav-links — see
   render_public_english.py nav(). flex:none so it's never shrunk or
   scrolled away regardless of how narrow .ifw-nav-scroll gets. */
body.ifw-public-page .ifw-nav-cta {
  font-size: 14px; font-weight: 600; background: var(--ink); color: var(--paper);
  padding: 8px 18px; border-radius: 8px; transition: opacity .15s;
  flex: none; white-space: nowrap;
}
body.ifw-public-page .ifw-nav-cta:hover { opacity: .85; color: var(--paper); }
/* site.js 注入的 utility 控件（主题切换 / locale 菜单）。tryaiapi-site.js
   ensurePublicShellControls() 创建 <span class="ifw-nav-utilities"> 作为
   .ifw-nav-links 的**直接子元素**（在 lang-switch 之前插入），内含两个
   <span class="ifw-nav-utility">（bell / theme toggle）。V11 首版只样式化了
   .ifw-nav-utility 单数类，完全漏了 .ifw-nav-utilities 复数 wrapper 和两者的
   flex:none——结果这块在窄屏被当成可收缩 flex item 挤压，与 nav 链接一起错位
   （owner "导航条位置不对" 的一部分根因）。两个类都必须显式非收缩。 */
body.ifw-public-page .ifw-nav-utilities { display: inline-flex; align-items: center; gap: 8px; flex: none; }
body.ifw-public-page .ifw-nav-utility { display: inline-flex; align-items: center; position: relative; flex: none; }
body.ifw-public-page .ifw-icon-button {
  width: 30px; height: 30px; border-radius: 8px; border: 1px solid var(--line);
  background: transparent; color: var(--mute); cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center;
}
body.ifw-public-page .ifw-icon-button:hover,
body.ifw-public-page .ifw-nav-utility.is-open .ifw-icon-button { color: var(--ink); border-color: var(--line-strong); background: var(--accent-soft); }
/* Icon ink MUST be explicitly bound to currentColor (round 4, owner
   2026-07-04: dark-mode 铃铛/月亮"几乎看不见"). site.js publicIcon() emits
   outline-style paths with NO fill/stroke attributes — they are drawn for
   stroke rendering and rely on CSS for ink. V11 first shipped only
   width/height here, so the SVGs fell back to the UA default paint
   (fill:black, stroke:none): solid black blobs in light mode, near-invisible
   black-on-dark in dark mode (the sun's ray strokes vanished entirely,
   leaving a lone black dot). Ported 1:1 from tryaiapi-public.css (V9), which
   always carried these four declarations. currentColor chains to
   .ifw-icon-button's `color: var(--mute)` → flips with the theme tokens, no
   per-theme override needed. Guarded by check_mobile_nav_cta.py
   (icon-ink invariant, manifest-driven). */
body.ifw-public-page .ifw-icon-button svg {
  width: 15px; height: 15px;
  fill: none; stroke: currentColor; stroke-width: 2;
  stroke-linecap: round; stroke-linejoin: round;
}

@media (max-width: 1040px) {
  body.ifw-public-page .ifw-nav { gap: 14px; }
  body.ifw-public-page .ifw-nav-links { gap: 14px; font-size: 13px; overflow-x: auto; -webkit-overflow-scrolling: touch; scrollbar-width: none; }
  body.ifw-public-page .ifw-nav-links::-webkit-scrollbar { display: none; }
  /* "more content" hint replacing the (now-hidden) native scrollbar: a
     right-edge fade on .ifw-nav-scroll — the NON-scrolling wrapper, so the
     fade stays pinned at the viewport edge instead of scrolling away with
     .ifw-nav-links' content. Static/always-on rather than scroll-position-
     -aware (no JS needed): simplest thing that satisfies the ask ("横向滚动条
     太丑...没有任何提示" — the CTA itself no longer needs "discovering" since
     it's permanently visible outside this region; this fade only needs to
     signal "there's more here", not track the exact scroll offset). */
  body.ifw-public-page .ifw-nav-scroll::after {
    content: ""; position: absolute; top: 0; right: 0; bottom: 0; width: 22px;
    background: linear-gradient(to right, transparent, var(--paper));
    pointer-events: none;
  }
  body.ifw-public-page .ifw-nav-cta {
    border: 1px solid var(--ink);
    border-color: var(--ink-900) !important;
    background: var(--ink-900) !important;
    color: var(--canvas) !important;
    padding: 6px 13px; white-space: nowrap;
  }
}


/* site.js utility dropdowns（公告 / 语言菜单）：默认隐藏，is-open 展开 */
body.ifw-public-page .ifw-nav-badge {
  position: absolute; top: 2px; right: 1px; min-width: 14px; height: 14px;
  display: none; align-items: center; justify-content: center; padding: 0 4px;
  border-radius: 999px; background: var(--accent); color: #fff;
  font-size: 9px; line-height: 1; font-weight: 700;
}
body.ifw-public-page .ifw-nav-badge[data-count]:not([data-count="0"]) { display: inline-flex; }
body.ifw-public-page .ifw-control-menu,
body.ifw-public-page .ifw-announcement-panel {
  position: absolute; top: calc(100% + 10px); right: 0; z-index: 160;
  display: none; min-width: 180px; padding: 6px;
  border: 1px solid var(--line-strong); border-radius: 10px;
  background: var(--panel); box-shadow: var(--shadow-lift);
}
body.ifw-public-page .ifw-nav-utility.is-open .ifw-control-menu,
body.ifw-public-page .ifw-nav-utility.is-open .ifw-announcement-panel { display: grid; gap: 2px; }
body.ifw-public-page .ifw-control-menu button,
body.ifw-public-page .ifw-control-menu a {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  width: 100%; padding: 7px 10px; border: none; border-radius: 7px;
  background: transparent; color: var(--mute); font-size: 13px;
  font-family: var(--sans); cursor: pointer; text-align: left;
}
body.ifw-public-page .ifw-control-menu button:hover,
body.ifw-public-page .ifw-control-menu a:hover { background: var(--accent-soft); color: var(--ink); }
body.ifw-public-page .ifw-announcement-panel { width: min(340px, calc(100vw - 32px)); padding: 12px; gap: 10px; }
body.ifw-public-page .ifw-announcement-panel h3 { margin: 0; color: var(--ink); font-size: 14px; font-weight: 600; }
body.ifw-public-page .ifw-announcement-list { display: grid; gap: 8px; max-height: 320px; overflow: auto; }
body.ifw-public-page .ifw-announcement-item { padding: 9px 10px; border: 1px solid var(--line); border-radius: 8px; background: var(--paper); }
body.ifw-public-page .ifw-announcement-item b { display: block; margin-bottom: 3px; color: var(--ink); font-size: 12px; }
body.ifw-public-page .ifw-announcement-item p { margin: 0; color: var(--mute); font-size: 12px; line-height: 1.45; }

/* ---------- section 语法 ---------- */
/* Round-3 density pass (owner 2026-07-04): all section-level 90px-class gaps
   tightened 15-20% site-wide (92→76 here; .ifw-foot below; page-level
   .hm-hero/.hm-stats/.hm-sitefoot in home-V11). Keep the RATIOS if adjusting. */
.ifw-sec { padding-top: 76px; }
.ifw-kicker {
  font-size: 12px; font-weight: 650; color: var(--accent); letter-spacing: .16em;
  display: flex; align-items: center; gap: 10px;
}
.ifw-kicker::before { content: ""; width: 16px; height: 1.5px; background: var(--accent); border-radius: 1px; }
.ifw-h1 { font-size: 28px; font-weight: 650; letter-spacing: -0.018em; line-height: 1.35; margin: 14px 0 0; }
.ifw-h1-lg { font-size: 34px; letter-spacing: -0.02em; line-height: 1.3; margin-top: 16px; }
.ifw-h2 { font-size: 26px; font-weight: 650; letter-spacing: -0.015em; line-height: 1.35; margin: 14px 0 0; }
.ifw-h1 .acc, .ifw-h2 .acc { color: var(--accent); }
.ifw-sub { font-size: 15px; color: var(--mute); margin: 10px 0 0; max-width: 560px; }
.ifw-sec-head { margin-bottom: 30px; }

/* ---------- buttons ---------- */
.ifw-btn {
  display: inline-flex; align-items: center; gap: 8px;
  font-size: 14px; font-weight: 600; border-radius: 10px; padding: 10px 20px;
  transition: all .15s; border: 1px solid transparent; cursor: pointer; font-family: var(--sans);
}
body.ifw-public-page .ifw-btn-primary, .ifw-btn-primary { background: var(--ink); color: var(--paper); }
body.ifw-public-page a.ifw-btn-primary:hover { opacity: .85; color: var(--paper); }
body.ifw-public-page .ifw-btn-ghost, .ifw-btn-ghost { border-color: var(--line-strong); color: var(--ink); background: transparent; }
.ifw-btn-ghost:hover { background: var(--panel); border-color: var(--faint); }

/* ---------- cards ---------- */
.ifw-card {
  background: var(--panel); border: 1px solid var(--line); border-radius: 14px;
  padding: 22px; display: flex; flex-direction: column;
  box-shadow: var(--shadow); transition: border-color .15s;
}
.ifw-card:hover { border-color: var(--line-strong); }
.ifw-card-no { font-family: var(--mono); font-size: 11.5px; color: var(--faint); letter-spacing: .08em; }
.ifw-card h3 { font-size: 16px; font-weight: 650; margin: 12px 0 0; letter-spacing: -0.01em; }
.ifw-card p { font-size: 13.5px; color: var(--mute); line-height: 1.75; margin: 8px 0 0; flex: 1; }
.ifw-card-fact {
  border-top: 1px solid var(--line); margin-top: 18px; padding-top: 12px;
  display: flex; justify-content: space-between; align-items: baseline;
  font-size: 12px; color: var(--faint);
}
.ifw-card-fact b { font-family: var(--mono); font-weight: 600; color: var(--ink); font-size: 12px; }

/* ---------- 模型清单表 primitives（列宽节奏规则：名称定宽 + 数据列均分） ---------- */
.ifw-shelf-group { margin-top: 28px; }
.ifw-shelf-group:first-of-type { margin-top: 0; }
.ifw-shelf-head {
  display: flex; align-items: baseline; gap: 14px;
  padding-bottom: 10px; border-bottom: 1px solid var(--line-strong);
}
.ifw-shelf-head h3 { font-size: 14px; font-weight: 650; letter-spacing: .02em; margin: 0; }
.ifw-shelf-head span { font-size: 12px; color: var(--faint); }
.ifw-shelf-head .cnt { margin-left: auto; font-family: var(--mono); font-size: 11.5px; color: var(--faint); }
.ifw-cols, .ifw-mrow { display: grid; grid-template-columns: 250px 1fr 1fr 1fr 1fr 86px; gap: 12px; }
.ifw-cols {
  padding: 10px 4px 6px; font-size: 11px; color: var(--faint); letter-spacing: .06em;
}
.ifw-cols span:nth-child(n+2) { text-align: right; }
.ifw-mrow { align-items: center; padding: 12px 4px; border-bottom: 1px solid var(--line); transition: background .12s; }
.ifw-mrow:hover { background: var(--accent-soft); }
.ifw-mname { display: flex; align-items: center; gap: 9px; font-family: var(--mono); font-size: 13px; font-weight: 600; flex-wrap: wrap; }
.ifw-mname img { width: 16px; height: 16px; flex: none; }
body.ifw-theme-dark .ifw-mname img.inv { filter: invert(1) brightness(1.4); }
.ifw-mname .nm { cursor: pointer; border-bottom: 1px dashed transparent; transition: border-color .12s; }
.ifw-mrow:hover .ifw-mname .nm { border-bottom-color: var(--faint); }
.ifw-mvar {
  font-size: 10px; color: var(--faint); border: 1px solid var(--line); border-radius: 5px;
  padding: 1px 6px; font-weight: 500; white-space: nowrap;
}
.ifw-mdisc {
  justify-self: end; font-family: var(--mono); font-size: 11px; font-weight: 600;
  color: var(--accent); background: var(--accent-soft); border-radius: 6px;
  padding: 3px 9px; white-space: nowrap;
}
.ifw-mdisc-na { background: transparent; color: var(--faint); font-weight: 400; }
.ifw-mdisc .caret { font-style: normal; font-size: 9px; opacity: .8; margin-left: 2px; }
.ifw-mprice { font-family: var(--mono); font-size: 12.5px; text-align: right; font-variant-numeric: tabular-nums; }
.ifw-mprice small { display: block; font-size: 10.5px; color: var(--faint); font-family: var(--sans); font-weight: 400; }
.ifw-mtag {
  justify-self: end; font-size: 11px; color: var(--mute);
  border: 1px solid var(--line); border-radius: 6px; padding: 2.5px 8px;
  display: flex; align-items: center; gap: 5px; white-space: nowrap;
}
.ifw-mtag i { width: 5px; height: 5px; border-radius: 50%; background: var(--ok); display: inline-block; }
.ifw-mrow.has-exp { cursor: pointer; }
.ifw-mexp {
  border-bottom: 1px solid var(--line);
  background: color-mix(in srgb, var(--panel) 60%, var(--paper));
  border-radius: 0 0 10px 10px;
}
.ifw-mexp-row {
  display: grid; grid-template-columns: 250px 1fr 1fr 1fr 1fr 86px; gap: 12px;
  align-items: center; padding: 9px 4px;
}
.ifw-mexp-row + .ifw-mexp-row { border-top: 1px dashed var(--line); }
.ifw-mexp-tier { display: flex; flex-direction: column; gap: 1px; padding-left: 29px; }
.ifw-mexp-tier b { font-size: 12.5px; font-weight: 650; }
.ifw-mexp-desc { font-size: 11px; color: var(--faint); line-height: 1.5; }
.ifw-mexp-disc { justify-self: end; font-family: var(--mono); font-size: 11px; color: var(--accent); }
.ifw-mexp .ifw-mprice { font-size: 12px; }
.ifw-mempty { padding: 28px 4px; font-size: 13.5px; color: var(--faint); display: none; }

@media (max-width: 980px) {
  .ifw-cols { display: none; }
  .ifw-mrow {
    grid-template-columns: 1fr auto;
    grid-template-areas: "name tag" "pin pout" "pcache disc";
    row-gap: 6px;
  }
  .ifw-mname { grid-area: name; }
  .ifw-mtag { grid-area: tag; }
  .ifw-mprice.pin { grid-area: pin; text-align: left; }
  .ifw-mprice.pout { grid-area: pout; text-align: left; }
  .ifw-mprice.pcache { grid-area: pcache; text-align: left; }
  .ifw-mdisc { grid-area: disc; justify-self: end; align-self: center; }
  .ifw-mexp-row { grid-template-columns: 1fr; gap: 4px; }
  .ifw-mexp-tier { padding-left: 16px; }
}

/* ---------- code 块 ---------- */
.ifw-code {
  background: var(--term-bg); border-radius: 12px; padding: 16px 18px;
  font-family: var(--mono); font-size: 12.5px; line-height: 1.85; color: var(--term-ink);
  overflow-x: auto; border: 1px solid rgba(255, 255, 255, 0.06);
}
.ifw-code pre { font-family: var(--mono); white-space: pre; margin: 0; }
.ifw-code .tc { color: var(--term-mute); }
.ifw-code .ts { color: var(--term-str); }

/* ---------- footer（renderer footer() 既有结构，新皮肤） ---------- */
body.ifw-public-page .ifw-foot {
  border-top: 1px solid var(--line); background: var(--panel);
  margin-top: 76px; padding: 40px 0 32px;
}
body.ifw-public-page .ifw-foot-inner {
  display: flex; justify-content: space-between; align-items: center;
  flex-wrap: wrap; gap: 10px;
}
body.ifw-public-page .ifw-foot-brand { font-family: var(--mono); font-size: 12px; color: var(--faint); }
body.ifw-public-page .ifw-foot-links { display: flex; gap: 20px; align-items: center; font-size: 13px; color: var(--mute); flex-wrap: wrap; }
body.ifw-public-page .ifw-foot-links a { cursor: pointer; transition: color .15s; }
body.ifw-public-page .ifw-foot-links a:hover { color: var(--ink); }
body.ifw-public-page .ifw-foot-mail { font-family: var(--mono); font-size: 12px; color: var(--faint); }

/* 首页 sitemap footer（页面级扩展，位于 ifw-foot 内） */
.ifw-sitefoot-grid {
  display: grid; grid-template-columns: 1.6fr 1fr 1fr 1fr; gap: 32px;
  padding-bottom: 36px; margin-bottom: 22px; border-bottom: 1px solid var(--line);
}
.ifw-sitefoot-brand p { font-size: 12.5px; color: var(--faint); margin: 14px 0 0; max-width: 240px; }
.ifw-sitefoot-col h5 {
  font-size: 12px; font-weight: 650; color: var(--faint); letter-spacing: .1em; margin: 0 0 14px;
}
.ifw-sitefoot-col a { display: block; font-size: 13px; color: var(--mute); padding: 4px 0; transition: color .15s; }
.ifw-sitefoot-col a:hover { color: var(--ink); }

/* ---------- misc ---------- */
.ifw-bnote {
  margin-top: 34px; border: 1px solid var(--line); border-radius: 14px;
  background: var(--panel); padding: 20px 24px;
  display: flex; gap: 24px; align-items: baseline; flex-wrap: wrap;
}
.ifw-bnote p { font-size: 13px; color: var(--mute); flex: 1; min-width: 260px; margin: 0; }
.ifw-bnote a { color: var(--accent); font-weight: 600; font-size: 13.5px; }
.ifw-bnote code { font-family: var(--mono); font-size: 12px; color: var(--ink); }

@media (prefers-reduced-motion: no-preference) {
  .ifw-rise { opacity: 0; transform: translateY(14px); animation: ifw-rise .7s cubic-bezier(.2, .6, .2, 1) forwards; }
  .ifw-rise.d1 { animation-delay: .08s; }
  .ifw-rise.d2 { animation-delay: .16s; }
  @keyframes ifw-rise { to { opacity: 1; transform: none; } }
}

@media (max-width: 640px) {
  .ifw-shell { padding: 0 20px; }
  .ifw-h1 { font-size: 24px; }
  .ifw-h1-lg { font-size: 28px; }
  .ifw-h2 { font-size: 22px; }
  .ifw-sec { padding-top: 56px; }
  .ifw-sitefoot-grid { grid-template-columns: 1fr 1fr; }
  body.ifw-public-page .ifw-foot-inner { flex-direction: column; align-items: flex-start; }
  /* Phone-width nav budget (round 3): with the tool group + CTA now living on
     the fixed right side, the scrollable link region is what's left over. Trim
     chrome (nav padding/gaps, 28px icon buttons) and let the BELL yield its
     width — hard constraints are zero page overflow + CTA visible + theme/lang
     reachable (owner round-3 brief); announcements stay reachable on wider
     viewports and in the console. ~80px of scroll region remains at 375px. */
  body.ifw-public-page .ifw-nav { padding: 0 18px; gap: 10px; }
  body.ifw-public-page .ifw-nav-right { gap: 8px; }
  body.ifw-public-page .ifw-nav-utility.ifw-announcement-control { display: none; }
  body.ifw-public-page .ifw-icon-button { width: 28px; height: 28px; }
  /* Round-4: desktop brand went 18→22px (ink-height fix above). At phone width
     the brand's extra ~28px would come straight out of the ~80px scrollable
     link region (brand is flex:none — width pressure has nowhere else to go).
     20px keeps the brand optically above the 13px CJK links here (cap ~14.1px
     vs ~12.2px ink, +16%) while giving ~10px back to the scroll region. */
  body.ifw-public-page .ifw-brand { font-size: 20px; }
}
