/* ============================================================================
   agentcss / 03-patterns / nav / nav.css
   页头 + 长文目录 + 移动端抽屉

   依赖：01-tokens/tokens.css  +  02-primitives/button/button.css
   版本：A ✅ / B ✅ / C ✅

   配套：toc.js（目录高亮，可降级）
   规范：抽屉的展开/收起见本文件顶部说明
   ========================================================================= */

/* ============================================================================
   1. 跳到主内容
   =========================================================================
   键盘用户第一个 Tab 就该能跳过整个导航。
   平时移出视口，聚焦时滑入 —— 用 transform 不用 display:none，
   否则它无法被 Tab 聚焦（display:none 会移出 tab 顺序）。 */
.skip {
  position: absolute;
  top: 0; inset-inline-start: 0;
  z-index: var(--z-toast);
  transform: translateY(-120%);
  background: var(--accent);
  /* 🔴 暗色下 --accent 变亮（#7aa9de），白字会看不清。 */
  color: var(--text-on-accent);
  padding: var(--sp-2) var(--sp-4);
  font-size: var(--fs-sm);
  text-decoration: none;
  transition: transform var(--dur-fast) var(--ease-out);
}
.skip:focus { transform: translateY(0); }

/* ============================================================================
   2. 页头
   ========================================================================= */
.nav {
  position: sticky;
  top: 0;
  z-index: var(--z-header);
  background: var(--paper);
  border-bottom: 1px solid var(--border-decor);
}
.nav__inner {
  display: flex;
  align-items: center;
  gap: var(--sp-4);
  max-width: 1040px;
  margin: 0 auto;
  padding: 0 var(--sp-5);
  min-height: 56px;                 /* 触摸目标不小于 44px，这里是页头整体 */
}
.nav__brand {
  /* 🔴 补内边距：移动端实测高度正好 24px，
     卡在 WCAG 2.5.8 的下限上，**没有余量** ——
     换字号/换字体就可能掉到 24px 以下。
     点击区用内边距撑开而不是固定 height：内容变了，触摸目标不会退化。 */
  display: inline-flex;
  align-items: center;
  min-height: 44px;          /* Apple/Google 建议值；WCAG 2.5.8 下限是 24 */
  padding: var(--sp-2) 0;
  font-size: var(--fs-sm);
  font-weight: 500;
  color: var(--text-primary);
  text-decoration: none;
  white-space: nowrap;
}
.nav__brand span { color: var(--text-tertiary); font-weight: 400; }

.nav__list {
  display: flex;
  align-items: center;
  gap: var(--sp-4);
  list-style: none;
  margin: 0 0 0 auto;               /* 靠右 */
  padding: 0;
}
.nav__link {
  display: block;
  padding: var(--sp-2) 0;
  font-size: var(--fs-sm);
  color: var(--text-secondary);
  text-decoration: none;
  border-bottom: 2px solid transparent;   /* 预留位：选中时下方那条线不推内容 */
  transition: color var(--dur-fast) var(--ease-out),
              border-color var(--dur-fast) var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
.nav__link:hover { color: var(--text-primary); }
}
/* 🔴 当前页指示用 aria-current，不是自定义 class ——
   屏幕阅读器会播报"当前页面"，自定义 class 它不知道。 */
.nav__link[aria-current="page"] {
  color: var(--accent);
  border-bottom-color: var(--accent);
  font-weight: 500;
}
.nav__link:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* 汉堡：桌面隐藏 */
.nav__toggle {
  display: none;
  margin-inline-start: auto;
  width: 44px; height: 44px;         /* 触摸目标 44px，硬下限 */
  align-items: center; justify-content: center;
  background: none;
  border: 1px solid var(--border-decor);
  border-radius: var(--r-sm);
  cursor: pointer;
  color: var(--text-primary);
}
.nav__toggle:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* 三条线：中间那条用 transform 收成箭头，展开时变 X */
.nav__toggle i {
  display: block;
  width: 18px; height: 1.5px;
  background: currentColor;
  position: relative;
  transition: transform var(--dur-base) var(--ease-out),
              opacity var(--dur-fast) var(--ease-out);
}
.nav__toggle i::before,
.nav__toggle i::after {
  content: "";
  position: absolute;
  inset-inline-start: 0;
  width: 18px; height: 1.5px;
  background: currentColor;
  transition: transform var(--dur-base) var(--ease-out);
}
.nav__toggle i::before { top: -5.5px; }
.nav__toggle i::after  { top: 5.5px; }

.nav__toggle[aria-expanded="true"] i { transform: rotate(45deg); }
.nav__toggle[aria-expanded="true"] i::before { transform: translateY(5.5px) rotate(-90deg); }
.nav__toggle[aria-expanded="true"] i::after  { opacity: 0; }

/* ============================================================================
   3. 移动端：抽屉
   =========================================================================
   🔴 按 08-状态切换规范：展开/收起**只动 transform**，不动 width/height/top ——
      那样会引起重排，页面会"抖一下"。

   🔴 抽屉打开时背景必须锁（inert），否则用户能 Tab 到抽屉外面去 ——
      视觉上抽屉是覆盖层，逻辑上却不是模态，两边不一致。 */
@media (max-width: 48rem) {
  .nav__toggle { display: flex; }

  .nav__list {
    position: fixed;
    top: 0; inset-inline-end: 0; bottom: 0;
    z-index: var(--z-overlay);
    width: min(280px, 82vw);
    margin: 0;
    padding: var(--sp-7) var(--sp-5) var(--sp-5);
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    background: var(--surface);
    border-inline-start: 1px solid var(--border-decor);
    box-shadow: var(--shadow-2);

    transform: translateX(100%);        /* 收起态：在视口外 */
    transition: transform var(--dur-base) var(--ease-out);
    overflow-y: auto;
  }
  .nav__list[data-state="open"] { transform: translateX(0); }

  .nav__link {
    padding: var(--sp-3) 0;
    border-bottom: 1px solid var(--border-decor);
    /* 抽屉里用整行色块表示当前页，比 2px 下划线清楚（竖排时） */
    border-bottom-width: 1px;
  }
  .nav__link[aria-current="page"] {
    color: var(--accent);
    font-weight: 500;
  }

  .nav__scrim {
    position: fixed;
    inset: 0;
    z-index: var(--z-header);      /* 比抽屉低一层 */
    /* 🔴 原来写死 rgba(21,24,28,.4)（深色遮罩）。
     暗色模式下纸底本来就是深的 ⇒ 遮罩与底几乎同色 ⇒ **看不出"有遮罩"**。
     改用令牌，深浅两套各自成立。 */
  background: var(--scrim);
    opacity: 0;
    pointer-events: none;
    transition: opacity var(--dur-base) var(--ease-out);
  }
  .nav__scrim[data-state="open"] { opacity: 1; pointer-events: auto; }
}

/* ============================================================================
   4. 长文目录
   ========================================================================= */
.toc {
  /* 容器本身也要有定义 —— 否则 HTML 里的 class="toc" 是个悬空引用。
     refs.py 会抓这种"引用了但没定义"的类。 */
  min-width: 0;
}

/* 🔴 sticky 必须**在库里**而不是 demo 里。
   修正：原来这条只写在 demo 的内联 <style> 里，
   于是任何引了 nav.css 的页面都**没有 sticky** ——
   目录会随正文滚出视口，"跟着走"这个最基本的效果没有。
   **布局规则写在 demo 里 = 分层崩了。**

   偏移量要大于页头高度，否则 sticky 会停在页头下面被遮住。
   窄屏时目录在正文上方，不需要 sticky。 */
@media (min-width: 60rem) {
  .toc {
    position: sticky;
    top: 76px;              /* 页头 56px + 20px 留白 */
    align-self: start;      /* 🔴 grid 子项默认 stretch，会让 sticky 无处可动 */
    max-height: calc(100vh - 96px);
    overflow-y: auto;       /* 目录比视口高时可滚 */
  }
}
.toc__title {
  font-size: var(--fs-xs);
  color: var(--text-tertiary);
  text-transform: uppercase;
  letter-spacing: 0.1em;
  margin: 0 0 var(--sp-3);
  font-weight: 500;
}
.toc__list { list-style: none; margin: 0; padding: 0; }
/* 🔴 为什么这里保留竖条（0.8.4 · 全库竖条政策）
   它不是装饰竖条，是**当前项指示器**：目录里"你在这一节"由它标记，
   与当前项的文字加重是**两条独立线索** ——
   去掉它，纯色弱 / 低对比场景下当前项就只剩字重变化可辨。
   ⚠️ 未选中时是灰调分隔色（--border-decor）、选中时才变强调色（--accent），
      所以它平时就是一条安静的目录导轨，只有当前项会被点亮。 */
.toc__link {
  display: block;
  padding: var(--sp-1) 0 var(--sp-1) var(--sp-3);
  color: var(--text-tertiary);
  text-decoration: none;
  font-size: var(--fs-xs);
  border-inline-start: 2px solid var(--border-decor);
  white-space: nowrap;                 /* 目录项换行就乱了 */
  overflow: hidden;
  text-overflow: ellipsis;
  transition: color var(--dur-fast) var(--ease-out),
              border-color var(--dur-fast) var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
.toc__link:hover { color: var(--text-primary); }
}
.toc__link:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
/* 🔴 当前节用 aria-current="true"（不是 "location"）——
   "true" 表示"在当前范围内当前位置"，目录高亮用它是通行做法。 */
.toc__link[aria-current="true"] {
  color: var(--accent);
  /* 🔴 必须是 border-inline-start-color（逻辑），与 .toc__link 的
     border-inline-start 同侧。写物理 border-left-color 的话 RTL 下会着错边。 */
  border-inline-start-color: var(--accent);
  font-weight: 500;
}

/* ============================================================================
   reduced-motion
   =========================================================================
   抽屉的位移动画对前庭功能障碍患者是有刺激的 ⇒ 关掉，
   但保留遮罩的 opacity 过渡（无刺激，且能交代"挡住了"）。
   ========================================================================= */
@media (prefers-reduced-motion: reduce) {
  .nav__list, .nav__toggle i, .nav__toggle i::before, .nav__scrim {
    transition: opacity var(--dur-fast) linear;
    transform: none;
  }
  .nav__toggle[aria-expanded="true"] i { transform: none; }
  .nav__toggle[aria-expanded="true"] i::before { transform: none; }
}

/* 🔴 这两条**必须**带断点。抽屉的"收起态"靠 translateX(100%) 移出视口，
   动画被关掉后得有东西撑着它；但曾经写在**无断点**的 reduced-motion 段里
   ⇒ 开启「减少动态效果」的桌面用户，顶部导航整体飞出屏幕右侧
      （实测 1440 视口 scrollWidth 1440 → 1512 = 列表自身宽度），菜单直接消失。
   默认环境下截图看不到它，只有 emulateMedia({reducedMotion:'reduce'}) 才暴露。
   ⭐ 教训：「关掉动画」不能顺手把布局也关掉。 */
@media (prefers-reduced-motion: reduce) and (max-width: 48rem) {
  .nav__list { transform: translateX(100%); }        /* 收起态：仍在视口外 */
  .nav__list[data-state="open"] { transform: translateX(0); }
}

/* ============================================================================
   反模式
   =========================================================================
   1. 抽屉展开时动 width / left / top
      ⇒ 引起重排，页面抖一下。只该动 transform。

   2. 抽屉打开后背景仍可 Tab / 可点
      视觉上是覆盖层，逻辑上不是模态，两边不一致。
      打开时给背景加 inert。

   3. 汉堡按钮小于 44px
      触摸目标是硬下限（WCAG 2.5.8 要 24px，但 44 是实践标准）。

   4. 当前页指示用自定义 class 而不是 aria-current
      屏幕阅读器不知道，用户失去"我在哪"。

   5. 目录项允许换行
      换行会让行高跳变，目录看着散。截断（ellipsis）。

   6. 目录高亮在不支持 IntersectionObserver 时就整个不做
      目录会变成一堆"点得动但看不出当前位置"的死链接。
       scroll 监听，体验降级但功能不消失。

   7. 页头 sticky 但没给背景色
      内容会从页头下面透出来，看着像重影。
   ========================================================================= */

/* ============================================================================
   RTL：收起态要往**左**移出视口
   ----------------------------------------------------------------------------
   🔴 抽屉是 `inset-inline-end: 0`（逻辑），收起态是 `translateX(100%)`（物理）。
      LTR：贴在视口右侧，+100% 向右移出 ⇒ 正确
      RTL：inset-inline-end 变成**左**侧，+100% 却仍向右移
           ⇒ 抽屉从视口外**移进**视口并盖住内容，看起来像"导航一直开着"

   这类错在 LTR 页面上完全看不到，只在 dir="rtl" 且宽度 ≤48rem 时出现。
   ========================================================================== */
/* ⚠️ 必须包在断点里：抽屉形态**只在这个断点下存在**。
   第一版漏了媒体查询 ⇒ 1280 宽下桌面导航也被整体左移 -100%，
   页面横向溢出 391px —— 被 rtl-render 门禁当场抓到（文字膨胀 1.3× 那条）。
   "规则写对了"不等于"作用域写对了"。 */
@media (max-width: 48rem) {
  [dir="rtl"] .nav__list {
    transform: translateX(-100%);
  }
  [dir="rtl"] .nav__list[data-state="open"] {
    transform: translateX(0);
  }
}
