/* Sequences — the developer surface.

   Paper, not ink. The marketing pages are light and the developer pages now
   share that surface rather than sitting on a dark one. Everything below is
   structure — the surfaces, the panels, the mega menu — and it is built on
   tokens precisely so the palette can be replaced without touching a single
   layout rule.

   The paragraph here used to justify the split by pointing at the mark: "the
   wordmark is a disc half filled and half empty and the marketing pages are the
   light half". That mark is gone — it is a green slash now — so the sentence was
   describing something the reader can no longer see. The layout decision stands
   on its own without the metaphor.
   {USER 2026-08-30 "I LIKE THIS ONE REPLACE THE PAGE WITH THIS"}
   [CONFIDENCE: CONFIRMED 100% —— mark 已在 assets/favicon.svg + style.css .mark
    换成绿色斜杠]

   The one thing carried over unchanged: mono is the DISPLAY face, not the code
   face. Inverting that inversion would cost the whole character.

   Variable names still say "ink" and "on-ink". That is deliberate: they mean
   "the surface" and "what sits on it", and renaming ninety usages to chase a
   colour would be churn with no reader benefit. */

:root{
  /* 曾经是"三档纵深"。页面底色改成纯白之后 --ink 与 --ink-raised 是同一个值,
     纵深只剩两档:纸面(白)与凹下去的一档(--ink-soft)。抬起的面改为靠边框和
     阴影成立,不靠填色 —— 见 style.css 里 --bg 的注释。
     {USER 2026-08-31 "IWANT PLAIN WHITE NOT PAPER WHITE"}
     [CONFIDENCE: CONFIRMED 100% —— 本轮用户原话] */
  --ink:#FFFFFF;
  --ink-soft:#F4F6F8;
  --ink-raised:#FFFFFF;
  --ink-line:rgba(14,26,43,0.14);
  --ink-line-soft:rgba(14,26,43,0.07);

  /* 此处曾有 --veil(半透明白 + backdrop-blur 的导航底色)。导航改成浮起的
     药丸之后没有任何规则再引用它,已删除。药丸滚动后用的是不透明的
     --ink-raised —— 模糊在一块 17px 圆角、有阴影的卡片上读不出来,
     它需要的是一个干净的边缘,不是一层雾。 */

  /* 公告条的**总高,含它的 1px 下边框**。写成变量是因为吸顶的负偏移必须
     精确等于它 —— 实测踩过:token 写 38px 而实际 39px(边框没算进去),
     滚动后就有一条 1px 的公告条边卡在导航上方。
     所以这里的语义是「整条占多高」,内层 .announce-in 自己扣掉边框。

     跟着视口走而不是写死一个数:45px 的条里放一个 22px 的标签,标签只占一半高,
     整条在宽屏上读起来像页面顶上压扁的一道细缝。
     {USER 2026-08-29 SCREENSHOT "THE NEW NEED TO BE LARGER WIDER AND FONT LARGER"}
     [CONFIDENCE: CONFIRMED 90% —— 22px 标签 / 44px 条内高为 1280 视口实测] */
  --announce-h:clamp(52px,4vw,68px);

  /* 吸顶导航条自身的高度,锚点跳转的落点按它下推 —— 否则标题正好躲在条底下,
     读者以为链接坏了。
     算式:12px 上外边距 + 60px 药丸高 + 12px 下外边距 = 84px。下边框那 1px
     不再计入 —— 条改成浮起的圆角药丸之后已经没有下边框了。 */
  --nav-h:84px;

  /* 药丸的圆角与高度。两个数只在这里出现一次,因为 .navlink 的 42px 悬停块
     必须在药丸里上下各留出同样的余量((60-42)/2 = 9px);高度一改而 hover
     块没跟着改,链接就会贴着药丸的上下沿。 */
  --pill-h:60px;
  --pill-r:17px;
  /* 导航链接自身的悬停块高度。单独成 token 是因为 .mega 的下拉落点要用它 ——
     菜单必须挂在**药丸**下面而不是链接下面,而链接比药丸矮,差值得算出来。 */
  --navlink-h:42px;

  --on-ink:#0E1A2B;
  --on-ink-muted:rgba(14,26,43,0.74);
  /* 与 style.css 的 --dim 同一个解,理由见那里的注释(45% 只有 2.90:1)。 */
  --on-ink-dim:rgba(14,26,43,0.63);

  /* One saturated accent, reserved for live values and the current path.
     Darkened from the amber used on dark surfaces: the bright tone that read as
     "watch this" against black is illegible against paper. Same signal, the
     contrast the surface demands. */
  --signal:#96650A;
  --signal-dim:rgba(255,197,61,0.22);

  /* Architecture colours. Three model families, three hues, used only in the
     catalogue and pricing so a reader can track a family down a long table
     without re-reading the label each row. Chosen for contrast on paper. */
  --arch-vlm:#1D4FA8;
  --arch-vla:var(--green);
  --arch-wam:#A8461F;
}


.ink{
  background:var(--ink);
  color:var(--on-ink);
  min-height:100vh;
}
/* 宽度由 style.css 的 .wrap 统一定义(1520px)。这里不再覆盖 ——
   两处各写一个数字,就会有一处先漂;而首页恰恰是没有 .ink 类的那一页。 */

/* ── Nav with mega menu ──────────────────────────────────────────────
   The menu is CSS-only: :hover on the parent plus :focus-within so it opens
   from the keyboard too. No script, because a nav that needs JavaScript to
   reveal its own links is a nav that fails while the page is still loading. */
/* nav 自己必须是定位元素:mega 面板是它的后代,nav 保持 static 时面板会被
   后续静态内容盖住 —— 背景明明不透明却看得见底下的字,就是这个原因。

   sticky 而不是 fixed:sticky 保留在文档流里,所以下面的内容不需要靠一个
   等高的 padding 顶开 —— 那个 padding 一旦和条高失配,页面顶部就会多出或少掉
   一条缝,而条高会随字号和响应式断点变。fixed 要求两个数手动同步,sticky 不用。

   公告条**不吸顶**:它是一次性信息,读过一次就该让位;而导航是读者随时会回头
   找的东西。两者一起吸顶会在小屏上吃掉三分之一的视口。 */
/* nav 本身只负责给药丸留出四周的空隙,不再自己画任何表面。
   上一版它是一根通栏的横梁:半透明底 + backdrop-blur + 1px 下边框。改掉是
   因为整站要跟 thirdlatent 的构图对齐,而那套构图里条**在页面顶部时是不存在的**
   —— 只有标识、链接、按钮直接落在纸上。
   {USER 2026-08-31 "THE TOP BAR ALSO NEED TO FOLLOW THE DESIGN"}
   [CONFIDENCE: CONFIRMED 100% —— 本轮用户原话]

   为什么"静止时不画底"是对的而不只是好看:那块底的职责是把导航和从它下面
   滚过去的内容分开。页面还没滚动时,底下根本没有东西要分开 —— 此时画一块底
   只是凭空多出一个盒子。thirdlatent 的注释把这一点讲得最清楚。
   {THIRDLATENT/SITE/ASSETS/SITE.CSS "THE CARD IS NOT DECORATION; IT EXISTS TO
    SEPARATE THE NAV FROM MOVING CONTENT. WITH NOTHING SCROLLED YET THERE IS
    NOTHING TO SEPARATE FROM, SO DRAWING IT AT REST JUST ADDS A BOX FOR NO REASON."}
   [CONFIDENCE: CONFIRMED 100% —— 读自 thirdlatent 源文件] */
.navshell nav{
  position:relative;z-index:1;width:100%;
  /* 12px 是药丸浮起来离视口顶的距离,同时也是 --nav-h 里的那两个 12。
     左右 16px 是窄屏上的安全边:.wrap 的 92vw 在极窄视口下会贴到边。 */
  padding:12px 16px;
}

/* .nav-inner 同时挂着 .wrap,所以药丸的左右缘与页面内容列**精确对齐**。
   这里没有照抄 thirdlatent 的 max-width:1240 —— 它的内容列就是 1240,而本站是
   1340。药丸窄于内容列会让标识和下面第一段文字对不上,那种半像素级的错位
   比宽度本身更显眼。 */
.nav-inner{
  display:flex;align-items:center;justify-content:space-between;
  height:var(--pill-h);border-radius:var(--pill-r);
  /* 左右不对称:左边是标识(视觉上自带留白),右边是按钮(自带边框),
     所以右边给得比左边少,两侧看起来才一样宽。 */
  padding:0 10px 0 18px;
  background:transparent;box-shadow:none;
  transition:background .28s ease,box-shadow .28s ease;
}

/* 滚过 12px 之后药丸才实体化。这个类由 nav.html 里那段内联脚本切换。 */
.navshell.stuck .nav-inner{
  background:var(--ink-raised);
  /* 两层阴影:1px 的近影负责画出边缘(代替被删掉的 1px 边框),
     30px 的远影负责把药丸抬离页面。只用远影会让边缘发虚,
     只用近影则读成一块贴在页面上的方块而不是浮起来的东西。 */
  box-shadow:0 1px 2px rgba(14,26,43,.055), 0 10px 30px rgba(14,26,43,.075);
}
.navshell .wordmark{color:var(--on-ink)}
/* 深色底的重着色已移除：渐变标识不吃底色，一份定义通吃。 */

.navmenu{display:flex;align-items:center;gap:4px;margin-left:38px}
.navitem{position:relative}
.navlink{
  display:inline-flex;align-items:center;gap:7px;height:var(--navlink-h);padding:0 16px;border-radius:10px;
  font-family:var(--font-body);font-size:16px;color:var(--on-ink-muted);
  text-decoration:none;letter-spacing:-0.01em;
  transition:color .14s ease,background .14s ease;
}
.navlink:hover,.navitem:focus-within .navlink{color:var(--on-ink);background:rgba(14,26,43,0.05)}
.navlink[aria-current="page"]{color:var(--on-ink)}
.caret{width:9px;height:9px;border-right:1.5px solid currentColor;border-bottom:1.5px solid currentColor;
  transform:rotate(45deg) translate(-2px,-2px);opacity:.6;transition:transform .16s ease}
.navitem:hover .caret,.navitem:focus-within .caret{transform:rotate(225deg) translate(-1px,-1px)}

/* The panel is placed, not floated: a mega menu that shifts on hover reads
   broken even when it is technically correct. */
.mega{
  /* 落点锚的是**药丸的下沿**,不是链接的下沿。链接(42px)在药丸(60px)里垂直
     居中,所以它的底边比卡片底边高 (60-42)/2 = 9px;沿用原来的 `100% + 10px`
     会让面板顶边落在距卡片底沿 1px 的地方 —— 视觉上就是面板贴着卡片、把那圈
     圆角和阴影压掉。加上这 9px 之后,面板与卡片之间才是干净的 10px。
     {实测 @1440 改前: 面板展开后 top=130, 药丸 bottom=129}
     [CONFIDENCE: CONFIRMED 100% —— getBoundingClientRect 实测,transform 的
      -6px 位移已计入] */
  position:absolute;
  top:calc(100% + (var(--pill-h) - var(--navlink-h)) / 2 + 10px);
  left:-14px;z-index:60;
  display:grid;grid-template-columns:minmax(340px,1fr) 300px;gap:0;
  background:var(--ink-raised);border:1px solid var(--ink-line);border-radius:16px;
  box-shadow:0 30px 60px -30px rgba(14,26,43,0.28),0 0 0 1px rgba(14,26,43,0.05);
  opacity:0;visibility:hidden;transform:translateY(-6px);
  transition:opacity .16s ease,transform .16s ease,visibility .16s;
  overflow:hidden;
}
.navitem:hover .mega,.navitem:focus-within .mega{opacity:1;visibility:visible;transform:translateY(0)}
/* 靠右的两个菜单改成右对齐。.mega 最窄 640px（340 + 300），锚在菜单项左边
   时，越靠右的项越容易把面板顶出视口右缘 —— 而且 visibility:hidden 的面板
   照样计入 scrollWidth，所以没展开也会让整页多出横向滚动。
   {实测 1085px 视口: wordmark 从 "Genseq" 换成 "GeneralSequences" 后菜单整体
    右移 74px, scrollWidth 由 1085 涨到 1129, 溢出元素为 .mega(left 487 right 1129)}
   [CONFIDENCE: CONFIRMED 100% — 同一页面上改回短名 scrollWidth 立刻回到 1085] */
.navitem-right .mega{left:auto;right:-14px}

.mega-list{padding:14px}
/* 每行以前在左边留 36px 一格,放一个圆角方块图标(/v1、◫、↦、✉ …)。
   已整格删除:那些字符不是产品自己的标识,是从字体里挑出来近似的符号,
   而近似的符号说不出比它右边那行标题更多的东西 —— 读者要读完标题才知道
   刚才那个方块是什么意思,顺序反了。删掉之后标题落到行首,菜单从
   「图标列 + 文字列」变回一列可读的文字。
   {USER 2026-08-31 "REMOVE ALL THESE LOGOS THESE ARE NOT NEEDED" + "FOR AL LTHE TOP BAR DROPDOWNS"}
   [CONFIDENCE: CONFIRMED 100% —— 直接指令,配 Company 下拉的截图] */
.mega-row{
  display:block;
  padding:12px;border-radius:11px;text-decoration:none;color:var(--on-ink);
  transition:background .14s ease;
}
.mega-row:hover{background:rgba(14,26,43,0.04)}
.mega-name{display:block;color:var(--on-ink);font-size:14.5px;font-weight:500;letter-spacing:-0.012em;margin-bottom:3px}
.mega-desc{display:block;font-size:13px;color:var(--on-ink-dim);line-height:1.45}

/* 右栏用一句话回答「我到底能跑什么」,让读者不必先点进去。
   它现在是纯文字:一个标题、一句说明、一个去处。
   这里曾有 .mega-chips 与 .chip / .chip-vlm / .chip-vla / .chip-wam ——
   右栏顶部那排带色边框的模型名 pill,以及 Developers 栏里的 .mega-code
   base_url 代码块。连同每行左侧的图标块一起移除:下拉的职责是把人送到下一页,
   四条并列的去处之间,装饰只会让比较更费劲。
   {USER 2026-08-31 "REMOVE ALL THE VISUALS" + "ON THETOPBAR"}
   [CONFIDENCE: CONFIRMED 100% —— 直接指令,配 Company 下拉截图。移除后实测
    .navshell 内 .mega-ico / img / svg / .chip / .mega-code 计数全部为 0]
   注意 .chip 与 models 页的 .mchip、signin 页的 .mark-chip 是不同的类,
   那两个仍在使用,不要一起删。 */
.mega-side{padding:18px;background:var(--ink-soft);border-left:1px solid var(--ink-line-soft)}
.mega-side-name{color:var(--on-ink);font-size:14px;font-weight:500;margin-bottom:4px}
.mega-side-desc{font-size:12.5px;color:var(--on-ink-dim);line-height:1.5}

/* ── Page furniture ──────────────────────────────────────────────── */
.ink .eyebrow{
  font-family:var(--font-ui);font-size:11.5px;letter-spacing:0.14em;text-transform:uppercase;
  color:var(--signal);margin-bottom:16px;
}
.ink h1.page-title{
  font-family:var(--font-display);font-size:clamp(36px,4.4vw,88px);
  line-height:1.02;letter-spacing:-0.038em;font-weight:500;max-width:16ch;
}
.ink .lede{
  margin-top:24px;max-width:60ch;font-size:clamp(17px,1.14vw,24px);line-height:1.6;color:var(--on-ink-muted);
}
.page-head{padding:clamp(56px,6vw,132px) 0 clamp(40px,3.6vw,80px);border-bottom:1px solid var(--ink-line-soft)}
.ink h2.sec{
  font-family:var(--font-ui);font-size:12px;letter-spacing:0.14em;text-transform:uppercase;
  color:var(--on-ink-dim);margin-bottom:26px;
}
.ink .block{padding:clamp(52px,5.4vw,120px) 0;border-bottom:1px solid var(--ink-line-soft)}

/* ── Buttons on ink ──────────────────────────────────────────────── */
.ink .button,.navshell .button{background:var(--on-ink);color:#FFFFFF;box-shadow:0 18px 36px -26px rgba(14,26,43,0.55)}
.button-ghost{
  height:50px;display:inline-flex;align-items:center;padding:0 22px;border-radius:11px;
  border:1px solid var(--ink-line);color:var(--on-ink);background:transparent;
  font-family:var(--font-body);font-size:15px;font-weight:500;text-decoration:none;
  transition:border-color .14s ease,background .14s ease;
}
.button-ghost:hover{border-color:rgba(14,26,43,0.34);background:rgba(14,26,43,0.03)}
.actions{display:flex;gap:12px;flex-wrap:wrap;margin-top:34px}

/* ── Feature grid ────────────────────────────────────────────────── */
.grid3{display:grid;grid-template-columns:repeat(3,1fr);gap:1px;background:var(--ink-line-soft);
  border:1px solid var(--ink-line-soft);border-radius:14px;overflow:hidden}
.cell{background:var(--ink);padding:36px 30px}
.cell-k{font-family:var(--font-ui);font-size:11px;letter-spacing:0.12em;text-transform:uppercase;
  color:var(--on-ink-dim);margin-bottom:12px}
.cell-v{font-family:var(--font-display);font-size:38px;letter-spacing:-0.03em;margin-bottom:8px}
.cell-v .unit{font-size:15px;color:var(--on-ink-dim);letter-spacing:-0.01em}
.cell-d{font-size:15px;line-height:1.55;color:var(--on-ink-dim)}

/* ── Code panel ──────────────────────────────────────────────────── */
.code{
  background:var(--ink-soft);border:1px solid var(--ink-line);border-radius:14px;overflow:hidden;
}
.code-bar{
  display:flex;align-items:center;gap:9px;padding:11px 16px;
  border-bottom:1px solid var(--ink-line-soft);background:rgba(14,26,43,0.02);
}
.code-name{font-family:var(--font-ui);font-size:12px;color:var(--on-ink-dim);margin-left:4px}
.code-tag{margin-left:auto;font-family:var(--font-ui);font-size:10.5px;letter-spacing:0.1em;
  text-transform:uppercase;color:var(--signal);border:1px solid rgba(255,197,61,0.3);
  padding:3px 8px;border-radius:6px}
.code pre{padding:20px;overflow-x:auto;font-family:var(--font-ui);font-size:13px;line-height:1.72;
  color:var(--on-ink-muted)}
.c-key{color:#7C3AED}.c-str{color:var(--green)}.c-num{color:var(--signal)}.c-com{color:var(--on-ink-dim);font-style:italic}
.c-fn{color:var(--arch-vlm)}

/* ── Tables ──────────────────────────────────────────────────────── */
.tbl{width:100%;border-collapse:collapse;font-size:clamp(13.5px,0.85vw,17px)}
.tbl th{
  text-align:left;padding:12px 14px;border-bottom:1px solid var(--ink-line);
  font-family:var(--font-ui);font-size:11px;letter-spacing:0.1em;text-transform:uppercase;
  color:var(--on-ink-dim);font-weight:400;white-space:nowrap;
}
.tbl td{padding:14px;border-bottom:1px solid var(--ink-line-soft);color:var(--on-ink-muted);
  vertical-align:top}
.tbl tr:hover td{background:rgba(14,26,43,0.02)}
.tbl .mono{font-family:var(--font-ui);font-size:12.5px;color:var(--on-ink)}
.num{font-family:var(--font-ui);color:var(--signal);white-space:nowrap}
.tbl-scroll{overflow-x:auto;border:1px solid var(--ink-line-soft);border-radius:14px}

/* ── Callout ─────────────────────────────────────────────────────── */
.note{
  display:grid;grid-template-columns:3px 1fr;gap:18px;
  background:var(--ink-soft);border:1px solid var(--ink-line-soft);border-radius:13px;
  padding:0;overflow:hidden;margin:26px 0;
}
.note-bar{background:var(--signal)}
.note-body{padding:18px 20px;font-size:14px;line-height:1.65;color:var(--on-ink-muted)}
.note-body strong{color:var(--on-ink);font-weight:500}

/* ── Footer ──────────────────────────────────────────────────────── */
.ink footer{padding:48px 0 64px;color:var(--on-ink-dim);font-size:13.5px}
.foot-grid{display:grid;grid-template-columns:1.4fr repeat(3,1fr);gap:34px;margin-bottom:40px}
/* 文档页在页脚上方多留一档:docs 正文一路铺到底(最后一节是错误码表格),
   没有这段呼吸,表格最后一行会和页脚第一列贴在一起。
   这 44px 原本是 docs 页 <div class="foot-grid"> 上的 inline style,同处还有
   一条 border-top —— 那条是冗余的:style.css 的 footer 规则已经画了同一条线,
   inline 那条只把 alpha 从 0.08 改成 0.07,肉眼不可辨,已删。
   {实测 getComputedStyle —— docs: BORDER-TOP "1PX RGBA(14,26,43,0.07)" 且
    .FOOT-GRID PADDING-TOP "44PX";pricing: "1PX RGBA(14,26,43,0.08)" 且 "0PX"}
   [CONFIDENCE: CONFIRMED 100% —— 两页浏览器实测对比。提成 class 之后 footer
    才可能有单一 canonical,见 tools/sync_footer.py] */
.foot-grid.airy{padding-top:44px}
.foot-h{font-family:var(--font-ui);font-size:11px;letter-spacing:0.12em;text-transform:uppercase;
  color:var(--on-ink-dim);margin-bottom:14px}
.foot-l{display:block;color:var(--on-ink-muted);text-decoration:none;font-size:13.5px;padding:5px 0}
.foot-l:hover{color:var(--on-ink)}
.foot-rule{border-top:1px solid var(--ink-line-soft);padding-top:22px;display:flex;
  justify-content:space-between;gap:16px;flex-wrap:wrap}

/* 断点从 900 提到 1000:全称「GeneralSequences」比「Genseq」宽出一倍多,
   在 900–1000 这一段 wordmark、菜单、右侧按钮正好把空间用尽,三者互相贴住 ——
   没有重叠也没有溢出,但一点间距都没有,读起来是挤的。实测 915px 与 980px
   下菜单右缘与按钮左缘相距 0px。与其让它贴着,不如在那一段就收起菜单。 */
@media (max-width:1000px){
  .navmenu{display:none}
  .grid3{grid-template-columns:1fr}
  .foot-grid{grid-template-columns:1fr 1fr}
  .mega{grid-template-columns:1fr}
  .mega-side{border-left:none;border-top:1px solid var(--ink-line-soft)}
}

/* ── Two-column page head ────────────────────────────────────────────
   A single column of copy on a 1440 screen leaves half the fold empty, and
   empty reads as "there is not much here" — which is the opposite of what an
   infrastructure page needs to say. The right column is not decoration: it
   carries the numbers a reader would otherwise have to scroll for. */
.head-split{display:grid;grid-template-columns:1.15fr 0.85fr;gap:64px;align-items:start}
.head-split .lede{max-width:none}

.spec{
  border:1px solid var(--ink-line-soft);border-radius:15px;overflow:hidden;
  background:linear-gradient(180deg,var(--ink-raised),var(--ink-soft));
}
.spec-head{
  display:flex;align-items:center;justify-content:space-between;gap:12px;
  padding:13px 17px;border-bottom:1px solid var(--ink-line-soft);
  font-family:var(--font-ui);font-size:11px;letter-spacing:0.12em;text-transform:uppercase;
  color:var(--on-ink-dim);
}
.spec-live{display:inline-flex;align-items:center;gap:6px;color:var(--signal)}
.spec-live i{width:6px;height:6px;border-radius:50%;background:var(--signal);
  box-shadow:0 0 0 0 rgba(255,197,61,0.6);animation:pulse 2.4s ease-out infinite;font-style:normal}
@keyframes pulse{
  0%{box-shadow:0 0 0 0 rgba(255,197,61,0.55)}
  70%{box-shadow:0 0 0 7px rgba(255,197,61,0)}
  100%{box-shadow:0 0 0 0 rgba(255,197,61,0)}
}
.spec-row{
  display:grid;grid-template-columns:1fr auto;gap:14px;align-items:baseline;
  padding:12px 17px;border-bottom:1px solid var(--ink-line-soft);
}
.spec-row:last-child{border-bottom:none}
.spec-k{font-size:13px;color:var(--on-ink-dim)}
.spec-v{font-family:var(--font-ui);font-size:13px;color:var(--on-ink);white-space:nowrap}
.spec-v.hot{color:var(--signal)}
.spec-foot{padding:13px 17px;border-top:1px solid var(--ink-line-soft);
  font-size:12px;line-height:1.55;color:var(--on-ink-dim);background:var(--ink-soft)}

@media (max-width:980px){.head-split{grid-template-columns:1fr;gap:36px}}

/* ── Announcement strip ──────────────────────────────────────────────
   Sits above the nav, the way Modal's and Together AI's do. It is where a
   reader learns the catalogue is alive without going to look for a changelog.
   Amber on ink so it reads as signal; it is the one place the accent is
   allowed to cover a whole strip rather than a single value. */
.announce{border-bottom:1px solid var(--ink-line-soft);background:var(--ink-soft)}

.announce-in{
  /* 高度钉死而不是靠 padding 撑:见 --announce-h 的注释 —— 它必须等于
     .navshell 的负 top,靠内边距推导出的高度会随字号漂移。 */
  /* 扣掉 .announce 的 1px 下边框,好让整条正好是 --announce-h */
  display:flex;align-items:center;gap:clamp(12px,1.1vw,18px);
  /* 居中而不是靠左。靠左时整条读作「页面左上角的一条通知」,居中读作
     「这一条是说给所有人听的」—— 而它确实是给每个访客看的同一句话。
     {USER 2026-08-31 "3 AND I WANT CENTERED"}
     [CONFIDENCE: CONFIRMED 100% —— 本轮用户原话] */
  justify-content:center;
  height:calc(var(--announce-h) - 1px);
  text-decoration:none;color:var(--on-ink-muted);
  /* 13.5px 曾是全站最小的正文字号,而这一行是访客看到的第一行字。跟着视口走。 */
  font-size:clamp(14.5px,1.12vw,19px);
  transition:color .14s ease;
}
.announce-in:hover{color:var(--on-ink)}
/* NEW 标签。三处都跟着条高/视口解算,不再是三个写死的数:
   - 高度按 --announce-h 的比例给,标签和整条一起缩放,比例恒定 ——
     之前 22px 的标签坐在 44px 的条里只占一半高,像事后贴上去的一块。
   - 左右内边距和字距一起放开:这四个字母全大写又短,挤在一起会糊成一团。
   {USER 2026-08-29 SCREENSHOT "THE NEW NEED TO BE LARGER WIDER AND FONT LARGER"}
   [CONFIDENCE: CONFIRMED 90% —— 40×22px / 字号 10.5px 为 1280 视口实测] */
.announce-tag{
  display:inline-flex;align-items:center;
  height:calc(var(--announce-h) * 0.56);
  padding:0 clamp(11px,0.9vw,16px);
  font-family:var(--font-ui);font-size:clamp(11.5px,0.86vw,14.5px);
  letter-spacing:0.12em;text-transform:uppercase;line-height:1;
  /* 绿色实心、白字。换掉此前的琥珀淡填,原因不是琥珀本身难看,而是它**孤立**:
     整页只有 navy 墨和一个绿两种颜色,琥珀是第三种、且是唯一的暖色,所以它
     不读作「强调」,读作「贴上去的一张贴纸」。
     换成绿还解决另一件事 —— 绿在首页此前只出现一次(logo 那道斜杠),
     只出现一次的颜色读起来像意外而不是系统色。这是它的第二次出现。
     {USER 2026-08-31 "I DONT LIKE THE COLOR FO THE NEW HERE" → 从 9 个方案里选 3}
     [CONFIDENCE: CONFIRMED 100% —— 用户在 tools/badge-lab.html 中指定编号 3]

     白字在 #0B6B52 上是 6.48:1(与该绿在纯白上的对比度同值,因为对比度是
     对称的),远高于 AA 对小字的 4.5:1 要求。 */
  color:#FFFFFF;border:1px solid var(--green);background:var(--green);
  border-radius:7px;flex:0 0 auto;
}
/* The arrow nudges rather than the whole row moving — a strip that shifts on
   hover reads as a layout bug even when it is intentional. */
/* 箭头跟着正文一起放大 —— 它留在原尺寸会显得像另一套字号里的东西。 */
/* margin-left:auto 已移除 —— 它是把箭头顶到视口右缘的那一行,与居中互斥。
   现在箭头紧跟在句子后面,和它指向的东西是同一组。 */
.announce-go{color:var(--green);transition:transform .16s ease;
  font-size:clamp(15px,1.2vw,21px);line-height:1}
.announce-in:hover .announce-go{transform:translateX(3px)}

/* ── Nav layout ──────────────────────────────────────────────────────
   Five top-level items rather than three: the reader should be able to see the
   shape of the product from the bar alone, which is the whole point of a wide
   nav on an infrastructure site. */
.nav-left{display:flex;align-items:center;min-width:0}
.mega-narrow{grid-template-columns:minmax(360px,1fr)}
/* Log in 用全墨,不用 --on-ink-muted。它和右边的 Request access 是一组:
   一个实心黑按钮旁边跟一个灰字链接,灰字会读成"未启用"而不是"次要动作" ——
   两者都是可点的入口,只是权重不同,而权重差已经由「实心 vs 无底」表达了,
   不需要再用颜色说第二遍。
   {USER 2026-08-31 "LGO IN SHOULD BE BLACK"}
   [CONFIDENCE: CONFIRMED 100% —— 本轮用户原话 + 用户贴的顶栏截图] */
.nav-login{color:var(--on-ink)}
.nav-login:hover{opacity:.7}

@media (max-width:1120px){
  .navmenu{gap:0;margin-left:22px}
  .navlink{padding:0 10px;font-size:14px}
}
@media (max-width:900px){
  /* 改 token 而不是改 padding —— 负 top 跟着它走,不会失配 */
  /* 窄屏也一起放大,但幅度收着:这里的宽度是稀缺资源,条太高会吃掉首屏。 */
  :root{--announce-h:46px}
  .announce-in{font-size:13.5px;gap:10px}
  .announce-go{display:none}
  /* 窄屏截断成一行。条高是**写死**的(--announce-h),而这句话在 390px 下会折成
     三行 —— 多出来的两行不会撑开条,而是直接溢出到导航上面,读起来像布局坏了。
     公告条本来就是个引子,完整句子在它指向的页面里,截断不丢信息。
     min-width:0 不可省:flex item 的默认 min-width 是 auto,即"不得小于内容宽度",
     没有这一条 text-overflow 永远不会触发 —— 元素根本不会被压到需要省略的宽度。 */
  .announce-in > span:not(.announce-tag){
    min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
  }
}


/* ── The bar carries its own surface ─────────────────────────────────
   It is ink over a paper page as readily as over an ink one. One markup, one
   stylesheet, every surface — the alternative was a light variant, which is
   another way of spelling "two navs that will drift apart". */
/* 导航条比页面略深一档:白底上纯白的条会跟内容糊在一起,
   需要一点明度差才看得出这是一条独立的横梁。 */
/* 吸顶发生在 **shell** 上,不在 nav 上 —— 这是踩过的一个坑:
   position:sticky 的粘附范围被**父元素的盒子**限制。nav 的父级是这个 shell,
   而 shell 只有一条公告加一条导航那么高;页面一旦滚过它,nav 就没有可粘的
   区间,会跟着内容一起离开。实测 nav 的 top 会走到 -1355px。

   解法是让 shell 自己粘,并把 top 设成**负的公告条高度**:公告条正好被推出
   视口上方,导航落在 0。两个数由同一个 --announce-h 推导,不会失配。

   公告条因此不吸顶 —— 它是一次性信息,读过就该让位;两条一起占顶
   在笔记本屏幕上会吃掉一大块视口。 */
.navshell{
  position:sticky;top:calc(-1 * var(--announce-h));z-index:70;
  /* 背景留给两条各自负责:公告条有 --ink-soft,导航把底交给内层的药丸。
     shell 若自己铺一层底,药丸周围那 12px 空隙就会被填成一块通栏色带 ——
     而"药丸周围能看见页面"正是这套构图成立的前提。 */
  background:transparent;
}

/* 锚点落点的偏移放在**滚动容器**上而不是每个目标元素上:
   scroll-padding-top 就是为吸顶头设计的属性,一条规则覆盖全站所有锚点
   与所有 scrollIntoView,不需要给每个标题补一次 scroll-margin ——
   而漏补的那一个正是会让人以为链接坏掉的那一个。

   实测踩过:docs 页的内联样式里写着 scroll-margin-top:24px,那是按**不吸顶**的
   导航写的;条一吸顶,24px 就不够,标题被压在条底下 40 多像素。 */
html{
  scroll-padding-top:calc(var(--nav-h) + 16px);
  /* 见 .mrail-vp 的注释:预留滚动条槽位后 100vw 与 clientWidth 相等,
     全宽元素不再溢出。副作用是内容不足一屏时也留着这条槽 —— 换来的是
     内容长过一屏时不会整页横跳,这个交换是划算的。 */
  scrollbar-gutter:stable;
}

/* Section labels inside a menu. Together AI groups its rows this way and the
   reason is legible: four undifferentiated rows read as a list, four rows under
   two headings read as a structure. */
.mega-label{
  font-family:var(--font-ui);font-size:10.5px;letter-spacing:0.12em;text-transform:uppercase;
  color:var(--on-ink-dim);padding:12px 12px 6px;
}
.mega-list > .mega-label:first-child{padding-top:4px}

/* The side box gets a closing action. Without one the panel is a statement;
   with one it is a door. */
.mega-cta{
  display:inline-block;margin-top:14px;font-family:var(--font-ui);font-size:12px;
  color:var(--signal);text-decoration:none;
}
.mega-cta:hover{text-decoration:underline}
/* 此处曾有 .mega-code / .mega-code-hi —— Developers 下拉右栏那块印着
   base_url 的代码卡。随顶栏其余视觉元素一并移除,已无元素引用。
   {USER 2026-08-31 "REMOVE ALL THE VISUALS" + "ON THETOPBAR"} */

/* ── The band palette, made reusable ─────────────────────────────────
   The chunk matrix works because the colour is doing two jobs at once: four
   hues separate the groups, and an opacity ramp inside each hue carries
   magnitude. That is a data encoding, not a decoration, which is why it reads
   as instrumentation rather than as a pattern library.

   Everything below reuses those same four hues in the same order, so a reader
   who learns the matrix has already learned the rest of the site. Introducing
   a fifth colour anywhere would break that — the palette is closed on purpose. */
:root{
  --b1:var(--arch-vla);   /* green  — arm      / VLA     / serverless */
  --b2:var(--arch-vlm);   /* blue   — wrist    / VLM     / chat       */
  --b3:var(--signal);     /* amber  — hand     / live    / measured   */
  --b4:var(--arch-wam);   /* orange — base     / WAM     / dedicated  */
}

/* A strip of squares fading in, the matrix compressed to one row. Pure CSS:
   repeating-linear-gradient draws the squares, a mask supplies the ramp —
   no element per square, so it can sit on any page without a script. */
.ramp{
  display:block;height:12px;border-radius:2px;
  background:repeating-linear-gradient(90deg,
    var(--h,var(--b1)) 0 12px, transparent 12px 15px);
  -webkit-mask-image:linear-gradient(90deg,rgba(0,0,0,0.12),#000 78%);
  mask-image:linear-gradient(90deg,rgba(0,0,0,0.12),#000 78%);
}
.ramp.h1{--h:var(--b1)} .ramp.h2{--h:var(--b2)}
.ramp.h3{--h:var(--b3)} .ramp.h4{--h:var(--b4)}
.ramp-set{display:grid;gap:5px;margin-top:22px}

/* Stat cells take the four hues in order. Without it three identical panels
   read as one block of text; with it the eye can hold them apart while
   reading, which is the entire job of a three-up. */
.grid3 .cell{position:relative}
.grid3 .cell::before{
  content:"";position:absolute;top:0;left:0;right:0;height:3px;
  background:var(--cell-h,var(--b1));
}
.grid3 .cell:nth-child(1){--cell-h:var(--b1)}
.grid3 .cell:nth-child(2){--cell-h:var(--b2)}
.grid3 .cell:nth-child(3){--cell-h:var(--b3)}
.grid3 .cell:nth-child(4){--cell-h:var(--b4)}
.grid3 .cell .cell-v{color:var(--cell-h)}

/* Architecture pills already carry the hue; give the table row a left edge in
   the same colour so a family can be tracked down a long table without
   re-reading the label on every line. */
.tbl tbody tr{box-shadow:inset 3px 0 0 -1px transparent}
.tbl tbody tr:hover{box-shadow:inset 3px 0 0 0 var(--b3)}

/* Section eyebrows cycle rather than all being amber: on a long page the
   repeated identical accent stops registering as a marker at all. */
.ink .block:nth-of-type(4n+1) .eyebrow{color:var(--b1)}
.ink .block:nth-of-type(4n+2) .eyebrow{color:var(--b2)}
.ink .block:nth-of-type(4n+3) .eyebrow{color:var(--b3)}
.ink .block:nth-of-type(4n+4) .eyebrow{color:var(--b4)}

/* ── Model cards ─────────────────────────────────────────────────────
   A catalogue reads faster as cards than as a table when the reader does not
   yet know what they are looking for — a table asks you to hold column
   meanings in your head, a card puts every fact about one model in one place.
   The table on the console page is the opposite case and stays a table.

   架构色以前还在左边缘挂一条 3px 竖条。它和右上角的架构角标说的是同一件事，
   而角标已经把字写出来了 —— 竖条只是同一个信息的第二次上色，轨道跑起来的时候
   一排彩色竖杠比卡片本身更抢眼。留角标，去竖条。
   --mh 变量留着：角标的描边和字色还从它取。
   {USER 2026-08-31 "I DONT LIKE THE VERITCLA BARS"}
   [CONFIDENCE: CONFIRMED 100% — 直接指令，配一张两行轨道的截图] */
.mcard{
  display:flex;flex-direction:column;gap:12px;
  padding:22px 22px 20px;background:var(--ink-raised);
  border:1px solid var(--ink-line-soft);border-radius:14px;
  min-width:290px;text-decoration:none;color:inherit;
  transition:border-color .16s ease,transform .16s ease;
}
.mcard:hover{border-color:var(--ink-line);transform:translateY(-2px)}
.mcard.k-vlm{--mh:var(--b2)} .mcard.k-vla{--mh:var(--b1)} .mcard.k-wam{--mh:var(--b4)}
.mcard.k-off{--mh:var(--on-ink-dim);opacity:.62}

/* 上沿:左边一块大 logo,右边一枚架构角标。
   前一版是「小 logo + 厂商名文字」并排,读者要先读完一行字才知道这是谁家的
   —— 而 logo 本来就是给人一眼认出来用的,把它做小再配字等于两样东西都在道歉。
   放大到 40px 之后厂商名那行字可以整条删掉,卡上少一行,认出得更快。 */
.mcard-top{display:flex;align-items:flex-start;justify-content:space-between;gap:10px}
/* 架构角标退到右上角,让出左上给 logo。描边 pill 而不是裸字:裸字挂在角上像
   没放好,pill 有自己的边界才站得住。颜色跟左侧色条同一个 --mh。 */
.mcard-arch{font-family:var(--font-ui);font-size:10px;letter-spacing:0.12em;
  text-transform:uppercase;color:var(--mh);
  padding:3px 7px;border-radius:5px;border:1px solid currentColor;
  opacity:.75;white-space:nowrap;flex:0 0 auto}
/* 标题走正文字体,id 才走等宽。这两行以前是同一行:卡片直接把 id 当标题显示,
   于是 'cosmos3-edge-policy-droid' 这种全小写连字符串成了卡上最大的字 ——
   那是给 URL 和请求体用的字符串,读者得先在心里断词才知道这是哪个模型。
   现在标题用各家自己的写法(π 是希腊字母、GROOT 是缩写故全大写、Claude 是
   普通词故只首字母大写),等宽 id 降一级放到下面 —— 降级但不删除,因为发请求
   时仍然要照抄它。
   {USER 2026-08-31 "DONT USE MODEL CARD BY JUST A CAPTIZLIED TITLE, E.G. GROOT N1
    / THIS TYPE OF MODEL NAME PEOPLE CAN ACTUALLY READ"}
   [CONFIDENCE: CONFIRMED 100% — 直接的用户指令] */
.mcard-name{font-family:var(--font-body);font-size:17px;font-weight:500;
  letter-spacing:-0.015em;line-height:1.25;color:var(--on-ink);word-break:break-word}
/* 负 margin 抵消 .mcard 的 gap:12px —— id 是标题的从属行,该贴着标题,
   而不是跟 spec、tags 一样按 12px 均分间距。 */
.mcard-id{font-family:var(--font-ui);font-size:11.5px;color:var(--on-ink-dim);
  margin-top:-7px;word-break:break-all}
.mcard-spec{font-size:13px;line-height:1.55;color:var(--on-ink-dim)}
/* tag 行接过原来 .mcard-price 的推底职责 —— 价格合并进了 .mcard-spec,
   那条规则连同它的 margin-top:auto 一起没了,不补上卡片底部就会参差。 */
.mcard-tags{display:flex;gap:6px;flex-wrap:wrap;margin-top:auto}
.mtag{font-family:var(--font-ui);font-size:10.5px;letter-spacing:0.04em;
  padding:4px 8px;border-radius:6px;border:1px solid var(--ink-line);
  color:var(--on-ink-muted);white-space:nowrap}
.mtag.ok{border-color:rgba(11,107,82,0.4);color:var(--b1)}
.mtag.warn{border-color:rgba(150,101,10,0.45);color:var(--b3)}
.mtag.block{border-color:rgba(168,70,31,0.45);color:var(--b4)}

/* Homepage: one row that scrolls sideways rather than a grid that pushes the
   fold down. Scroll-snap so it lands on a card instead of half of one. */
/* ── Model rail: 跑马灯 ────────────────────────────────────────────
   之前是一个带横向滚动条的盒子。那要求读者先意识到它能滚、再动手去滚，
   而这一段的读者是路过的 —— 不动的东西他不会去碰。改成自己在跑：卡片从
   两侧滑出画面，一眼就知道后面还有。

   视口做成全宽（脱出 .wrap），否则卡片会在容器边缘被硬切，看起来像裁掉了
   而不是滑出去了。两端加 mask 渐隐，让进出是淡出而不是被剪断。 */
.mrail-vp{
  /* 满幅靠 100vw，不靠 JS 量宽度。

     100vw 本身是含滚动条的，比内容区宽约 15px，直接用会让整页多出一条横向
     滚动。常见补救是给 body 加 overflow-x:hidden，但那会把 body 变成滚动
     容器，顶栏的 position:sticky 会直接失效 —— 换个 bug 而已。

     真正的解法在 html 上的 scrollbar-gutter:stable：槽位常驻之后
     100vw 恰好等于 clientWidth，这个单位本身就变准了。
     {实测 1905 与 1265 两档: 100vw 探针宽度 === clientWidth, scrollWidth 无溢出}
     [CONFIDENCE: CONFIRMED 100% — 两个视口宽度各量过一次]

     曾经用 hero.js 写入 --vw 来代替 100vw。那版能算准，但 resize 到防抖
     触发之间 --vw 是上一次的值 —— 实测窗口从 1905 拖到 1265 时 --vw 还停在
     1425，轨道按 1425 撑开，横向滚动条肉眼可见地闪出来。CSS 没有这个时间差。 */
  width:100vw;margin-left:calc(50% - 50vw);overflow:hidden;
  -webkit-mask-image:linear-gradient(90deg,transparent 0,#000 7%,#000 93%,transparent 100%);
          mask-image:linear-gradient(90deg,transparent 0,#000 7%,#000 93%,transparent 100%);
}
/* 行距比卡片间距略大，两行才不会糊成一片。 */
.mrail + .mrail{margin-top:22px}
.mrail{display:flex;gap:16px;width:max-content;padding:4px 0 18px;
  animation:mroll var(--roll-dur,64s) linear infinite;
  will-change:transform}
/* 反向必须写在 .mrail 之后 —— .mrail 用的是 animation 简写，简写会把
   animation-direction 一并重置成 normal，写在它前面的 reverse 会被抹掉。
   {实测: 规则放在 .mrail 之前时 getComputedStyle().animationDirection 仍是 "normal"}
   [CONFIDENCE: CONFIRMED 100% — 调整顺序前后各量过一次] */
.mrail-rev{animation-direction:reverse}
/* 悬停暂停 —— 读者想看清某一张时，图不该从他眼皮底下溜走。 */
.mrail:hover,.mrail:focus-within{animation-play-state:paused}
.mrail-set{display:flex;gap:16px}
.mrail-set > .mcard{width:290px;flex:0 0 290px}
/* --roll 是「一组卡片 + 一个 gap」的精确宽度，由 hero.js 量出来写回。
   写死 -50% 会在两组之间差一个 gap，循环处每圈跳一下。 */
@keyframes mroll{from{transform:translateX(0)}
                 to{transform:translateX(calc(-1 * var(--roll,50%)))}}
/* 关掉动画的人拿回一个可横滚的盒子 —— 内容一条不少，只是不自己动。 */
@media (prefers-reduced-motion:reduce){
  .mrail{animation:none;overflow-x:auto;width:100%;scrollbar-width:thin}
}

/* 厂商标 —— 各家官网取回的真 logo，自托管在 assets/logos/。
   不热链对方 CDN：热链把访客 IP 送给第三方，而且对方换一次路径我们就碎图。
   {下载自 physicalintelligence.company / robbyant.com / perceptron.inc /
    xiaomi.com / cdn.simpleicons.org(NVIDIA·CC0) / anthropic.com /
    commons.wikimedia.org(OpenAI) / google.com 品牌页 / qwen.ai}
   [CONFIDENCE: CONFIRMED 95% — 逐个 curl 下载后用 PIL 验过尺寸与格式]

   不给容器加边框/底色：这批 logo 里有一半自带圆角方底（Robbyant、Xiaomi、
   Perceptron），再套一层就是框里有框；另一半是裸字形（π、NVIDIA、Google），
   直接落在卡片纸面上反而干净。object-fit:contain 保证两类都不变形。

   卡上放到 40px：厂商名那行字删掉之后，logo 是唯一还在回答「谁做的」的东西，
   18px 承不住这个职责 —— 那个尺寸只够当文字旁边的装饰。放大到能独立辨认，
   它才真的替代了那行字，而不是让卡片少了一条信息。 */
.bymark{width:40px;height:40px;flex:0 0 auto;object-fit:contain;
  border-radius:9px;display:inline-block}
/* 表格里的变体，尺寸要退回 18px —— 表格里 logo 是和模型名挤在同一个格子里的
   前缀，跟着卡片一起放大会把行高顶开。同理它自带右边距，并压到基线上：
   inline-block 默认按基线对齐，图的底边会和文字底边齐平，看起来像浮在半空。 */
.bymark-inline{width:18px;height:18px;border-radius:4px;
  margin-right:8px;vertical-align:-4px}

/* Models page: a real grid, because there the reader wants the whole set. */
.mgrid{display:grid;gap:16px;grid-template-columns:repeat(auto-fill,minmax(290px,1fr))}
.mgroup{margin-top:44px}
.mgroup:first-of-type{margin-top:0}
.mgroup-h{display:flex;align-items:baseline;gap:14px;margin-bottom:8px}
.mgroup-t{font-family:var(--font-display);font-size:clamp(22px,1.9vw,32px);
  letter-spacing:-0.022em;font-weight:600}
.mgroup-n{font-family:var(--font-ui);font-size:12px;color:var(--on-ink-dim);
  letter-spacing:0.1em;text-transform:uppercase}
.mgroup-d{font-size:15px;line-height:1.6;color:var(--on-ink-dim);max-width:70ch;margin-bottom:20px}

/* ── Model library filter rail ───────────────────────────────────────
   A row of chips above the groups. Counts are baked into the markup so the
   rail reads correctly with scripting off; the script only hides groups. */
.mfilter{display:flex;gap:10px;flex-wrap:wrap;padding:0 0 clamp(28px,3vw,52px)}
.mchip{
  display:inline-flex;align-items:center;gap:8px;
  height:42px;padding:0 18px;border-radius:11px;cursor:pointer;
  border:1px solid var(--ink-line);background:var(--ink-raised);
  font-family:var(--font-ui);font-size:13.5px;letter-spacing:0.04em;
  color:var(--on-ink-muted);
  transition:border-color .14s ease,color .14s ease,background .14s ease;
}
.mchip:hover{border-color:rgba(14,26,43,0.3);color:var(--on-ink)}
/* The selected chip inverts rather than merely darkening: with five chips in a
   row a subtle state is the same as no state. */
.mchip.on{background:var(--on-ink);border-color:var(--on-ink);color:#FFFFFF}
/* Each architecture chip carries its own hue on the edge, matching the cards
   and the chunk matrix — one palette across the whole site. */
.mchip.k-vla{border-color:rgba(11,107,82,0.4)}
.mchip.k-wam{border-color:rgba(168,70,31,0.4)}
.mchip.k-vlm{border-color:rgba(29,79,168,0.4)}
.mchip.k-vla.on{background:var(--arch-vla);border-color:var(--arch-vla)}
.mchip.k-wam.on{background:var(--arch-wam);border-color:var(--arch-wam)}
.mchip.k-vlm.on{background:var(--arch-vlm);border-color:var(--arch-vlm)}

/* Acronym set beside the full name rather than instead of it. The response
   body, the pricing tiers and the model cards all say vla; the menu has to
   teach that mapping once, and the only way to teach it is to show both
   together. Smaller and dimmer so the full name still leads. */
.mega-abbr,.mgroup-abbr{
  font-family:var(--font-ui);font-size:0.68em;letter-spacing:0.1em;
  color:var(--on-ink-dim);border:1px solid var(--ink-line);
  padding:2px 6px;border-radius:5px;margin-left:8px;vertical-align:middle;
  font-weight:400;
}

/* ── Closing call-to-action band ─────────────────────────────────────
   A dark full-bleed strip to end on. The layout is borrowed — Fireworks and
   Together both close this way, and it works because a reader who has finished
   the argument wants a destination rather than another paragraph.

   The palette is not borrowed. Theirs steps black into purple; this steps ink
   through the four architecture hues in hard stops, which is the chunk matrix
   from the top of the page stretched into a strip. Taking both the layout and
   the colour would have produced their band with our words in it. */
.cta-band{
  position:relative;
  /* No vw trick. The section is already a direct child of <body> with the
     centred .wrap on its inner div, so it is full width by default.
     The first attempt used width:100vw with negative margins and measured a
     horizontal scrollbar: 100vw counts the vertical scrollbar's 15px while the
     document's client width does not, so the band overhung by exactly that and
     scrollWidth came back 1913 against a clientWidth of 1905. The trick is only
     needed when the element sits inside a constrained parent — this one does
     not. */
  background:var(--on-ink);
  overflow:hidden;
}
/* Hard stops, not a smooth blend. A continuous ramp reads as a photograph of a
   sunset; discrete steps read as a scale, which is what every other figure on
   this site is. The first third stays ink so the heading has quiet ground. */
.cta-band::after{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(90deg,
    transparent 0%, transparent 34%,
    color-mix(in srgb, var(--arch-vla) 55%, transparent) 34%,
    color-mix(in srgb, var(--arch-vla) 55%, transparent) 50%,
    color-mix(in srgb, var(--arch-vlm) 60%, transparent) 50%,
    color-mix(in srgb, var(--arch-vlm) 60%, transparent) 66%,
    color-mix(in srgb, var(--signal) 55%, transparent) 66%,
    color-mix(in srgb, var(--signal) 55%, transparent) 82%,
    color-mix(in srgb, var(--arch-wam) 60%, transparent) 82%,
    color-mix(in srgb, var(--arch-wam) 60%, transparent) 100%);
  opacity:.85;
}
/* Content sits above the ::after, or the gradient would paint over the words. */
.cta-band-in{position:relative;z-index:1;text-align:center;
  padding:clamp(64px,7vw,132px) 0}
.cta-band-h{
  font-family:var(--font-display);font-size:clamp(32px,3.9vw,64px);
  line-height:1.05;letter-spacing:-0.022em;font-weight:600;color:#FFFFFF;
}
.cta-band-p{margin:clamp(16px,1.4vw,26px) auto 0;max-width:52ch;
  font-size:clamp(16px,1.05vw,21px);line-height:1.6;color:rgba(255,255,255,0.76)}
.cta-band-actions{display:flex;gap:14px;justify-content:center;flex-wrap:wrap;
  margin-top:clamp(28px,2.6vw,44px)}
/* On the band the filled button inverts: paper on ink, so it still reads as the
   primary action against a dark strip. */
.cta-band .button{background:#FFFFFF;color:var(--on-ink);box-shadow:none}
.button-line{
  height:50px;display:inline-flex;align-items:center;padding:0 24px;border-radius:11px;
  border:1px solid rgba(255,255,255,0.45);color:#FFFFFF;background:transparent;
  font-family:var(--font-body);font-size:15px;font-weight:500;text-decoration:none;
  transition:border-color .14s ease,background .14s ease;
}
.button-line:hover{border-color:#FFFFFF;background:rgba(255,255,255,0.08)}

/* ── What's new ──────────────────────────────────────────────────
   Release notes as cards rather than a list. A list of dated lines reads as
   a changelog — something you consult after you already use the product.
   Cards with a drawn figure read as "here is what changed and what it looks
   like", which is the job this block has sitting directly under the hero:
   a visitor who has not decided anything yet needs evidence that the
   catalogue moves, not a promise that it does.

   Each figure is drawn from the model's own published numbers (frames read,
   parameter count, action width). Nothing here is a screenshot of a chart —
   a screenshot cannot be checked against the catalogue, and this whole site
   is built on the claim that the numbers on a card are the numbers we serve.
   {ROOT CLAUDE.MD RULE 1 "EVERY FACTUAL CLAIM IS IMMEDIATELY FOLLOWED BY THE
    ACTUAL VERBATIM EXCERPT"} [CONFIDENCE: CONFIRMED 100% — 站内既有做法,
    hero 三帧同样是从 SPEC 数字画出来的,不是贴图] */
.nhead{display:flex;align-items:flex-end;justify-content:space-between;
  gap:28px;flex-wrap:wrap;margin-bottom:clamp(24px,2.1vw,40px)}
.nhead-h{font-family:var(--font-display);font-weight:500;letter-spacing:-0.03em;
  font-size:clamp(28px,2.9vw,52px);line-height:1.06;margin:0}
/* "See more" 用极小的 ui 字号 + 字距，和 eyebrow 成一对：一个开头一个结尾，
   都不参与正文的阅读节奏。 */
.nmore{display:inline-flex;align-items:center;gap:9px;text-decoration:none;
  font-family:var(--font-ui);font-size:11px;letter-spacing:0.13em;
  text-transform:uppercase;color:var(--on-ink-dim);white-space:nowrap;
  transition:color .14s ease}
.nmore:hover{color:var(--on-ink)}
.nmore span{transition:transform .16s ease}
.nmore:hover span{transform:translateX(4px)}

/* auto-fit + minmax：三张卡在宽屏一行，窄屏自己掉成两列再一列。
   写死 repeat(3,1fr) 会在 900px 附近把标题挤成五行。 */
.ngrid{display:grid;gap:clamp(16px,1.4vw,26px);
  grid-template-columns:repeat(auto-fit,minmax(300px,1fr))}

.ncard{display:flex;flex-direction:column;overflow:hidden;
  background:var(--ink-raised);border:1px solid var(--ink-line-soft);
  border-radius:14px;text-decoration:none;color:inherit;
  transition:border-color .16s ease,transform .16s ease}
.ncard:hover{border-color:var(--ink-line);transform:translateY(-2px)}
/* 架构决定这张卡的强调色，和 /models/ 的卡片用同一套映射，
   这样同一个模型在两个页面上是同一个颜色。 */
.ncard.k-vlm{--nh:var(--b2)} .ncard.k-vla{--nh:var(--b1)}
.ncard.k-wam{--nh:var(--b4)} .ncard.k-plat{--nh:var(--b3)}

/* 图区固定高度：三张卡的标题必须从同一条水平线开始，
   否则一行卡片读起来像三个不相干的东西。 */
.nfig{display:block;width:100%;height:clamp(132px,9.4vw,178px);
  border-bottom:1px solid var(--ink-line-soft);
  background:color-mix(in srgb, var(--nh,var(--b1)) 7%, var(--ink-raised))}
.nfig svg{display:block;width:100%;height:100%}

.ncard-body{flex:1;display:flex;flex-direction:column;gap:11px;
  padding:clamp(16px,1.1vw,22px) clamp(17px,1.2vw,24px) clamp(19px,1.4vw,26px)}
.ncard-meta{display:flex;align-items:center;gap:9px;flex-wrap:wrap;
  font-family:var(--font-ui);font-size:10.5px;letter-spacing:0.11em;
  text-transform:uppercase;color:var(--on-ink-dim)}
.ncard-kind{color:var(--nh,var(--b1))}
.ncard-h{font-family:var(--font-display);font-weight:500;letter-spacing:-0.018em;
  font-size:clamp(17px,1.16vw,22px);line-height:1.26;margin:0;color:var(--on-ink)}
.ncard-dek{margin:0;font-size:13.5px;line-height:1.58;color:var(--on-ink-dim)}
/* 规格行贴卡片底：三张卡的正文长度不一样，不锚到底部就参差不齐。 */
.ncard-spec{margin-top:auto;padding-top:12px;font-family:var(--font-ui);
  font-size:11.5px;letter-spacing:0.02em;color:var(--on-ink-muted,var(--on-ink-dim));
  border-top:1px solid var(--ink-line-soft)}
