/* ==========================================================================
   Simbatch Homepage V5 — Candidate-03
   Six sections, six different rhythms. White ground, near-black type,
   one blue used only for connection / active / product life.
   ========================================================================== */

:root {
  --ink-900: #08090c;
  --ink-800: #16181d;
  --ink-700: #2b313c;
  --ink-500: #5b6472;
  --ink-400: #6a7383;            /* 4.78:1 on white — floor for body text */
  --ink-300: #b4bbc6;            /* borders / dots only — 1.93:1, never text */

  --bg: #ffffff;
  --bg-soft: #f8f9fb;
  --bg-sink: #f1f3f7;
  --line: #e6eaf0;
  --line-soft: #eff2f7;

  --blue: #2563eb;
  --blue-strong: #1d4ed8;
  --blue-wash: #f0f5ff;

  --ok: #0f7b4f;      --ok-bg: #e8f6ef;
  --build: #4a5262;   --build-bg: #f1f3f7;
  --next: #6a7383;    --next-bg: #f6f7fa;

  --font: -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC",
          "Hiragino Sans GB", "Microsoft YaHei", "Noto Sans SC", "Source Han Sans SC",
          Roboto, Helvetica, Arial, sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, "SF Mono", Consolas, monospace;

  --t-display:  clamp(40px, 4.6vw, 74px);
  --t-h2:       clamp(31px, 3.6vw, 54px);
  --t-h3:       17px;
  --t-body-lg:  20px;
  --t-body:     17px;
  --t-caption:  13px;
  --t-nav:      15px;
  --t-button:   15px;

  --lh-display: 1.03;
  --lh-head:    1.12;
  --lh-body:    1.68;

  --shell: 1280px;
  --gut: 34px;
  --sect: 156px;

  --shadow-soft: 0 1px 2px rgba(8,9,12,.04), 0 10px 28px -14px rgba(8,9,12,.10);
  --shadow-deep: 0 2px 6px rgba(8,9,12,.05), 0 40px 90px -34px rgba(8,9,12,.26);
}

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body { margin: 0; background: var(--bg); color: var(--ink-900); font-family: var(--font); font-size: var(--t-body); line-height: var(--lh-body); -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility; }
img { max-width: 100%; height: auto; display: block; }
a { color: inherit; }
[hidden] { display: none !important; }

h1, h2, h3 { margin: 0; font-weight: 620; letter-spacing: -.026em; line-height: var(--lh-head); }
h1 { font-size: var(--t-display); font-weight: 660; letter-spacing: -.042em; line-height: var(--lh-display); }
h2 { font-size: var(--t-h2); letter-spacing: -.032em; }
h3 { font-size: var(--t-h3); letter-spacing: -.012em; }
p  { margin: 0; }

.shell { width: 100%; max-width: var(--shell); margin: 0 auto; padding: 0 var(--gut); }
.eyebrow { font-size: var(--t-caption); font-weight: 600; letter-spacing: .11em; text-transform: uppercase; color: var(--ink-500); }
.lede { font-size: var(--t-body-lg); line-height: var(--lh-body); color: var(--ink-500); }

.skip { position: absolute; top: 0; left: 0; z-index: 200; background: var(--ink-900); color: #fff; padding: 12px 20px; border-radius: 0 0 10px 0; clip-path: inset(50%); width: 1px; height: 1px; overflow: hidden; white-space: nowrap; }
.skip:focus { clip-path: none; width: auto; height: auto; overflow: visible; }
:focus-visible { outline: 2px solid var(--blue); outline-offset: 3px; border-radius: 5px; }

/* ==========================================================================
   Navigation
   ========================================================================== */
.nav { position: sticky; top: 0; z-index: 100; background: rgba(255,255,255,.86); backdrop-filter: saturate(180%) blur(20px); -webkit-backdrop-filter: saturate(180%) blur(20px); border-bottom: 1px solid transparent; transition: border-color .3s ease; }
.nav[data-scrolled="true"] { border-bottom-color: var(--line-soft); }
.nav__inner { display: flex; align-items: center; gap: 44px; height: 72px; }
.brand { display: inline-flex; align-items: center; gap: 11px; text-decoration: none; font-weight: 640; font-size: 17px; letter-spacing: -.022em; padding: 6px 0; }
.brand__mark { width: 28px; height: 28px; border-radius: 8px; background: var(--ink-900); color: #fff; display: grid; place-items: center; font-size: 14px; font-weight: 700; letter-spacing: 0; }
.nav__links { display: flex; gap: 2px; margin: 0; padding: 0; list-style: none; }
.nav__links a { display: block; padding: 9px 15px; border-radius: 9px; text-decoration: none; font-size: var(--t-nav); color: var(--ink-700); transition: background .18s ease, color .18s ease; }
.nav__links a:hover { background: var(--bg-sink); color: var(--ink-900); }
.nav__end { margin-left: auto; display: flex; align-items: center; gap: 10px; }
.nav__toggle { display: none; width: 40px; height: 40px; border: 1px solid var(--line); background: #fff; border-radius: 10px; cursor: pointer; padding: 0; place-items: center; }
.nav__toggle span, .nav__toggle span::before, .nav__toggle span::after { display: block; width: 16px; height: 1.5px; background: var(--ink-900); border-radius: 2px; content: ""; }
.nav__toggle span { position: relative; }
.nav__toggle span::before { position: absolute; top: -5px; }
.nav__toggle span::after { position: absolute; top: 5px; }

.btn { display: inline-flex; align-items: center; justify-content: center; gap: 9px; padding: 13px 24px; border-radius: 11px; font-size: var(--t-button); font-weight: 560; text-decoration: none; border: 1px solid transparent; cursor: pointer; white-space: nowrap; transition: transform .2s cubic-bezier(.2,.7,.3,1), background .2s ease, border-color .2s ease, box-shadow .2s ease; }
.btn--primary { background: var(--ink-900); color: #fff; }
.btn--primary:hover { background: var(--ink-800); transform: translateY(-1px); box-shadow: 0 14px 30px -16px rgba(8,9,12,.8); }
.btn--ghost { background: #fff; color: var(--ink-900); border-color: var(--line); }
.btn--ghost:hover { border-color: var(--ink-300); transform: translateY(-1px); }
.btn--onDark { background: #fff; color: var(--ink-900); }
.btn--onDark:hover { background: #f2f4f8; transform: translateY(-1px); }
.btn--ghostDark { background: transparent; color: #fff; border-color: rgba(255,255,255,.28); }
.btn--ghostDark:hover { border-color: rgba(255,255,255,.55); transform: translateY(-1px); }
.btn--lg { padding: 17px 32px; font-size: 16px; border-radius: 13px; }
.btn__arrow { width: 14px; height: 14px; flex: none; }
@media (prefers-reduced-motion: reduce) { .btn:hover { transform: none; } }

.chip { font-size: 11px; font-weight: 640; letter-spacing: .05em; padding: 3px 9px; border-radius: 999px; white-space: nowrap; text-transform: uppercase; }
.chip[data-s="live"]     { color: var(--ok);    background: var(--ok-bg); }
.chip[data-s="building"] { color: var(--build); background: var(--build-bg); }
.chip[data-s="next"]     { color: var(--next);  background: var(--next-bg); }

/* ==========================================================================
   Section frame
   ========================================================================== */
.section { padding: var(--sect) 0; }
.section--soft { background: var(--bg-soft); }
.section__head { max-width: 940px; margin-bottom: 66px; }
.section__head .eyebrow { margin-bottom: 22px; display: block; }
.section__head .lede { margin-top: 24px; }

html.js-anim .reveal { opacity: 0; transform: translateY(14px); }
html.js-anim .reveal.is-vis { opacity: 1; transform: none; transition: opacity .8s cubic-bezier(.2,.7,.3,1), transform .8s cubic-bezier(.2,.7,.3,1); }

/* ==========================================================================
   01 · HERO — layered product scene
   ========================================================================== */
.hero { position: relative; padding: 40px 0 60px; overflow: hidden; }
@media (min-width: 1081px) { .hero { min-height: 84vh; display: flex; align-items: center; padding: 12px 0 32px; } .hero > .shell { width: 100%; } .hero h1 span { white-space: nowrap; } }
.hero::before { content: ""; position: absolute; z-index: 0; pointer-events: none; right: -14%; top: -18%; width: 78%; height: 120%; background: radial-gradient(58% 52% at 52% 46%, rgba(37,99,235,.075) 0%, rgba(37,99,235,.03) 42%, rgba(37,99,235,0) 72%); }
.hero > .shell { position: relative; z-index: 1; }
.hero__grid { display: grid; grid-template-columns: minmax(0, 44fr) minmax(0, 56fr); gap: 56px; align-items: center; }
.hero__brand { display: flex; align-items: baseline; gap: 12px; margin-bottom: 32px; flex-wrap: wrap; }
.hero__brand b { font-size: 15px; font-weight: 660; letter-spacing: -.016em; }
.hero__brand span { font-size: 11.5px; letter-spacing: .13em; text-transform: uppercase; color: var(--ink-400); font-weight: 600; }
/* The two lines are declared, not left to the line-breaker — a hero headline
   that breaks as "让 AI 真正进 / 入你的业务" reads as a mistake. */
.hero h1 span { display: block; }
.hero__sub { margin-top: 28px; font-size: var(--t-body-lg); line-height: 1.62; color: var(--ink-500); max-width: 30em; }
.hero__cta { margin-top: 40px; display: flex; flex-wrap: wrap; gap: 12px; }

/* --- product scene ------------------------------------------------------ */
.scene { border-radius: 22px; background: #fff; border: 1px solid var(--line); box-shadow: var(--shadow-deep); overflow: hidden; }
.scene__bar { height: 42px; display: flex; align-items: center; gap: 7px; padding: 0 17px; border-bottom: 1px solid var(--line-soft); }
.scene__dot { width: 9px; height: 9px; border-radius: 50%; background: #e2e6ee; flex: none; }
.scene__label { margin-left: 13px; font-size: 12px; color: var(--ink-400); font-family: var(--font-mono); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.scene__badge { margin-left: auto; font-size: 11px; color: var(--ink-500); background: var(--bg-sink); border: 1px solid var(--line); padding: 4px 11px; border-radius: 999px; white-space: nowrap; }
.scene__body { padding: 17px 18px 18px; background: linear-gradient(180deg, #ffffff 0%, #f7f9fd 100%); }

/* progress rail + live caption */
.rail { display: flex; align-items: center; margin: 0 2px 14px; }
.rail__node { width: 7px; height: 7px; border-radius: 50%; background: #dfe4ed; flex: none; transition: background .5s ease, transform .5s cubic-bezier(.2,.7,.3,1); }
.rail__node[data-on="true"] { background: var(--blue); }
.rail__node[data-now="true"] { transform: scale(1.6); }
.rail__seg { height: 1.5px; flex: 1 1 auto; background: #e6eaf0; position: relative; overflow: hidden; }
.rail__seg::after { content: ""; position: absolute; inset: 0; background: var(--blue); transform: scaleX(0); transform-origin: left; transition: transform .55s cubic-bezier(.4,0,.2,1); }
.rail__seg[data-fill="true"]::after { transform: scaleX(1); }
.rail__cap { margin-left: 14px; font-size: 11.5px; color: var(--ink-500); font-family: var(--font-mono); white-space: nowrap; }

/* the scene grid: main order card + a side panel that slides in */
.scene__grid { display: grid; grid-template-columns: minmax(0, 1fr) 176px; gap: 12px; align-items: start; }

.oc { border: 1px solid var(--line); border-radius: 14px; background: #fff; padding: 14px 15px 13px; box-shadow: 0 1px 2px rgba(8,9,12,.03); }
.oc__top { display: flex; align-items: center; gap: 10px; }
.oc__mark { width: 30px; height: 30px; border-radius: 9px; background: var(--blue-wash); color: var(--blue-strong); display: grid; place-items: center; flex: none; }
.oc__mark svg { width: 15px; height: 15px; }
.oc__id { font-size: 14.5px; font-weight: 600; letter-spacing: -.012em; }
.oc__src { font-size: 12px; color: var(--ink-400); margin-top: 1px; }
.oc__state { margin-left: auto; font-size: 10.5px; font-weight: 640; letter-spacing: .05em; text-transform: uppercase; color: var(--blue-strong); background: var(--blue-wash); border-radius: 999px; padding: 3px 9px; white-space: nowrap; }

/* The card is always full. Motion moves STATE through it, it does not build it
   out of nothing — an empty frame in the first second would read as an empty
   product, and it would also make the panel height jump. */
.oc__row { position: relative; opacity: .42; transition: opacity .55s ease; }
.oc__row[data-on="true"] { opacity: 1; }
.oc__row::before {
  content: ""; position: absolute; left: -15px; top: 12px; bottom: 1px; width: 2px; border-radius: 2px;
  background: var(--blue); transform: scaleY(0); transform-origin: top; transition: transform .5s cubic-bezier(.2,.7,.3,1);
}
.oc__row[data-now="true"]::before { transform: scaleY(1); }
.oc__inner { padding-top: 11px; margin-top: 11px; border-top: 1px solid var(--line-soft); }
.oc__k { font-size: 11px; color: var(--ink-400); letter-spacing: .04em; text-transform: uppercase; font-weight: 600; }
.oc__v { font-size: 13.5px; color: var(--ink-700); margin-top: 4px; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.oc__tag { font-size: 11.5px; font-family: var(--font-mono); color: var(--blue-strong); background: var(--blue-wash); border-radius: 6px; padding: 2px 7px; }

.thumbs { display: flex; gap: 6px; margin-top: 7px; }
.thumb { width: 34px; height: 34px; border-radius: 8px; background: linear-gradient(135deg, #eef1f6 0%, #e2e7f0 100%); border: 1px solid var(--line); flex: none; transform: scale(.9); transition: transform .45s cubic-bezier(.2,.7,.3,1); }
.oc__row[data-on="true"] .thumb { transform: none; }
.oc__row[data-on="true"] .thumb:nth-child(2) { transition-delay: .06s; }
.oc__row[data-on="true"] .thumb:nth-child(3) { transition-delay: .12s; }
.oc__row[data-on="true"] .thumb:nth-child(4) { transition-delay: .18s; }
.oc__row[data-on="true"] .thumb:nth-child(5) { transition-delay: .24s; }
.oc__row[data-on="true"] .thumb:nth-child(6) { transition-delay: .30s; }

.ship { display: flex; align-items: center; gap: 9px; margin-top: 7px; }
.ship__bar { flex: 1 1 auto; height: 3px; border-radius: 2px; background: var(--line); position: relative; overflow: hidden; }
.ship__bar::after { content: ""; position: absolute; inset: 0; background: var(--blue); transform: scaleX(0); transform-origin: left; transition: transform 1.1s cubic-bezier(.4,0,.2,1); }
.oc__row[data-on="true"] .ship__bar::after { transform: scaleX(.72); }
.ship__t { font-size: 11.5px; color: var(--ink-500); font-family: var(--font-mono); white-space: nowrap; }

/* the side panel is a different UI form on purpose */
.sp { border: 1px solid var(--line); border-radius: 14px; background: #fff; padding: 13px 14px; opacity: .42; transform: translateX(8px); transition: opacity .5s ease, transform .5s cubic-bezier(.2,.7,.3,1), border-color .5s ease, box-shadow .5s ease; }
.sp[data-on="true"] { opacity: 1; transform: none; border-color: #cfdcf8; box-shadow: 0 12px 28px -20px rgba(37,99,235,.55); }
.sp__k { font-size: 10.5px; font-weight: 640; letter-spacing: .07em; text-transform: uppercase; color: var(--ink-400); }
.sp__t { font-size: 13.5px; font-weight: 590; margin-top: 8px; letter-spacing: -.01em; }
.sp__v { font-size: 12.5px; color: var(--ink-500); margin-top: 5px; }
.sp__meta { margin-top: 11px; padding-top: 10px; border-top: 1px solid var(--line-soft); font-size: 11.5px; color: var(--blue-strong); font-family: var(--font-mono); }

/* AI summary bubble */
.ai { margin-top: 12px; border: 1px solid #dde7fb; background: linear-gradient(180deg, #f6f9ff 0%, #eff5ff 100%); border-radius: 14px; padding: 13px 15px; display: flex; gap: 11px; align-items: flex-start; opacity: .4; transform: translateY(4px); transition: opacity .55s ease, transform .55s cubic-bezier(.2,.7,.3,1); }
.ai[data-on="true"] { opacity: 1; transform: none; }
.ai__k { font-size: 10.5px; font-weight: 660; letter-spacing: .08em; text-transform: uppercase; color: var(--blue-strong); flex: none; padding-top: 3px; }
.ai__v { font-size: 13px; color: var(--ink-700); line-height: 1.56; }

@media (prefers-reduced-motion: reduce) {
  .oc__row, .thumb, .sp, .ai, .rail__node, .rail__seg::after, .ship__bar::after { transition: none; }
  .hero::before { display: none; }
}

/* ==========================================================================
   02 · SCATTERED  →  SIMBATCH  →  CONNECTED   (one big diagram, not cards)
   ========================================================================== */
.converge { position: relative; display: grid; grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr); gap: 42px; align-items: center; }
.col__k { font-size: 11.5px; font-weight: 640; letter-spacing: .1em; text-transform: uppercase; color: var(--ink-400); margin-bottom: 20px; }

.sources { display: flex; flex-wrap: wrap; gap: 9px; }
.src {
  border: 1px solid var(--line); background: #fff; border-radius: 11px; padding: 10px 14px;
  font-size: 14px; color: var(--ink-700); box-shadow: 0 1px 2px rgba(8,9,12,.03);
  transition: transform .8s cubic-bezier(.2,.7,.3,1), opacity .8s ease, border-color .3s ease, color .3s ease;
}
html.js-anim .src { opacity: 0; }
/* Must be scoped under html.js-anim too: `.src.is-vis` alone is (0,2,0) and
   loses to `html.js-anim .src` (0,2,1), which left the source nodes invisible
   for every visitor who had JS enabled. */
html.js-anim .src.is-vis { opacity: 1; }
.src:hover { border-color: var(--ink-300); color: var(--ink-900); }

.hub { display: grid; place-items: center; gap: 12px; }
.hub__mark { width: 84px; height: 84px; border-radius: 24px; background: var(--ink-900); color: #fff; display: grid; place-items: center; font-size: 30px; font-weight: 700; letter-spacing: -.03em; box-shadow: 0 24px 50px -26px rgba(8,9,12,.7); }
.hub__mark img { display: block; width: 52%; height: 58%; object-fit: contain; }
.hub__n { font-size: 14px; font-weight: 620; letter-spacing: -.014em; }

/* Connectors live in the grid gaps either side of the hub. A stretched SVG
   viewBox turned the curves into stray diagonals across the chips, so these are
   two precise rules that grow on entry instead. */
.hub { position: relative; }
.hub::before, .hub::after {
  content: ""; position: absolute; top: 41px; width: 42px; height: 1.5px;
  background: var(--blue); opacity: .55; transform: scaleX(0);
  transition: transform .85s cubic-bezier(.4,0,.2,1);
}
.hub::before { right: 100%; transform-origin: right; }
.hub::after  { left: 100%; transform-origin: left; transition-delay: .25s; }
.converge.is-vis .hub::before, .converge.is-vis .hub::after { transform: scaleX(1); }
@media (prefers-reduced-motion: reduce) { .hub::before, .hub::after { transform: scaleX(1); transition: none; } }

.outs { display: flex; flex-wrap: wrap; gap: 9px; }
.out { border: 1px solid #d8e3fa; background: var(--blue-wash); border-radius: 11px; padding: 10px 14px; font-size: 14px; color: var(--blue-strong); font-weight: 550; }

.converge__say { margin-top: 74px; max-width: 900px; }
.converge__say p:first-child { font-size: clamp(27px, 3.2vw, 42px); font-weight: 640; letter-spacing: -.032em; line-height: 1.28; }
.converge__say p + p { margin-top: 18px; font-size: var(--t-body-lg); color: var(--ink-500); }

/* ==========================================================================
   03 · CAPABILITY NAVIGATOR (a list that tracks, not a card matrix)
   ========================================================================== */
.navi { display: grid; grid-template-columns: minmax(0, 38fr) minmax(0, 62fr); gap: 64px; align-items: start; }
.navi__title h2 { max-width: 9ch; }
.navi__note { margin-top: 26px; font-size: 14.5px; color: var(--ink-400); max-width: 26em; }

.caplist { list-style: none; margin: 0; padding: 0; position: relative; }
.caplist::before { content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 1.5px; background: var(--line); }
.captrack { position: absolute; left: 0; width: 1.5px; background: var(--blue); transition: transform .5s cubic-bezier(.2,.7,.3,1), height .5s cubic-bezier(.2,.7,.3,1); top: 0; height: 0; }
.capitem { position: relative; padding: 22px 0 22px 34px; border-bottom: 1px solid var(--line-soft); display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 18px; align-items: baseline; transition: opacity .45s ease, transform .45s cubic-bezier(.2,.7,.3,1); }
.capitem:last-child { border-bottom: 0; }
.capitem__n { font-size: 12px; font-family: var(--font-mono); color: var(--ink-400); transition: color .45s ease; }
.capitem__t { font-size: clamp(19px, 1.7vw, 24px); font-weight: 600; letter-spacing: -.022em; transition: color .45s ease; }
.capitem__d { font-size: 14.5px; color: var(--ink-500); margin-top: 6px; line-height: 1.6; }
.capitem[data-on="true"] { transform: translateX(5px); }
.capitem[data-on="true"] .capitem__n { color: var(--blue); }
.capitem[data-on="false"] .capitem__t { color: var(--ink-500); }
@media (prefers-reduced-motion: reduce) { .capitem, .captrack { transition: none; } }

/* ==========================================================================
   04 · REAL PRODUCT + REAL WORKFLOW
   ========================================================================== */
.dual { display: grid; grid-template-columns: minmax(0, 46fr) minmax(0, 54fr); gap: 26px; align-items: stretch; }
.panel { border: 1px solid var(--line); border-radius: 21px; background: #fff; overflow: hidden; box-shadow: var(--shadow-soft); display: flex; flex-direction: column; }
.panel__head { display: flex; align-items: center; gap: 12px; padding: 17px 22px; border-bottom: 1px solid var(--line-soft); flex-wrap: wrap; }
.panel__title { font-size: 14.5px; font-weight: 590; letter-spacing: -.012em; }
.panel__cap { font-size: 12.5px; color: var(--ink-400); margin-left: auto; }
.panel__body { padding: 22px 24px 24px; flex: 1 1 auto; }

/* Crop: show the left navigation + header of the real console, which is where
   the product structure lives. The file itself is untouched — this is framing,
   not retouching. A soft edge keeps the crop from reading as a hard cut. */
.console { position: relative; overflow: hidden; aspect-ratio: 820 / 900; background: #fff; }
.console img { position: absolute; top: 0; left: 0; width: 175.61%; max-width: none; }
.console::after { content: ""; position: absolute; inset: 0; pointer-events: none; background: linear-gradient(90deg, rgba(255,255,255,0) 62%, rgba(255,255,255,.92) 100%); }

.steps { list-style: none; margin: 0; padding: 0; position: relative; }
.steps::before { content: ""; position: absolute; left: 12px; top: 12px; bottom: 12px; width: 1.5px; background: var(--line); }
.step { position: relative; padding: 0 0 19px 40px; }
.step:last-child { padding-bottom: 0; }
.step__n { position: absolute; left: 0; top: 1px; width: 25px; height: 25px; border-radius: 50%; background: #fff; border: 1.5px solid var(--line); display: grid; place-items: center; font-size: 11px; font-weight: 660; color: var(--ink-400); }
.step[data-tone="accent"] .step__n { border-color: var(--blue); color: var(--blue-strong); background: var(--blue-wash); }
.step b { display: block; font-size: 14.5px; font-weight: 575; letter-spacing: -.012em; }
.step span { font-size: 13px; color: var(--ink-400); }

.statusline { margin-top: 30px; display: flex; align-items: baseline; gap: 10px 26px; flex-wrap: wrap; font-size: 13.5px; color: var(--ink-500); }
.statusline b { font-weight: 570; color: var(--ink-700); }

/* ==========================================================================
   05 · PROOF STATEMENTS (big type, not cards)
   ========================================================================== */
.proofs { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--line); }
.proof { display: grid; grid-template-columns: 74px minmax(0, 1fr) auto; gap: 26px; align-items: start; padding: 34px 0; border-bottom: 1px solid var(--line); }
.proof__n { font-size: 13px; font-family: var(--font-mono); color: var(--ink-400); padding-top: 9px; }
.proof__t { font-size: clamp(22px, 2.3vw, 32px); font-weight: 620; letter-spacing: -.028em; line-height: 1.24; }
.proof__d { margin-top: 10px; font-size: 15px; color: var(--ink-500); line-height: 1.62; max-width: 46em; }
.proof__s { padding-top: 11px; }

/* ==========================================================================
   Testimonials — ships hidden until real, attributable, permitted entries exist
   ========================================================================== */
.tst { margin-top: 84px; }
.tst__rail { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(300px, 360px); gap: 16px; overflow-x: auto; padding-bottom: 8px; scroll-snap-type: x mandatory; }
.tst__card { border: 1px solid var(--line); border-radius: 19px; padding: 28px 26px; background: #fff; scroll-snap-align: start; }
.tst__quote { font-size: 15.5px; line-height: 1.62; color: var(--ink-700); }
.tst__who { margin-top: 20px; display: flex; align-items: center; gap: 12px; }
.tst__avatar { width: 36px; height: 36px; border-radius: 50%; background: var(--bg-sink); display: grid; place-items: center; font-size: 13px; font-weight: 640; color: var(--ink-500); }
.tst__name { font-size: 14px; font-weight: 570; }
.tst__role { font-size: 12.5px; color: var(--ink-400); }

/* ==========================================================================
   06 · FINAL CTA — dark brand close
   ========================================================================== */
.final { background: var(--ink-900); color: #fff; padding: 150px 0 156px; text-align: center; position: relative; overflow: hidden; }
.final::before { content: ""; position: absolute; inset: 0; pointer-events: none; background: radial-gradient(46% 58% at 50% 8%, rgba(37,99,235,.30) 0%, rgba(37,99,235,.09) 44%, rgba(37,99,235,0) 74%); }
.final > .shell { position: relative; z-index: 1; }
.final h2 { color: #fff; font-size: clamp(34px, 4.8vw, 66px); letter-spacing: -.04em; margin: 0 auto; }
/* Declared line break — the breaker leaves 的业务 as an orphan otherwise. */
.final h2 span { display: block; }
.final p { margin: 28px auto 0; max-width: 34em; font-size: var(--t-body-lg); color: #aab3c2; }
.final__cta { margin-top: 46px; display: flex; gap: 12px; justify-content: center; flex-wrap: wrap; }
.final__mark { display: inline-flex; align-items: center; gap: 10px; margin-bottom: 34px; font-size: 12px; letter-spacing: .14em; text-transform: uppercase; color: #7b8698; font-weight: 600; }
.final__mark i { width: 22px; height: 22px; border-radius: 7px; background: #fff; color: var(--ink-900); display: grid; place-items: center; font-size: 12px; font-weight: 700; font-style: normal; letter-spacing: 0; }
.final__mark img { display: block; width: 146px; height: auto; }

/* ==========================================================================
   Footer
   ========================================================================== */
.foot { border-top: 1px solid var(--line-soft); padding: 48px 0 46px; }
.foot__row { display: flex; align-items: center; gap: 28px; flex-wrap: wrap; }
.foot__links { display: flex; gap: 4px; flex-wrap: wrap; margin-left: auto; }
.foot__links a { font-size: 14px; color: var(--ink-500); text-decoration: none; padding: 8px 12px; border-radius: 8px; }
.foot__links a:hover { color: var(--ink-900); background: var(--bg-sink); }
.foot__legal { margin-top: 26px; padding-top: 22px; border-top: 1px solid var(--line-soft); display: flex; justify-content: space-between; gap: 16px; flex-wrap: wrap; font-size: var(--t-caption); color: var(--ink-400); }

/* ==========================================================================
   Responsive
   ========================================================================== */
@media (max-width: 1080px) {
  :root { --sect: 108px; }
  .hero { padding: 30px 0 66px; }
  .hero__grid { grid-template-columns: minmax(0, 1fr); gap: 44px; }
  .hero h1 { max-width: 16ch; }
  .hero::before { right: -30%; top: 24%; width: 110%; height: 68%; }
  .converge { grid-template-columns: minmax(0, 1fr); gap: 30px; justify-items: start; }
  .hub::before, .hub::after { display: none; }
  .navi { grid-template-columns: minmax(0, 1fr); gap: 40px; }
  .navi__title h2 { max-width: none; }
  .dual { grid-template-columns: minmax(0, 1fr); }
  .console { aspect-ratio: 1440 / 620; }
  .console img { width: 100%; }
  .console::after { background: linear-gradient(180deg, rgba(255,255,255,0) 66%, rgba(255,255,255,.9) 100%); }
}

@media (max-width: 860px) {
  .nav__inner { gap: 16px; height: 66px; }
  .nav__end .btn { padding: 10px 16px; font-size: 14px; }
  .nav__links { display: none; }
  .nav__toggle { display: grid; }
  .nav[data-open="true"] .nav__links { display: grid; position: absolute; left: 0; right: 0; top: 66px; background: #fff; border-bottom: 1px solid var(--line); padding: 10px var(--gut) 18px; gap: 2px; }
  .nav[data-open="true"] .nav__links a { padding: 12px 14px; }
  .proof { grid-template-columns: 48px minmax(0, 1fr); gap: 16px; padding: 28px 0; }
  .proof__s { grid-column: 2; padding-top: 12px; }
}

/* --- Mobile: shorter, fewer separate objects ---------------------------- */
@media (max-width: 620px) {
  :root { --sect: 76px; --gut: 20px; --t-body-lg: 17.5px; }
  body { font-size: 16px; }
  .nav__end .btn { display: none; }

  .hero { padding: 24px 0 44px; }
  .hero h1 { font-size: clamp(38px, 11.6vw, 52px); max-width: 11ch; letter-spacing: -.04em; }
  .hero__brand { margin-bottom: 22px; }
  .hero__sub { margin-top: 18px; font-size: 17px; line-height: 1.58; }
  .hero__cta { margin-top: 26px; }
  .hero__cta .btn { width: 100%; }
  .hero::before { display: none; }

  /* Phone scene: one column, no side panel — the panel's content folds into
     the order card so the story stays complete but the object count drops. */
  .scene { border-radius: 18px; }
  .scene__bar { height: 40px; padding: 0 13px; }
  .scene__label { display: none; }
  .scene__body { padding: 14px 13px 15px; }
  .scene__grid { grid-template-columns: minmax(0, 1fr); gap: 10px; }
  .rail__cap { font-size: 11px; }
  .thumb { width: 30px; height: 30px; }

  .section__head { margin-bottom: 38px; }
  .converge { gap: 22px; }
  .converge__say { margin-top: 40px; }
  .col__k { margin-bottom: 14px; }
  .src, .out { padding: 8px 12px; font-size: 13.5px; border-radius: 10px; }
  .sources, .outs { gap: 7px; }
  .hub__mark { width: 66px; height: 66px; border-radius: 20px; font-size: 24px; }

  .capitem { padding: 17px 0 17px 26px; grid-template-columns: minmax(0, 1fr); gap: 0; }
  .capitem__n { display: none; }
  .capitem__t { font-size: 18.5px; }
  .capitem__d { font-size: 14px; margin-top: 5px; }

  .panel__body { padding: 18px 18px 20px; }
  .step { padding-bottom: 15px; }
  .statusline { margin-top: 22px; gap: 8px 18px; font-size: 13px; }

  .proof { padding: 22px 0; }
  .proof__t { font-size: 20px; }
  .proof__d { font-size: 14px; margin-top: 7px; }

  .final { padding: 96px 0 100px; }
  .final__cta { margin-top: 32px; }
  .final__cta .btn { width: 100%; }
  .foot__links { margin-left: 0; }
  .foot__links a { padding: 10px 12px; }
}


/* ==========================================================================
   CANDIDATE-04 — mobile brand & motion refinement
   Only four things change: §02 relationship visual, §03 capability navigation,
   §04 real console on phones, §05 proof typography. Desktop keeps its layout.
   ========================================================================== */

/* --- §03 structure: the list rows are blocks, not inline spans -------- */
.capitem__body { display: block; }
.capitem__t, .capitem__d { display: block; }
.capitem__fx { display: none; }

/* a small piece of the real product, rebuilt from the hero's own elements */
.fx { display: flex; align-items: center; gap: 10px; margin-top: 14px; padding: 11px 14px;
      border: 1px solid var(--line); border-radius: 12px; background: #fff; }
.fx b { font-size: 13.5px; font-weight: 600; letter-spacing: -.01em; }
.fx em { font-style: normal; font-size: 12.5px; color: var(--ink-400); }
.fx--thumbs { gap: 6px; }
.fx--thumbs i { width: 28px; height: 28px; border-radius: 7px; background: linear-gradient(135deg,#eef1f6,#e2e7f0); border: 1px solid var(--line); }
.fx--ship .fx__bar { flex: 1 1 auto; height: 3px; border-radius: 2px; background: var(--line); overflow: hidden; }
.fx--ship .fx__bar i { display: block; height: 100%; width: 72%; background: var(--blue); }
.fx--ai { align-items: flex-start; background: var(--blue-wash); border-color: #dde7fb; }
.fx--ai b { font-size: 10.5px; letter-spacing: .08em; color: var(--blue-strong); padding-top: 2px; }
.fx--ai em { color: var(--ink-700); line-height: 1.5; }
.caplist__note { margin-top: 22px; font-size: 12.5px; color: var(--ink-400); }

/* --- §04 real console on phones: three crops of one untouched file ---- */
.cmob { display: none; }
.cmob__tabs { display: flex; gap: 6px; padding: 14px 14px 0; }
.cmob__tab {
  flex: 1 1 0; min-height: 44px; border: 1px solid var(--line); background: #fff; border-radius: 10px;
  font: inherit; font-size: 13.5px; font-weight: 550; color: var(--ink-500); cursor: pointer;
  transition: background .2s ease, color .2s ease, border-color .2s ease;
}
.cmob__tab[aria-selected="true"] { background: var(--ink-900); border-color: var(--ink-900); color: #fff; }
.cshot {
  --ch: 292px; --sx: 0; --sy: 25; --sh: 600;
  position: relative; height: var(--ch); overflow: hidden; margin: 14px 0 0;
  border-top: 1px solid var(--line-soft); border-bottom: 1px solid var(--line-soft); background: #fff;
}
.cshot img {
  position: absolute; max-width: none; width: auto;
  height: calc(900 / var(--sh) * var(--ch));
  left: calc(-1 * var(--sx) / var(--sh) * var(--ch));
  top:  calc(-1 * var(--sy) / var(--sh) * var(--ch));
  transition: left .45s cubic-bezier(.2,.7,.3,1), top .45s cubic-bezier(.2,.7,.3,1), height .45s cubic-bezier(.2,.7,.3,1);
}
.cshot[data-view="nav"]  { --sx: 0;    --sy: 22;  --sh: 600; }
.cshot[data-view="work"] { --sx: 258;  --sy: 96;  --sh: 600; }
.cshot[data-view="ai"]   { --sx: 1108; --sy: 4;   --sh: 262; }
@media (prefers-reduced-motion: reduce) { .cshot img { transition: none; } }

/* --- §04 workflow: one step open at a time, but only when JS is here --- */
.steps.js-steps .step span { display: none; }
.steps.js-steps .step[data-open="true"] span { display: block; }
.steps.js-steps .step[data-open="true"] .step__n { border-color: var(--blue); color: var(--blue-strong); background: var(--blue-wash); }
.steps.js-steps .step:not([data-open="true"]) b { color: var(--ink-500); font-weight: 550; }

/* ==========================================================================
   Mobile (<= 620px)
   ========================================================================== */
@media (max-width: 620px) {
  :root { --sect: 74px; }

  /* --- §02 : 分散来源 → Simbatch → 统一业务, read top to bottom --- */
  .converge { grid-template-columns: minmax(0, 1fr); gap: 0; justify-items: stretch; text-align: center; }
  .src[data-m="hide"] { display: none; }          /* 6 source nodes on phones */
  .col__k { margin-bottom: 16px; font-size: 11px; }
  .sources { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
  .src { text-align: center; padding: 13px 10px; font-size: 14px; border-radius: 12px; }
  .outs { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
  .out { text-align: center; padding: 13px 8px; font-size: 14px; border-radius: 12px; }

  .hub { margin: 34px auto; padding: 0; }
  .hub__mark { width: 72px; height: 72px; border-radius: 22px; font-size: 26px; }
  /* connectors run vertically here, not across a gap that no longer exists */
  .hub::before, .hub::after {
    display: block; left: 50%; right: auto; top: auto; margin-left: -.75px;
    width: 1.5px; height: 32px; transform: scaleY(0);
  }
  .hub::before { bottom: 100%; transform-origin: bottom; }
  .hub::after  { top: 100%; transform-origin: top; }
  .converge[data-stage="2"] .hub::before,
  .converge[data-stage="3"] .hub::before, .converge[data-stage="3"] .hub::after,
  .converge[data-stage="4"] .hub::before, .converge[data-stage="4"] .hub::after { transform: scaleY(1); }

  /* the conclusion must out-weigh the nodes above it */
  .converge__say { margin-top: 44px; }
  .converge__say p:first-child { font-size: 30px; letter-spacing: -.032em; line-height: 1.26; }
  .converge__say p + p { margin-top: 14px; font-size: 16.5px; }

  /* --- §03 : product catalogue, not a text list --- */
  .capitem { padding: 22px 0 22px 26px; min-height: 44px; grid-template-columns: minmax(0, 1fr); gap: 0; cursor: pointer; }
  .capitem__n { display: block; font-size: 12px; color: var(--ink-400); margin-bottom: 8px; }
  .capitem__t { font-size: 25px; font-weight: 620; letter-spacing: -.026em; line-height: 1.2; }
  .capitem__d { font-size: 15px; margin-top: 9px; color: var(--ink-400); }
  .capitem[data-on="true"] .capitem__t { color: var(--ink-900); }
  .capitem[data-on="true"] .capitem__n { color: var(--blue-strong); }
  .capitem[data-on="true"] .capitem__d { color: var(--ink-500); }
  .capitem[data-on="false"] .capitem__t { color: var(--ink-500); font-weight: 570; }
  .capitem[data-on="true"] .capitem__fx { display: block; }
  .navi__note { font-size: 15px; margin-top: 20px; }

  /* --- §04 : crops instead of a shrunken desktop screenshot --- */
  .console { display: none; }
  .cmob { display: block; }
  .panel__body { padding: 18px 18px 20px; }
  .statusline { margin-top: 20px; gap: 6px 16px; font-size: 12.5px; color: var(--ink-400); }
  .statusline b { color: var(--ink-500); }

  /* --- §05 : big facts, no boxes --- */
  .proofs { border-top: 0; }
  .proof { grid-template-columns: minmax(0, 1fr); gap: 0; padding: 0 0 44px; border-bottom: 0; }
  .proof:last-child { padding-bottom: 0; }
  .proof__n { font-size: 15px; font-weight: 400; color: var(--ink-400); padding: 0 0 12px; }
  .proof__t { font-size: 26px; letter-spacing: -.03em; line-height: 1.22; }
  .proof__d { font-size: 15px; margin-top: 11px; line-height: 1.6; }
  .proof__s { padding-top: 14px; }

  /* --- touch targets --- */
  .nav[data-open="true"] .nav__links a { padding: 14px; min-height: 44px; }
  .foot__links a { min-height: 44px; display: flex; align-items: center; }
  .final__cta .btn, .hero__cta .btn { min-height: 48px; }
  .final__cta { gap: 10px; }
}

/* --- §02 staged entrance (all viewports), one shot, ~4.6s -------------- */
html.js-anim .out { opacity: 0; transform: translateY(6px); }
.converge[data-stage="4"] .out {
  opacity: 1; transform: none;
  transition: opacity .6s ease, transform .6s cubic-bezier(.2,.7,.3,1);
}
.converge[data-stage="4"] .out:nth-child(2) { transition-delay: .07s; }
.converge[data-stage="4"] .out:nth-child(3) { transition-delay: .14s; }
.converge[data-stage="4"] .out:nth-child(4) { transition-delay: .21s; }
.converge[data-stage="4"] .out:nth-child(5) { transition-delay: .28s; }
.converge[data-stage="4"] .out:nth-child(6) { transition-delay: .35s; }
.converge[data-stage="3"] .hub__mark { animation: hubpulse 1.1s cubic-bezier(.2,.7,.3,1) 1; }
@keyframes hubpulse {
  0%   { box-shadow: 0 24px 50px -26px rgba(8,9,12,.7), 0 0 0 0 rgba(37,99,235,.32); }
  70%  { box-shadow: 0 24px 50px -26px rgba(8,9,12,.7), 0 0 0 16px rgba(37,99,235,0); }
  100% { box-shadow: 0 24px 50px -26px rgba(8,9,12,.7), 0 0 0 0 rgba(37,99,235,0); }
}
@media (prefers-reduced-motion: reduce) {
  .hub__mark { animation: none !important; }
  .out { opacity: 1 !important; transform: none !important; }
}


/* ==========================================================================
   CANDIDATE-04 — mobile length budget
   The page must not get longer than Candidate-03 (6232px @390). Bigger type
   and the console tabs cost height, so it is paid back structurally — fewer
   separate objects and tighter rhythm — never by hiding content behind JS.
   ========================================================================== */
@media (max-width: 620px) {
  :root { --sect: 58px; }

  .section__head { margin-bottom: 30px; }

  /* Hero: the side panel becomes one line inside the story instead of a
     second box stacked under the order card (§37: fewer small elements). */
  .hero { padding: 22px 0 34px; }
  .scene__body { padding: 12px 11px 13px; }
  .rail { margin-bottom: 11px; }
  .oc { padding: 12px 13px 11px; }
  .oc__inner { padding-top: 9px; margin-top: 9px; }
  .scene__grid { gap: 8px; }
  .sp { padding: 10px 13px; display: flex; align-items: baseline; gap: 9px; flex-wrap: wrap; }
  .sp__k, .sp__meta { display: none; }
  .sp__t { margin-top: 0; font-size: 13.5px; }
  .sp__v { margin-top: 0; }
  .ai { margin-top: 9px; padding: 10px 12px; }
  .thumb { width: 28px; height: 28px; }

  /* §02 */
  .hub { margin: 26px auto; }
  .hub::before, .hub::after { height: 26px; }
  .src { padding: 11px 10px; font-size: 13.5px; }
  .out { padding: 10px 8px; font-size: 13.5px; }
  .converge__say { margin-top: 34px; }

  /* §03 — the row itself carries the weight; the product fragment belongs to
     the row the reader is on. Descriptions stay visible in every state so the
     no-JS gate keeps holding. */
  .capitem { padding: 16px 0 16px 24px; }
  .capitem__n { margin-bottom: 6px; }
  .capitem__t { font-size: 22px; }
  .capitem__d { font-size: 14.5px; margin-top: 7px; }
  .capitem__fx { display: none; }
  .capitem[data-on="true"] .capitem__fx { display: block; }
  .fx { margin-top: 11px; padding: 9px 12px; }
  .fx--thumbs i { width: 26px; height: 26px; }
  .caplist__note { margin-top: 16px; }
  .navi__note { margin-top: 14px; font-size: 14.5px; }

  /* §04 */
  .cshot { --ch: 236px; margin-top: 12px; }
  .cmob__tabs { padding: 12px 12px 0; }
  .panel__head { padding: 14px 16px; }
  .panel__body { padding: 15px 16px 16px; }
  .dual { gap: 16px; }
  .step { padding: 0 0 14px 38px; }
  .step span { font-size: 12.5px; }
  .statusline { margin-top: 16px; }

  /* §05 */
  .proof { padding: 0 0 32px; }
  .proof__n { padding-bottom: 9px; }
  .proof__d { margin-top: 9px; }
  .proof__s { padding-top: 11px; }

  /* close */
  .final { padding: 76px 0 80px; }
  .foot { padding: 34px 0 34px; }
  .foot__legal { margin-top: 20px; padding-top: 18px; }

  /* touch targets that measured under 44px */
  .nav__toggle { width: 44px; height: 44px; }
  .brand { padding: 9px 0; }
}

/* Static / no-JS / reduced-motion: descriptions and the story stay complete,
   but only the first row carries a product fragment — six previews at once is
   noise, and the fragment is decoration, not content. */
/* The product fragment is a phone-only affordance, so its static fallback is
   scoped to phones too — otherwise the deterministic desktop capture would
   show something the live desktop page never shows.
   Specificity matters: .capitem[data-on="true"] .capitem__fx is (0,3,0). */
@media (max-width: 620px) {
  html:not(.js-anim) .capitem[data-on="true"] .capitem__fx { display: none; }
  html:not(.js-anim) .capitem[data-cap="0"][data-on="true"] .capitem__fx { display: block; }
}
@media (min-width: 621px) { .caplist__note { display: none; } }

@media (max-width: 620px) {
  :root { --sect: 52px; }
  /* wrapped, centred rows read as one group; a rigid grid just adds rows */
  .sources { display: flex; flex-wrap: wrap; justify-content: center; gap: 7px; }
  .outs { display: flex; flex-wrap: wrap; justify-content: center; gap: 7px; }
  .src, .out { padding: 10px 13px; }
  .cshot { --ch: 210px; }
  .step { padding: 0 0 11px 38px; }
}


/* ==========================================================================
   CANDIDATE-05 — fullness, motion and attraction
   Nothing new is said. Density is added as PICTURE, never as sentences:
   more product surface, more layers, more state that actually moves.
   Every added element is either a rearrangement of words already on the page
   or a crop of the one real screenshot whose bytes are untouched.
   ========================================================================== */

/* --------------------------------------------------------------------------
   00 · two inherited run-together lines
   .oc__id/.oc__src and .proof__t/.proof__d are spans inside a single grid or
   flex child, so they ran on one line: "订单 #1042Shopify · 09:12" and
   "公开站点已经上线simbatch.com 已对公众开放…". Both carry a margin-top that
   only ever applied because nobody looked. They are stacked pairs, so they
   are declared as blocks.
   -------------------------------------------------------------------------- */
.oc__id, .oc__src, .proof__t, .proof__d { display: block; }

/* --------------------------------------------------------------------------
   01 · HERO — a field behind the words, a shell around the product
   -------------------------------------------------------------------------- */
.hero__field { position: absolute; inset: 0; z-index: 0; pointer-events: none; overflow: hidden; }
/* structure, not decoration: a faint build grid, masked so it never reaches
   the headline and never reads as a pattern. */
.hero__field::before {
  content: ""; position: absolute; inset: -2px;
  background-image: linear-gradient(to right, rgba(8,9,12,.038) 1px, transparent 1px),
                    linear-gradient(to bottom, rgba(8,9,12,.038) 1px, transparent 1px);
  background-size: 68px 68px;
  -webkit-mask-image: radial-gradient(66% 60% at 68% 46%, #000 0%, rgba(0,0,0,.45) 50%, transparent 78%);
          mask-image: radial-gradient(66% 60% at 68% 46%, #000 0%, rgba(0,0,0,.45) 50%, transparent 78%);
}
.hero__field::after {
  content: ""; position: absolute; right: 2%; bottom: -18%; width: 48%; height: 78%;
  background: radial-gradient(50% 50% at 50% 50%, rgba(37,99,235,.055) 0%, rgba(37,99,235,0) 70%);
}
.hero__say { position: relative; z-index: 1; }

@media (min-width: 1081px) {
  .hero__grid { grid-template-columns: minmax(0, 42fr) minmax(0, 58fr); gap: 52px; }
}

/* the scene is now a shell (module rail + workspace), not one white box */
.scene__shell { display: flex; align-items: stretch; }
.scene__side {
  flex: none; width: 46px; padding: 16px 0; display: flex; flex-direction: column;
  align-items: center; gap: 12px; border-right: 1px solid var(--line-soft);
  background: linear-gradient(180deg, #fbfcfe 0%, #f3f6fc 100%);
}
.sd {
  width: 20px; height: 20px; border-radius: 7px; background: #e6ebf3; position: relative; flex: none;
  transition: background .45s ease, transform .45s cubic-bezier(.2,.7,.3,1);
}
.sd::after { content: ""; position: absolute; inset: 5px; border-radius: 3px; background: #fff; opacity: .82; transition: opacity .45s ease; }
.sd[data-on="true"]  { background: #b8cef5; }
.sd[data-on="true"]::after { opacity: .5; }
.sd[data-now="true"] { background: var(--blue); transform: scale(1.14); }
.sd[data-now="true"]::after { opacity: .42; }
.scene__body { flex: 1 1 auto; min-width: 0; }

/* a micro data strip that lights up as the story reaches each fact.
   Every string here already exists in the AI summary / order card below. */
.mstats { display: flex; gap: 7px; margin: 0 2px 11px; flex-wrap: wrap; }
.mstat {
  display: inline-flex; align-items: center; gap: 6px; font-size: 11.5px; color: var(--ink-400);
  background: #fff; border: 1px solid var(--line); border-radius: 999px; padding: 4px 11px 4px 9px;
  white-space: nowrap; transition: color .45s ease, border-color .45s ease, background .45s ease;
}
.mstat i { width: 5px; height: 5px; border-radius: 50%; background: #d7dde8; flex: none;
           transition: background .45s ease, box-shadow .45s ease; }
.mstat[data-on="true"] { color: var(--ink-700); border-color: #cfdcf8; background: var(--blue-wash); }
.mstat[data-on="true"] i { background: var(--blue); box-shadow: 0 0 0 3px rgba(37,99,235,.14); }

/* the connector that makes the side panel look generated BY the order card */
.sp { position: relative; }
.sp__link {
  position: absolute; right: 100%; top: 24px; width: 12px; height: 1.5px; background: var(--blue);
  opacity: .55; transform: scaleX(0); transform-origin: right;
  transition: transform .5s cubic-bezier(.4,0,.2,1);
}
.sp[data-on="true"] .sp__link { transform: scaleX(1); }

/* the signal row under the hero — brand signals, not numbers */
.signalrow {
  list-style: none; margin: 42px 0 0; padding: 20px 0 0; border-top: 1px solid var(--line);
  display: flex; flex-wrap: wrap; align-items: center; gap: 10px 44px; position: relative; z-index: 1;
}
.signalrow li { position: relative; padding-left: 17px; font-size: 13.5px; color: var(--ink-500); }
.signalrow li::before {
  content: ""; position: absolute; left: 0; top: 50%; margin-top: -2.5px;
  width: 5px; height: 5px; border-radius: 50%; background: var(--blue); opacity: .65;
}

/* --------------------------------------------------------------------------
   02 · the relationship picture gets a ground, two fields and a real centre
   -------------------------------------------------------------------------- */
.converge__field {
  position: absolute; left: 50%; top: 50%; width: 520px; height: 520px; margin: -260px 0 0 -260px;
  pointer-events: none; z-index: 0;
  background: radial-gradient(50% 50% at 50% 50%, rgba(37,99,235,.085) 0%, rgba(37,99,235,0) 68%);
}
.converge > .field, .converge > .hub { position: relative; z-index: 1; }
.field { border-radius: 20px; padding: 22px 22px 24px; }
.field--scatter { border: 1px dashed #d7dee9; background: rgba(255,255,255,.6); }
.field--united  { border: 1px solid #d8e3fa; background: linear-gradient(180deg, #f8fbff 0%, #eef4ff 100%); }
/* scattered reads as scattered (chips wrap where they land); unified reads as
   unified (a regular grid that fills its field). The contrast IS the argument. */
@media (min-width: 1081px) {
  .converge { align-items: stretch; }
  .converge > .hub { align-self: center; }
  .field { display: flex; flex-direction: column; }
  .field--united .outs { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; flex: 1 1 auto; align-content: center; }
  .field--united .out { text-align: center; padding: 13px 10px; }
}

/* the centre keeps a quiet energy ring once it has answered — it arrives with
   the hub's reply and then just stays, rather than pulsing for attention. */
.hub__ring {
  position: absolute; left: 50%; top: 42px; width: 130px; height: 130px; margin: -65px 0 0 -65px;
  border-radius: 50%; border: 1px solid rgba(37,99,235,.24); pointer-events: none;
  opacity: 0; transform: scale(.9); transition: opacity .9s ease, transform .9s cubic-bezier(.2,.7,.3,1);
}
.hub__ring::after { content: ""; position: absolute; inset: 17px; border-radius: 50%; border: 1px solid rgba(37,99,235,.15); }
.converge[data-stage="3"] .hub__ring, .converge[data-stage="4"] .hub__ring { opacity: 1; transform: none; }

/* --------------------------------------------------------------------------
   03 · the capability list gains a live product panel on every screen
   -------------------------------------------------------------------------- */
.capdots { display: flex; gap: 7px; margin-top: 34px; }
.capdot {
  width: 32px; height: 4px; border-radius: 2px; background: var(--line);
  transition: background .4s ease, transform .4s cubic-bezier(.2,.7,.3,1);
}
.capdot[data-on="true"] { background: var(--blue); transform: scaleY(1.6); }

/* the left column's product panel — empty and gone without scripting */
.capstage { display: none; }
.capstage:empty { display: none !important; }

@media (min-width: 1081px) {
  /* the title column stays with the reader instead of leaving a tall empty
     half-screen once the list scrolls past it */
  .navi { align-items: start; grid-template-columns: minmax(0, 36fr) minmax(0, 64fr); }
  .navi__title { position: sticky; top: 96px; }
  .caplist__note { grid-column: 2; }
}
@media (min-width: 621px) {
  .capitem__n { font-size: 13.5px; }
  .capitem {
    padding: 24px 20px 24px 34px; border-radius: 0 16px 16px 0;
    transition: background .45s ease, transform .45s cubic-bezier(.2,.7,.3,1);
  }
  .capitem[data-on="true"] { background: linear-gradient(90deg, rgba(240,245,255,.95) 0%, rgba(240,245,255,0) 86%); }
  /* the small piece of product now belongs to the active row on desktop too —
     this is the whole point of §16: the list should feel like looking AT the
     product, not at a table of contents. It opens by height rather than by
     display so the rows below it slide instead of jumping. */
  .capitem__fx {
    display: block; overflow: hidden; max-height: 0; opacity: 0; margin-top: 0;
    transition: max-height .5s cubic-bezier(.2,.7,.3,1), opacity .4s ease, margin-top .5s cubic-bezier(.2,.7,.3,1);
  }
  .capitem[data-on="true"] .capitem__fx { max-height: 140px; opacity: 1; margin-top: 17px; }
  .capitem__fx .fx { margin-top: 0; padding: 13px 16px; }
  .capitem__fx .fx b { font-size: 14.5px; }
  .capitem__fx .fx em { font-size: 13px; }
  .capitem__fx .fx--thumbs i { width: 32px; height: 32px; }
  .captrack { width: 3px; left: -.75px; border-radius: 2px; }
  .caplist__note { display: block; margin-top: 26px; font-size: 12.5px; color: var(--ink-400); }
}

/* --------------------------------------------------------------------------
   04 · the real console becomes the centrepiece
   The PNG is byte-identical to the one taken from the running system. Nothing
   here retouches it — the frame, the callouts and the close-ups are all just
   framing and cropping of that same untouched file.
   -------------------------------------------------------------------------- */
/* align-items:start, because a stretched console panel leaves a band of empty
   white under the screenshot: the image can only be as tall as its own aspect
   ratio allows, so the flex growth was pure padding. The rows below (close-ups,
   status band) carry the width instead. */
@media (min-width: 1081px) {
  .dual { grid-template-columns: minmax(0, 60fr) minmax(0, 40fr); gap: 24px; align-items: start; }
  .dual .step { padding-bottom: 16px; }
}

.panel--stage { border-color: #dce2ec; box-shadow: 0 2px 8px rgba(8,9,12,.05), 0 46px 92px -48px rgba(8,9,12,.36); }
.console {
  position: relative; overflow: hidden; background: #fff; aspect-ratio: 1440 / 900;
  flex: none; border-top: 1px solid var(--line-soft);
}
.console__layer { position: absolute; left: 0; top: 0; width: 100%; aspect-ratio: 1440 / 900; }
.console__layer img { position: static; width: 100%; max-width: 100%; display: block; }
.console::after { background: linear-gradient(180deg, rgba(255,255,255,0) 88%, rgba(255,255,255,.55) 100%); }

/* Callouts frame regions that really exist in the file: the module navigation
   (x 6–228, y 88–644) and Ask Simbatch (x 1230–1402, y 16–58) of the 1440×900
   original. No labels — the screenshot already says "Ask Simbatch" itself, and
   the close-ups below name what each region is. */
.callout { position: absolute; z-index: 2; }
.callout i {
  position: absolute; inset: 0; border: 1.5px solid var(--blue); border-radius: 9px;
  background: rgba(37,99,235,.055); box-shadow: 0 0 0 3px rgba(37,99,235,.10);
}
.callout--nav { left: .42%; top: 9.78%; width: 15.42%; height: 61.78%; }
.callout--ask { left: 85.42%; top: 1.78%; width: 11.94%; height: 4.67%; }
html.js-anim .callout { opacity: 0; transform: scale(.99); }
html.js-anim .reveal.is-vis .callout {
  opacity: 1; transform: none;
  transition: opacity .7s ease .4s, transform .7s cubic-bezier(.2,.7,.3,1) .4s;
}

/* close-ups: two magnified regions of the SAME untouched file. A third frame
   for Ask Simbatch was cut — that corner of the real console is almost all
   empty ground, so blowing it up produced a mostly-blank box. The callout on
   the big image points at it instead. */
.croprow { display: grid; grid-template-columns: 264px minmax(0, 1fr); gap: 16px; margin-top: 20px; align-items: start; }
.crop { margin: 0; }
.crop__win {
  --ch: 300px; --sx: 0; --sy: 0; --sh: 600;
  position: relative; height: var(--ch); overflow: hidden; border-radius: 14px;
  border: 1px solid var(--line); background: #fff; box-shadow: var(--shadow-soft);
}
.crop__win img {
  position: absolute; max-width: none; width: auto;
  height: calc(900 / var(--sh) * var(--ch));
  left: calc(-1 * var(--sx) / var(--sh) * var(--ch));
  top:  calc(-1 * var(--sy) / var(--sh) * var(--ch));
}
.crop figcaption { margin-top: 11px; font-size: 12.5px; color: var(--ink-400); }
/* both close-ups land at ~1:1 against the original, so the words inside the
   real product stay legible; the nav frame ends just past 物流 rather than
   slicing a label in half */
.crop--nav  .crop__win { --ch: 320px; --sh: 320; --sx: 2;   --sy: 80; }
.crop--work .crop__win { --ch: 320px; --sh: 322; --sx: 258; --sy: 84; }

/* the status line becomes a band with its own ground */
.statusline {
  margin-top: 22px; padding: 18px 22px; border-radius: 16px; background: #fff;
  border: 1px solid var(--line); gap: 12px 34px; align-items: flex-start;
}
.statusline span { position: relative; padding-left: 16px; }
.statusline span::before { content: ""; position: absolute; left: 0; top: .62em; width: 6px; height: 6px; border-radius: 50%; }
.statusline span:nth-child(1)::before { background: var(--ok); }
.statusline span:nth-child(2)::before { background: var(--build); }
.statusline span:nth-child(3)::before { background: var(--next); }

/* --------------------------------------------------------------------------
   signal band — six words that are already the outputs of section 02
   -------------------------------------------------------------------------- */
.band { border-top: 1px solid var(--line-soft); border-bottom: 1px solid var(--line-soft); background: var(--bg-sink); }
.band__inner { display: flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: 6px 0; padding: 20px var(--gut); }
.band__inner span { position: relative; font-size: 13.5px; font-weight: 560; color: var(--ink-500); letter-spacing: .03em; padding: 0 26px; }
.band__inner span + span::before {
  content: ""; position: absolute; left: 0; top: 50%; margin-top: -2px;
  width: 4px; height: 4px; border-radius: 50%; background: var(--ink-300);
}

/* --------------------------------------------------------------------------
   05 · the four facts read as brand proof, not as a list
   -------------------------------------------------------------------------- */
.proofs { position: relative; border-top: 0; }
.proof {
  position: relative; grid-template-columns: 92px minmax(0, 1fr) auto; gap: 28px;
  padding: 36px 0; border-bottom: 1px solid var(--line-soft); border-radius: 0 14px 14px 0;
  transition: background .4s ease;
}
.proof:first-child { border-top: 1px solid var(--line-soft); }
.proof::before { content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 2px; border-radius: 2px; background: var(--line); }
.proof::after {
  content: ""; position: absolute; left: 0; top: 0; width: 2px; height: 100%; border-radius: 2px;
  background: var(--blue); transform: scaleY(0); transform-origin: top;
  transition: transform .9s cubic-bezier(.2,.7,.3,1) .2s;
}
.proof.is-vis::after { transform: scaleY(1); }
html:not(.js-anim) .proof::after { transform: scaleY(1); }
.proof__n { font-family: var(--font-mono); font-size: 30px; font-weight: 400; color: var(--ink-400); padding: 0 0 0 22px; line-height: 1.15; letter-spacing: -.02em; }
.proof__s { padding-top: 8px; }
.proof:hover { background: linear-gradient(90deg, rgba(246,248,251,.95) 0%, rgba(246,248,251,0) 78%); }

/* --------------------------------------------------------------------------
   06 · the dark close gets depth
   -------------------------------------------------------------------------- */
.final { padding: 168px 0 172px; }
.final::before {
  background:
    radial-gradient(44% 56% at 50% 10%, rgba(37,99,235,.34) 0%, rgba(37,99,235,.10) 46%, rgba(37,99,235,0) 74%),
    radial-gradient(58% 44% at 16% 98%, rgba(37,99,235,.15) 0%, rgba(37,99,235,0) 70%);
}
.final__grid {
  position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background-image: linear-gradient(to right, rgba(255,255,255,.038) 1px, transparent 1px),
                    linear-gradient(to bottom, rgba(255,255,255,.038) 1px, transparent 1px);
  background-size: 78px 78px;
  -webkit-mask-image: radial-gradient(62% 70% at 50% 36%, #000 0%, rgba(0,0,0,.32) 56%, transparent 82%);
          mask-image: radial-gradient(62% 70% at 50% 36%, #000 0%, rgba(0,0,0,.32) 56%, transparent 82%);
}
.final__mark { color: #a3adbd; }
.final__signal {
  list-style: none; margin: 56px 0 0; padding: 26px 0 0; border-top: 1px solid rgba(255,255,255,.10);
  display: flex; flex-wrap: wrap; justify-content: center; gap: 10px 36px;
}
.final__signal li { position: relative; padding-left: 16px; font-size: 13px; color: #9aa4b4; }
.final__signal li::before {
  content: ""; position: absolute; left: 0; top: 50%; margin-top: -2.5px;
  width: 5px; height: 5px; border-radius: 50%; background: #3b82f6;
}

/* --------------------------------------------------------------------------
   Tablet
   -------------------------------------------------------------------------- */
@media (max-width: 1080px) {
  .hero__field::before { -webkit-mask-image: radial-gradient(78% 46% at 60% 70%, #000 0%, transparent 82%);
                                 mask-image: radial-gradient(78% 46% at 60% 70%, #000 0%, transparent 82%); }
  .console { aspect-ratio: 1440 / 620; min-height: 0; flex: none; }
  .callout { display: none; }
  .croprow { grid-template-columns: 208px minmax(0, 1fr); }
  .crop--nav .crop__win, .crop--work .crop__win { --ch: 250px; }
  .crop--nav .crop__win { --sh: 278; }
  .crop--work .crop__win { --sh: 340; }
}
@media (max-width: 860px) { .croprow { display: none; } }

/* --------------------------------------------------------------------------
   Phones — fuller, but paid for structurally. Nothing is hidden behind JS.
   -------------------------------------------------------------------------- */
/* The phone budget is 6300 @390 / 6350 @375. Once the proof grid was put back
   to one column the page came in at 5930/5974 — under Candidate-04 while
   carrying more. That headroom is spent on breathing room, not on more
   objects: fuller is not the same as tighter. */
@media (max-width: 620px) {
  :root { --sect: 48px; }
  .section__head { margin-bottom: 28px; }
  .section__head .lede { margin-top: 18px; }

  .hero { padding: 22px 0 32px; }
  .hero__sub { margin-top: 17px; }
  .hero__cta { margin-top: 24px; }
  .hero__field { display: none; }
  .scene__side { width: 34px; padding: 13px 0; gap: 9px; }
  .sd { width: 16px; height: 16px; border-radius: 6px; }
  .sd::after { inset: 4px; }
  .mstats { gap: 5px; margin-bottom: 9px; }
  .mstat { font-size: 10.5px; padding: 3px 9px 3px 7px; gap: 5px; }
  .sp__link { display: none; }

  /* three signals, one row, aligned — not three wrapped bullet lines */
  .signalrow {
    margin-top: 26px; padding-top: 18px; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 0; text-align: center;
  }
  .signalrow li { padding: 0; font-size: 11.5px; color: var(--ink-500); }
  .signalrow li::before { position: static; display: block; margin: 0 auto 7px; opacity: .8; }

  .field { padding: 16px 14px 18px; border-radius: 16px; }
  .converge__field { width: 300px; height: 300px; margin: -150px 0 0 -150px; }
  .hub { margin: 24px auto; }
  .hub__ring { width: 104px; height: 104px; margin: -52px 0 0 -52px; top: 36px; }
  .hub::before, .hub::after { height: 26px; }
  .sources { gap: 7px; }
  /* the six unified outputs land on a regular 3×2 grid — free-wrapping left
     "AI" alone on its own centred line, which reads as a leftover */
  .outs { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 7px; }
  .out { text-align: center; padding: 11px 6px; }
  .converge__say { margin-top: 32px; }
  .converge__say p:first-child { font-size: 28px; line-height: 1.24; }
  .converge__say p + p { margin-top: 13px; }

  .capdots { margin-top: 20px; gap: 6px; }
  .capdot { width: 22px; }
  .capitem { padding: 16px 0 16px 24px; }
  .capitem__d { margin-top: 7px; }
  .fx { margin-top: 11px; }
  .caplist__note { margin-top: 15px; }
  .navi__note { margin-top: 14px; }

  /* The inherited crops asked a 348px-wide frame to show ~890px of the
     original, i.e. 0.36×, which made the real console unreadable on a phone —
     the point of showing it at all. These are ~1:1 (and 0.78× for the work
     area), so the words in the product are actually legible. The file is
     still untouched; only which rectangle is shown changes.
     Widths are checked against 1440: sx + 348·sh/ch must not exceed it, or
     the frame runs off the right edge of the image into white. */
  .cshot { --ch: 214px; margin-top: 12px; }
  .cshot[data-view="nav"]  { --sx: 0;    --sy: 20; --sh: 214; }
  .cshot[data-view="work"] { --sx: 258;  --sy: 84; --sh: 273; }
  .cshot[data-view="ai"]   { --sx: 1092; --sy: 4;  --sh: 214; }
  .panel__body { padding: 15px 16px 16px; }
  .step { padding: 0 0 12px 38px; }
  .statusline { margin-top: 14px; padding: 14px 15px; border-radius: 14px; gap: 9px 16px; }
  .statusline span { padding-left: 14px; }

  .band__inner { padding: 16px var(--gut); gap: 5px 0; }
  .band__inner span { font-size: 12px; padding: 0 15px; }

  /* the desktop three-column proof grid above is unscoped, so the phone's
     single column has to be restated here or it silently comes back as
     "92px | text | 0px" — which is what the grid-template readout caught. */
  .proof {
    grid-template-columns: minmax(0, 1fr); gap: 0;
    padding: 0 0 26px 0; border-bottom: 0; border-radius: 0;
  }
  .proof:first-child { border-top: 0; }
  .proof::before, .proof::after { display: none; }
  .proof:hover { background: none; }
  .proof__n { font-size: 17px; padding: 0 0 10px; font-family: var(--font-mono); }
  .proof__d { margin-top: 10px; }
  .proof__s { padding-top: 12px; }

  .final { padding: 72px 0 76px; }
  .final__signal {
    margin-top: 34px; padding-top: 20px; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 0; text-align: center;
  }
  .final__signal li { padding: 0; font-size: 11.5px; }
  .final__signal li::before { position: static; display: block; margin: 0 auto 7px; }
  .foot { padding: 32px 0 32px; }
  .foot__legal { margin-top: 18px; padding-top: 16px; }
}

/* --------------------------------------------------------------------------
   Static / no-JS / reduced-motion — the finished picture, never a blank one.
   The product fragment is decoration, so in a state with no active row only
   the first one carries it (six previews at once is noise). Specificity has to
   beat .capitem[data-on="true"] .capitem__fx (0,3,0) at every viewport.
   -------------------------------------------------------------------------- */
/* Candidate-04 pinned the product fragment to row 01 in the static state,
   because that state marked all six rows active and six previews at once is
   noise. Exactly one row is active now — in every state — and the reader can
   still change which one, so pinning it would silently break that choice.
   These two rules neutralise the pin; they must stay after it to win the tie
   at (0,4,1). With scripting off entirely there is no data-on at all, so no
   fragment shows and nothing depends on one. */
html:not(.js-anim) .capitem[data-on="true"] .capitem__fx { display: block; }
@media (min-width: 621px) {
  html:not(.js-anim) .capitem[data-on="true"] .capitem__fx { max-height: 200px; opacity: 1; margin-top: 17px; }
}
html:not(.js-anim) .hub__ring { opacity: 1; transform: none; }

/* --------------------------------------------------------------------------
   §03 on wide screens: the fragment moves OUT of the row and into the left
   column, so the list holds one steady rhythm and the empty half-screen next
   to the heading becomes the product. Written last so it beats the
   html:not(.js-anim) guard above at equal specificity.
   -------------------------------------------------------------------------- */
@media (min-width: 1081px) {
  /* a small product window, sized so it never resizes as the reader moves
     between capabilities — a panel that jumps height reads as a glitch */
  .capstage {
    display: flex; flex-direction: column; justify-content: center;
    margin-top: 42px; padding: 36px 0 0; min-height: 186px; position: relative; overflow: hidden;
    border: 1px solid var(--line); border-radius: 18px; background: #fff; box-shadow: var(--shadow-soft);
  }
  .capstage::before {
    content: ""; position: absolute; left: 0; right: 0; top: 0; height: 36px;
    border-bottom: 1px solid var(--line-soft); background: linear-gradient(180deg, #fcfdff 0%, #f6f8fc 100%);
  }
  .capstage::after {
    content: ""; position: absolute; left: 18px; top: 14px; width: 7px; height: 7px; border-radius: 50%;
    background: #e2e6ee; box-shadow: 13px 0 0 #e2e6ee, 26px 0 0 #e2e6ee;
  }
  .capstage .fx { margin: 24px 22px; padding: 16px 18px; }
  .capstage .fx b { font-size: 15px; }
  .capstage .fx em { font-size: 13.5px; }
  .capstage .fx--thumbs i { width: 38px; height: 38px; border-radius: 9px; }
  .capstage .fx--ship .fx__bar { height: 4px; }

  .capitem__fx,
  .capitem[data-on="true"] .capitem__fx,
  html:not(.js-anim) .capitem[data-on="true"] .capitem__fx {
    display: none; max-height: 0; opacity: 0; margin-top: 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  .sd, .mstat, .mstat i, .capdot, .capitem, .capitem__fx, .proof, .callout, .sp__link { transition: none !important; }
  .hub__ring { animation: none !important; opacity: 1; transform: none; transition: none; }
  .proof::after { transform: scaleY(1); transition: none; }
  .sp__link { transform: scaleX(1); }
  .hero__field, .final__grid { display: none; }
  .callout { opacity: 1 !important; transform: none !important; }
}


/* ==========================================================================
   CANDIDATE-06 — closure of the Candidate-05 visual review findings
   HIGH-01 手机端事实序号压在标题上 · HIGH-02 手机端后台裁切信息量太低
   MEDIUM-01 能力片段太单薄 ＋ 桌面 H2 孤字 · MEDIUM-02 §02 动效兜底
   MEDIUM-03 事实文案的内部工程口吻 · MEDIUM-04 流程缺少现状语境
   LOW-01 统一区输出词结果化
   没有重新设计任何一屏。Hero 与深色收尾一个像素都没动。
   ========================================================================== */

/* --------------------------------------------------------------------------
   HIGH-01 · 事实行改用具名网格区域
   根因：`@media (max-width: 860px)` 里的 `.proof__s { grid-column: 2 }` 一直有效，
   它在只声明了一列的手机网格上开出一条**隐式第二列**，把 1fr 那列压成 0px
   （实测 grid-template-columns = "0px 350px"），于是序号和标题落进同一个视觉盒子。
   具名区域让每个子项的位置成为显式事实，隐式列不可能再出现。
   -------------------------------------------------------------------------- */
.proof { grid-template-areas: "num body status"; align-items: start; }
.proof__n    { grid-area: num; }
.proof__body { grid-area: body; }
.proof__s    { grid-area: status; grid-column: auto; }

/* --------------------------------------------------------------------------
   MEDIUM-01 · 能力片段：一个主对象 ＋ 2–3 条属性
   仍然是紧凑的一小块产品，不是六个仪表盘。
   -------------------------------------------------------------------------- */
.fx {
  display: block; margin-top: 14px; padding: 13px 15px 12px;
  border: 1px solid var(--line); border-radius: 12px; background: #fff;
}
.fx__hd { display: flex; align-items: baseline; gap: 10px; }
.fx__hd b { font-size: 14px; font-weight: 600; letter-spacing: -.012em; }
/* `.fx em` from the Candidate-04 layer is (0,1,1) and was quietly winning the
   colour, painting the status pill --ink-400 on --blue-wash: 4.37:1, a real
   contrast failure the audit caught. Matched at (0,2,0) so it cannot recur. */
.fx .fx__st {
  margin-left: auto; flex: none; font-style: normal; font-size: 10.5px; font-weight: 640;
  letter-spacing: .05em; text-transform: uppercase; color: var(--blue-strong);
  background: var(--blue-wash); border-radius: 999px; padding: 3px 9px; white-space: nowrap;
}
.fx__ln {
  display: flex; gap: 9px; margin-top: 7px; padding-top: 7px;
  border-top: 1px solid var(--line-soft); font-size: 12.5px; color: var(--ink-700);
}
.fx__ln i {
  font-style: normal; flex: none; min-width: 3.6em; color: var(--ink-400);
  font-size: 11px; letter-spacing: .04em; padding-top: 1px;
}
.fx__thumbs { display: flex; gap: 6px; margin-top: 9px; }
.fx__thumbs i {
  width: 30px; height: 30px; border-radius: 7px; flex: none;
  background: linear-gradient(135deg, #eef1f6, #e2e7f0); border: 1px solid var(--line);
}
.fx__bar { display: block; height: 4px; border-radius: 2px; background: var(--line); overflow: hidden; margin-top: 10px; }
.fx__bar i { display: block; height: 100%; width: 72%; background: var(--blue); }
.fx--ai { background: var(--blue-wash); border-color: #dde7fb; }
.fx--ai .fx__st { background: #fff; }
.fx__say { display: block; margin-top: 8px; font-size: 12.5px; line-height: 1.55; color: var(--ink-700); }
.fx--ai .fx__ln { border-top-color: #dde7fb; }

/* --------------------------------------------------------------------------
   MEDIUM-01b · 桌面 H2 声明式换行（避免 "…整个业 / 务" 的单字孤行）
   -------------------------------------------------------------------------- */
.navi__title h2 span { display: block; }
.navi__title h2 { max-width: none; }

/* --------------------------------------------------------------------------
   MEDIUM-04 · 流程的现状语境，就放在流程旁边
   一个标签 ＋ 一句限定，不写长篇免责。
   -------------------------------------------------------------------------- */
.panel__tag {
  margin-left: auto; flex: none; font-size: 11px; font-weight: 600; letter-spacing: .04em;
  color: var(--ink-500); background: var(--bg-sink); border: 1px solid var(--line);
  border-radius: 999px; padding: 4px 11px; white-space: nowrap;
}
.flownote {
  margin: 0 0 16px; padding: 9px 12px; border-radius: 10px;
  background: var(--bg-soft); border: 1px solid var(--line-soft);
  font-size: 12.5px; color: var(--ink-500);
}

/* --------------------------------------------------------------------------
   桌面：产品视窗要装得下更厚的片段
   -------------------------------------------------------------------------- */
/* desktop budget: Candidate-05 was 6568 and the cap is +1%. The richer
   fragments and the flow note cost height, so it is paid back from padding
   that was never doing work. */
.proof { padding: 32px 0; }
.croprow { margin-top: 16px; }
.statusline { margin-top: 18px; }
/* Stop the nav close-up just short of the console's own scrollbar strip
   (x 220–232 of the original) — it read as a torn edge.
   --sx must stay > 0: .crop__win has a 1px border and the image is positioned
   against the padding box, so --sx:0 puts the image edge 1px INSIDE the frame
   and leaks a hairline of white. The coverage guard caught exactly that. */
.crop--nav .crop__win { --sh: 264; --sx: 2; --sy: 80; }

@media (min-width: 1081px) {
  .capstage { min-height: 200px; }
  .dual .step { padding-bottom: 14px; }
  .flownote { margin-bottom: 13px; }
  .capstage .fx { margin: 20px; padding: 15px 17px 14px; }
  .capstage .fx__hd b { font-size: 15px; }
  .capstage .fx__ln { font-size: 13px; }
  .capstage .fx__thumbs i { width: 34px; height: 34px; }
  .capstage .fx__say { font-size: 13px; }
}

/* --------------------------------------------------------------------------
   HIGH-02 · 手机端后台三视图：换掉两个信息量低的裁切
   旧的「导航」只露出 4 个模块项，旧的「AI」几乎全是空底——真实后台右上角
   除那颗按钮外没有内容，放大它得到的就是一个空框。Ask Simbatch 的指认交给
   桌面大图上的高亮框；这里换成截图里真正有内容的三块。
   框高 214 → 300px，是为了让竖向的导航栏能以 ≈1:1 显示更多模块。
   约束：sx + 348·sh/ch ≤ 1440，sy + sh ≤ 900，否则框会滑出 PNG 露白。
   -------------------------------------------------------------------------- */
@media (max-width: 620px) {
  .cshot { --ch: 300px; }
  .cshot[data-view="nav"]  { --sx: 0;   --sy: 10;  --sh: 300; }   /* 1.00× 品牌＋首页/工作/任务/订单/商品＋内容区左缘 */
  .cshot[data-view="work"] { --sx: 246; --sy: 80;  --sh: 322; }   /* 0.93× 今日经营卡片＋业务累计 */
  .cshot[data-view="todo"] { --sx: 246; --sy: 610; --sh: 290; }   /* 1.03× 需要关注的待办卡 */
  .cmob__tab { font-size: 12.5px; padding: 0 4px; }
}

/* --------------------------------------------------------------------------
   手机端：HIGH-01 的最终版式 ＋ 本轮新增内容的长度预算
   序号列固定 34px，内容列自适应，状态另起一行——序号与标题永不同框。
   -------------------------------------------------------------------------- */
@media (max-width: 620px) {
  :root { --sect: 40px; }
  .section__head { margin-bottom: 20px; }

  .proof {
    grid-template-columns: 34px minmax(0, 1fr);
    grid-template-areas: "num body" ".   status";
    gap: 0 12px; padding: 0 0 18px;
  }
  .proof__n { font-size: 15px; padding: 0; line-height: 1.5; color: var(--ink-400); }
  .proof__t { font-size: 22px; line-height: 1.26; }
  .proof__d { font-size: 14.5px; margin-top: 9px; }
  .proof__s { padding-top: 12px; }

  .fx { margin-top: 10px; padding: 10px 12px 9px; }
  .fx__hd b { font-size: 13.5px; }
  .fx__ln { font-size: 12px; margin-top: 5px; padding-top: 5px; }
  .fx__thumbs { margin-top: 7px; }
  .fx__thumbs i { width: 26px; height: 26px; }
  .fx__say { margin-top: 6px; font-size: 12px; }

  .flownote { margin-bottom: 11px; padding: 8px 11px; font-size: 12px; }
  .panel__tag { margin-left: 0; }

  .capitem { padding: 11px 0 11px 24px; }
  .capitem__d { margin-top: 6px; }
  .signalrow { padding-top: 16px; }
  .band__inner { padding: 14px var(--gut); }
  .foot__legal { margin-top: 16px; }
  .hub { margin: 18px auto; }
  .converge__say { margin-top: 24px; }
  .step { padding: 0 0 8px 38px; }
  .cshot { margin-top: 10px; }
  .statusline { margin-top: 11px; }
  .final { padding: 58px 0 62px; }
  .foot { padding: 26px 0 26px; }
  .out { font-size: 12.5px; padding: 11px 4px; }
}


/* ==========================================================================
   CANDIDATE-07 — three exact closures, nothing else
   HIGH  §05 事实 02 的措辞回归（HTML only）
   MED-02 §02 静态兜底不得消费故事（本节 ＋ JS）
   LOW   片段字段标签在浅蓝底上的对比度
   没有布局改动、没有新动效、没有新元素。
   ========================================================================== */

/* --------------------------------------------------------------------------
   LOW · 片段字段标签（来源／下一步／读到…）
   `--ink-400 #6a7383` on `--blue-wash #f0f5ff` = 4.37:1，差 0.13 不达标。
   换成既有的更深 token `--ink-500 #5b6472`：浅蓝底 5.46:1、白底 6.02:1。
   只改颜色，字号、行高、间距、面板尺寸一律不动。
   -------------------------------------------------------------------------- */
.fx__ln i { color: var(--ink-500); }

/* --------------------------------------------------------------------------
   MEDIUM-02 · 从"已经静态可见"的状态重播故事，而不先把内容藏回去
   静态兜底把关系图放出来之后，storyPlayed 仍然是 false——机会还在。
   真正的首次遭遇到来时，stage 序列照常 1→2→3→4，但 `.is-static` 保证
   期间没有任何东西消失：连接线、中心、输出各做一次强调即可。
   §13：目标是"保留故事机会"，不是"先隐藏再重播"。
   -------------------------------------------------------------------------- */
.converge.is-static .src { opacity: 1; transform: none; }
.converge.is-static .out { opacity: 1; }
.converge.is-static .hub::before,
.converge.is-static .hub::after { transform: scaleX(1); }

.converge.is-static[data-stage="2"] .hub::before,
.converge.is-static[data-stage="3"] .hub::before,
.converge.is-static[data-stage="3"] .hub::after,
.converge.is-static[data-stage="4"] .hub::before,
.converge.is-static[data-stage="4"] .hub::after { animation: connEmph .8s ease 1; }
@keyframes connEmph { 0%, 100% { opacity: .55; } 45% { opacity: 1; } }

.converge.is-static[data-stage="4"] .out { animation: outEmph .5s cubic-bezier(.2,.7,.3,1) both; }
.converge.is-static[data-stage="4"] .out:nth-child(2) { animation-delay: .07s; }
.converge.is-static[data-stage="4"] .out:nth-child(3) { animation-delay: .14s; }
.converge.is-static[data-stage="4"] .out:nth-child(4) { animation-delay: .21s; }
.converge.is-static[data-stage="4"] .out:nth-child(5) { animation-delay: .28s; }
.converge.is-static[data-stage="4"] .out:nth-child(6) { animation-delay: .35s; }
@keyframes outEmph { 0%, 100% { transform: none; } 46% { transform: translateY(-4px); } }

@media (max-width: 620px) {
  .converge.is-static .hub::before,
  .converge.is-static .hub::after { transform: scaleY(1); }
}

@media (prefers-reduced-motion: reduce) {
  .converge.is-static .out,
  .converge.is-static .hub::before,
  .converge.is-static .hub::after { animation: none !important; }
}
