/* 字体与主站 zerb.net 保持一致(2026-08-22 用户定):标题 Montserrat、正文 Mulish。
   字体文件自托管在 web/fonts/,不外链主站 —— 外链等于把这个站的可用性绑在
   另一个域名上。两个都是可变字重 woff2(100-900),一个文件覆盖所有字重。
   font-display:swap:字体没到之前先用系统字显示,别让首屏空着。 */
@font-face {
  font-family: Montserrat;
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("./fonts/montserrat-latin.woff2") format("woff2");
}
@font-face {
  font-family: Mulish;
  font-style: normal;
  font-weight: 100 900;
  font-display: swap;
  src: url("./fonts/mulish-latin.woff2") format("woff2");
}

:root {
  --brand-origin: "zerb-lion";
  --motion-signature: "zerb.net";
  --motion-origin-date: "2026-06-09";
  color-scheme: light;
  --bg: #f6f7f9;
  --panel: #ffffff;
  --ink: #16181d;
  --muted: #626a78;
  --line: #d7dce5;
  --line-strong: #aab2c0;
  --accent: #176b87;
  --accent-ink: #ffffff;
  --soft: #e9f2f5;
  --font-display: Montserrat, "Helvetica Neue", system-ui, sans-serif;
  --font-body: Mulish, system-ui, -apple-system, sans-serif;
  font-family: var(--font-body);
}

* {
  box-sizing: border-box;
}

html {
  /* Always reserve the scrollbar gutter so switching between a scrolling page
     (Spec/Guide) and a non-scrolling one (MotionSheet) doesn't shift the layout. */
  scrollbar-gutter: stable;
}

body {
  margin: 0;
  min-height: 100vh;
  background: var(--bg);
  color: var(--ink);
}

/* Hide content until the page's language is applied, so a saved 中文 page does
   not flash English first. Set by an inline <head> script only when needed. */
.lang-loading .app-shell {
  visibility: hidden;
}

button,
input {
  font: inherit;
}

.app-shell {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}


/* 标题走 Montserrat(display),正文走 Mulish(body)—— 与主站同一套分工。
   只列真正的标题类,不用通配:通配会把表格/代码块也拽进 display 字体,
   那种字体做数据密集的表格会变难读。 */
.topbar h1,
.hub-hero h1,
.hub-section-title,
.hub-card h3,
.table-toolbar h2,
.finding-panel h2,
.spec-block h2,
.spec-hero h1,
.guide-hero h1,
.eyebrow,
h1, h2, h3 {
  font-family: var(--font-display);
}

.topbar {
  min-height: 84px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  padding: 18px 24px;
  border-bottom: 1px solid var(--line);
  background: #ffffff;
}

.topbar h1,
.topbar p,
.table-toolbar h2,
.table-toolbar p,
.finding-panel h2 {
  margin: 0;
}

/* 字标里的 l 画成一把尺(B2)。**比例直接复刻 wordmark3.html 里用户认可的那版**
   (30px 下:尺宽 4px、高 30px、刻度厚 1.4px、间距 5px),换算成 em 就是下面这组。
   关键是**刻度厚度只占尺宽的 35%** —— 我自己重调的一版是 55%,刻度粗过尺身,
   看着就是一截色块不是刻度。以后要改比例,回去看那张图,别凭感觉调。

   hover:刻度整体下移半格,像尺子被抽动了一下。只用 background-position 过渡,
   不触发重排;移动端没有 hover,自然降级成静态。 */
.brand-rule {
  font-style: normal;
  color: transparent;
  position: relative;
}
.brand-rule::after {
  content: "";
  position: absolute;
  left: 50%;
  bottom: 0.16em;              /* 坐在基线上 */
  transform: translateX(-50%);
  width: 0.133em;
  height: 0.95em;
  border-radius: 1px;
  background:
    linear-gradient(var(--panel), var(--panel)) no-repeat right 0 bottom 0.167em / 100% 0.047em,
    linear-gradient(var(--panel), var(--panel)) no-repeat left  0 bottom 0.333em /  55% 0.047em,
    linear-gradient(var(--panel), var(--panel)) no-repeat right 0 bottom 0.500em / 100% 0.047em,
    linear-gradient(var(--panel), var(--panel)) no-repeat left  0 bottom 0.667em /  55% 0.047em,
    linear-gradient(var(--panel), var(--panel)) no-repeat right 0 bottom 0.833em / 100% 0.047em,
    var(--accent);
  transition: background-position 320ms cubic-bezier(0.326, 0.702, 0.129, 1);
}
.brand-link:hover .brand-rule::after {
  background-position:
    right 0 bottom 0.250em, left 0 bottom 0.417em, right 0 bottom 0.583em,
    left 0 bottom 0.750em,  right 0 bottom 0.917em;
}
@media (prefers-reduced-motion: reduce) {
  .brand-rule::after { transition: none; }
}

.topbar h1 {
  font-size: 26px;
  line-height: 1.1;
  font-weight: 720;
}

.brand-link {
  color: inherit;
  text-decoration: none;
}

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

.topbar p,
.table-toolbar p {
  margin-top: 4px;
  color: var(--muted);
  font-size: 13px;
}

.brand-signature {
  /* 后缀式署名:跟在字标后面,极浅 + 细体。原来是 font-weight 600 + --muted,
     跟字标抢注意力。署名的作用是"在场"不是"被读",越淡越好。 */
  color: #a9b0bb;
  font-weight: 300;
  font-size: 12px;
  letter-spacing: 0.02em;
  margin-left: 10px;
  white-space: nowrap;
}

/* 字标层次:Motion 用主色墨,Rules 退成灰 —— 一个词两层,不是一坨黑 */
.topbar h1 .brand-dim { color: var(--muted); font-weight: inherit; }

.brand-kicker {
  display: block;
  font-size: 11px;
  font-weight: 680;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--accent);
  line-height: 1;
  margin-bottom: 2px;
}

.nav-link.is-active {
  border-color: var(--accent);
  background: var(--soft);
  color: var(--accent);
  font-weight: 640;
}

.status-pill {
  border: 1px solid var(--line);
  background: var(--soft);
  color: #214c58;
  padding: 7px 10px;
  border-radius: 8px;
  font-size: 13px;
  white-space: nowrap;
}

.site-footer {
  border-top: 1px solid var(--line);
  padding: 14px 24px;
  color: var(--muted);
  font-size: 12px;
  line-height: 1.4;
  background: #ffffff;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px 16px;
  flex-wrap: wrap;
}

.footer-links {
  display: inline-flex;
  align-items: center;
  gap: 14px;
}

.footer-link {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  color: var(--muted);
  text-decoration: none;
}

.footer-link:hover {
  color: var(--accent);
  text-decoration: underline;
}

.footer-link svg {
  width: 14px;
  height: 14px;
  fill: currentColor;
  flex: none;
}

.top-actions {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px;
}

.nav-link,
.back-link,
.lang-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 30px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: #ffffff;
  color: var(--ink);
  text-decoration: none;
  padding: 0 10px;
  font-size: 13px;
  line-height: 1;
  cursor: pointer;
  transition: background-color 140ms ease, border-color 140ms ease, color 140ms ease, transform 80ms ease, box-shadow 140ms ease;
}

.nav-link:hover,
.back-link:hover,
.lang-toggle:hover {
  border-color: var(--line-strong);
  background: #f4f8fa;
  color: var(--accent);
}

.nav-link:active,
.back-link:active,
.lang-toggle:active {
  transform: translateY(1px);
  background: #e7f0f4;
}

.nav-link:focus-visible,
.back-link:focus-visible,
.lang-toggle:focus-visible,
.button-grid button:focus-visible,
.view-tab:focus-visible,
.player-controls button:focus-visible,
.track-label:focus-visible,
.timeline-segment:focus-visible {
  outline: 2px solid #2f83a0;
  outline-offset: 2px;
}

.lang-toggle {
  min-width: 82px;
}

.workspace {
  flex: 1;
  display: grid;
  grid-template-columns: minmax(280px, 340px) minmax(0, 1fr);
  gap: 0;
}

.control-panel {
  border-right: 1px solid var(--line);
  background: #fbfcfd;
  padding: 18px;
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.file-drop {
  position: relative;
  display: grid;
  gap: 8px;
  padding: 18px;
  min-height: 150px;
  align-content: center;
  border: 1px dashed var(--line-strong);
  border-radius: 8px;
  background: #ffffff;
  cursor: pointer;
}

.sample-btn {
  margin-top: 8px;
  width: 100%;
  padding: 9px 12px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--panel);
  color: var(--accent);
  font-size: 13px;
  font-weight: 640;
  cursor: pointer;
  transition: background 0.15s, border-color 0.15s;
}

.sample-btn:hover {
  background: var(--soft);
  border-color: var(--accent);
}

.file-drop.is-dragging {
  border-color: var(--accent);
  background: var(--soft);
}

.file-drop input {
  position: absolute;
  inset: 0;
  opacity: 0;
  cursor: pointer;
}

.file-icon {
  width: 48px;
  height: 32px;
  display: inline-grid;
  place-items: center;
  border: 1px solid var(--line);
  border-radius: 6px;
  font-size: 12px;
  font-weight: 700;
  color: var(--accent);
  background: var(--soft);
}

.file-title {
  font-weight: 700;
}

.file-note {
  color: var(--muted);
  font-size: 13px;
  overflow-wrap: anywhere;
}

.summary-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 8px;
}

.summary-grid div {
  min-width: 0;
  padding: 10px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: #ffffff;
}

.summary-grid span {
  display: block;
  color: var(--muted);
  font-size: 12px;
}

.summary-grid strong {
  display: block;
  margin-top: 4px;
  font-size: 18px;
  overflow-wrap: anywhere;
}

.button-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
}

.button-grid button {
  min-height: 38px;
  border: 1px solid #12576d;
  border-radius: 8px;
  background: var(--accent);
  color: var(--accent-ink);
  cursor: pointer;
  font-size: 13px;
  font-weight: 650;
  transition: background-color 140ms ease, border-color 140ms ease, transform 80ms ease, box-shadow 140ms ease;
}

.button-grid button:not(:disabled):hover {
  background: #125f78;
  box-shadow: 0 2px 8px rgb(18 87 109 / 18%);
}

.button-grid button:not(:disabled):active {
  transform: translateY(1px);
  background: #0f5066;
  box-shadow: inset 0 2px 3px rgb(0 0 0 / 18%);
}

.button-grid button:disabled {
  border-color: var(--line);
  background: #eef1f5;
  color: #8a92a0;
  cursor: not-allowed;
}

.action-status {
  min-height: 18px;
  margin: -4px 0 0;
  color: var(--muted);
  font-size: 12px;
  line-height: 1.4;
}

.action-status[data-kind="busy"] {
  color: #7a5d00;
}

.action-status[data-kind="success"] {
  color: #14633d;
}

.action-status[data-kind="error"] {
  color: #a12d2d;
}

.action-status a {
  color: inherit;
  font-weight: 700;
  text-decoration: underline;
  text-underline-offset: 2px;
}

.finding-panel {
  padding: 14px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: #ffffff;
}

.finding-panel h2,
.table-toolbar h2 {
  font-size: 16px;
}

.finding-panel ul {
  margin: 10px 0 0;
  padding-left: 18px;
  color: var(--muted);
  font-size: 13px;
  line-height: 1.6;
  overflow-wrap: anywhere;
}

html[lang="zh-CN"] .finding-panel ul,
html[lang="zh-CN"] .action-status,
html[lang="zh-CN"] #sourceMeta {
  line-height: 1.7;
}

.finding-panel li[data-kind="warning"] {
  color: #8a5b00;
}

.table-area {
  min-width: 0;
  display: flex;
  flex-direction: column;
}

.table-toolbar {
  min-height: 72px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 14px 18px;
  border-bottom: 1px solid var(--line);
  background: #ffffff;
}

.view-tabs {
  display: inline-flex;
  gap: 4px;
  padding: 4px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: #f7f9fb;
}

.view-tab {
  min-width: 78px;
  min-height: 32px;
  border: 0;
  border-radius: 6px;
  background: transparent;
  color: var(--muted);
  cursor: pointer;
  font-size: 13px;
  font-weight: 700;
  transition: background-color 140ms ease, color 140ms ease, transform 80ms ease, box-shadow 140ms ease;
}

.view-tab:hover {
  color: var(--accent);
}

.view-tab:active {
  transform: translateY(1px);
}

.view-tab.is-active {
  background: #ffffff;
  color: var(--ink);
  box-shadow: 0 1px 3px rgb(19 29 42 / 12%);
}

.table-scroll {
  flex: 1;
  overflow: auto;
  padding: 18px;
}

.timeline-view {
  flex: 1;
  min-height: 0;
  overflow: auto;
  padding: 18px;
}

.player-panel,
.timeline-panel,
.detail-panel {
  border: 1px solid var(--line);
  border-radius: 8px;
  background: #ffffff;
}

.player-panel {
  display: grid;
  gap: 12px;
  padding: 14px;
}

.lottie-stage {
  position: relative;
  display: grid;
  place-items: center;
  min-height: 280px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background:
    linear-gradient(45deg, #f5f7fa 25%, transparent 25%) 0 0 / 20px 20px,
    linear-gradient(45deg, transparent 75%, #f5f7fa 75%) 0 0 / 20px 20px,
    linear-gradient(45deg, transparent 75%, #f5f7fa 75%) 10px 10px / 20px 20px,
    linear-gradient(45deg, #f5f7fa 25%, #ffffff 25%) 10px 10px / 20px 20px;
  overflow: hidden;
}

.lottie-stage[data-bg="white"] {
  background: #ffffff;
}

.lottie-stage[data-bg="black"] {
  background: #000000;
}

.lottie-stage[data-bg="transparent"] {
  background:
    linear-gradient(45deg, #f5f7fa 25%, transparent 25%) 0 0 / 20px 20px,
    linear-gradient(45deg, transparent 75%, #f5f7fa 75%) 0 0 / 20px 20px,
    linear-gradient(45deg, transparent 75%, #f5f7fa 75%) 10px 10px / 20px 20px,
    linear-gradient(45deg, #f5f7fa 25%, #ffffff 25%) 10px 10px / 20px 20px;
}

.lottie-stage svg,
.lottie-stage canvas {
  width: 100% !important;
  height: 100% !important;
  max-height: 420px;
}

.layer-highlight {
  position: absolute;
  z-index: 4;
  border: 2px solid #ff5a3c;
  border-radius: 4px;
  box-shadow: 0 0 0 1px rgb(255 255 255 / 65%), 0 0 10px rgb(255 90 60 / 45%);
  pointer-events: none;
}

.layer-preview {
  margin: 0 0 14px;
  display: grid;
  gap: 6px;
}

.layer-preview-title {
  font-size: 12px;
  font-weight: 700;
  color: var(--muted);
}

.layer-preview-stage {
  display: grid;
  place-items: center;
  min-height: 128px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: #14161b;
  overflow: hidden;
}

.layer-preview-stage svg {
  width: 100%;
  height: 128px;
}

.layer-preview-empty {
  padding: 10px;
  color: var(--muted);
  font-size: 12px;
  text-align: center;
}

.player-empty,
.timeline-empty {
  color: var(--muted);
  font-size: 13px;
  text-align: center;
}

.player-controls {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px;
}

.player-controls button,
.select-label select {
  min-height: 34px;
  border: 1px solid var(--line-strong);
  border-radius: 8px;
  background: #ffffff;
  color: var(--ink);
  transition: background-color 140ms ease, border-color 140ms ease, box-shadow 140ms ease;
}

.player-controls button {
  min-width: 78px;
  background: var(--accent);
  border-color: #12576d;
  color: var(--accent-ink);
  cursor: pointer;
  font-weight: 700;
  transition: background-color 140ms ease, border-color 140ms ease, transform 80ms ease, box-shadow 140ms ease;
}

.player-controls button:not(:disabled):hover {
  background: #125f78;
  box-shadow: 0 2px 8px rgb(18 87 109 / 18%);
}

.player-controls button:not(:disabled):active {
  transform: translateY(1px);
  background: #0f5066;
  box-shadow: inset 0 2px 3px rgb(0 0 0 / 18%);
}

.player-controls button:disabled,
.select-label select:disabled,
.scrubber:disabled {
  opacity: 0.55;
  cursor: not-allowed;
}

.toggle-label,
.select-label {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--muted);
  font-size: 13px;
  font-weight: 650;
}

.toggle-label input {
  accent-color: var(--accent);
  cursor: pointer;
}

.toggle-label:hover,
.select-label:hover {
  color: var(--accent);
}

.select-label select:not(:disabled):hover {
  border-color: var(--accent);
  background: #f7fbfc;
}

.select-label select:focus-visible {
  outline: 2px solid #2f83a0;
  outline-offset: 2px;
}

.select-label select {
  min-width: 102px;
  padding: 0 8px;
}

.time-readout {
  margin-left: auto;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
  font-size: 13px;
}

.scrubber {
  display: none;
  width: 100%;
  accent-color: var(--accent);
}

.timeline-workspace {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(240px, 300px);
  gap: 14px;
  margin-top: 14px;
}

.timeline-panel {
  min-width: 0;
  overflow: hidden;
}

.timeline-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  padding: 14px;
  border-bottom: 1px solid var(--line);
}

.timeline-header h3,
.detail-panel h3 {
  margin: 0;
  font-size: 15px;
}

.timeline-header p {
  margin: 0;
  color: var(--muted);
  font-size: 12px;
}

.timeline-ruler {
  position: relative;
  height: 34px;
  margin-left: 190px;
  border-bottom: 1px solid var(--line);
  background: #fbfcfd;
  cursor: ew-resize;
  user-select: none;
}

.timeline-ruler span {
  position: absolute;
  top: 9px;
  transform: translateX(-50%);
  color: var(--muted);
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.timeline-ruler span::before {
  content: "";
  position: absolute;
  left: 50%;
  top: 18px;
  width: 1px;
  height: 10px;
  background: var(--line);
}

.timeline-tracks {
  position: relative;
  display: grid;
  gap: 0;
  max-height: 520px;
  overflow: auto;
}

.timeline-track-row {
  display: grid;
  grid-template-columns: 190px minmax(420px, 1fr);
  min-height: 48px;
  margin: 0;
  border-bottom: 1px solid var(--line);
}

.track-label {
  min-width: 0;
  border: 0;
  border-right: 1px solid var(--line);
  background: #ffffff;
  color: var(--ink);
  padding: 10px 12px;
  text-align: left;
  font-size: 12px;
  font-weight: 700;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  transition: background-color 140ms ease, color 140ms ease;
}

.track-label:hover {
  background: #f4f8fa;
  color: var(--accent);
}

.track-lane {
  position: relative;
  min-width: 420px;
  cursor: ew-resize;
  background:
    repeating-linear-gradient(to right, transparent 0, transparent calc(12.5% - 1px), #edf1f5 calc(12.5% - 1px), #edf1f5 12.5%),
    #fbfcfd;
}

.timeline-segment {
  position: absolute;
  top: 11px;
  height: 26px;
  min-width: 26px;
  overflow: hidden;
  border: 1px solid #13627b;
  border-radius: 6px;
  background: #dceff5;
  color: #103f4d;
  cursor: pointer;
  font-size: 11px;
  font-weight: 700;
  text-overflow: ellipsis;
  white-space: nowrap;
  transition: background-color 140ms ease, border-color 140ms ease, transform 80ms ease, box-shadow 140ms ease;
}

.timeline-segment:hover {
  background: #c9e7f0;
  box-shadow: 0 2px 8px rgb(19 98 123 / 16%);
}

.timeline-segment:active {
  transform: translateY(1px);
  box-shadow: inset 0 2px 3px rgb(0 0 0 / 12%);
}

.timeline-segment.seg-join-right {
  border-top-right-radius: 0;
  border-bottom-right-radius: 0;
  border-right: 0;
}

.timeline-segment.seg-join-left {
  border-top-left-radius: 0;
  border-bottom-left-radius: 0;
  margin-left: -1px;
}

.timeline-segment.is-live {
  background: #f5e8a9;
  border-color: #9f7a0b;
  color: #4f3b00;
}

.timeline-segment.is-selected {
  outline: 2px solid #133f8a;
  outline-offset: 1px;
}

.timeline-playhead {
  position: absolute;
  top: 0;
  bottom: 0;
  z-index: 3;
  width: 2px;
  background: #183bc7;
  pointer-events: none;
}

.timeline-playhead::before {
  content: "";
  position: absolute;
  top: 0;
  left: -6px;
  width: 14px;
  height: 14px;
  border-radius: 0 0 7px 7px;
  background: #183bc7;
  box-shadow: 0 1px 4px rgb(24 59 199 / 30%);
}

.detail-panel {
  padding: 14px;
}

.detail-panel dl {
  display: grid;
  gap: 10px;
  margin: 12px 0 0;
}

.detail-panel div {
  display: grid;
  gap: 4px;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--line);
}

.detail-panel div:last-child {
  border-bottom: 0;
}

.detail-panel dt {
  color: var(--muted);
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
}

.detail-panel dd {
  margin: 0;
  font-size: 13px;
  line-height: 1.35;
  overflow-wrap: anywhere;
}

table {
  width: 100%;
  min-width: 1040px;
  border-collapse: collapse;
  background: #ffffff;
  border: 1px solid var(--line-strong);
  /* Timing values line up vertically across rows. */
  font-variant-numeric: tabular-nums;
}

.summary-grid strong,
.hl-details dd,
.detail-panel dd {
  font-variant-numeric: tabular-nums;
}

th,
td {
  border: 1px solid var(--line-strong);
  padding: 8px 9px;
  text-align: left;
  vertical-align: middle;
  font-size: 13px;
  line-height: 1.35;
  white-space: pre-line;
}

th {
  background: #f0f3f7;
  font-weight: 720;
  text-align: center;
}

td {
  min-height: 38px;
}

.merged-cell {
  vertical-align: middle;
}

/* A keyframe transition cut by the composition's out point — kept whole but
   highlighted (usually a designer truncation to double-check). */
#motionTable tr.is-clipped td {
  background: #fff5e3;
}

.parent-cell {
  background: #f8fbfc;
}

.empty-state {
  height: 220px;
  text-align: center;
  color: var(--muted);
}

.multiline {
  min-width: 180px;
}

@media (max-width: 860px) {
  .topbar {
    align-items: flex-start;
    flex-direction: column;
    gap: 10px;
  }

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

  .control-panel {
    border-right: 0;
    border-bottom: 1px solid var(--line);
  }

  .summary-grid,
  .button-grid {
    grid-template-columns: 1fr 1fr;
  }

  .table-toolbar {
    align-items: flex-start;
    flex-direction: column;
  }

  .timeline-workspace {
    grid-template-columns: 1fr;
  }

  .timeline-ruler {
    margin-left: 140px;
  }

  .timeline-track-row {
    grid-template-columns: 140px minmax(360px, 1fr);
  }

}

.guide-shell {
  width: min(1120px, calc(100% - 48px));
  margin: 0 auto;
  padding: 26px 0 52px;
}

.guide-title {
  padding-bottom: 14px;
}

.guide-title h1 {
  margin: 0 0 8px;
  font-size: 30px;
  line-height: 1.16;
  letter-spacing: 0;
}

.guide-title p,
.guide-copy p {
  color: var(--muted);
}

.guide-title p {
  margin: 0;
  font-size: 14px;
}

.guide-section {
  display: grid;
  grid-template-columns: minmax(280px, 0.9fr) minmax(430px, 1.1fr);
  gap: 30px;
  align-items: center;
  padding: 30px 0;
  border-bottom: 1px solid var(--line);
}

.guide-section.wide {
  grid-template-columns: 1fr;
}

.guide-copy h2 {
  margin: 6px 0 10px;
  font-size: 22px;
  line-height: 1.24;
  letter-spacing: 0;
}

.guide-copy p {
  margin: 0;
  font-size: 14px;
  line-height: 1.62;
}

.eyebrow {
  color: var(--accent) !important;
  font-weight: 720;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

.formula-panel,
.timeline-card,
.mini-table-card,
.marker-panel,
.rule-strip article,
.capability-grid article,
.workflow-list,
.output-list article {
  border: 1px solid var(--line);
  background: #ffffff;
  border-radius: 8px;
}

.capability-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 12px;
}

.capability-grid article,
.output-list article {
  padding: 14px;
}

.capability-grid strong,
.output-list strong {
  display: block;
  margin-bottom: 6px;
  font-size: 14px;
}

.capability-grid p,
.output-list p {
  margin: 0;
  color: var(--muted);
  font-size: 14px;
  line-height: 1.55;
}

.workflow-list {
  margin: 0;
  padding: 8px;
  list-style: none;
}

.workflow-list li {
  display: grid;
  grid-template-columns: 32px 1fr;
  gap: 10px;
  align-items: center;
  padding: 10px;
  border-bottom: 1px solid var(--line);
}

.workflow-list li:last-child {
  border-bottom: 0;
}

.workflow-list span {
  display: grid;
  place-items: center;
  width: 28px;
  height: 28px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--soft);
  color: #214c58;
  font-size: 13px;
  font-weight: 720;
}

.workflow-list p {
  margin: 0;
  font-size: 14px;
}

.marker-panel {
  display: grid;
  gap: 10px;
  padding: 16px;
}

.marker-panel code {
  display: block;
  width: 100%;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: #f7f9fb;
  padding: 10px 12px;
  color: #123f52;
  font: 700 13px/1.35 Consolas, "SFMono-Regular", monospace;
}

.marker-panel span,
.marker-panel p {
  margin: 0;
  color: var(--muted);
  font-size: 13px;
  line-height: 1.5;
}

.output-list {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 10px;
}

.formula-panel {
  display: grid;
  grid-template-columns: 88px 1fr 88px;
  align-items: center;
  column-gap: 12px;
  min-height: 104px;
  padding: 16px;
}

.formula-main {
  border: 1px solid var(--line);
  background: #eef4f6;
  border-radius: 8px;
  padding: 14px 18px;
  text-align: center;
  font-size: 14px;
  font-weight: 700;
  color: var(--ink);
}

.formula-token {
  position: relative;
  text-align: center;
  font-weight: 700;
  font-size: 14px;
}

.formula-token.plus {
  color: var(--accent);
}

.formula-token.minus {
  color: var(--muted);
}

.formula-token.plus::after,
.formula-token.minus::before {
  content: "";
  position: absolute;
  top: 50%;
  width: 12px;
  height: 2px;
  background: currentColor;
  opacity: 0.45;
}

.formula-token.plus::after {
  right: -12px;
}

.formula-token.minus::before {
  left: -12px;
}

.timeline-card {
  padding: 22px 24px 20px;
}

/* Single shared coordinate system: every mark is positioned by time/330*100%
   via inline left/width, so the bar ends and all labels line up exactly. */
.ms-axis {
  position: relative;
  height: 70px;
  margin: 0 36px;
}

.ms-line {
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  height: 2px;
  transform: translateY(-50%);
  background: var(--line);
  border-radius: 2px;
}

.ms-bar {
  position: absolute;
  top: 50%;
  height: 12px;
  transform: translateY(-50%);
  background: var(--accent);
  border-radius: 6px;
}

.ms-tick {
  position: absolute;
  top: 50%;
  width: 2px;
  height: 14px;
  transform: translate(-50%, -50%);
  background: var(--line-strong);
  border-radius: 1px;
}

.ms-top,
.ms-bottom {
  position: absolute;
  transform: translateX(-50%);
  font-size: 14px;
  font-weight: 700;
  white-space: nowrap;
}

.ms-bottom {
  bottom: 0;
  color: var(--muted);
}

/* Top anchors label the gaps: +Xms over the lead-in gap (before the bar),
   -Yms over the tail gap (after the bar), each centered on its idle region. */
.ms-top {
  top: 0;
  color: var(--accent);
}

.ms-top.is-minus {
  color: var(--muted);
}

.mini-table-card {
  overflow: auto;
  padding: 12px;
}

.guide-table {
  min-width: 900px;
}

.guide-table th,
.guide-table td {
  font-size: 13px;
}

.guide-table td span {
  color: var(--muted);
  font-size: 12px;
}

.rule-strip {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 14px;
  padding-top: 24px;
}

.rule-strip article {
  padding: 14px;
}

.rule-strip strong {
  display: block;
  margin-bottom: 8px;
  font-size: 14px;
}

.rule-strip p {
  margin: 0;
  color: var(--muted);
  font-size: 13px;
  line-height: 1.5;
}

@media (max-width: 860px) {
  .top-actions {
    align-items: flex-start;
  }

  .lang-toggle {
    min-width: auto;
  }

  .guide-section,
  .rule-strip,
  .capability-grid,
  .output-list {
    grid-template-columns: 1fr;
  }

  .guide-title h1 {
    font-size: 26px;
  }

  .formula-panel {
    grid-template-columns: 1fr;
    gap: 10px;
  }
}

/* Guide: interactive layer-highlight demo */
.hl-demo {
  margin-top: 18px;
  display: grid;
  grid-template-columns: 1.5fr 1fr;
  grid-template-areas:
    "stage side"
    "timeline timeline"
    "hint hint";
  gap: 14px;
}

.hl-stage {
  grid-area: stage;
  position: relative;
  min-height: 210px;
  border: 1px solid var(--line);
  border-radius: 10px;
  /* Match the real app playback canvas (light transparency checkerboard). */
  background:
    linear-gradient(45deg, #f5f7fa 25%, transparent 25%) 0 0 / 20px 20px,
    linear-gradient(45deg, transparent 75%, #f5f7fa 75%) 0 0 / 20px 20px,
    linear-gradient(45deg, transparent 75%, #f5f7fa 75%) 10px 10px / 20px 20px,
    linear-gradient(45deg, #f5f7fa 25%, #ffffff 25%) 10px 10px / 20px 20px;
  overflow: hidden;
}

.hl-shape {
  position: absolute;
  border-radius: 6px;
  cursor: pointer;
  transition: opacity 200ms ease;
}

.hl-shape.is-circle {
  border-radius: 50%;
}

.hl-shape.is-dim {
  opacity: 0.32;
}

.hl-box {
  position: absolute;
  z-index: 3;
  border: 2px solid #ff5a3c;
  border-radius: 5px;
  box-shadow: 0 0 0 3px rgb(255 90 60 / 18%), 0 2px 10px rgb(255 90 60 / 25%);
  pointer-events: none;
  transition: left 280ms ease, top 280ms ease, width 280ms ease, height 280ms ease;
}

.hl-side {
  grid-area: side;
  display: grid;
  gap: 8px;
  align-content: start;
  padding: 12px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: #ffffff;
}

.hl-side-title {
  margin: 0;
  font-size: 12px;
  font-weight: 700;
  color: var(--muted) !important;
}

.hl-thumb {
  display: grid;
  place-items: center;
  min-height: 96px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background:
    linear-gradient(45deg, #f5f7fa 25%, transparent 25%) 0 0 / 20px 20px,
    linear-gradient(45deg, transparent 75%, #f5f7fa 75%) 0 0 / 20px 20px,
    linear-gradient(45deg, transparent 75%, #f5f7fa 75%) 10px 10px / 20px 20px,
    linear-gradient(45deg, #f5f7fa 25%, #ffffff 25%) 10px 10px / 20px 20px;
  overflow: hidden;
}

.hl-thumb .hl-shape {
  position: static;
  cursor: default;
  transition: none;
}

.hl-details {
  margin: 0;
  display: grid;
  gap: 5px;
}

.hl-details div {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  font-size: 12px;
}

.hl-details dt {
  margin: 0;
  color: var(--muted);
}

.hl-details dd {
  margin: 0;
  font-weight: 600;
  color: var(--ink);
}

.hl-timeline {
  grid-area: timeline;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 8px;
}

.hl-seg {
  padding: 8px 10px;
  border: 1px solid #13627b;
  border-radius: 6px;
  background: #dceff5;
  color: #103f4d;
  font-size: 12px;
  font-weight: 700;
  cursor: pointer;
  transition: background-color 140ms ease, box-shadow 140ms ease;
}

.hl-seg:hover {
  background: #c9e7f0;
}

.hl-seg.is-active {
  background: #f5e8a9;
  border-color: #9f7a0b;
  color: #4f3b00;
  box-shadow: 0 2px 8px rgb(159 122 11 / 22%);
}

.hl-hint {
  grid-area: hint;
  margin: 0;
  font-size: 12px;
  color: var(--muted) !important;
}

@media (max-width: 860px) {
  .hl-demo {
    grid-template-columns: 1fr;
    grid-template-areas:
      "stage"
      "side"
      "timeline"
      "hint";
  }
}

/* ---------------------------------------------------------------------------
   Motion Tokens editor page
--------------------------------------------------------------------------- */
.tokens-shell {
  width: min(1120px, 100%);
  margin: 0 auto;
  padding: 28px 24px 56px;
  flex: 1;
}

.tokens-head {
  display: flex;
  flex-wrap: wrap;
  gap: 24px;
  justify-content: space-between;
  align-items: flex-start;
  margin-bottom: 22px;
}

.tokens-head h1 {
  margin: 4px 0 8px;
  font-size: 26px;
  font-weight: 720;
}

.tokens-sub {
  margin: 0;
  max-width: 560px;
  color: var(--muted);
  font-size: 14px;
  line-height: 1.5;
}

.tokens-sub code {
  background: var(--soft);
  padding: 1px 5px;
  border-radius: 4px;
  font-size: 12.5px;
}

.tokens-meta {
  display: grid;
  gap: 10px;
  min-width: 260px;
}

.meta-field {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 12px;
  color: var(--muted);
}

.meta-field input {
  padding: 7px 10px;
  border: 1px solid var(--line);
  border-radius: 8px;
  color: var(--ink);
  background: var(--panel);
}

.meta-field input:focus-visible,
.scale-row input:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}

.tokens-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.1fr) minmax(0, 0.9fr);
  gap: 18px;
  align-items: stretch;
}

.tokens-main {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.tokens-main .tokens-actions {
  margin-top: 2px;
}

.card {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 16px;
}

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

.card-head h2 {
  margin: 0;
  font-size: 15px;
  font-weight: 660;
}

.curve-name-tag {
  font-size: 12px;
  font-weight: 600;
  color: var(--accent);
  background: var(--soft);
  padding: 3px 9px;
  border-radius: 999px;
}

.mini-btn {
  border: 1px solid var(--line);
  background: var(--panel);
  color: var(--ink);
  border-radius: 8px;
  padding: 4px 10px;
  font-size: 12px;
  cursor: pointer;
}

.mini-btn:hover {
  border-color: var(--line-strong);
  background: var(--soft);
}

.bezier-wrap {
  display: grid;
  grid-template-columns: 320px minmax(0, 1fr);
  gap: 14px;
  align-items: center;
}

.bezier-svg {
  width: 100%;
  max-width: 320px;
  height: auto;
  touch-action: none;
  user-select: none;
}

.bezier-unit {
  fill: var(--soft);
  stroke: var(--line-strong);
  stroke-width: 1;
  opacity: 0.5;
}

.grid-line {
  stroke: var(--line);
  stroke-width: 0.6;
}

.ctrl-line {
  stroke: var(--line-strong);
  stroke-width: 1.4;
  stroke-dasharray: 4 3;
}

.bezier-curve {
  stroke: var(--accent);
  stroke-width: 3;
}

.bezier-handle {
  fill: var(--accent);
  stroke: #fff;
  stroke-width: 2.5;
  cursor: grab;
}

.bezier-handle:active {
  cursor: grabbing;
}

.bezier-handle:focus-visible {
  outline: 2px solid var(--ink);
  outline-offset: 2px;
}

.bezier-side {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.preview-pad {
  position: relative;
  height: 44px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--soft);
  overflow: hidden;
}

.preview-track {
  position: absolute;
  left: 16px;
  right: 16px;
  top: 50%;
  height: 2px;
  background: var(--line-strong);
  transform: translateY(-50%);
}

.preview-dot {
  position: absolute;
  top: 50%;
  left: 16px;
  width: 16px;
  height: 16px;
  margin-top: -8px;
  border-radius: 50%;
  background: var(--accent);
  animation: tokenSlide 1.6s infinite;
  animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
}

@keyframes tokenPreview {
  from { left: 16px; }
  to { left: calc(100% - 32px); }
}

/* Main preview: ease forward with the curve, hold, then fade out, reset while
   invisible, and fade back in — so the loop never shows a reversed curve or a
   hard snap (the two things that read as a stutter). */
@keyframes tokenSlide {
  0% { left: 16px; opacity: 1; }
  55% { left: calc(100% - 32px); opacity: 1; }
  72% { left: calc(100% - 32px); opacity: 1; }
  82% { left: calc(100% - 32px); opacity: 0; }
  83% { left: 16px; opacity: 0; }
  93% { left: 16px; opacity: 1; }
  100% { left: 16px; opacity: 1; }
}

.preview-hint,
.overshoot-note {
  margin: 0;
  font-size: 11.5px;
  color: var(--muted);
  line-height: 1.4;
}

.bezier-readout {
  display: flex;
  align-items: center;
  gap: 8px;
}

.bezier-input {
  flex: 1;
  min-width: 0;
  font-family: "SFMono-Regular", Consolas, "Liberation Mono", monospace;
  font-size: 12px;
  color: var(--ink);
  background: var(--soft);
  padding: 7px 9px;
  border: 1px solid transparent;
  border-radius: 8px;
}

.bezier-input:hover {
  border-color: var(--line);
}

.bezier-input:focus-visible {
  outline: none;
  border-color: var(--accent);
  background: var(--panel);
}

.curve-fields {
  display: grid;
  grid-template-columns: 1fr 1.4fr;
  gap: 12px;
  margin-top: 14px;
}

.tokens-side {
  display: flex;
  flex-direction: column;
  gap: 14px;
}

/* The Curves palette takes the slack so the right column's bottom (Durations)
   lines up with the left column's bottom (Advanced). The extra height is empty
   space at the bottom of the card (room to add more curves) — the list stays at
   its natural height at the top so items never overflow. */
.tokens-side > .card:first-child {
  flex: 1;
  min-height: 0;
}

.curve-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: 6px;
}

.curve-item {
  display: flex;
  align-items: stretch;
  gap: 6px;
  border: 1px solid var(--line);
  border-radius: 10px;
  overflow: hidden;
}

.curve-item.is-active {
  border-color: var(--accent);
  box-shadow: 0 0 0 1px var(--accent);
}

.curve-item-main {
  flex: 1;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  background: var(--panel);
  border: none;
  cursor: pointer;
  text-align: left;
  color: var(--ink);
}

.curve-item-main:hover {
  background: var(--soft);
}

.curve-swatch {
  width: 30px;
  height: 30px;
  border-radius: 7px;
  background: var(--soft);
  border: 1px solid var(--line);
  position: relative;
  overflow: hidden;
  flex-shrink: 0;
}

.curve-swatch::after {
  content: "";
  position: absolute;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--accent);
  left: 3px;
  top: 50%;
  margin-top: -4.5px;
  animation: tokenPreview 1.4s infinite alternate;
  animation-timing-function: var(--bz, cubic-bezier(0.4, 0, 0.2, 1));
}

.curve-item-text {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.curve-item-text strong {
  font-size: 13px;
  font-weight: 640;
}

.curve-item-text em {
  font-size: 11.5px;
  color: var(--muted);
  font-style: normal;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.curve-del {
  border: none;
  background: transparent;
  color: var(--muted);
  cursor: pointer;
  padding: 0 12px;
  font-size: 13px;
}

.curve-del:hover:not(:disabled) {
  background: #fbe9e9;
  color: #b3261e;
}

.curve-del:disabled {
  opacity: 0.3;
  cursor: not-allowed;
}

.scale-grid {
  display: grid;
  gap: 6px;
}

.scale-row {
  display: grid;
  grid-template-columns: 1fr 90px auto;
  gap: 6px;
  align-items: center;
}

.scale-row input {
  padding: 6px 9px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--panel);
  color: var(--ink);
}

.card-hint {
  margin: -6px 0 12px;
  font-size: 12px;
  color: var(--muted);
  line-height: 1.45;
}

.prop-grid {
  display: grid;
  gap: 6px;
}

.prop-row {
  display: grid;
  grid-template-columns: 1.3fr 1fr auto 1fr auto auto;
  gap: 6px;
  align-items: center;
}

.prop-row select,
.prop-row .prop-num {
  padding: 6px 8px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--panel);
  color: var(--ink);
  font-size: 12.5px;
  min-width: 0;
  width: 100%;
}

.prop-row select:focus-visible,
.prop-row .prop-num:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}

.prop-sep {
  color: var(--muted);
  text-align: center;
}

.prop-unit {
  font-size: 12px;
  color: var(--muted);
  min-width: 18px;
}

/* Named presets — full-width card spanning both grid columns */
.presets-card {
  grid-column: 1 / -1;
}

.preset-grid {
  display: grid;
  gap: 8px;
}

.preset-cols {
  grid-template-columns: 1.4fr 1fr 0.7fr 14px 0.7fr 22px 1.3fr 1fr 26px;
}

.preset-head,
.preset-row {
  display: grid;
  grid-template-columns: 1.4fr 1fr 0.7fr 14px 0.7fr 22px 1.3fr 1fr 26px;
  gap: 6px;
  align-items: center;
}

.preset-head {
  margin: 6px 0 2px;
  font-size: 11px;
  font-weight: 640;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted);
}

.preset-head span:nth-child(3) {
  grid-column: 3 / 7; /* "Range" label spans from / → / to / unit */
}

.preset-row input,
.preset-row select {
  width: 100%;
  min-width: 0;
  padding: 7px 8px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--panel);
  color: var(--ink);
  font-size: 12.5px;
}

.preset-row .preset-name {
  font-weight: 600;
}

.preset-row input:focus-visible,
.preset-row select:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}

@media (max-width: 760px) {
  .preset-head {
    display: none;
  }
  .preset-row {
    grid-template-columns: 1fr 1fr;
    padding: 10px;
    border: 1px solid var(--line);
    border-radius: 10px;
  }
  .preset-row .prop-sep,
  .preset-row .prop-unit {
    display: none;
  }
}

.advanced-card {
  padding: 0;
}

.advanced-card summary {
  padding: 14px 16px;
  cursor: pointer;
  font-size: 14px;
  font-weight: 600;
}

.audit-grid {
  display: grid;
  gap: 12px;
  padding: 0 16px 16px;
}

.tokens-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 22px;
}

.tokens-actions button {
  border: 1px solid var(--accent);
  background: var(--accent);
  color: var(--accent-ink);
  border-radius: 9px;
  padding: 9px 16px;
  font-size: 13px;
  font-weight: 580;
  cursor: pointer;
}

.tokens-actions button:hover {
  filter: brightness(1.08);
}

.tokens-actions .ghost-btn {
  background: var(--panel);
  color: var(--ink);
  border-color: var(--line);
}

.tokens-actions .ghost-btn:hover {
  background: var(--soft);
  filter: none;
}

.tokens-shell .action-status {
  margin: 12px 0 0;
  font-size: 13px;
  color: var(--muted);
}

.tokens-shell .action-status[data-kind="success"] {
  color: #1a7a44;
}

.tokens-shell .action-status[data-kind="error"] {
  color: #b3261e;
}

@media (max-width: 920px) {
  .tokens-grid {
    grid-template-columns: 1fr;
  }
  .bezier-wrap {
    grid-template-columns: 1fr;
  }
  .bezier-svg {
    margin: 0 auto;
  }
}

/* ---------------------------------------------------------------------------
   Hub landing page
--------------------------------------------------------------------------- */
.hub-shell {
  width: min(1040px, 100%);
  margin: 0 auto;
  padding: 52px 24px 72px;
  flex: 1;
}

.hub-hero {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
  gap: 34px;
  align-items: center;
  margin-bottom: 30px;
}

.hub-hero-copy {
  max-width: 620px;
}

.hub-hero-visual {
  margin: 0;
  border: 1px solid var(--line);
  border-radius: 14px;
  overflow: hidden;
  background: #ffffff;
  box-shadow: 0 14px 34px rgb(22 24 29 / 9%);
}

.hub-hero-visual img {
  display: block;
  width: 100%;
  height: auto;
}

@media (max-width: 940px) {
  .hub-hero {
    grid-template-columns: 1fr;
    gap: 22px;
  }
}

.hub-hero h1 {
  margin: 10px 0 16px;
  font-size: 34px;
  line-height: 1.2;
  font-weight: 740;
  letter-spacing: -0.01em;
}

.hub-lead {
  margin: 0;
  font-size: 15px;
  line-height: 1.65;
  color: var(--muted);
}

.hub-lead code {
  background: var(--soft);
  padding: 1px 6px;
  border-radius: 5px;
  font-size: 13px;
  color: var(--ink);
}

/* Hero call-to-action buttons */
.hero-cta-row {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: 22px;
}

.btn-primary,
.btn-ghost {
  display: inline-flex;
  align-items: center;
  height: 42px;
  padding: 0 22px;
  border-radius: 10px;
  font-size: 14px;
  font-weight: 640;
  text-decoration: none;
  border: 1px solid transparent;
  transition: filter 0.15s, background 0.15s, border-color 0.15s, transform 0.1s;
}

.btn-primary {
  background: var(--accent);
  color: var(--accent-ink);
}

.btn-primary:hover {
  filter: brightness(1.08);
  transform: translateY(-1px);
}

.btn-ghost {
  background: var(--panel);
  color: var(--ink);
  border-color: var(--line);
}

.btn-ghost:hover {
  background: var(--soft);
  border-color: var(--line-strong);
}

/* Process line — a single minimal row, not a boxed diagram */
.flow {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 12px;
  margin: 40px 0 48px;
  padding: 14px 18px;
  border-radius: 12px;
  background: var(--soft);
  font-size: 13.5px;
}

/* One-shot entrance for the pipeline: each step settles in sequence — a small
   nod to the fact that this is a motion-tools site. Guarded for reduced motion. */
@keyframes flow-step-in {
  from {
    opacity: 0;
    transform: translateY(6px);
  }

  to {
    opacity: 1;
    transform: none;
  }
}

.flow > * {
  animation: flow-step-in 420ms cubic-bezier(0.4, 0, 0.2, 1) backwards;
}

.flow > :nth-child(1) { animation-delay: 80ms; }
.flow > :nth-child(2) { animation-delay: 180ms; }
.flow > :nth-child(3) { animation-delay: 280ms; }
.flow > :nth-child(4) { animation-delay: 380ms; }
.flow > :nth-child(5) { animation-delay: 480ms; }
.flow > :nth-child(6) { animation-delay: 580ms; }
.flow > :nth-child(7) { animation-delay: 680ms; }

@media (prefers-reduced-motion: reduce) {
  .flow > * {
    animation: none;
  }

  .hub-card,
  .hub-card:hover {
    transform: none;
    transition: none;
  }
}

.flow-step {
  color: var(--muted);
}

.flow-step b {
  color: var(--ink);
  font-weight: 660;
}

.flow-step i {
  font-style: normal;
  color: var(--muted);
}

.flow-mid code {
  font-family: "SFMono-Regular", Consolas, monospace;
  font-size: 12.5px;
  color: var(--accent);
  background: var(--panel);
  padding: 2px 7px;
  border-radius: 6px;
}

.flow-arrow {
  color: var(--line-strong);
  font-weight: 700;
}

.hub-section-title {
  margin: 0 0 16px;
  font-size: 13px;
  font-weight: 680;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--muted);
}

.hub-cards {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 16px;
}

.hub-card {
  display: flex;
  flex-direction: column;
  gap: 7px;
  padding: 22px;
  border: 1px solid var(--line);
  border-radius: 16px;
  background: var(--panel);
  text-decoration: none;
  color: inherit;
  transition: transform 160ms ease, box-shadow 160ms ease, border-color 160ms ease;
}

.hub-card:hover {
  transform: translateY(-2px);
  border-color: var(--accent);
  box-shadow: 0 10px 24px rgb(23 107 135 / 12%);
}

.hub-card h3 {
  margin: 6px 0 0;
  font-size: 21px;
  font-weight: 720;
}

.hub-card-role {
  margin: 0;
  font-size: 13px;
  font-weight: 600;
  color: var(--accent);
}

.hub-card p {
  margin: 0;
  font-size: 13.5px;
  line-height: 1.5;
  color: var(--muted);
  flex: 1;
}

.hub-card-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.hub-card-tag {
  font-size: 11px;
  font-weight: 660;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted);
}

/* Clickable cards: button affordance so they obviously invite a click */
.hub-card-link {
  cursor: pointer;
  transition: border-color 0.15s, box-shadow 0.15s, transform 0.15s;
}

.hub-card-link:hover {
  border-color: var(--accent);
  box-shadow: 0 10px 28px rgb(23 107 135 / 14%);
  transform: translateY(-3px);
}

.hub-card-arrow {
  width: 30px;
  height: 30px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: var(--soft);
  color: var(--accent);
  font-weight: 700;
  transition: background 0.15s, transform 0.15s;
}

.hub-card-link:hover .hub-card-arrow {
  background: var(--accent);
  color: var(--accent-ink);
  transform: translateX(2px);
}

.hub-card-go {
  margin-top: 6px;
  font-size: 13.5px;
  font-weight: 680;
  color: var(--accent);
}

.hub-card-down {
  background: var(--bg);
  border-style: dashed;
  cursor: default;
}

.hub-card-note {
  margin-top: 6px;
  font-size: 12px;
  color: var(--muted);
  font-style: italic;
}

@media (max-width: 680px) {
  .flow {
    flex-direction: column;
    align-items: flex-start;
    gap: 6px;
  }
  .flow-arrow {
    transform: rotate(90deg);
  }
}

/* Guide: tabbed — show one tool's guide at a time */
.guide-tabs {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin: 4px 0 6px;
  border-bottom: 1px solid var(--line);
  padding-bottom: 14px;
}

.guide-tab {
  padding: 8px 18px;
  border: 1px solid var(--line);
  border-radius: 999px;
  font-size: 14px;
  font-weight: 620;
  color: var(--muted);
  background: var(--panel);
  cursor: pointer;
}

.guide-tab:hover {
  border-color: var(--line-strong);
  color: var(--ink);
}

.guide-tab.is-active {
  border-color: var(--accent);
  background: var(--accent);
  color: var(--accent-ink);
}

.guide-panel-sub {
  margin: 18px 0 0;
  font-size: 14px;
  color: var(--muted);
}

/* ---------------------------------------------------------------------------
   MotionPilot subpage
--------------------------------------------------------------------------- */
.pilot-shell {
  width: min(900px, 100%);
  margin: 0 auto;
  padding: 52px 24px 72px;
  flex: 1;
}

.pilot-hero {
  max-width: 680px;
  margin-bottom: 32px;
}

.pilot-hero h1 {
  margin: 8px 0 14px;
  font-size: 36px;
  font-weight: 740;
  letter-spacing: -0.01em;
}

.pilot-lead {
  margin: 0;
  font-size: 15px;
  line-height: 1.65;
  color: var(--muted);
}

.pilot-note {
  margin: 14px 0 0;
  font-size: 12px;
  color: var(--muted);
  font-style: italic;
}

.pilot-demo-frame {
  display: block;
  margin: 0 0 40px;
  border: 1px solid var(--line);
  border-radius: 14px;
  overflow: hidden;
  background: #07090e;
  box-shadow: 0 18px 44px rgb(23 46 67 / 14%);
}

.pilot-demo-media {
  aspect-ratio: 16 / 9;
  overflow: hidden;
  background: #07090e;
}

.pilot-demo-media img,
.pilot-demo-media video {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.pilot-demo-frame figcaption {
  padding: 14px 18px 16px;
  border-top: 1px solid var(--line);
  background: var(--panel);
  color: var(--muted);
  font-size: 13px;
  line-height: 1.55;
}

.pilot-points {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 16px;
  margin-bottom: 40px;
}

.pilot-points article {
  padding: 18px;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: var(--panel);
}

.pilot-points strong {
  display: block;
  margin-bottom: 6px;
  font-size: 15px;
  font-weight: 680;
}

.pilot-points p {
  margin: 0;
  font-size: 13px;
  line-height: 1.5;
  color: var(--muted);
}

.pilot-install {
  border-top: 1px solid var(--line);
  padding-top: 28px;
}

.pilot-install h2 {
  margin: 0 0 12px;
  font-size: 17px;
  font-weight: 700;
}

.pilot-install ol {
  margin: 0;
  padding-left: 20px;
  color: var(--muted);
  font-size: 14px;
  line-height: 1.7;
}

/* ---------------------------------------------------------------------------
   QA spec-audit view (in the main app)
--------------------------------------------------------------------------- */
.qa-view {
  padding: 18px;
}

.qa-toolbar {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-bottom: 14px;
}

.qa-token-source {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
}

/* One consistent secondary-button look for every control in the QA toolbar
   (upload label, refresh, use-local, edit-spec link) — they used to be 4
   different styles, including a native unstyled button. */
.qa-token-source > .qa-upload,
.qa-token-source > button,
.qa-token-source > a {
  display: inline-flex;
  align-items: center;
  height: 36px;
  padding: 0 14px;
  border: 1px solid var(--line);
  border-radius: 9px;
  background: var(--panel);
  color: var(--ink);
  font-size: 13px;
  font-weight: 560;
  cursor: pointer;
  text-decoration: none;
  transition: border-color 140ms ease, background-color 140ms ease, color 140ms ease;
}

.qa-token-source > .qa-upload:hover,
.qa-token-source > button:hover,
.qa-token-source > a:hover {
  border-color: var(--accent);
  background: var(--soft);
  color: var(--accent);
}

.qa-upload {
  position: relative;
  overflow: hidden;
}

.qa-upload input {
  position: absolute;
  inset: 0;
  opacity: 0;
  cursor: pointer;
}

.qa-token-note {
  margin: 0;
  font-size: 13px;
  color: var(--muted);
}

.qa-token-note[data-kind="success"] {
  color: #1a7a44;
}

.qa-token-note[data-kind="error"] {
  color: #b3261e;
}

.qa-summary {
  display: flex;
  align-items: center;
  gap: 22px;
  padding: 14px 18px;
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--panel);
  margin-bottom: 14px;
}

.qa-score {
  display: flex;
  flex-direction: column;
  line-height: 1.1;
}

.qa-score strong {
  font-size: 28px;
  font-weight: 720;
}

.qa-score strong[data-kind="good"] { color: #1a7a44; }
.qa-score strong[data-kind="warn"] { color: #9f7a0b; }
.qa-score strong[data-kind="bad"] { color: #b3261e; }

.qa-score span {
  font-size: 12px;
  color: var(--muted);
}

.qa-counts {
  display: flex;
  gap: 18px;
  font-size: 13px;
  color: var(--muted);
}

.qa-counts b {
  color: var(--ink);
  font-size: 16px;
}

.qa-summary #exportViolations {
  margin-left: auto;
  border: 1px solid var(--accent);
  background: var(--accent);
  color: var(--accent-ink);
  border-radius: 9px;
  padding: 8px 14px;
  font-size: 13px;
  cursor: pointer;
}

.qa-summary #exportViolations:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

.qa-table-scroll {
  overflow-x: auto;
}

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

.qa-table th,
.qa-table td {
  text-align: left;
  padding: 8px 10px;
  border-bottom: 1px solid var(--line);
  vertical-align: top;
}

.qa-table thead th {
  font-weight: 620;
  color: var(--muted);
  border-bottom: 1px solid var(--line-strong);
}

.qa-row-fail {
  background: #fdf2f2;
}

.qa-mono {
  font-family: "SFMono-Regular", Consolas, "Liberation Mono", monospace;
  font-size: 12px;
  white-space: nowrap;
}

.qa-tag {
  display: inline-block;
  padding: 2px 8px;
  border-radius: 999px;
  font-size: 11.5px;
  font-weight: 560;
}

.qa-tag.qa-ok {
  background: #e3f4ea;
  color: #1a7a44;
}

.qa-tag.qa-bad {
  background: #fbe4e4;
  color: #b3261e;
}

.qa-skip {
  color: var(--muted);
}

.qa-prop-change {
  color: var(--muted);
  font-size: 11px;
  margin-top: 1px;
}

.qa-prop-change + .qa-tag,
.qa-verdict .qa-tag {
  margin-top: 3px;
}

.qa-empty {
  margin: 8px 0 0;
  font-size: 13px;
  color: var(--muted);
}

/* ---------------------------------------------------------------------------
   Motion Spec viewer (spec.html) — read-only, teaching-first.
   --------------------------------------------------------------------------- */
.spec-shell {
  flex: 1;
  width: min(1100px, 100%);
  margin: 0 auto;
  padding: 28px 24px 56px;
}

.spec-head {
  max-width: 760px;
}

.spec-head h1 {
  margin: 6px 0 10px;
  font-size: 30px;
  line-height: 1.2;
  font-weight: 740;
}

.spec-lead {
  margin: 0;
  font-size: 15px;
  line-height: 1.6;
  color: var(--muted);
}

.spec-official {
  margin: 14px 0 0;
  padding: 10px 14px;
  border: 1px solid #e3d6a8;
  background: #fdf8e8;
  border-radius: 10px;
  font-size: 13px;
  line-height: 1.5;
  color: #6d5500;
}

.spec-tabs {
  display: flex;
  gap: 8px;
  margin: 24px 0 6px;
  flex-wrap: wrap;
}

.spec-tab {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 16px;
  border: 1px solid var(--line);
  border-radius: 999px;
  background: #fff;
  color: var(--ink);
  font-size: 14px;
  font-weight: 640;
  cursor: pointer;
  transition: background 140ms ease, border-color 140ms ease, color 140ms ease;
}

.spec-tab:hover {
  border-color: var(--line-strong);
}

.spec-tab.is-active {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--accent-ink);
}

.spec-tab-default {
  font-size: 11px;
  font-weight: 600;
  opacity: 0.7;
}

.spec-target-note {
  margin: 0 0 8px;
  font-size: 13px;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}

.spec-block {
  margin-top: 34px;
}

.spec-block h2 {
  margin: 0 0 6px;
  font-size: 20px;
  font-weight: 720;
}

.spec-block-note {
  margin: 0 0 16px;
  max-width: 760px;
  font-size: 14px;
  line-height: 1.6;
  color: var(--muted);
}

/* Curve cards */
.curve-cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
  gap: 12px;
}

/* One hero per card: the curve. Head stacks (name over numbers) so long
   beziers never wrap awkwardly; the eased dot is a slim track below the graph,
   clearly secondary to the curve rather than a competing box. */
.curve-card {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: #fff;
  padding: 16px 16px 18px;
  transition: border-color 160ms ease, box-shadow 160ms ease;
}

.curve-card:hover {
  border-color: #c3d3da;
  box-shadow: 0 6px 18px rgb(23 107 135 / 8%);
}

.curve-card-head {
  margin-bottom: 12px;
}

.curve-card-head strong {
  display: block;
  font-size: 15px;
  letter-spacing: -0.01em;
}

.curve-card-head code {
  display: block;
  margin-top: 2px;
  font-size: 11px;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
}

.curve-graph {
  width: 104px;
  height: 104px;
  align-self: center;
  display: block;
  border-radius: 10px;
  background: #fafcfd;
}

.curve-grid {
  stroke: #eaeff3;
  stroke-width: 1;
}

.curve-axis {
  stroke: #d7dee5;
  stroke-width: 1;
}

.curve-area {
  fill: rgb(23 107 135 / 8%);
  stroke: none;
}

.curve-line {
  fill: none;
  stroke: var(--accent);
  stroke-width: 2.5;
  stroke-linecap: round;
  stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
}

/* Slim eased track: the dot's speed IS the curve. Secondary to the graph.
   One-way only — the forward run shows the easing; a return trip would just
   replay the curve reversed, which is meaningless. The dot fades out at the
   end and fades back in at the start so the reset isn't a visible jump. */
.curve-track {
  position: relative;
  height: 16px;
  margin-top: 14px;
  border-radius: 999px;
  background: var(--soft);
}

.curve-dot {
  position: absolute;
  top: 50%;
  left: 4px;
  width: 12px;
  height: 12px;
  margin-top: -6px;
  border-radius: 50%;
  background: var(--accent);
  /* 一轮 2600ms:走 600ms(带该曲线)→ 终点停 1500ms → 淡出 300ms →
     隐身时瞬回起点 → 淡入 200ms → 再走。
     **曲线只作用在"走"那一段**,写在 @keyframes 里面(var(--curve));
     写在元素上的 animation-timing-function 会作用于**每一段**,回程和停顿
     也跟着走曲线 —— 那正是"到终点直接弹回来、回来的曲线不对"的原因。 */
  animation: spec-run 2600ms linear infinite, spec-fade 2600ms linear infinite;
}

.curve-use {
  margin: 14px 0 0;
  font-size: 13px;
  line-height: 1.55;
  color: var(--muted);
}

@keyframes spec-run {
  0%     { left: 4px; animation-timing-function: var(--curve, ease); }
  23.08% { left: calc(100% - 16px); animation-timing-function: linear; }  /* 600ms 走完 */
  88.46% { left: calc(100% - 16px); }                                     /* 停 1500ms + 淡出 300ms */
  88.47% { left: 4px; }                                                   /* 隐身时瞬回起点 */
  100%   { left: 4px; }
}

@keyframes spec-fade {
  0%     { opacity: 1; }        /* 起点已可见,直接开走 */
  76.92% { opacity: 1; }        /* 走 600 + 停 1500 = 2100ms */
  88.46% { opacity: 0; }        /* 淡出 300ms */
  92.30% { opacity: 0; }        /* 隐身 100ms,期间瞬回起点 */
  100%   { opacity: 1; }        /* 在起点淡入 200ms */
}

/* Durations */
.dur-list {
  display: grid;
  gap: 8px;
  max-width: 640px;
}

.dur-row {
  display: grid;
  grid-template-columns: 92px 1fr 62px;
  align-items: center;
  gap: 12px;
}

.dur-name {
  font-size: 14px;
  font-weight: 640;
}

.dur-bar-wrap {
  height: 12px;
  border-radius: 6px;
  background: var(--soft);
  overflow: hidden;
}

.dur-bar {
  display: block;
  height: 100%;
  border-radius: 6px;
  background: var(--accent);
}

.dur-ms {
  font-size: 13px;
  color: var(--muted);
  text-align: right;
  font-variant-numeric: tabular-nums;
}

/* Presets */
.preset-table-wrap {
  overflow-x: auto;
}

.preset-table {
  width: 100%;
  min-width: 560px;
  border-collapse: collapse;
  background: #fff;
  border: 1px solid var(--line-strong);
  font-variant-numeric: tabular-nums;
}

.preset-table th,
.preset-table td {
  border: 1px solid var(--line);
  padding: 9px 11px;
  text-align: left;
  font-size: 13px;
}

.preset-table th {
  background: #f0f3f7;
  font-weight: 700;
}

.preset-ms {
  color: var(--muted);
}

/* Why two platforms */
.why-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
  margin-bottom: 12px;
}

.why-grid > div {
  border: 1px solid var(--line);
  border-radius: 12px;
  background: #fff;
  padding: 16px;
}

.why-grid h3 {
  margin: 0 0 6px;
  font-size: 15px;
}

.why-grid p {
  margin: 0;
  font-size: 13.5px;
  line-height: 1.55;
  color: var(--muted);
}

/* How it lands in AE */
.apply-demo {
  display: block;
  max-width: 560px;
  margin: 4px auto 0;
  border: 1px solid var(--line);
  border-radius: 12px;
  overflow: hidden;
  background: #fff;
  text-decoration: none;
  transition: border-color .15s ease, box-shadow .15s ease;
}

.apply-demo:hover {
  border-color: var(--accent);
  box-shadow: 0 6px 20px rgba(0, 0, 0, .08);
}

.apply-demo img {
  display: block;
  width: 100%;
  height: auto;
}

.apply-cta {
  display: block;
  padding: 10px 14px;
  font-size: 13.5px;
  font-weight: 700;
  color: var(--accent);
  border-top: 1px solid var(--line);
}

/* Endpoints */
.endpoint-list {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 8px;
}

.endpoint-list li {
  display: flex;
  align-items: center;
  gap: 10px;
  flex-wrap: wrap;
}

.endpoint-tag {
  min-width: 62px;
  padding: 3px 8px;
  border-radius: 6px;
  background: var(--soft);
  color: var(--accent);
  font-size: 12px;
  font-weight: 700;
}

.endpoint-list code {
  font-size: 12px;
  word-break: break-all;
}

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

@media (prefers-reduced-motion: reduce) {
  .curve-dot { animation: none; left: calc(50% - 6px); }
}

/* Cross-links to the read-only spec page */
.editor-banner {
  margin: 10px 0 0;
  font-size: 13px;
}

.editor-banner a,
.hub-spec-link a {
  color: var(--accent);
  text-decoration: none;
  font-weight: 640;
}

.editor-banner a:hover,
.hub-spec-link a:hover {
  text-decoration: underline;
}

.hub-spec-link {
  margin: 0 0 4px;
  font-size: 14px;
}
