/* LivingData 官网首页（landing）
 * 视觉语言复用 designer-ui.css 的共享令牌（--designer-*）：
 * 这里的 --ld-* 只是语义别名 + 首页专属排版，不另立一套品牌色。
 * 规范见 docs/12_FRONTEND_DESIGN_LANGUAGE.md 与 docs/plans/02-landing-visual-system.md。 */

:root {
    --ld-ink: var(--designer-text);
    --ld-ink-soft: #344054;
    --ld-muted: var(--designer-muted);
    --ld-faint: #98a2b3;
    --ld-line: var(--designer-line);
    --ld-line-soft: var(--designer-line-soft);
    --ld-surface: var(--designer-surface);
    --ld-surface-soft: #f8fafc;
    --ld-brand: var(--designer-primary);
    --ld-brand-deep: #1d4ed8;
    --ld-brand-soft: var(--designer-primary-soft);
    --ld-navy: #172033;
    --ld-navy-soft: #1f2937;
    /* 页面画布底色：比内容面（--ld-surface）深一档，两侧留白成为「画布」而不是死白 */
    --ld-page: #f1f4f8;
    /* 氛围层：点阵纹理与柔光斑（纯色 + blur，不用渐变） */
    --ld-glow-a: #d7e4ff;
    --ld-glow-b: #e6ecfb;
    --ld-radius: var(--designer-radius);
    --ld-radius-sm: var(--designer-radius);
    /* 双线包边专用色。踩过三轮「不明显」，记录清楚避免第四次：
     * 第一版 --ld-line-soft(#e9edf2) / --ld-surface-soft(#f8fafc)：三条带全在「浅灰 vs 白」区间，糊成一片。
     * 第二版 #b9c3d1 / #eef2f7：外框(223,227,232) 与内线(185,195,209) 只差 38 阶且紧贴，缝隙仅深 7 阶，
     *                   观感是「一条脏边」而不是「两道线」。
     * 第三版(本版) 按用户参照图实测取值 —— 参照里字段框描边 (153,171,190)、表单卡描边 (88,106,126)，
     *                   都是有分量的深线。故外框压到 #8492a6 一档，内线 #a8b5c6，
     *                   缝隙取带一丝冷调的 #f2f5fa（而非纯白），与卡片内浅蓝底呼应。
     * 结论：**对比度来自节奏 + 分量**。只把颜色整体加深会糊；只拉开节奏但都太浅仍然轻飘。
     *   三条带两两差值需 ≥ 30 阶，且内线离外框足够远（见 ring 偏移 6px），1:1 下才读得出是两圈。 */
    --ld-ring-outer: #8492a6;
    --ld-ring-gap: #e8eef8;
    --ld-ring-inner: #a8b5c6;
    /* 暗色覆盖见下方 html[data-color-mode="dark"] 块（.ld-demo 也在此列 —— 它的
     * 双层包边画在组件**外**（向外扩散 box-shadow），见 .ld-demo 规则处注释）。 */
    /* 首屏演示卡按设计稿一比一复刻用的色（2026-09-23 实测设计稿取值）：
     * --ld-demo-edge = 外层卡的边，设计稿实测是**极浅的柔蓝** (231,238,246)（JPG 压缩把
     *                  1px 线糊成了 2-3px 软边），取同档浅蓝，不能深 —— 深了就是「框」不是「卡」。
     * --ld-photo-canvas = 照片的画布蓝，只在圆角缝隙里露出（图自带 ~4.4% 宽画布留边）。
     * （原 --ld-frame-line 照片深色框线已于第七轮移除，见 .ld-demo__photo 注释。） */
    --ld-demo-edge: #dfe8f4;
    --ld-photo-canvas: #e6effa;
    --ld-shadow: 0 1px 3px rgba(16, 24, 40, .05);
    --ld-shadow-lg: 0 8px 24px rgba(16, 24, 40, .08);
    /* 演示卡「凸出来」用的真实投影（包边之外的两层浮起阴影）+ 顶部高光唇线，
     * 这两层是卡片浮起感的主杠杆，深浅都走主题令牌。 */
    --ld-demo-elevate: 0 16px 32px -8px rgba(16, 24, 40, .20), 0 36px 68px -16px rgba(16, 24, 40, .26);
    --ld-demo-sheen: inset 0 1px 0 rgba(255, 255, 255, .9);
    /* 首屏演示卡的外部装饰（2026-10-16 追加，用户反馈「红框区域不够精致」）。
     * 这套体系明令「纯色块 + 细描边，不用渐变」（见本文件 .ld-demo 段首），所以这里
     * 也**不引入任何渐变**：底光 = 纯色圆 + blur（与 .ld-ambient 同一手法），
     * 唇线 = 纯色实线，卡外胶囊 = 白底 + 细边（与 .ld-eyebrow 同源）。
     * 第二轮（同日）用户复述「装饰需要明显点」—— 第一版全部取值偏保守，观感上几乎
     * 只是「卡边稍微讲究了一点」。本轮统一按**能一眼看到**重新取值：底光半径/不透明
     * 度、包边带宽度与色深、唇线粗细、胶囊尺寸与用色、卡外点阵块，全部上调一档。 */
    --ld-halo: rgba(37, 99, 235, .34);          /* 卡外品牌底光（纯色圆，靠 blur 化开） */
    --ld-halo-2: rgba(96, 165, 250, .22);        /* 副光：右下角错位一枚，两团光叠加更有体积 */
    --ld-demo-lift: 0 34px 76px -22px rgba(37, 99, 235, .55);   /* 投影里叠的一层品牌色柔光 */
    /* 演示卡专属的加强包边（不复用 --ld-ring-*：那套还挂在能力卡/场景卡上，
     * 一起加深会把整页都变重）。带子拉到 12px，且三条带都带明确蓝调。 */
    --ld-demo-ring-outer: #4f6787;
    --ld-demo-ring-band: #d3e2fa;
    --ld-demo-ring-inner: #7d9cc6;
    --ld-chip-bg: #ffffff;                       /* 卡外悬浮胶囊底 */
    --ld-chip-line: rgba(29, 78, 216, .52);
    --ld-chip-halo: 0 0 0 5px rgba(37, 99, 235, .12);   /* 胶囊外圈淡品牌光晕 */
    --ld-demo-dot: rgba(37, 99, 235, .42);       /* 卡外点阵装饰块的点色 */
    --ld-container: 1180px;
    /* 次级文字（正文说明、卡片描述）在浅色底上的对比度 */
    --ld-body-text: #344054;
}

/* 主题色沿用工作台的 data-system-color（取值与 jinshuju-ui.css 的 --wb-* 保持一致） */
html[data-system-color="green"] .ld { --ld-brand: #047857; --ld-brand-deep: #036349; --ld-brand-soft: #ecfdf5; }
html[data-system-color="red"] .ld { --ld-brand: #b42318; --ld-brand-deep: #912018; --ld-brand-soft: #fef3f2; }
html[data-system-color="gray"] .ld { --ld-brand: #344054; --ld-brand-deep: #1d2939; --ld-brand-soft: #f2f4f7; }

/* 暗色模式沿用 theme-init 的 html[data-color-mode="dark"]，不新造开关 */
html[data-color-mode="dark"] body.ld-body { background: #0f141b; color: #cbd5e1; }
html[data-color-mode="dark"] .ld {
    --ld-ink: #f2f4f7;
    --ld-ink-soft: #d0d5dd;
    --ld-muted: #98a2b3;
    --ld-faint: #667085;
    --ld-line: #2b3444;
    --ld-line-soft: #222b38;
    --ld-surface: #161d27;
    --ld-surface-soft: #1b2230;
    --ld-navy: #0f141b;
    --ld-navy-soft: #161d27;
    --ld-page: #0b1017;
    --ld-dot: rgba(226, 232, 240, .07);
    --ld-glow-a: #16263f;
    --ld-glow-b: #131c2b;
    --ld-body-text: #d0d5dd;
    --ld-shadow: 0 1px 2px rgba(0, 0, 0, .35);
    --ld-shadow-lg: 0 12px 34px rgba(0, 0, 0, .5);
    --ld-demo-elevate: 0 18px 36px -8px rgba(0, 0, 0, .60), 0 38px 72px -16px rgba(0, 0, 0, .68);
    --ld-demo-sheen: inset 0 1px 0 rgba(255, 255, 255, .07);
    /* 演示卡外部装饰的暗色档：底光换成更亮的蓝，投影里的品牌光在深底上会脏，改回中性黑 */
    --ld-halo: rgba(56, 132, 255, .40);
    --ld-halo-2: rgba(56, 132, 255, .24);
    --ld-demo-lift: 0 34px 76px -22px rgba(0, 0, 0, .70);
    --ld-demo-ring-outer: #7f9cc4;
    --ld-demo-ring-band: #1d2837;
    --ld-demo-ring-inner: #3d567c;
    --ld-chip-bg: #1b2230;
    --ld-chip-line: #5b83bd;
    --ld-chip-halo: 0 0 0 5px rgba(56, 132, 255, .18);
    --ld-demo-dot: rgba(122, 172, 255, .48);
}
html[data-color-mode="dark"][data-system-color="green"] .ld { --ld-brand: #34d399; --ld-brand-deep: #6ee7b7; --ld-brand-soft: #12261f; }
html[data-color-mode="dark"][data-system-color="red"] .ld { --ld-brand: #f97066; --ld-brand-deep: #fda29b; --ld-brand-soft: #2c1614; }
html[data-color-mode="dark"][data-system-color="gray"] .ld { --ld-brand: #d0d5dd; --ld-brand-deep: #e4e7ec; --ld-brand-soft: #1d2939; }

html {
    scroll-behavior: smooth;
    -webkit-text-size-adjust: 100%;
}

body.ld-body {
    margin: 0;
    background: var(--ld-page);
    color: var(--ld-ink-soft);
    font-family: "PingFang SC", "Microsoft YaHei", "Segoe UI", system-ui, -apple-system, "Helvetica Neue", Arial, sans-serif;
    font-size: 15px;
    line-height: 1.75;
    letter-spacing: .01em;
}

.ld *,
.ld *::before,
.ld *::after { box-sizing: border-box; }

/* ⚠️ 必须用 :where() 把特异性降到 0。
 * 若写成 `.ld p`（特异性 0,1,1），会压过 `.ld-hero__lead`(0,1,0) 这类组件类规则，
 * 组件里写好的 margin-top / padding-top 会被静默清零 —— 2026-09-22 实测踩到：
 * Hero 标题与副标题贴死(0px)、CTA 按钮与要点列表贴死(0px)、列表分隔线上移。
 * :where() 仍能覆盖浏览器默认样式，但不会再盖住组件类规则。 */
:where(.ld) :where(h1, h2, h3, h4, p, ul, ol, dl, figure) { margin: 0; }
:where(.ld) :where(ul, ol) { padding: 0; list-style: none; }
.ld img { max-width: 100%; display: block; }
/* 只作用于普通链接：按钮的文字色由 .ld-btn--* 决定，不能被这里覆盖 */
.ld a:not(.ld-btn) { color: inherit; text-decoration: none; }
.ld svg { display: block; }

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

.ld-skip {
    position: absolute;
    left: -9999px;
    top: 0;
    z-index: 100;
    padding: 10px 16px;
    background: var(--ld-brand);
    color: #fff;
    border-radius: 0 0 var(--ld-radius-sm) 0;
}
.ld-skip:focus { left: 0; }

.ld-container {
    width: 100%;
    max-width: var(--ld-container);
    margin: 0 auto;
    padding: 0 24px;
}

/* 大屏别让内容缩在中间一条：随视口分档放宽，两侧留白收窄 */
@media (min-width: 1440px) {
    :root { --ld-container: 1240px; }
}
@media (min-width: 1680px) {
    :root { --ld-container: 1320px; }
}

/* ---------- 氛围层：填充两侧留白 + 缓慢漂浮 ----------
 * 固定在视口、压在内容之下（z-index: -1）。中间的白色版块会把它盖住，
 * 于是只有两侧留白与 hero 区能看到纹理与柔光——空白不再是一片死白。 */
.ld { position: relative; isolation: isolate; }

.ld-ambient {
    position: fixed;
    inset: 0;
    z-index: -1;
    pointer-events: none;
    overflow: hidden;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='26' height='26'%3E%3Ccircle cx='2' cy='2' r='1.4' fill='%230f172a' fill-opacity='.075'/%3E%3C/svg%3E");
    background-repeat: repeat;
    background-size: 26px 26px;
}
html[data-color-mode="dark"] .ld-ambient {
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='26' height='26'%3E%3Ccircle cx='2' cy='2' r='1.4' fill='%23e2e8f0' fill-opacity='.07'/%3E%3C/svg%3E");
}

.ld-ambient::before,
.ld-ambient::after {
    content: "";
    position: absolute;
    border-radius: 50%;
    filter: blur(64px);
    will-change: transform;
}
.ld-ambient::before {
    width: 460px;
    height: 460px;
    left: -140px;
    top: 6%;
    background: var(--ld-glow-a);
    animation: ld-drift-a 28s ease-in-out infinite alternate;
}
.ld-ambient::after {
    width: 380px;
    height: 380px;
    right: -120px;
    top: 36%;
    background: var(--ld-glow-b);
    animation: ld-drift-b 34s ease-in-out infinite alternate;
}

@keyframes ld-drift-a {
    0%   { transform: translate3d(0, 0, 0) scale(1); }
    50%  { transform: translate3d(48px, -72px, 0) scale(1.08); }
    100% { transform: translate3d(-24px, 56px, 0) scale(.96); }
}
@keyframes ld-drift-b {
    0%   { transform: translate3d(0, 0, 0) scale(1); }
    50%  { transform: translate3d(-56px, 64px, 0) scale(1.06); }
    100% { transform: translate3d(32px, -48px, 0) scale(.98); }
}

/* 首屏产品预览的悬浮感。
 * 幅度从 9px 提到 22px、周期 9s→7.2s：原来几乎看不出来，现在一眼能感到"浮"。
 * 同时叠加轻微的旋转与缩放，避免纯平移显得呆板。 */
@keyframes ld-float-y {
    0%, 100% { transform: translate3d(0, 0, 0) rotate(0deg) scale(1); }
    28%      { transform: translate3d(0, -22px, 0) rotate(-.55deg) scale(1.012); }
    62%      { transform: translate3d(0, 9px, 0) rotate(.42deg) scale(.994); }
}

/* 徽标的独立漂浮：与主卡片反相，制造层次（卡片上升时徽标下沉一点） */
@keyframes ld-float-badge {
    0%, 100% { transform: translate3d(0, 0, 0); }
    50%      { transform: translate3d(0, 14px, 0); }
}

/* 状态点呼吸：暗示「实时处理中」 */
@keyframes ld-pulse-dot {
    0%, 100% { box-shadow: 0 0 0 3px rgba(22, 163, 74, .20); }
    50%      { box-shadow: 0 0 0 8px rgba(22, 163, 74, .04); }
}

/* ---------- 按钮 ---------- */
.ld-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 8px;
    min-height: 40px;
    padding: 0 16px;
    border: 1px solid transparent;
    border-radius: var(--ld-radius);
    font-size: 14px;
    font-weight: 600;
    line-height: 1;
    cursor: pointer;
    transition: background-color .18s ease, color .18s ease, border-color .18s ease;
}
.ld-btn svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
.ld-btn--primary { background: var(--ld-brand); color: #fff; }
.ld-btn--primary:hover { background: var(--ld-brand-deep); color: #fff; }
/* 次按钮：沿用 designer-ui.css 的 .btn 色板，不使用白色底 */
.ld-btn--ghost { background: #eef1f4; border-color: #cbd5e1; color: #344054; }
.ld-btn--ghost:hover { background: var(--ld-brand-soft); border-color: #93c5fd; color: var(--ld-brand-deep); }
/* 深色区主按钮：品牌浅底 + 品牌深字，避免白底按钮 */
.ld-btn--solid-light { background: var(--ld-brand-soft); border-color: transparent; color: var(--ld-brand-deep); }
.ld-btn--solid-light:hover { background: #dbeafe; color: var(--ld-brand-deep); }
/* 深色区次按钮：半透明白，不是白底 */
.ld-btn--light { background: rgba(255, 255, 255, .12); border-color: rgba(255, 255, 255, .4); color: #fff; }
.ld-btn--light:hover { background: rgba(255, 255, 255, .2); color: #fff; }
.ld-btn--sm { min-height: 34px; padding: 0 12px; font-size: 13px; }
html[data-color-mode="dark"] .ld-btn--ghost { background: #1d2939; border-color: #344054; color: #d0d5dd; }
html[data-color-mode="dark"] .ld-btn--ghost:hover { background: #26303f; border-color: #475467; color: #fff; }
html[data-color-mode="dark"] .ld-btn--solid-light:hover { background: var(--ld-brand); color: #fff; }

/* ---------- 导航 ---------- */
.ld-nav {
    position: sticky;
    top: 0;
    z-index: 60;
    background: var(--ld-surface);
    border-bottom: 1px solid transparent;
    transition: border-color .2s ease;
}
.ld-nav.is-stuck { border-bottom-color: var(--ld-line); }
.ld-nav__inner {
    display: flex;
    align-items: center;
    gap: 24px;
    height: 64px;
}
.ld-brand {
    display: inline-flex;
    align-items: center;
    gap: 10px;
    font-size: 17px;
    font-weight: 700;
    color: var(--ld-ink);
}
.ld-brand img { width: 28px; height: 28px; object-fit: contain; }
.ld-brand__tagline {
    padding-left: 12px;
    margin-left: 2px;
    border-left: 1px solid var(--ld-line);
    color: var(--ld-faint);
    font-size: 12px;
    font-weight: 500;
    line-height: 1.3;
}
.ld-nav__menu {
    display: flex;
    align-items: center;
    gap: 4px;
    margin-left: auto;
}
.ld-nav__menu a {
    padding: 9px 14px;
    border-radius: var(--ld-radius-sm);
    color: var(--ld-ink-soft);
    font-size: 15px;
    font-weight: 500;
    transition: color .16s ease, background-color .16s ease;
}
.ld-nav__menu a:hover { color: var(--ld-brand); background: var(--ld-brand-soft); }
.ld-nav__actions {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-left: 8px;
    padding-left: 18px;
    border-left: 1px solid var(--ld-line);
}
.ld-nav__toggle {
    display: none;
    width: 42px;
    height: 42px;
    margin-left: auto;
    padding: 0;
    border: 1px solid var(--ld-line);
    border-radius: var(--ld-radius-sm);
    background: #fff;
    cursor: pointer;
}
.ld-nav__toggle span {
    display: block;
    width: 18px;
    height: 1.6px;
    margin: 3.5px auto;
    background: var(--ld-ink);
    transition: transform .2s ease, opacity .2s ease;
}
.ld-nav__toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(5px) rotate(45deg); }
.ld-nav__toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.ld-nav__toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-5px) rotate(-45deg); }
.ld-nav__drawer {
    display: none;
    border-top: 1px solid var(--ld-line);
    background: var(--ld-surface);
}
.ld-nav__drawer a {
    display: block;
    padding: 13px 0;
    border-bottom: 1px solid var(--ld-line-soft);
    color: var(--ld-ink);
    font-size: 15px;
    font-weight: 500;
}
.ld-nav__drawer .ld-nav__drawer-actions { display: flex; gap: 10px; padding: 18px 0 22px; }
.ld-nav__drawer .ld-nav__drawer-actions .ld-btn { flex: 1; }

/* ---------- 主视觉 ---------- */
.ld-hero {
    position: relative;
    overflow: hidden;
    /* 拉长首屏：min-height 撑高度 + 适量上下留白。
     * 注意 padding 不能过大：min-height 已经负责"占满一屏"，
     * 再叠 108/128 的 padding 会让内容被挤在中段、上下留大片死白。
     * 这里 padding 收到 72/88，把"拉长"的职责完全交给 min-height。
     * 同时给浮动动画留出足够位移余量（否则大幅浮会被裁切）。 */
    display: flex;
    align-items: center;
    min-height: clamp(600px, 88vh, 940px);
    padding: 72px 0 88px;
    /* 不再铺白：露出页面画布与氛围层，首屏才有纵深（两侧留白也被纹理填上） */
    background: transparent;
    border-bottom: 1px solid var(--ld-line-soft);
}
.ld-hero__inner {
    position: relative;
    width: 100%;
    display: grid;
    /* 右列比左列宽：演示卡里是一张真实表单照片，只有拿到足够宽度，纸面上的字才不会缩到看不清。
     * gap 同步从 72 收到 56，把空间让给右列而不是留在中间当空白。 */
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.1fr);
    gap: 56px;
    align-items: center;
}
/* 左栏文案：内容比右侧预览卡矮，居中会显"飘"。让它在自身高度内
 * 舒展开、并在视觉上与右侧卡片中轴对齐即可 —— 用 padding 微调而非拉伸。 */
.ld-hero__copy { padding: 6px 0; }
.ld-eyebrow {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 26px;
    padding: 5px 12px;
    border: 1px solid rgba(29, 78, 216, .2);
    border-radius: var(--ld-radius);
    background: rgba(255, 255, 255, .8);
    color: var(--ld-brand);
    font-size: 13px;
    font-weight: 600;
    letter-spacing: .02em;
}
.ld-eyebrow::before {
    content: "";
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--ld-brand);
}
.ld-hero__title {
    color: var(--ld-ink);
    /* 字号下调（44→38 上限）并放宽行高：两行标题原本像一块实心色块，
     * 压得下面的副标题没有呼吸空间。降低字号 + 拉开行距后分层立刻清晰。 */
    font-size: clamp(28px, 3.3vw, 38px);
    font-weight: 700;
    line-height: 1.32;
    letter-spacing: -.01em;
}
.ld-hero__title span { display: block; }
.ld-hero__title em {
    font-style: normal;
    color: var(--ld-brand);
}
.ld-hero__lead {
    /* 放宽到 620px：560px 在 1280 视口下会折成 4 行，是本区最刺眼的密度来源。
     * 620px 后稳定 2~3 行，既保留可读行长又不堆叠。 */
    max-width: 620px;
    margin-top: 26px;
    color: var(--ld-body-text);
    font-size: 16px;
    line-height: 1.85;
}
.ld-hero__actions {
    display: flex;
    flex-wrap: wrap;
    gap: 14px;
    /* 块间距 30→38：文案块之间需要有明显的"段"感，而不是连续一坨 */
    margin-top: 38px;
}
/* 首屏 CTA 加高：40px 在这套留白里显得单薄，46px 才有"主行动点"的份量 */
.ld-hero__actions .ld-btn { min-height: 46px; padding: 0 22px; font-size: 15px; }
.ld-hero__points {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 14px 28px;
    margin-top: 38px;
    padding-top: 28px;
    border-top: 1px solid var(--ld-line-soft);
}
.ld-hero__points li {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    color: var(--ld-ink-soft);
    font-size: 14px;
    font-weight: 500;
    line-height: 1.5;
}
.ld-hero__points svg {
    flex: none;
    width: 16px;
    height: 16px;
    margin-top: 3px;
    fill: none;
    stroke: var(--ld-brand);
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
}

/* 主视觉右侧：工作台界面示意（纯 CSS 模拟，不依赖截图） */
.ld-mock {
    position: relative;
    z-index: 1;
    border: 1px solid var(--ld-line);
    border-radius: 14px;
    background: #fff;
    box-shadow: var(--ld-shadow-lg);
    overflow: hidden;
    /* 明显上下浮动 + 轻微俯仰：7.2s / 22px 振幅（原 9s / 9px 几乎看不出）。
     * prefers-reduced-motion 下由文件末尾的规则自动停止。 */
    animation: ld-float-y 7.2s ease-in-out infinite;
    transform-origin: 50% 62%;
    will-change: transform;
}
/* 悬浮时的柔光随动画一起呼吸，强化"浮起来"的观感 */
.ld-hero__visual::after {
    content: "";
    position: absolute;
    left: 8%;
    right: 8%;
    bottom: -26px;
    height: 56px;
    border-radius: 50%;
    background: radial-gradient(closest-side, rgba(15, 23, 42, .18), transparent 72%);
    filter: blur(12px);
    /* 演示卡不再上下浮动，柔光也跟着静止：否则没有位移的卡片会显得在「呼吸」 */
    pointer-events: none;
    z-index: -1;
}
@keyframes ld-shadow-breathe {
    0%, 100% { opacity: .40; transform: scale(.94); }
    28%      { opacity: .16; transform: scale(.80); }
    62%      { opacity: .52; transform: scale(1.02); }
}
.ld-hero__visual {
    position: relative;
    /* 自己开一个层叠上下文：卡外底光（::before）与底部阴影（::after）只在组件内比高低，
     * 不与页面其它板块的 z-index 相互干扰 */
    isolation: isolate;
}
/* 卡外品牌底光（2026-10-16 追加）：原来卡片四周是一整片空白，白卡像"平贴"在页面上。
 * 用一枚比卡大一圈的**纯色圆** + blur 压在最底层，卡片立刻有了"浮在光上"的空气感。
 * 手法刻意与 .ld-ambient 的柔光斑一致（纯色 + blur，不铺渐变）。
 * 第二轮（同日）用户要求"装饰明显点"：第一版只扩 6%/4% + 17% 不透明度，1280 下基本
 * 看不出来。现在扩到 12%/14%、不透明度翻倍，并把主光往左上错开一点，避免与卡片
 * 完全同心（同心圆看起来只是一个"衬底"，错位后才像"卡下面透出来的光"）。 */
.ld-hero__visual::before {
    content: "";
    position: absolute;
    z-index: 0;
    inset: -12% -14% -14% -10%;
    border-radius: 50%;
    background: var(--ld-halo);
    filter: blur(84px);
    pointer-events: none;
}
/* 副光：右下角再压一枚更小的错位光斑（--ld-halo-2），两团光叠出体积，
 * 卡片的右下角不会像只有单光源那样"半边亮半边死"。同样 z-index:0，藏在卡下面。 */
.ld-demo-glow {
    position: absolute;
    z-index: 0;
    right: -14%;
    bottom: -12%;
    width: 62%;
    height: 58%;
    border-radius: 50%;
    background: var(--ld-halo-2);
    filter: blur(72px);
    pointer-events: none;
}

/* 卡外点阵装饰带（2026-10-16 第二轮追加）：两条贴在卡外的窄点阵条 ——
 * 横条浮在卡片右上方，竖条贴在卡片左下方。它们完全在卡**外**（内侧那几 px 被
 * z-index 更高的卡片盖住，只露出外侧），读作"刻度 / 网格"，与页面全局点阵底纹同源，
 * 也让卡四周的留白有了内容。点用 radial-gradient 硬边圆点实现（不是色带渐变，
 * 1.6px 的实心点 + 1px 硬过渡），颜色走 --ld-demo-dot，随主题自动换档。 */
.ld-demo-dots {
    position: absolute;
    z-index: 0;
    pointer-events: none;
    background-image: radial-gradient(circle, var(--ld-demo-dot) 1.6px, transparent 1.8px);
    background-size: 11px 11px;
    background-position: 0 0;
}
.ld-demo-dots--top { top: -46px; right: 14px; width: 132px; height: 34px; }
.ld-demo-dots--left { bottom: 40px; left: -44px; width: 36px; height: 132px; }


.ld-mock__chrome {
    display: flex;
    align-items: center;
    gap: 7px;
    padding: 12px 16px;
    border-bottom: 1px solid var(--ld-line-soft);
    background: #fbfcfe;
}
.ld-mock__chrome i {
    width: 9px;
    height: 9px;
    border-radius: 50%;
    background: #d8e0ee;
}
.ld-mock__chrome i:first-child { background: #f0b4b4; }
.ld-mock__chrome i:nth-child(2) { background: #f2d6a2; }
.ld-mock__chrome em {
    margin-left: auto;
    font-style: normal;
    color: var(--ld-faint);
    font-size: 12px;
    letter-spacing: .04em;
}
.ld-mock__body { display: grid; grid-template-columns: 132px minmax(0, 1fr); }
.ld-mock__side {
    padding: 16px 12px;
    border-right: 1px solid var(--ld-line-soft);
    background: #fcfdff;
}
.ld-mock__side i {
    display: block;
    height: 9px;
    margin-bottom: 12px;
    border-radius: 4px;
    background: #e7ecf6;
}
.ld-mock__side i:nth-child(2) { width: 78%; }
.ld-mock__side i:nth-child(3) { width: 62%; }
.ld-mock__side i:nth-child(4) { width: 70%; }
.ld-mock__side i.is-active { background: var(--ld-brand); width: 84%; }
.ld-mock__main { padding: 16px; }
.ld-mock__toolbar {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 14px;
}
.ld-mock__toolbar span {
    height: 22px;
    border-radius: 5px;
    background: #f1f4fa;
}
.ld-mock__toolbar span:nth-child(1) { width: 96px; }
.ld-mock__toolbar span:nth-child(2) { width: 58px; }
.ld-mock__toolbar span:nth-child(3) { width: 42px; margin-left: auto; background: var(--ld-brand-soft); }
.ld-mock__table { border: 1px solid var(--ld-line-soft); border-radius: 10px; overflow: hidden; }
.ld-mock__row {
    display: grid;
    grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr) minmax(0, .9fr);
    gap: 10px;
    align-items: center;
    padding: 11px 12px;
    border-top: 1px solid var(--ld-line-soft);
    font-size: 12px;
    color: var(--ld-muted);
}
.ld-mock__row:first-child { border-top: 0; background: #fafbfe; color: var(--ld-faint); font-size: 11px; letter-spacing: .06em; }
.ld-mock__row b { color: var(--ld-ink); font-weight: 600; }
.ld-tag {
    display: inline-flex;
    align-items: center;
    padding: 2px 9px;
    border-radius: 999px;
    font-size: 11px;
    font-weight: 600;
    line-height: 1.7;
}
.ld-tag--ok { background: #e7f6ee; color: #157347; }
.ld-tag--warn { background: #fff3e0; color: #b26a00; }
.ld-tag--idle { background: #eef1f7; color: #6b7789; }
.ld-mock__badge {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: -1px 0 0;
    padding: 11px 16px;
    border-top: 1px solid var(--ld-line-soft);
    background: #f7fafd;
    color: var(--ld-ink);
    font-size: 12px;
    font-weight: 600;
}
.ld-mock__badge::before {
    content: "";
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: #16a34a;
    box-shadow: 0 0 0 4px rgba(22, 163, 74, .16);
    animation: ld-pulse-dot 2.6s ease-in-out infinite;
}

/* ---------- 通用分节 ---------- */
/* 默认分节铺白，与页面画布形成层次——两侧留白因此变成有内容的画布 */
.ld-section { padding: 72px 0; background: var(--ld-surface); }
.ld-section--soft { background: #e9eef5; border-block: 1px solid var(--ld-line-soft); }
html[data-color-mode="dark"] .ld-section--soft { background: #131a26; }
.ld-section--navy {
    background: linear-gradient(160deg, var(--ld-navy) 0%, var(--ld-navy-soft) 100%);
    color: #dfe6f5;
}
.ld-section__head { max-width: 720px; margin-bottom: 40px; }
.ld-section__head--center { margin-inline: auto; text-align: center; }
.ld-kicker {
    display: block;
    margin-bottom: 12px;
    color: var(--ld-brand);
    font-size: 12px;
    font-weight: 700;
    letter-spacing: .14em;
    text-transform: uppercase;
}
.ld-section--navy .ld-kicker { color: #7fb0ff; }
.ld-title {
    color: var(--ld-ink);
    font-size: clamp(24px, 2.7vw, 34px);
    font-weight: 700;
    line-height: 1.32;
}
.ld-section--navy .ld-title { color: #fff; }
.ld-lead { margin-top: 14px; color: var(--ld-body-text); font-size: 15px; line-height: 1.75; }
.ld-section--navy .ld-lead { color: #c5d1e8; }
.ld-section--navy .ld-secure__item p { color: #a9b7d0; }

/* ---------- 核心能力 ---------- */
.ld-grid { display: grid; gap: 20px; }
.ld-grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.ld-grid--2 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
/* 卡片的「双线包边」：外框是 1px 深线，内侧再收一道 2px 细线（inset ring）。
 * 外框与内线之间留 6px 近纯白缝隙，视觉上等价于「纸张裱了一层卡纸」。
 * 实现要点：
 *  1) 用 box-shadow inset 画内线而不是 ::before 绝对定位 —— 卡片内容不参与定位，
 *     内线不会盖住任何文字，也不必给子元素补 position/z-index。
 *  2) 内线宽度用 2px 而不是 1px：1px 在 0.59 倍缩放的窗口/截图中会被重采样糊掉，
 *     2px 能在非 100% 缩放下活下来。偏移 6px = 2px 内线 + 4px 缝隙。
 *  3) 内容边距由 padding 撑开：原 25px 里已有 6px 给了 ring（原为 4px），
 *     故 padding 同步 +2px 保持文字位置不变（25→27 / 27→29）。
 *  4) transform 参与 hover 位移，ring 是 box-shadow 会跟着一起动，不会错位。
 *  5) ⚠️ 三色必须走 CSS 变量，不能把颜色写死在 box-shadow 里。
 *     否则暗色模式只能覆盖变量、覆盖不掉 box-shadow 里的字面量浅色，深底上会亮着一圈浅线。
 *     实测踩过：`html[data-color-mode="dark"] .ld-card` 特异性更高但只换了 gap，内线仍是字面量浅色。 */
.ld-card {
    padding: 27px 27px 29px;
    border: 1px solid var(--ld-ring-outer);
    border-radius: var(--ld-radius);
    background: #fff;
    box-shadow: inset 0 0 0 2px var(--ld-ring-inner), inset 0 0 0 6px var(--ld-ring-gap);
    transition: border-color .2s ease, box-shadow .2s ease, transform .2s ease;
}
.ld-card:hover {
    border-color: #8fa6d4;
    box-shadow: inset 0 0 0 2px #a9bde0, inset 0 0 0 6px var(--ld-brand-soft), var(--ld-shadow);
    transform: translateY(-2px);
}
.ld-card__icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 40px;
    height: 40px;
    margin-bottom: 16px;
    border-radius: var(--ld-radius);
    background: var(--ld-brand-soft);
}
.ld-card__icon svg {
    width: 20px;
    height: 20px;
    fill: none;
    stroke: var(--ld-brand);
    stroke-width: 1.7;
    stroke-linecap: round;
    stroke-linejoin: round;
}
.ld-card__title { margin-bottom: 8px; color: var(--ld-ink); font-size: 17px; font-weight: 650; }
.ld-card__text { color: var(--ld-body-text); font-size: 14px; line-height: 1.7; }
.ld-card__list { margin-top: 14px; padding-top: 12px; border-top: 1px dashed var(--ld-line); }
.ld-card__list li {
    position: relative;
    padding-left: 14px;
    color: var(--ld-ink-soft);
    font-size: 13px;
    line-height: 1.8;
}
.ld-card__list li::before {
    content: "";
    position: absolute;
    left: 2px;
    top: 10px;
    width: 4px;
    height: 4px;
    border-radius: 50%;
    background: var(--ld-brand);
}

/* ---------- 工作流程 ---------- */
.ld-steps {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 0;
    counter-reset: ld-step;
}
.ld-step {
    position: relative;
    padding: 0 22px;
    counter-increment: ld-step;
}
.ld-step::before {
    content: "";
    position: absolute;
    top: 19px;
    left: 0;
    right: 0;
    height: 1px;
    background: repeating-linear-gradient(to right, #cfd9ea 0 6px, transparent 6px 12px);
}
.ld-step:first-child::before { left: 22px; }
.ld-step:last-child::before { right: calc(100% - 22px - 38px); }
.ld-step__no {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 38px;
    height: 38px;
    margin-bottom: 16px;
    border: 1px solid var(--ld-line);
    border-radius: 50%;
    background: #fff;
    color: var(--ld-brand);
    font-size: 14px;
    font-weight: 700;
}
.ld-step__no::before { content: "0" counter(ld-step); }
.ld-step__title { margin-bottom: 6px; color: var(--ld-ink); font-size: 16px; font-weight: 650; }
.ld-step__text { color: var(--ld-body-text); font-size: 14px; line-height: 1.7; }

/* ---------- 应用场景 ---------- */
/* 场景卡与能力卡同格网同层级，一并使用双线包边，避免同页出现两种卡片描边 */
.ld-scenario {
    display: flex;
    flex-direction: column;
    padding: 29px 27px;
    border: 1px solid var(--ld-ring-outer);
    border-radius: var(--ld-radius);
    background: #fff;
    box-shadow: inset 0 0 0 2px var(--ld-ring-inner), inset 0 0 0 6px var(--ld-ring-gap);
    height: 100%;
}
.ld-scenario__head { display: flex; align-items: center; gap: 10px; margin-bottom: 12px; }
.ld-scenario__head svg {
    width: 18px;
    height: 18px;
    fill: none;
    stroke: var(--ld-brand);
    stroke-width: 1.7;
    stroke-linecap: round;
    stroke-linejoin: round;
}
.ld-scenario__head h3 { color: var(--ld-ink); font-size: 16px; font-weight: 650; }
.ld-scenario p { color: var(--ld-body-text); font-size: 14px; line-height: 1.7; }
.ld-scenario ul { margin-top: auto; padding-top: 16px; }
.ld-scenario ul li {
    padding: 6px 0;
    border-top: 1px solid var(--ld-line-soft);
    color: var(--ld-ink-soft);
    font-size: 13px;
    line-height: 1.6;
}
.ld-scenario ul li:first-child { border-top: 0; }

/* ---------- 安全合规 ---------- */
.ld-secure {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 1px;
    margin-top: 8px;
    border: 1px solid rgba(255, 255, 255, .12);
    border-radius: var(--ld-radius);
    background: rgba(255, 255, 255, .12);
    overflow: hidden;
}
.ld-secure__item {
    padding: 24px 22px;
    background: rgba(9, 18, 36, .92);
}
.ld-secure__item h3 {
    display: flex;
    align-items: center;
    gap: 9px;
    margin-bottom: 8px;
    color: #fff;
    font-size: 15px;
    font-weight: 650;
}
.ld-secure__item h3 svg {
    flex: none;
    width: 17px;
    height: 17px;
    fill: none;
    stroke: #7fb0ff;
    stroke-width: 1.8;
    stroke-linecap: round;
    stroke-linejoin: round;
}
.ld-secure__item p { color: #c3cfe6; font-size: 14px; line-height: 1.7; }
.ld-section--navy .ld-extra {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-top: 26px;
}
.ld-pill {
    padding: 6px 12px;
    border: 1px solid rgba(255, 255, 255, .18);
    border-radius: var(--ld-radius);
    background: rgba(255, 255, 255, .05);
    color: #cbd7ee;
    font-size: 13px;
}

/* ---------- 服务方案 ---------- */
.ld-plans { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 20px; align-items: start; }
.ld-plan {
    display: flex;
    flex-direction: column;
    padding: 28px 24px;
    border: 1px solid var(--ld-line);
    border-radius: var(--ld-radius);
    background: #fff;
}
.ld-plan.is-featured {
    border-color: var(--ld-brand);
    box-shadow: var(--ld-shadow);
    position: relative;
}
.ld-plan__flag {
    position: absolute;
    top: -11px;
    left: 24px;
    padding: 3px 10px;
    border-radius: var(--ld-radius);
    background: var(--ld-brand);
    color: #fff;
    font-size: 12px;
    font-weight: 600;
}
.ld-plan__name { color: var(--ld-ink); font-size: 17px; font-weight: 650; }
.ld-plan__for { margin-top: 4px; color: var(--ld-faint); font-size: 13px; }
.ld-plan__price {
    display: flex;
    align-items: baseline;
    gap: 6px;
    margin: 16px 0 6px;
    color: var(--ld-ink);
    font-size: 26px;
    font-weight: 700;
}
.ld-plan__price small { color: var(--ld-faint); font-size: 13px; font-weight: 500; }
.ld-plan__note { color: var(--ld-body-text); font-size: 13px; line-height: 1.7; }
.ld-plan__features { margin: 20px 0 24px; }
.ld-plan__features li {
    display: flex;
    align-items: flex-start;
    gap: 9px;
    padding: 6px 0;
    color: var(--ld-ink-soft);
    font-size: 14px;
    line-height: 1.6;
}
.ld-plan__features svg {
    flex: none;
    width: 16px;
    height: 16px;
    margin-top: 4px;
    fill: none;
    stroke: var(--ld-brand);
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
}
.ld-plan .ld-btn { margin-top: auto; }

/* ---------- 常见问题 ---------- */
.ld-faq { max-width: 860px; margin: 0 auto; }
.ld-faq__item {
    border: 1px solid var(--ld-line);
    border-radius: var(--ld-radius-sm);
    background: #fff;
    overflow: hidden;
}
.ld-faq__item + .ld-faq__item { margin-top: 12px; }
.ld-faq__item summary {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    padding: 16px 20px;
    cursor: pointer;
    color: var(--ld-ink);
    font-size: 15px;
    font-weight: 600;
    list-style: none;
}
.ld-faq__item summary::-webkit-details-marker { display: none; }
.ld-faq__item summary::after {
    content: "";
    flex: none;
    width: 10px;
    height: 10px;
    border-right: 1.6px solid var(--ld-faint);
    border-bottom: 1.6px solid var(--ld-faint);
    transform: rotate(45deg) translateY(-2px);
    transition: transform .2s ease;
}
.ld-faq__item[open] summary::after { transform: rotate(225deg) translateY(-2px); }
.ld-faq__item p { padding: 0 20px 18px; color: var(--ld-body-text); font-size: 14px; line-height: 1.75; }

/* ---------- 转化区 ---------- */
.ld-cta {
    padding: 64px 0;
    background: linear-gradient(120deg, #0a1428 0%, #16305e 58%, #1d4ed8 100%);
    color: #fff;
    text-align: center;
}
.ld-cta h2 { font-size: clamp(23px, 2.8vw, 32px); font-weight: 700; }
.ld-cta p { max-width: 640px; margin: 14px auto 0; color: #d3ddf2; font-size: 15px; line-height: 1.75; }
.ld-cta__actions { display: flex; flex-wrap: wrap; gap: 12px; justify-content: center; margin-top: 28px; }

/* ---------- 页脚 ---------- */
.ld-footer { padding: 56px 0 24px; background: #07101f; color: #93a2bd; font-size: 14px; }
.ld-footer__grid {
    display: grid;
    grid-template-columns: minmax(0, 1.4fr) repeat(4, minmax(0, 1fr));
    gap: 36px;
}
.ld-footer__brand { display: inline-flex; align-items: center; gap: 10px; color: #fff; font-size: 17px; font-weight: 700; }
.ld-footer__brand img { width: 32px; height: 32px; object-fit: contain; }
.ld-footer__about { margin-top: 16px; max-width: 300px; color: #a7b5cf; line-height: 1.85; font-size: 13.5px; }
.ld-footer h4 { margin-bottom: 14px; color: #fff; font-size: 14px; font-weight: 600; }
.ld-footer li { padding: 6px 0; }
.ld-footer li a { color: #93a2bd; transition: color .16s ease; }
.ld-footer li a:hover { color: #fff; }
.ld-footer__bottom {
    display: flex;
    flex-wrap: wrap;
    gap: 10px 24px;
    align-items: center;
    margin-top: 44px;
    padding-top: 22px;
    border-top: 1px solid rgba(255, 255, 255, .09);
    color: #93a2bd;
    font-size: 13px;
}
.ld-footer__bottom span { margin-right: auto; }

/* ---------- 滚动揭示（无 JS 时全部可见） ---------- */
.ld-js-reveal .ld-reveal { opacity: 0; transform: translateY(16px); }
.ld-js-reveal .ld-reveal.is-in {
    opacity: 1;
    transform: none;
    transition: opacity .55s ease, transform .55s ease;
}

/* ---------- 响应式 ---------- */
@media (max-width: 1080px) {
    .ld-hero__inner { grid-template-columns: minmax(0, 1fr); gap: 48px; }
    .ld-hero__visual { max-width: 620px; }
    .ld-grid--3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .ld-plans { grid-template-columns: minmax(0, 1fr); max-width: 520px; margin: 0 auto; }
    .ld-plan.is-featured { order: -1; }
    .ld-secure { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .ld-footer__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 900px) {
    .ld-nav__menu, .ld-nav__actions { display: none; }
    .ld-nav__toggle { display: block; }
    .ld-nav__drawer.is-open { display: block; }
    .ld-brand__tagline { display: none; }
    .ld-steps { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 30px 0; }
    .ld-step::before { display: none; }
    .ld-section { padding: 56px 0; }
    .ld-section__head { margin-bottom: 32px; }
}

@media (max-width: 640px) {
    .ld-container { padding: 0 20px; }
    /* 小屏重置 hero 高度约束：clamp 下限 600px 在手机上会把单列内容拉出大片空白 */
    .ld-hero { min-height: 0; padding: 44px 0 52px; }
    .ld-hero__lead { max-width: none; font-size: 15px; }
    .ld-hero__actions { margin-top: 28px; }
    .ld-hero__actions .ld-btn { width: 100%; }
    .ld-hero__points { grid-template-columns: minmax(0, 1fr); gap: 12px; margin-top: 28px; padding-top: 22px; }
    .ld-mock__body { grid-template-columns: minmax(0, 1fr); }
    .ld-mock__side { display: none; }
    .ld-mock__badge { font-size: 11px; padding: 9px 12px; }
    .ld-grid--3, .ld-grid--2 { grid-template-columns: minmax(0, 1fr); gap: 16px; }
    .ld-secure { grid-template-columns: minmax(0, 1fr); }
    .ld-steps { grid-template-columns: minmax(0, 1fr); gap: 26px; }
    .ld-section { padding: 48px 0; }
    .ld-section__head { margin-bottom: 28px; }
    .ld-footer__grid { grid-template-columns: minmax(0, 1fr); gap: 26px; }
    .ld-footer__bottom span { margin-right: 0; }
}

@media (prefers-reduced-motion: reduce) {
    html { scroll-behavior: auto; }
    .ld *, .ld *::before, .ld *::after { transition-duration: .01ms !important; animation-duration: .01ms !important; }
    .ld-js-reveal .ld-reveal { opacity: 1; transform: none; }
}

/* ============================================================
 * 视觉体系对齐：圆角收敛 ≤6px、去营销式装饰、补齐暗色与主题色
 * 规范：docs/12_FRONTEND_DESIGN_LANGUAGE.md、docs/plans/02-landing-visual-system.md
 * ============================================================ */

/* —— 圆角统一到 --ld-radius（4px）；眉标/标签不再是胶囊 —— */
.ld-eyebrow, .ld-pill, .ld-tag, .ld-plan__flag { border-radius: var(--ld-radius); }
.ld-mock { border-radius: 6px; }
.ld-mock__table, .ld-card__icon, .ld-mock__toolbar span { border-radius: var(--ld-radius); }

/* —— 深色区改为纯色中性墨底，不再用渐变 —— */
.ld-section--navy, .ld-cta { background: var(--ld-navy); }

/* —— 移动端导航按钮不使用白色底 —— */
.ld-nav__toggle { background: #eef1f4; border-color: #cbd5e1; }

/* —— 字号取整，正文回到 14px 基线 —— */
.ld-card__text, .ld-scenario p, .ld-faq__item p { font-size: 14px; }
.ld-card__list li, .ld-scenario ul li, .ld-footer__about { font-size: 13px; }

/* —— 暗色模式：把仍是硬编码浅色的面收口到 --ld-surface —— */
html[data-color-mode="dark"] .ld-nav__drawer,
html[data-color-mode="dark"] .ld-mock,
html[data-color-mode="dark"] .ld-mock__table,
html[data-color-mode="dark"] .ld-card,
html[data-color-mode="dark"] .ld-step__no,
html[data-color-mode="dark"] .ld-scenario,
html[data-color-mode="dark"] .ld-plan,
html[data-color-mode="dark"] .ld-faq__item { background: var(--ld-surface); }

/* 双线包边卡在暗色下同样要走「深—亮—深」的节奏，只是明暗关系反过来：
 * 深底上外框取更暗的一档（比画布还暗，形成分离），缝隙取近纯黑把两道线撑开，
 * 内线取比画布亮的一档作为「看得见的那道线」。
 * 浅色下黑名单踩过两次「整体加深导致糊成一片」，这里刻意让三带差值 ≥ 20 阶。 */
html[data-color-mode="dark"] .ld-card,
html[data-color-mode="dark"] .ld-scenario,
html[data-color-mode="dark"] .ld-demo {
    --ld-ring-outer: #05080d;
    --ld-ring-gap: #131c28;
    --ld-ring-inner: #6b7fa0;
}
html[data-color-mode="dark"] .ld-card:hover {
    --ld-ring-inner: #93a9cc;
    --ld-ring-gap: #1b2637;
    border-color: #93a9cc;
}

html[data-color-mode="dark"] .ld-nav__toggle { background: #1d2939; border-color: #344054; }
html[data-color-mode="dark"] .ld-nav__toggle span { background: var(--ld-ink); }

/* 产品预览卡（.ld-mock）内部的浅色面一并收口，避免暗色下明暗夹层 */
html[data-color-mode="dark"] .ld-mock__chrome,
html[data-color-mode="dark"] .ld-mock__side,
html[data-color-mode="dark"] .ld-mock__badge,
html[data-color-mode="dark"] .ld-mock__row:first-child { background: #1b2230; }
html[data-color-mode="dark"] .ld-mock__side i,
html[data-color-mode="dark"] .ld-mock__toolbar span { background: #2b3444; }
html[data-color-mode="dark"] .ld-mock__toolbar span:nth-child(3) { background: var(--ld-brand-soft); }
html[data-color-mode="dark"] .ld-tag--ok { background: #12261f; color: #6ee7b7; }
html[data-color-mode="dark"] .ld-tag--warn { background: #2c1f14; color: #f0b26a; }
html[data-color-mode="dark"] .ld-tag--idle { background: #222b38; color: #98a2b3; }

/* ============================================================
 * 首屏可交互演示（.ld-demo）与两大核心卖点（.ld-core）
 * 设计：纯色块 + 细描边，不用渐变；圆角 ≤6px；动效可被
 * prefers-reduced-motion 与「JS 未接管」两种情况安全降级。
 * 「JS 已接管」由 head 内联脚本加的 html.ld-js-reveal 表示 —— 用它而不是等 JS 再补一个
 * class，是因为后者会让「脚本执行前」的那一帧闪出满屏字段、再把它们收回去。
 * 状态类由 landing.js 施加：
 *   .is-scanning = 扫描线动画中
 *   .is-on = 该行/该字段已产出
 *   .is-cur = 当前正在产出的那一行（左右联动高亮）
 *   .is-flip-out / .is-flip-in = 场景翻转的两段（见 .ld-demo__stage）
 * ============================================================ */

/* 首屏演示卡（figure.ld-demo）：白色圆角卡 + **组件外侧的双层包边** + 浮起投影。
 * 双层包边用向外扩散的 box-shadow 画（2026-09-23 定稿，用户明确要求「在组件外」）：
 *   0 0 0 1px 贴卡深线 → 0 0 0 10px **实色填充带** → 0 0 0 11px 外圈线，
 * 与能力卡/场景卡的 inset 双线环同一套 --ld-ring-* 令牌，只是方向朝外。
 * 「拉长 + 填充」（2026-09-23 追加）：填充带从 5px 拉到 **10px**，让两圈线之间有
 *   一条一眼能看到的「相框条」；颜色也从近白的 #f2f5fa 换成有明确色感的 #e8eef8
 *   （浅蓝调，与卡内浅蓝底呼应）—— 原来是让页面底色透出来，等于没有填充。
 * 「凸出来」（2026-09-23 追加）：包边**之外**再叠 --ld-demo-elevate 两层真实投影
 *   （贴边紧影 + 远处柔影）抬升卡片，卡面顶部加 --ld-demo-sheen 高光唇线。
 *   只加深包边线不解决问题 —— 平面的环只会更像「框」，浮起感必须靠投影。
 * 注意顺序：inset 高光在最前，向外扩散的环按由内到外排列（同半径的后者会盖前者）。 */
.ld-demo {
    margin: 0;
    /* 抬到卡外底光之上（底光由 .ld-hero__visual::before 提供） */
    position: relative;
    z-index: 1;
    border: 1px solid var(--ld-demo-edge);
    border-radius: 8px;
    background: var(--ld-surface);
    box-shadow:
        /* 顶部高光唇线：让卡面看起来是「被上方光照到」的凸起面 */
        var(--ld-demo-sheen),
        /* 加强包边环，向外扩散：贴卡深线 → 实色填充带（拉到 12px）→ 外圈线。
         * 第二轮把三条带整体加深一档、带子加宽 2px：10px 浅带在 1280 下几乎只是一条
         * 模糊的边，「两圈线 + 中间一条相框条」的节奏感读不出来。 */
        0 0 0 1px var(--ld-demo-ring-outer),
        0 0 0 13px var(--ld-demo-ring-band),
        0 0 0 14px var(--ld-demo-ring-inner),
        /* 真实投影（浮起感主杠杆）：贴边紧影勾出脱离感，远处柔影给出高度 */
        var(--ld-demo-elevate),
        /* 2026-10-16：投影里再叠一层品牌色柔光，卡片边缘透出一点蓝，
         * 与卡外底光同源 —— 纯中性灰影在浅蓝画布上会显得"灰扑扑" */
        var(--ld-demo-lift),
        var(--ld-shadow-lg);
    overflow: hidden;
}
/* 卡片顶边的品牌色唇线（2026-10-16 追加）：整张卡原本只有白面 + 浅蓝边，没有一点
 * 品牌色"起点"。顶部压一条纯色品牌线后，卡与 tab 条之间有了明确的分界，
 * 视线也知道从哪儿读起。纯色、不通高渐变 —— 与「不用渐变」的体系一致。
 * 第二轮 2px → 4px：2px 在 1280 截图里几乎和卡边线糊在一起。 */
.ld-demo::before {
    content: "";
    position: absolute;
    z-index: 2;
    inset: 0 0 auto 0;
    height: 4px;
    background: var(--ld-brand);
    pointer-events: none;
}

/* —— 卡外悬浮胶囊（2026-10-16 追加）——
 * 两张贴在卡片对角**外侧**的小标签：左上«版面还原»、右下«高亮核对»。
 * 它们不承载任何必须读到的信息（纯装饰 + 语境提示），所以 aria-hidden、
 * pointer-events:none，窄屏整组隐藏（单列时卡外没有余量，硬留会顶到文案）。
 * 浮动幅度刻意只有 5px：卡片本身是静止的（见 .ld-hero__visual::after 注释），
 * 胶囊位移过大就像从卡上"漂走"了。 */
.ld-demo-chip {
    position: absolute;
    z-index: 3;
    display: inline-flex;
    align-items: center;
    gap: 7px;
    padding: 7px 13px;
    border: 1px solid var(--ld-chip-line);
    border-radius: var(--ld-radius);
    background: var(--ld-chip-bg);
    /* 外圈一圈淡品牌光晕 + 落地投影：胶囊不再只是"一张白纸片" */
    box-shadow: var(--ld-chip-halo), 0 14px 30px -10px rgba(16, 24, 40, .22);
    color: var(--ld-brand-deep);
    font-size: 12.5px;
    font-weight: 600;
    line-height: 1.2;
    white-space: nowrap;
    pointer-events: none;
}
/* 左上那枚做「实心」变体：浅品牌底 + 品牌实边，与右下的白底胶囊形成主次。
 * 用 --ld-brand-soft（而不是 --ld-brand 实底 + 白字）是为了在暗色 / 灰主题下
 * 不会出现「浅灰底 + 白字」的对比度事故。 */
.ld-demo-chip--tl {
    background: var(--ld-brand-soft);
    border-color: var(--ld-brand);
}
.ld-demo-chip svg {
    width: 15px;
    height: 15px;
    flex: none;
    fill: none;
    stroke: currentColor;
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
}
/* 胶囊里的小圆点：品牌实心 + 一圈浅蓝光晕，比纯圆点更有"信号"感 */
.ld-demo-chip i {
    width: 7px;
    height: 7px;
    flex: none;
    border-radius: 50%;
    background: var(--ld-brand);
    box-shadow: 0 0 0 4px var(--ld-brand-soft);
}
/* 位置：**完全在卡片外侧**。最初写 -18px 时胶囊底部有 8px 压在卡上，
 * 正好啃掉刚加的 2px 品牌唇线和 tab 条左上角 —— 装饰不能吃主体。
 * 第二轮胶囊长高了 ~3px，同步把偏移拉到 -44px（包边带外沿在 -14px），
 * 保证胶囊与包边之间还留 ~1px 空隙。 */
.ld-demo-chip--tl { top: -44px; left: -20px; animation: ld-chip-float 7s ease-in-out infinite; }
.ld-demo-chip--br { right: -20px; bottom: -44px; animation: ld-chip-float 8.6s ease-in-out .9s infinite reverse; }
@keyframes ld-chip-float {
    0%, 100% { transform: translate3d(0, 0, 0); }
    50%      { transform: translate3d(0, -5px, 0); }
}

/* —— 场景切换 —— */
.ld-demo__tabs {
    display: flex;
    align-items: stretch;
    border-bottom: 1px solid var(--ld-line);
    /* 2026-10-16：底色从 --ld-surface-soft(#f8fafc) 换成 --ld-page(#f1f4f8)。
     * 前者和卡面(#fff)只差 3 阶，tab 条看上去就是"卡面的一部分"，整张卡像没分节。
     * 换成画布色后 tab 条成为独立的一条"头部带"，和顶部品牌唇线一起把阅读顺序立起来。 */
    background: var(--ld-page);
}
.ld-demo__tab {
    flex: 1;
    min-width: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    min-height: 42px;
    padding: 8px 10px;
    border: 0;
    background: transparent;
    color: var(--ld-muted);
    font: inherit;
    font-size: 12.5px;
    line-height: 1.3;
    cursor: pointer;
    transition: color .18s ease, background-color .18s ease;
}
.ld-demo__tab + .ld-demo__tab { border-left: 1px solid var(--ld-line); }
.ld-demo__tab:hover { color: var(--ld-brand-deep); }
.ld-demo__tab.is-active {
    background: var(--ld-surface);
    color: var(--ld-brand-deep);
    font-weight: 600;
    /* 3px：2px 的下划线在 1280 下和 tab 条底边只差一点点，读不出"选中" */
    box-shadow: inset 0 -3px 0 var(--ld-brand);
}
.ld-demo__tab-no {
    display: inline-grid;
    place-items: center;
    width: 18px;
    height: 18px;
    flex: none;
    border-radius: 4px;
    background: var(--ld-brand-soft);
    box-shadow: inset 0 0 0 1px var(--ld-chip-line);
    color: var(--ld-brand-deep);
    font-size: 11px;
    font-style: normal;
    font-weight: 700;
}
/* 当前场景的序号牌翻成品牌实底：卡上唯一的"实心品牌块"，也是当前 tab 的第二重标识
 * （第一重是底部 2px 下划线）—— 小面积重点色是这类卡片最省力的精致来源。 */
.ld-demo__tab.is-active .ld-demo__tab-no {
    background: var(--ld-brand);
    color: #fff;
}
/* —— 演示舞台：左照片 / 右产出 ——
 * 左右分栏是这张卡的说服力所在：照片上的行与右侧字段在视觉上必须「并排可对照」。
 * 图因此做成竖版（900x1080）而不是横版 —— 分栏后图列只有 ~300px，横版构图会把
 * 行里的字压到 7px 完全看不清；竖版 + 6 行 + 大字号可保证 ~14px 的可读字号。 */
.ld-demo__stage {
    display: grid;
    /* 图列略宽：它是「识别」这件事的证据，字必须看得清 */
    grid-template-columns: minmax(0, 1.2fr) minmax(0, 1fr);
    align-items: stretch;
    /* 整块可点 = 重播（页面上不再留重播按钮，卡片本身就是那个按钮） */
    cursor: pointer;
    transform-origin: 50% 50%;
    transition: transform .34s cubic-bezier(.4, 0, .2, 1), opacity .34s ease;
}
/* 场景翻转（生成表单 ⇄ 高亮回填）。用「转到 90° → 换内容 → 从 -90° 转回来」两段式，
 * 而不是 backface-visibility 双面翻转：双面翻转会让背面那份内容镜像显示，中文镜像后
 * 完全不可读。两段式在侧对观众的那一帧换内容，两边看到的内容始终是正的。 */
.ld-demo__stage.is-flip-out { transform: perspective(1400px) rotateY(-88deg); opacity: .25; }
/* 第二段的起点：先无过渡地摆到 +88°，再摘掉这个类让 transition 把它转回 0 */
.ld-demo__stage.is-flip-in {
    transition: none;
    transform: perspective(1400px) rotateY(88deg);
    opacity: .25;
}
.ld-demo__source {
    display: flex;
    flex-direction: column;
    padding: 12px;
    border-right: 1px solid var(--ld-line);
    /* 设计稿里照片四周的留白是白色（不是灰面）：相框线 + 阴影负责把照片从白底上
     * 托出来，底色再压灰反而会吞掉「白卡纸」的层次 */
    background: var(--ld-surface);
}
.ld-demo__photo {
    position: relative;
    /* 照片面板：白卡纸(border) → 图自带的浅蓝画布留边 → 表单纸。
     * ⚠️ 2026-09-23 第七轮：**去掉了外层的深色框线**（原 outline: 2px --ld-frame-line
     *    #aac0d8）。用户明确不要这条深色线 —— 它和组件外侧的双层包边叠在一起显得杂。
     *    现在只剩「白卡纸 + 图画布带」两层，由组件外层的包边统一承担「框」的职责。
     * ⚠️ 卡纸必须用 border 不能用 padding：证据框按「照片盒子 padding box」解析百分比，
     *    border 在 padding box 之外不影响对位；padding 会把图内缩导致证据框错位。
     * background 只在圆角缝隙里露出（取画布同色，避免四角异色）。 */
    border: 8px solid var(--ld-surface);
    border-radius: 5px;
    background: var(--ld-photo-canvas);
    box-shadow: var(--ld-shadow);
    overflow: hidden;
    line-height: 0;
}
.ld-demo__shot {
    display: block;
    width: 100%;
    height: auto;
}
/* 证据框：按照片上的百分比坐标定位。--top/--bx/--bw/--bh 由 Blade 注入，
 * 与生成脚本画行时用的坐标同源，不是目测 —— 所以框能严丝合缝压在图中的行上。
 * 坐标本身已经收进到行盒子的边缘（行与行之间留了 14px 的缝），这里不再额外内缩，
 * 否则框会比图中的行矮一截，看起来像没对准。
 * 必须用半透明填充，否则实色底会把图上的字整个盖掉。 */
.ld-demo__box {
    position: absolute;
    left: var(--bx);
    top: var(--top);
    width: var(--bw);
    height: var(--bh);
    border: 1.5px solid var(--ld-brand);
    /* 圆角呼应图里的圆角行盒子：直角框压在圆角盒子上会显得「外来」 */
    border-radius: 7px;
    background: rgba(37, 99, 235, .09);
    opacity: 0;
    /* left/width 参与过渡：切到回填模式时框会平滑收窄到值单元格 */
    transition: opacity .22s ease, box-shadow .22s ease, left .3s ease, width .3s ease;
    pointer-events: none;
}
/* 回填模式：框收窄到值单元格，只圈住纸上手写的内容 */
.ld-demo[data-mode="fill"] .ld-demo__box { left: var(--vx); width: var(--vw); }
/* 生成表单阶段只是「圈出题目」，用浅蓝细框；回填阶段才用实线强调已读到的值。 */
.ld-demo[data-mode="gen"] .ld-demo__box {
    border-color: #60a5fa;
    background: rgba(96, 165, 250, .16);
}
.ld-demo__box.is-cur { box-shadow: 0 0 0 3px var(--ld-brand-soft); }

/* 扫描线 */
.ld-demo__scan {
    position: absolute;
    left: 0;
    right: 0;
    top: 0;
    height: 2px;
    background: var(--ld-brand);
    box-shadow: 0 0 10px 2px var(--ld-brand);
    opacity: 0;
    pointer-events: none;
}
.ld-demo.is-scanning .ld-demo__scan {
    opacity: 1;
    animation: ld-demo-scan 1.5s linear forwards;
}
@keyframes ld-demo-scan {
    0%   { top: 0; }
    92%  { top: 100%; opacity: 1; }
    100% { top: 100%; opacity: 0; }
}

.ld-demo__status {
    /* 2026-10-16：从"裸文字"收成品牌浅底小标签。它是卡内压在照片下方的最后一行，
     * 裸排时整张卡的下缘是"文字掉在白面上"；给一层浅品牌底 + 圆角后，卡的下缘有了收口。 */
    align-self: flex-start;
    display: flex;
    align-items: center;
    gap: 6px;
    margin-top: 10px;
    min-height: 18px;
    padding: 4px 11px 4px 10px;
    border: 1px solid var(--ld-chip-line);
    border-radius: var(--ld-radius);
    background: var(--ld-brand-soft);
    color: var(--ld-brand-deep);
    font-size: 11.5px;
    font-weight: 500;
}
.ld-demo__status::before {
    content: "";
    width: 6px;
    height: 6px;
    flex: none;
    border-radius: 50%;
    background: var(--ld-faint);
}
.ld-demo.is-scanning .ld-demo__status::before {
    background: var(--ld-brand);
    animation: ld-demo-pulse 1s ease-in-out infinite;
}
.ld-demo.is-done .ld-demo__status::before { background: #16a34a; }
@keyframes ld-demo-pulse {
    0%, 100% { opacity: 1; }
    50%      { opacity: .25; }
}

/* —— 右侧产出面板 ——
 * 字段行 flex:1 均分高度：列只有 ~230px 宽，放不下「字段名 + 值 + 置信 + 待复核」一整行，
 * 所以每行改为竖向两行（名称在上、值与置信在下），并让 6 行均分撑满，卡片高度由照片决定。 */
.ld-demo__result {
    display: flex;
    flex-direction: column;
    padding: 14px;
}
.ld-demo__panel { display: none; }
.ld-demo[data-mode="gen"] .ld-demo__panel[data-demo-panel="gen"],
.ld-demo[data-mode="fill"] .ld-demo__panel[data-demo-panel="fill"] {
    display: flex;
    flex: 1;
    flex-direction: column;
}
.ld-demo__panel-title {
    /* 标题前补一条 2px 品牌短竖线，与字段卡左侧那条同色同粗 ——
     * 面板标题不再是孤零零一行灰字，右侧整列有了自己的"起点"记号。 */
    display: flex;
    align-items: center;
    gap: 6px;
    margin-bottom: 8px;
    color: var(--ld-faint);
    font-size: 10.5px;
    letter-spacing: .1em;
}
.ld-demo__panel-title::before {
    content: "";
    flex: none;
    width: 3px;
    height: 11px;
    background: var(--ld-brand);
}
.ld-demo__fields {
    flex: 1;
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 4px;
}
.ld-demo__field {
    /* 不撑满（flex:1 会让每行涨到 53px，内容只占 26px，整体显得松散）；
     * 固定紧凑行高后整列垂直居中，卡片高度交给照片决定。 */
    flex: none;
    min-height: 48px;
    display: flex;
    flex-wrap: wrap;
    align-content: center;
    align-items: center;
    gap: 2px 6px;
    padding: 4px 9px;
    border: 1px solid var(--ld-line-soft);
    /* 左侧那条原本是 transparent（只为 is-cur 变蓝时不跳宽而预留）。
     * 2026-10-16 起填成品牌色；第二轮 2px → 3px 并改成实色 --ld-brand：
     * 2px 的 rgba 淡蓝在截图里几乎看不出，6 行字段读不到"统一把手"。
     * is-cur 仍能分出状态差：当前行会叠浅品牌底 + 一圈光圈（见 .is-cur）。 */
    border-left: 3px solid var(--ld-brand);
    border-radius: 4px;
    background: var(--ld-surface-soft);
    font-size: 11.5px;
    transition: opacity .22s ease, border-color .22s ease, background-color .22s ease, transform .22s ease;
}
.ld-demo__field-name {
    /* 占满一行：强制题型/控件换到第二行，窄列下才不会挤成一团。
     * 同时它自己是个 flex —— 回填区要在同一个字段名右边挂「置信 / 待复核」。 */
    flex: 1 0 100%;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 6px;
    color: var(--ld-muted);
    font-size: 10.5px;
}
.ld-demo__field-meta { display: flex; align-items: center; gap: 5px; }
.ld-demo__field-type {
    flex: none;
    padding: 0 5px;
    border-radius: 3px;
    background: var(--ld-brand-soft);
    color: var(--ld-brand-deep);
    font-size: 10.5px;
}
/* 控件示意（不是真实 input）：生成区是空框，回填区里装着读到的值。
 * 两个场景共用同一个类，翻转前后才像「同一张表单」。 */
.ld-demo__field-input {
    flex: 1 1 40px;
    min-width: 0;
    display: flex;
    align-items: center;
    height: 18px;
    padding: 0 6px;
    border: 1px solid var(--ld-line);
    border-radius: 3px;
    background: var(--ld-surface);
}
.ld-demo__field-value {
    min-width: 0;
    overflow: hidden;
    color: var(--ld-ink);
    font-weight: 600;
    font-style: normal;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.ld-demo__conf { color: var(--ld-faint); font-size: 10px; font-style: normal; }
.ld-demo__flag {
    padding: 0 5px;
    border: 1px solid #fed7aa;
    border-radius: 3px;
    background: #fff7ed;
    color: #b45309;
    font-size: 10px;
    font-style: normal;
}

/* 无 JS 兜底：head 里的内联脚本会加 .ld-js-reveal；没有它就说明脚本不可用，
 * 此时直接把证据框与「已完成」的状态行渲染成静态终态，而不是留一片空框。
 * 状态行隐藏是因为没有脚本就没人推进它，「待上传…」的初始文案与已列出的字段矛盾。 */
html:not(.ld-js-reveal) .ld-demo__box { opacity: .85; }
html:not(.ld-js-reveal) .ld-demo__status { display: none; }

/* JS 接管后（html.ld-js-reveal 由 head 内联脚本在解析前就加上）：
 * 未产出的字段**完全不显示**，右边就是一片空白，字段是「生成出来的」而不是「先摆好再点亮」。
 * 用 opacity 而不是 display:none —— 保持行高，产出时不会有跳动。
 * （旧版这里是 opacity: .2，等于把答案先透给用户，看不出「从无到有」。） */
html.ld-js-reveal .ld-demo__box { opacity: 0; }
html.ld-js-reveal .ld-demo__box.is-on { opacity: 1; }
html.ld-js-reveal .ld-demo__field { opacity: 0; transform: translateY(2px); }
html.ld-js-reveal .ld-demo__field.is-on { opacity: 1; transform: none; }
/* 回填区：字段卡与控件一开始就在（表单已经生成好了），逐个揭示的是「值」本身。
 * 用 opacity 而不是 display —— 输入框宽度不会因为值出现而跳动。 */
html.ld-js-reveal .ld-demo__field-value { opacity: 0; transition: opacity .24s ease; }
html.ld-js-reveal .ld-demo__field-value.is-on { opacity: 1; }
html.ld-js-reveal .ld-demo__field.is-cur {
    border-color: var(--ld-brand);
    background: var(--ld-brand-soft);
    box-shadow: 0 0 0 2px var(--ld-brand-soft);
}

/* —— 两大核心卖点 —— */
.ld-core {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 18px;
}
.ld-core__item {
    padding: 22px;
    border: 1px solid var(--ld-line);
    border-radius: 6px;
    background: var(--ld-surface);
    box-shadow: var(--ld-shadow);
}
.ld-core__head { display: flex; align-items: flex-start; gap: 12px; }
.ld-core__icon {
    flex: none;
    display: grid;
    place-items: center;
    width: 38px;
    height: 38px;
    border-radius: 6px;
    background: var(--ld-brand-soft);
    color: var(--ld-brand-deep);
}
.ld-core__icon svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
.ld-core__tag {
    display: inline-block;
    padding: 1px 6px;
    border-radius: 3px;
    background: var(--ld-brand-soft);
    color: var(--ld-brand-deep);
    font-size: 11px;
}
.ld-core__title { margin-top: 5px; font-size: 17px; font-weight: 600; color: var(--ld-ink); }
.ld-core__lead { margin-top: 12px; font-size: 14px; line-height: 1.8; color: var(--ld-body-text); }
.ld-core__steps {
    margin-top: 14px;
    display: flex;
    flex-direction: column;
    gap: 7px;
    counter-reset: ld-core-step;
}
.ld-core__steps li {
    position: relative;
    padding-left: 24px;
    font-size: 13px;
    line-height: 1.7;
    color: var(--ld-body-text);
    counter-increment: ld-core-step;
}
.ld-core__steps li::before {
    content: counter(ld-core-step);
    position: absolute;
    left: 0;
    top: 3px;
    display: grid;
    place-items: center;
    width: 16px;
    height: 16px;
    border-radius: 50%;
    background: var(--ld-brand-soft);
    color: var(--ld-brand-deep);
    font-size: 10px;
    font-weight: 700;
}
.ld-core__points {
    margin-top: 14px;
    padding-top: 12px;
    border-top: 1px dashed var(--ld-line);
    display: flex;
    flex-wrap: wrap;
    gap: 6px 14px;
}
.ld-core__points li {
    display: flex;
    align-items: center;
    gap: 5px;
    font-size: 12.5px;
    color: var(--ld-muted);
}
.ld-core__points svg {
    width: 13px;
    height: 13px;
    flex: none;
    fill: none;
    stroke: var(--ld-brand);
    stroke-width: 2.2;
    stroke-linecap: round;
    stroke-linejoin: round;
}
.ld-subhead {
    margin: 38px 0 16px;
    font-size: 15px;
    font-weight: 600;
    color: var(--ld-ink);
}

/* —— 暗色模式收口 —— */
html[data-color-mode="dark"] .ld-demo,
html[data-color-mode="dark"] .ld-core__item,
html[data-color-mode="dark"] .ld-demo__field { background: var(--ld-surface); }
/* 卡自身的软边在暗色下换深色（否则浅色 1px 边夹在深色包边和深卡面之间很突兀） */
html[data-color-mode="dark"] .ld-demo { border-color: #344054; }
html[data-color-mode="dark"] .ld-demo__tabs,
html[data-color-mode="dark"] .ld-demo__source { background: var(--ld-surface-soft); }
/* 照片在暗色下：只剩「白卡纸（走 --ld-surface 自动变深）+ 图自带的浅蓝画布」两层，
 * 不再需要 outline 覆盖（深色框线已于第七轮移除，见 .ld-demo__photo 注释） */
html[data-color-mode="dark"] .ld-demo__flag { border-color: #4a3423; background: #2c1f14; color: #f0b26a; }

/* —— 响应式 —— */
@media (max-width: 1080px) {
    .ld-core { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 900px) {
    /* 900px 以下继续保持左右分栏：照片列仍能拿到 ~440px，比堆叠成一整列更清楚。
     * 只是把列比压一点，给产出列让出空间。 */
    .ld-demo__stage { grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr); }
    /* 卡外装饰必须在这里收起（不能写在文件前半段的同名断点里）：
     * .ld-demo-chip 的主规则在本段之后，同特异性后写胜出 —— 写在前面等于没写。
     * 单列起卡外没有余量，胶囊会顶出容器左边缘；点阵带同理。 */
    .ld-demo-chip,
    .ld-demo-dots { display: none; }
}
@media (max-width: 640px) {
    /* 再窄就必须堆叠：分栏后每列不足 160px，纸上的字与字段名都会挤到不可读 */
    .ld-demo__stage { grid-template-columns: minmax(0, 1fr); }
    .ld-demo__source { border-right: 0; border-bottom: 1px solid var(--ld-line); }
    .ld-demo__tab { font-size: 12px; padding: 8px 6px; }
    .ld-demo__tab-no { display: none; }
    .ld-core__item { padding: 18px; }
    .ld-subhead { margin: 30px 0 14px; }
}
