Files
stack/design-refs/mockup/design-system.html
T

524 lines
37 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<title>设计系统 · 孟菲斯 × 拟物卡 · stack idealjs</title>
<style>
/* ====== 页面基座 ====== */
@page { size: 1280px 800px; margin: 0; }
*, *::before, *::after { box-sizing: border-box; }
html, body {
margin: 0; padding: 0; width: 1280px;
background: #f0f0ef;
font-family: "Noto Sans CJK SC", "PingFang SC", "Microsoft YaHei", sans-serif;
color: #1a1a1a;
-webkit-font-smoothing: antialiased;
}
.page { width: 1280px; height: 800px; position: relative; background: #f0f0ef; overflow: hidden; page-break-after: always; }
.page:last-child { page-break-after: auto; }
@media screen {
html { height: auto; display: flex; justify-content: center; background: #f0f0ef; }
body { transform-origin: top center; scale: min(1, calc(100vw / 1280px)); margin: 0 auto; box-shadow: 0 0 48px rgba(15, 23, 42, 0.18); }
}
.pagenum { position: absolute; bottom: 26px; right: 40px; font-size: 13px; color: #8a8a8a; letter-spacing: 2px; }
.footline { position: absolute; bottom: 26px; left: 40px; font-size: 13px; color: #8a8a8a; letter-spacing: 1px; }
.story-head { position: absolute; top: 36px; left: 40px; right: 40px; }
.story-head .tag {
display: inline-block; font-size: 15px; font-weight: 700; color: #6d28d9;
background: #efe6fb; border-radius: 8px; padding: 3px 12px;
font-family: "DejaVu Sans Mono", "Noto Sans CJK SC", monospace;
}
.story-head h2 { margin: 8px 0 4px; font-size: 28px; font-weight: 800; color: #1a1a1a; }
.story-head .desc { font-size: 14.5px; color: #6b6b6b; }
.canvas { background: #fbfbfa; border: 1px dashed #cfcfcd; border-radius: 18px; padding: 20px 22px; position: absolute; }
.panel { background: #ffffff; border-radius: 18px; padding: 18px 20px; box-shadow: 0 1px 2px rgba(26,26,26,0.06); }
.panel h3 { margin: 0 0 10px; font-size: 16px; font-weight: 700; color: #1a1a1a; }
.note { display: flex; gap: 10px; align-items: flex-start; margin-bottom: 8px; }
.note .idx {
flex: none; width: 22px; height: 22px; border-radius: 50%;
background: #1a1a1a; color: #ffffff; font-size: 13px; font-weight: 700;
display: flex; align-items: center; justify-content: center; margin-top: 1px;
}
.note .txt { font-size: 13px; line-height: 1.55; color: #3d3d3d; }
.note .txt b { color: #1a1a1a; }
table.spec { width: 100%; border-collapse: collapse; font-size: 12px; color: #3d3d3d; }
table.spec th { text-align: left; font-weight: 700; color: #1a1a1a; border-bottom: 2px solid #d5d5d3; padding: 5px 8px 5px 0; }
table.spec td { border-bottom: 1px solid #ececea; padding: 4px 8px 4px 0; vertical-align: top; }
table.spec td.k { color: #1a1a1a; font-weight: 600; white-space: nowrap; }
table.spec code { font-family: "DejaVu Sans Mono", monospace; font-size: 11.5px; background: #f4f2fa; color: #6d28d9; border-radius: 5px; padding: 1px 5px; }
.sec-label { font-size: 13.5px; font-weight: 700; color: #1a1a1a; margin-bottom: 8px; }
.sec-label i { font-style: normal; font-weight: 400; font-size: 11.5px; color: #6b6b6b; margin-left: 8px; }
/* 颜色页 */
.pair { display: flex; border: 2px solid #111111; border-radius: 10px; overflow: hidden; }
.pair div { width: 72px; height: 34px; }
.cchip { min-width: 0; }
.cchip .b { height: 44px; border-radius: 9px; border: 2px solid #111111; }
.cchip .n { font-size: 10.5px; font-weight: 700; margin-top: 5px; white-space: nowrap; }
.cchip .h { font-family: "DejaVu Sans Mono", monospace; font-size: 9px; color: #6b6b6b; white-space: nowrap; }
/* 形状页 */
.shapechip { text-align: center; }
.shapechip .box {
width: 44px; height: 44px; margin: 0 auto; border-radius: 10px; background: #ffffff;
border: 2px solid #111111; display: flex; align-items: center; justify-content: center;
}
.shapechip .sn { font-size: 11px; font-weight: 700; margin-top: 5px; }
.shapechip .sm { font-size: 9.5px; color: #6b6b6b; margin-top: 1px; line-height: 1.35; }
/* 组件页:孟菲斯 × 拟物卡 */
.mscard {
background: #fff9f0; border: 2px solid #111111; border-radius: 14px;
box-shadow: 0 3px 0 #ffffff, 0 5px 0 #eadfc4, 7px 8px 0 #111111;
padding: 11px; position: absolute;
}
.mscard .mszone {
height: 128px; border-radius: 8px; position: relative;
border: 3px solid #111111;
box-shadow: inset 0 3px 8px rgba(26,26,26,0.30), inset 0 -1px 0 rgba(255,255,255,0.55);
display: flex; align-items: center; justify-content: center;
}
.mscard .mszone span { font-size: 30px; }
.mscard .mst { display: flex; align-items: center; gap: 7px; margin-top: 9px; }
.mscard .mst .tri { width: 0; height: 0; border-left: 6px solid transparent; border-right: 6px solid transparent; border-bottom: 10px solid #111111; }
.mscard .mst b { font-size: 14px; flex: 1; color: #2b1d10; text-shadow: 0 1px 1px rgba(255,255,255,0.9); }
.mscard .dots { display: flex; gap: 4px; }
.mscard .dots i { width: 7px; height: 7px; border-radius: 50%; border: 1.5px solid #111111; background: #fff; }
.mscard .dots i.on { background: #111111; }
.entry-badge2 {
position: absolute; top: -11px; left: -11px; width: 24px; height: 24px; border-radius: 50%;
background: #111111; color: #ffd93d; font-size: 12px; font-weight: 800;
display: flex; align-items: center; justify-content: center; border: 2px solid #fff9f0;
}
/* 票券 */
.msticket {
width: 216px; background: #fff9f0; border: 2px solid #111111; border-radius: 12px;
box-shadow: 5px 5px 0 #111111; position: absolute; display: flex; align-items: stretch;
}
.msticket .tl {
width: 56px; border: 2px solid #111111; border-left: none; border-radius: 10px 0 0 10px;
display: flex; align-items: center; justify-content: center; font-size: 22px; margin-left: -2px;
}
.msticket .tb { flex: 1; padding: 9px 10px; }
.msticket .tb b { font-size: 12.5px; }
.msticket .tb .no { font-family: "DejaVu Sans Mono", monospace; font-size: 8.5px; color: #8a7a5c; margin-top: 3px; }
.msticket .stub {
width: 42px; border-left: 1.5px dashed #111111;
display: flex; align-items: center; justify-content: center;
font-family: "DejaVu Sans Mono", monospace; font-size: 9.5px; color: #8a7a5c;
}
.msticket.pk::before, .msticket.pk::after {
content: ""; position: absolute; left: 162px; width: 13px; height: 13px;
border-radius: 50%; background: #fbfbfa; border: 2px solid #111111;
}
.msticket.pk::before { top: -9px; }
.msticket.pk::after { bottom: -9px; }
.msline { stroke: #111111; stroke-width: 2.5; fill: none; }
.msstation { stroke: #111111; stroke-width: 2; }
</style>
</head>
<body>
<!-- ================= P1 颜色 ================= -->
<div class="page">
<div class="story-head">
<span class="tag">&lt;DesignSystem /&gt; 01</span>
<h2>颜色 · 鲜艳与碰撞</h2>
<div class="desc">三组撞色对轮转,黑描边收束一切鲜艳,大底永远是纸色。章节色只进相框,状态不用颜色表达——用形状。</div>
</div>
<div class="canvas" style="top: 138px; left: 40px; width: 880px; height: 594px;">
<div class="sec-label">撞色对 <i>相邻的鲜艳必须来自不同对;描边统一 ink</i></div>
<div style="display:flex; gap:18px; margin-bottom:18px; align-items:flex-start;">
<div>
<div class="pair"><div style="background:#ff6b6b;"></div><div style="background:#4ecdc4;"></div></div>
<div style="font-size:9.5px; color:#6b6b6b; margin-top:4px;">对 1 · coral × teal</div>
</div>
<div>
<div class="pair"><div style="background:#ffd93d;"></div><div style="background:#a78bfa;"></div></div>
<div style="font-size:9.5px; color:#6b6b6b; margin-top:4px;">对 2 · mustard × violet</div>
</div>
<div>
<div class="pair"><div style="background:#ff8fab;"></div><div style="background:#5b8def;"></div></div>
<div style="font-size:9.5px; color:#6b6b6b; margin-top:4px;">对 3 · pink × blue</div>
</div>
<div style="flex:1; font-size:11.5px; color:#3d3d3d; line-height:1.6; padding-top:2px;">
相邻色块<b>必撞色</b>(不同对取色);<b>ink #111</b> 描边收束一切;鲜艳总面积一屏 ≤ 10%。
</div>
</div>
<div class="sec-label">中性阶 <i>纸的世界——字、边、投影、底</i></div>
<div style="display:grid; grid-template-columns:repeat(4, 1fr); gap:10px; margin-bottom:18px;">
<div class="cchip"><div class="b" style="background:#111111;"></div><div class="n">ink</div><div class="h">#111111 · 描边/字/硬投影</div></div>
<div class="cchip"><div class="b" style="background:#fff9f0;"></div><div class="n">paper</div><div class="h">#FFF9F0 · 卡面/大底</div></div>
<div class="cchip"><div class="b" style="background:#ffffff;"></div><div class="n">stack-1</div><div class="h">#FFFFFF · 纸叠亮边</div></div>
<div class="cchip"><div class="b" style="background:#eadfc4;"></div><div class="n">stack-2</div><div class="h">#EADFC4 · 纸叠暗层</div></div>
</div>
<div class="sec-label">章节色 <i>六章六色,只进 16:9 相框与图标瓦</i></div>
<div style="display:grid; grid-template-columns:repeat(6, 1fr); gap:10px; margin-bottom:18px;">
<div class="cchip"><div class="b" style="background:#ff6b6b;"></div><div class="n">ch1 快速开始</div><div class="h">#FF6B6B</div></div>
<div class="cchip"><div class="b" style="background:#ff8fab;"></div><div class="n">ch2 React</div><div class="h">#FF8FAB</div></div>
<div class="cchip"><div class="b" style="background:#ffd93d;"></div><div class="n">ch3 更多示例</div><div class="h">#FFD93D</div></div>
<div class="cchip"><div class="b" style="background:#4ecdc4;"></div><div class="n">ch4 更多</div><div class="h">#4ECDC4</div></div>
<div class="cchip"><div class="b" style="background:#5b8def;"></div><div class="n">ch5 全栈基础</div><div class="h">#5B8DEF</div></div>
<div class="cchip"><div class="b" style="background:#a78bfa;"></div><div class="n">ch6 高级教程</div><div class="h">#A78BFA</div></div>
</div>
<div class="sec-label">站点轮换色 <i>只上先后线(实线),沿线路四色轮换</i></div>
<div style="display:flex; gap:26px; align-items:center; margin-bottom:18px;">
<svg width="330" height="34" viewBox="0 0 330 34">
<path class="msline" d="M 6 17 H 324"/>
<circle class="msstation" cx="6" cy="17" r="6" fill="#ffd93d"/>
<circle class="msstation" cx="110" cy="17" r="6" fill="#4ecdc4"/>
<circle class="msstation" cx="214" cy="17" r="6" fill="#ff8fab"/>
<circle class="msstation" cx="324" cy="17" r="6" fill="#ff6b6b"/>
</svg>
<div style="font-size:11.5px; color:#3d3d3d; line-height:1.6;">描边 2px ink;<b>r=6</b>;同色不相邻。虚线/点线(相关/同族)不带站点。</div>
</div>
<div class="sec-label">收束示例 <i>鲜艳 × 黑描边 × 纸底的合作</i></div>
<div style="display:flex; gap:14px; align-items:center;">
<div style="width:120px; height:64px; background:#ff6b6b; border:3px solid #111; border-radius:9px; box-shadow: inset 0 3px 8px rgba(26,26,26,0.30); display:flex; align-items:center; justify-content:center; font-size:22px;">🌐</div>
<div style="width:120px; height:64px; background:#ff8fab; border:3px solid #111; border-radius:9px; display:flex; align-items:center; justify-content:center; font-size:22px;">⚛️</div>
<div style="font-size:11.5px; color:#3d3d3d; line-height:1.6; flex:1;">相框内的章节色相邻即撞色(ch1 × ch2);黑描边与内阴影把鲜艳压回纸面。<b>禁色彩渐变</b>——立体感只来自描边、硬投影与内阴影。</div>
</div>
</div>
<div style="position:absolute; top: 138px; left: 948px; width: 292px;" class="panel">
<h3>用色规则</h3>
<div class="note" style="margin-bottom:6px;"><span class="idx">1</span><span class="txt"><b>鲜艳预算</b>:彩色只上形状、描边内与相框;一屏 ≤ 10%。</span></div>
<div class="note" style="margin-bottom:6px;"><span class="idx">2</span><span class="txt"><b>相邻必撞色</b>:相邻鲜艳取不同撞色对;同色不相邻。</span></div>
<div class="note" style="margin-bottom:6px;"><span class="idx">3</span><span class="txt"><b>黑描边收束</b>:一切鲜艳以 2px ink 描边为界。</span></div>
<div class="note" style="margin-bottom:0;"><span class="idx">4</span><span class="txt"><b>大底纸色</b>:背景只有 paper;白只作纸叠亮边。</span></div>
</div>
<div style="position:absolute; top: 420px; left: 948px; width: 292px;" class="panel">
<h3>状态即形状,不是颜色</h3>
<div class="note" style="margin-bottom:6px;"><span class="idx">1</span><span class="txt"><b>完成=打孔</b>:票券沿撕线打双孔;未开始无孔。</span></div>
<div class="note" style="margin-bottom:6px;"><span class="idx">2</span><span class="txt"><b>进度=积木点</b>:卡头点列,实心=已学。</span></div>
<div class="note" style="margin-bottom:0;"><span class="idx">3</span><span class="txt"><b>无锁</b>:状态是推荐不是门槛,卡片永远可入(死原则)。</span></div>
</div>
<div class="footline">设计系统 · 01 颜色 · stack idealjs</div>
<div class="pagenum">01 / 04</div>
</div>
<!-- ================= P2 符号、形状 ================= -->
<div class="page">
<div class="story-head">
<span class="tag">&lt;DesignSystem /&gt; 02</span>
<h2>符号、形状 · 装饰即语义</h2>
<div class="desc">孟菲斯形状对内容下定义、散落于空白;线条形式承载关系含义;站点与票券是关系上的铆钉。每个标记都有意思。</div>
</div>
<div class="canvas" style="top: 138px; left: 40px; width: 880px; height: 594px;">
<div class="sec-label">语义形状 ×7 <i>取自 ai-era-tutorial 概念;散落只在空白,密度 ≤ 8/屏</i></div>
<div style="display:grid; grid-template-columns:repeat(7, 1fr); gap:8px; margin-bottom:16px;">
<div class="shapechip"><div class="box"><svg width="26" height="24"><path d="M13 2 L25 22 L1 22 Z" fill="#ff6b6b" stroke="#111" stroke-width="2"/></svg></div><div class="sn">▲ 靶子</div><div class="sm">目标,卡头打头</div></div>
<div class="shapechip"><div class="box"><svg width="26" height="24"><circle cx="8" cy="12" r="5" fill="#ffd93d" stroke="#111" stroke-width="2"/><circle cx="19" cy="12" r="5" fill="#fff9f0" stroke="#111" stroke-width="2"/></svg></div><div class="sn">● 积木</div><div class="sm">清单点列,实=已学</div></div>
<div class="shapechip"><div class="box"><svg width="26" height="24"><circle cx="13" cy="12" r="8" fill="none" stroke="#4ecdc4" stroke-width="4"/><circle cx="13" cy="12" r="8" fill="none" stroke="#111" stroke-width="1.5"/></svg></div><div class="sn">○ 预期</div><div class="sm">可核对的结果</div></div>
<div class="shapechip"><div class="box"><svg width="28" height="24"><path d="M2 16 q3 -12 6 0 t6 0 t6 0 t6 0" fill="none" stroke="#5b8def" stroke-width="3" stroke-linecap="round"/></svg></div><div class="sn">~ 代理区</div><div class="sm">交给 agent</div></div>
<div class="shapechip"><div class="box"><svg width="26" height="24"><rect x="2" y="8" width="22" height="8" fill="#ff8fab" stroke="#111" stroke-width="2"/></svg></div><div class="sn">▬ 价值区</div><div class="sm">就地写过程</div></div>
<div class="shapechip"><div class="box"><svg width="26" height="24"><path d="M 13 22 L 9 18 L 17 14 L 9 10 L 17 6 L 13 2" fill="none" stroke="#ff6b6b" stroke-width="3" stroke-linejoin="round" stroke-linecap="round"/></svg></div><div class="sn">⌇ 脱靶</div><div class="sm">可能脱靶,重点关注</div></div>
<div class="shapechip"><div class="box"><svg width="26" height="24"><path d="M13 3 v20 M3 13 h20" stroke="#a78bfa" stroke-width="3.5" stroke-linecap="round"/><path d="M13 3 v20 M3 13 h20" stroke="#111" stroke-width="1.2"/></svg></div><div class="sn">+ 指派</div><div class="sm">位置/预期/场景</div></div>
</div>
<div class="sec-label">线条形式 ×4 <i>形式即含义;拓扑规则(横平竖直+R8)全形式通用</i></div>
<div style="display:grid; grid-template-columns:repeat(4, 1fr); gap:12px; margin-bottom:16px;">
<div>
<svg width="196" height="44" viewBox="0 0 196 44">
<rect x="6" y="8" width="2" height="30" fill="#c9c9c7"/><rect x="188" y="2" width="2" height="18" fill="#c9c9c7"/>
<path d="M 7 34 H 46 A 8 8 0 0 0 54 26 V 18 A 8 8 0 0 1 62 10 H 188" fill="none" stroke="#111" stroke-width="2.5"/>
<circle cx="7" cy="34" r="5.5" fill="#ffd93d" stroke="#111" stroke-width="2"/>
<circle cx="189" cy="10" r="5.5" fill="#4ecdc4" stroke="#111" stroke-width="2"/>
</svg>
<div style="font-size:11.5px; font-weight:700; margin-top:2px;">实线 = 先后</div>
<div style="font-size:9.5px; color:#6b6b6b;">推荐顺序 · 主线,唯一带站点</div>
</div>
<div>
<svg width="196" height="44" viewBox="0 0 196 44">
<rect x="6" y="14" width="2" height="18" fill="#c9c9c7"/><rect x="188" y="14" width="2" height="18" fill="#c9c9c7"/>
<path d="M 7 23 H 189" fill="none" stroke="#111" stroke-width="2" stroke-dasharray="4 2"/>
</svg>
<div style="font-size:11.5px; font-weight:700; margin-top:2px;">虚线 = 相关</div>
<div style="font-size:9.5px; color:#6b6b6b;">内容互参 · 无顺序,无站点</div>
</div>
<div>
<svg width="196" height="44" viewBox="0 0 196 44">
<rect x="6" y="14" width="2" height="18" fill="#c9c9c7"/><rect x="188" y="14" width="2" height="18" fill="#c9c9c7"/>
<path d="M 7 23 H 189" fill="none" stroke="#111" stroke-width="2.4" stroke-dasharray="0.1 6" stroke-linecap="round"/>
</svg>
<div style="font-size:11.5px; font-weight:700; margin-top:2px;">点线 = 同族</div>
<div style="font-size:9.5px; color:#6b6b6b;">同一积木家族(教一块带一族)</div>
</div>
<div>
<svg width="196" height="44" viewBox="0 0 196 44">
<path d="M 12 22 q 8 -18 16 0 t16 0 t16 0 t16 0 t16 0 t16 0 t16 0 t16 0 t16 0 t16 0" fill="none" stroke="#5b8def" stroke-width="3" stroke-linecap="round"/>
</svg>
<div style="font-size:11.5px; font-weight:700; margin-top:2px;">波浪带 = 代理交接</div>
<div style="font-size:9.5px; color:#6b6b6b;">agent 边界 · 区域标记,不连线</div>
</div>
</div>
<div class="sec-label">站点与胶囊 <i>关系上的铆钉——只上先后线</i></div>
<div style="display:flex; gap:22px; margin-bottom:16px; align-items:flex-start;">
<div style="flex:1;">
<svg width="340" height="66" viewBox="0 0 400 66">
<rect x="120" y="4" width="26" height="58" fill="#fff9f0" stroke="#111" stroke-width="2" rx="4"/>
<rect x="284" y="4" width="26" height="58" fill="#fff9f0" stroke="#111" stroke-width="2" rx="4"/>
<rect x="276" y="10" width="7" height="46" fill="#111111"/>
<circle class="msstation" cx="120" cy="33" r="6" fill="#ffd93d"/>
<circle class="msstation" cx="280" cy="33" r="6" fill="#4ecdc4"/>
</svg>
<div style="font-size:11px; color:#6b6b6b; margin-top:2px;">圆点 r6 半嵌卡边:<b>左侧贴描边;右侧骑硬投影外缘</b>(描边会被黑影吞没)。线从卡边/影缘出发。</div>
</div>
<div style="flex:1;">
<svg width="340" height="66" viewBox="0 0 400 66">
<path d="M 10 26 H 297" fill="none" stroke="#111" stroke-width="2.5"/>
<path d="M 10 30 H 297" fill="none" stroke="#111" stroke-width="2.5"/>
<path d="M 10 34 H 297" fill="none" stroke="#111" stroke-width="2.5"/>
<rect x="297" y="20" width="6" height="20" rx="3" fill="#ff6b6b" stroke="#111" stroke-width="2"/>
<rect x="360" y="8" width="2" height="50" fill="#c9c9c7"/>
</svg>
<div style="font-size:11px; color:#6b6b6b; margin-top:2px;">多线卡口=胶囊:<b>竖向 6×20 端头半圆</b>;并行线间距 4px 不合并;<b>线止于胶囊边界</b>;端头距最外侧线 ≥ 2× 线宽。</div>
</div>
</div>
<div class="sec-label">票券 <i>状态与指派的载体——完成即打孔</i></div>
<div style="display:flex; gap:24px; align-items:flex-start;">
<div class="msticket pk" style="position:relative;">
<div class="tl" style="background:#ff6b6b;">🌐</div>
<div class="tb"><b>快速开始</b><div class="no">No. 001 · 已完成(打孔)</div></div>
<div class="stub">№01</div>
</div>
<div class="msticket" style="position:relative;">
<div class="tl" style="background:#5b8def;">🔗</div>
<div class="tb"><b>全栈基础</b><div class="no">No. 005 · 未开始(无孔)</div></div>
<div class="stub" style="border-left-style:solid;">№05</div>
</div>
<div style="font-size:11.5px; color:#3d3d3d; line-height:1.6; flex:1;">撕线=4:2 点划(与虚线同节奏,语境不同:这是裁剪线不是关系线)。票号=章程序号。</div>
</div>
</div>
<div style="position:absolute; top: 138px; left: 948px; width: 292px;" class="panel">
<h3>形状 → 语义</h3>
<table class="spec">
<tr><th>形状</th><th>语义</th><th>出处</th></tr>
<tr><td class="k">▲ 三角</td><td>目标</td><td>靶子先行</td></tr>
<tr><td class="k">● 实心圆</td><td>积木(已学)</td><td>积木清单</td></tr>
<tr><td class="k">○ 圆环</td><td>预期结果</td><td>可核对的样子</td></tr>
<tr><td class="k">~ 横波</td><td>代理区</td><td>交给 agent</td></tr>
<tr><td class="k">▬ 实心条</td><td>价值区</td><td>就地写过程</td></tr>
<tr><td class="k">⌇ 竖抖</td><td>脱靶警示</td><td>重点关注</td></tr>
<tr><td class="k">+ 十字</td><td>指派学习</td><td>位置/预期/场景</td></tr>
</table>
</div>
<div style="position:absolute; top: 428px; left: 948px; width: 292px;" class="panel">
<h3>符号规则</h3>
<div class="note" style="margin-bottom:6px;"><span class="idx">1</span><span class="txt"><b>装饰即语义</b>:散落形状必须有含义,无义不落。</span></div>
<div class="note" style="margin-bottom:6px;"><span class="idx">2</span><span class="txt"><b>一横一竖对举</b>:代理区横波(蓝)vs 脱靶竖抖(红)。</span></div>
<div class="note" style="margin-bottom:0;"><span class="idx">3</span><span class="txt"><b>形状不压内容</b>:只在空白,永不压字与卡。</span></div>
</div>
<div class="footline">设计系统 · 02 符号形状 · stack idealjs</div>
<div class="pagenum">02 / 04</div>
</div>
<!-- ================= P3 组件 ================= -->
<div class="page">
<div class="story-head">
<span class="tag">&lt;DesignSystem /&gt; 03</span>
<h2>组件 · 入口载体与关系</h2>
<div class="desc">四个组件撑起教程:CourseCard(入口)、RouteLine(关系)、指派票(任务)、脱靶注(警示)。卡头三件套即靶子。</div>
</div>
<div class="canvas" style="top: 138px; left: 40px; width: 880px; height: 594px;">
<div class="sec-label">CourseCard <i>教程的入口载体——孟菲斯骨架 × 拟物纸感</i></div>
<div style="display:flex; gap:24px; margin-bottom:14px; align-items:flex-start;">
<div class="mscard" style="position:static; width:300px;">
<span class="entry-badge2" style="position:absolute; top:-11px; left:-11px;">①</span>
<div class="mszone" style="height:156px; background:#ff6b6b;">
<span style="font-size:38px;">🌐</span>
<svg style="position:absolute; right:6px; bottom:6px;" width="18" height="18"><circle cx="9" cy="9" r="6" fill="none" stroke="#fff9f0" stroke-width="3"/><circle cx="9" cy="9" r="6" fill="none" stroke="#111" stroke-width="1.2"/></svg>
<span style="position:absolute; left:6px; top:5px; font-size:8.5px; color:#fff9f0; font-weight:700; letter-spacing:1px;">预期结果 · GIF</span>
</div>
<div class="mst">
<span class="tri"></span>
<b>快速开始</b>
<span class="dots"><i class="on"></i><i class="on"></i><i class="on"></i><i></i></span>
</div>
</div>
<div style="flex:1; font-size:11.5px; color:#3d3d3d; line-height:1.5;">
<div style="margin-bottom:6px;"><b>结构</b>:2px ink 描边 · 硬投影 7px 8px 0 · 纸叠三层边(白 3px / 暗层 5px)· 相框 3px 黑边 + 内阴影 · 标题压凹白影。</div>
<div style="margin-bottom:6px;"><b>卡头三件套=靶子</b>:▲ 目标(三角+标题)+ ○ 预期结果(16:9 相框 GIF)+ ● 积木点列(实心=已学)。</div>
<div><b>交互</b>:hover 拿起(translateY -3px+投影加深至 10px 11px)并播放 GIF;desc ⇄ GIF 每 <b>8000ms</b> 自动翻转,hover / Tab 聚焦锁定;触屏与 prefers-reduced-motion 不翻转。</div>
</div>
</div>
<div class="sec-label">RouteLine <i>关系——线形即含义,拓扑全形式通用</i></div>
<div style="display:flex; gap:20px; margin-bottom:14px; align-items:flex-start;">
<svg width="420" height="64" viewBox="0 0 420 64">
<rect x="8" y="6" width="2" height="52" fill="#c9c9c7"/>
<rect x="410" y="6" width="2" height="20" fill="#c9c9c7"/>
<path class="msline" d="M 9 46 H 60 A 8 8 0 0 0 68 38 V 30 A 8 8 0 0 1 76 22 H 410"/>
<path class="msline" d="M 76 46 H 200 A 8 8 0 0 1 208 38 V 34 A 8 8 0 0 0 216 30 H 300"/>
<circle class="msstation" cx="9" cy="46" r="6" fill="#ffd93d"/>
<circle class="msstation" cx="411" cy="22" r="6" fill="#4ecdc4"/>
<rect x="300" y="20" width="6" height="20" rx="3" fill="#ff6b6b" stroke="#111" stroke-width="2"/>
</svg>
<div style="flex:1; font-size:11.5px; color:#3d3d3d; line-height:1.5;">
<b>拓扑</b>:横平竖直 + R8 小圆角直角步进;并行不合并(4px);分流/并线=直角步进。线宽 2.5px ink。<br>
<b>站点</b>:只上先后线,r6 半嵌卡边(左贴描边、右骑影缘),四色轮换。<b>胶囊</b>:多线卡口专用(见 02 页)。
</div>
</div>
<div class="sec-label">指派票 & 脱靶注 <i>任务与警示——总在指派之后</i></div>
<div style="display:flex; gap:24px; align-items:flex-start;">
<div class="msticket pk" style="position:relative; width:250px;">
<div class="tl" style="background:#a78bfa; border-radius:10px 0 0 10px;">+</div>
<div class="tb">
<b>指派学习 · npm</b>
<div style="font-size:10px; color:#3d3d3d; line-height:1.5; margin-top:4px;">位置:包管理家族坐标<br>预期:说清 lockfile 锁什么<br>场景:加依赖 / 换源重装</div>
</div>
<div class="stub" style="border-left-style:solid;">+</div>
</div>
<div style="flex:1; background:#fff9f0; border:2px solid #111; border-radius:12px; box-shadow:5px 5px 0 #111; padding:10px 12px;">
<div style="display:flex; align-items:center; gap:8px;">
<svg width="20" height="20"><path d="M 10 18 L 7 15 L 13 12 L 7 9 L 13 6 L 10 3" fill="none" stroke="#ff6b6b" stroke-width="3" stroke-linejoin="round" stroke-linecap="round"/></svg>
<b style="font-size:12px;">脱靶提醒 · 跟在指派后</b>
</div>
<div style="font-size:10.5px; color:#3d3d3d; line-height:1.55; margin-top:6px;">写两样:<b>可能怎么脱靶</b>(装了但没跑)+ <b>脱靶什么样子</b>(命令成功、页面空白)——读者撞上时认得出缺哪块。</div>
</div>
</div>
</div>
<div style="position:absolute; top: 138px; left: 948px; width: 292px;" class="panel">
<h3>组件参数</h3>
<table class="spec">
<tr><th>组件</th><th>关键 prop</th></tr>
<tr><td class="k">CourseCard</td><td><code>goal</code> ▲ · <code>gifUrl</code> ○16:9 · <code>dots</code> ● · <code>entry</code> ①② · <code>flipMs</code>=8000</td></tr>
<tr><td class="k">RouteLine</td><td><code>path</code> 实线段 · <code>rel</code> 虚线 · <code>family</code> 点线 · <code>stations</code> · <code>capsule</code></td></tr>
<tr><td class="k">指派票</td><td><code>pos</code> 位置 · <code>expect</code> 预期 · <code>scenes[]</code> 场景</td></tr>
<tr><td class="k">脱靶注</td><td><code>how</code> 怎么脱靶 · <code>looks</code> 什么样</td></tr>
</table>
<div style="font-size:12px; color:#555; line-height:1.6; margin-top:10px;">入口徽章 ①②③=读者画像推荐起点(EntryGuide),非强制排序。</div>
</div>
<div style="position:absolute; top: 506px; left: 948px; width: 292px;" class="panel">
<h3>组件原则</h3>
<div class="note" style="margin-bottom:6px;"><span class="idx">1</span><span class="txt"><b>卡不可缺</b>:入口与预期永远以卡呈现。</span></div>
<div class="note" style="margin-bottom:6px;"><span class="idx">2</span><span class="txt"><b>线不可缺</b>:章节之间必有关系可读。</span></div>
<div class="note" style="margin-bottom:0;"><span class="idx">3</span><span class="txt"><b>无锁</b>:任何状态不阻断进入(死原则)。</span></div>
</div>
<div class="footline">设计系统 · 03 组件 · stack idealjs</div>
<div class="pagenum">03 / 04</div>
</div>
<!-- ================= P4 样例 ================= -->
<div class="page">
<div class="story-head">
<span class="tag">&lt;DesignSystem /&gt; 04</span>
<h2>样例 · 组合场景与概念映射</h2>
<div class="desc">全系统同台:拟物卡 + 三种关系线 + 指派票与脱靶注 + 散落语义形状。右侧是 ai-era-tutorial 概念到组件的完整映射。</div>
</div>
<div class="canvas" style="top: 138px; left: 40px; width: 880px; height: 594px; padding: 0; overflow: hidden; background:#fff9f0;">
<svg style="position:absolute; left:0; top:0;" width="880" height="594" viewBox="0 0 880 594">
<path d="M 560 8 l 16 28 h -32 z" fill="#ffd93d" stroke="#111" stroke-width="2.5"/>
<circle cx="812" cy="96" r="8" fill="#4ecdc4" stroke="#111" stroke-width="2"/>
<circle cx="838" cy="82" r="5" fill="#ff8fab" stroke="#111" stroke-width="2"/>
<circle cx="826" cy="118" r="4" fill="#ffd93d" stroke="#111" stroke-width="2"/>
<path d="M 24 330 q 8 -22 16 0 t16 0 t16 0 t16 0" fill="none" stroke="#5b8def" stroke-width="3" stroke-linecap="round"/>
<path d="M 762 270 l 10 20 22 3 -16 15 4 22 -20 -11 -20 11 4 -22 -16 -15 22 -3 z" fill="#a78bfa" stroke="#111" stroke-width="2"/>
<path d="M 76 544 L 70 537 L 82 530 L 70 523 L 82 516 L 76 509" fill="none" stroke="#ff6b6b" stroke-width="3" stroke-linejoin="round" stroke-linecap="round"/>
<circle cx="852" cy="192" r="10" fill="none" stroke="#4ecdc4" stroke-width="4"/><circle cx="852" cy="192" r="10" fill="none" stroke="#111" stroke-width="1.5"/>
<path d="M 624 470 v22 M613 481 h22" stroke="#a78bfa" stroke-width="4" stroke-linecap="round"/><path d="M 624 470 v22 M613 481 h22" stroke="#111" stroke-width="1.2"/>
<path d="M 810 250 v20 M800 260 h20" stroke="#5b8def" stroke-width="4" stroke-linecap="round"/><path d="M 810 250 v20 M800 260 h20" stroke="#111" stroke-width="1.2"/>
<path class="msline" d="M 299 180 H 302 A 8 8 0 0 0 310 172 V 116 A 8 8 0 0 1 318 108 H 378"/>
<path class="msline" d="M 639 108 H 699"/>
<path d="M 505 237 V 266" fill="none" stroke="#111" stroke-width="2" stroke-dasharray="4 2"/>
<path d="M 600 237 V 150 H 698" fill="none" stroke="#111" stroke-width="2.4" stroke-dasharray="0.1 6" stroke-linecap="round"/>
<circle class="msstation" cx="299" cy="180" r="6" fill="#ffd93d"/>
<circle class="msstation" cx="378" cy="108" r="6" fill="#4ecdc4"/>
<circle class="msstation" cx="639" cy="108" r="6" fill="#ffd93d"/>
<circle class="msstation" cx="699" cy="108" r="6" fill="#ff8fab"/>
</svg>
<div class="mscard" style="left:40px; top:110px; width:250px;">
<span class="entry-badge2">①</span>
<div class="mszone" style="background:#ff6b6b;"><span>🌐</span>
<span style="position:absolute; left:6px; top:5px; font-size:8.5px; color:#fff9f0; font-weight:700; letter-spacing:1px;">预期结果 · GIF</span>
</div>
<div class="mst"><span class="tri"></span><b>快速开始</b><span class="dots"><i class="on"></i><i class="on"></i><i class="on"></i><i></i></span></div>
</div>
<div class="mscard" style="left:380px; top:44px; width:250px; transform:rotate(-1deg);">
<span class="entry-badge2">②</span>
<div class="mszone" style="background:#ff8fab;"><span>⚛️</span></div>
<div class="mst"><span class="tri"></span><b>React</b><span class="dots"><i class="on"></i><i class="on"></i><i></i><i></i></span></div>
</div>
<div class="mscard" style="left:700px; top:44px; width:140px;">
<div class="mszone" style="height:78px; background:#5b8def;"><span style="font-size:22px;">🔗</span></div>
<div class="mst"><span class="tri"></span><b style="font-size:12px;">全栈基础</b></div>
</div>
<div class="msticket pk" style="left:380px; top:268px;">
<div class="tl" style="background:#a78bfa;">+</div>
<div class="tb"><b>指派学习 · npm</b><div class="no">位置 / 预期 / 场景</div></div>
<div class="stub">+</div>
</div>
<div style="position:absolute; left:40px; top:420px; width:300px;">
<div style="display:flex; align-items:center; gap:8px;">
<svg width="22" height="22"><path d="M 11 20 L 8 17 L 14 14 L 8 11 L 14 8 L 11 4" fill="none" stroke="#ff6b6b" stroke-width="3" stroke-linejoin="round" stroke-linecap="round"/></svg>
<b style="font-size:12px;">脱靶提醒</b>
</div>
<div style="font-size:11px; color:#3d3d3d; line-height:1.6; margin-top:6px;">常见脱靶:装了但没跑。脱靶的样子——命令成功、页面空白;此时缺的是"真机验收"这块积木。</div>
</div>
<div style="position:absolute; left:380px; top:430px; display:flex; align-items:center; gap:8px;">
<svg width="40" height="20"><path d="M2 12 q5 -16 10 0 t10 0 t10 0" fill="none" stroke="#5b8def" stroke-width="3" stroke-linecap="round"/></svg>
<span style="font-size:11px; color:#3d3d3d;"><b>代理区</b>:安装交给 agent,只验收产物</span>
</div>
<div style="position:absolute; left:660px; top:430px; display:flex; align-items:center; gap:8px;">
<svg width="34" height="20"><rect x="2" y="6" width="30" height="9" fill="#ff8fab" stroke="#111" stroke-width="2"/></svg>
<span style="font-size:11px; color:#3d3d3d;"><b>价值区</b>:过程就地写清</span>
</div>
<div style="position:absolute; left:40px; top:562px; font-size:10.5px; color:#8a7a5c;">形状散落于空白,每个都有含义:▲ 靶子 · ● 积木 · ○ 预期 · ~ 代理区 · ▬ 价值区 · ⌇ 脱靶 · + 指派;线:实=先后 · 虚=相关 · 点=同族</div>
</div>
<div style="position:absolute; top: 138px; left: 948px; width: 292px;" class="panel">
<h3>概念 → 组件映射</h3>
<table class="spec" style="font-size:11.5px;">
<tr><th>skill 概念</th><th>组件</th></tr>
<tr><td class="k">靶子先行</td><td>卡头三件套:▲+○16:9+●点列</td></tr>
<tr><td class="k">步骤=目标+验收</td><td>卡内验收行(○ 空环待勾)</td></tr>
<tr><td class="k">代理区</td><td>~ 波浪带,"交给 agent"</td></tr>
<tr><td class="k">价值区</td><td>▬ 实心条,过程就地展开</td></tr>
<tr><td class="k">指派学习</td><td>+ 三行票:位置/预期/场景</td></tr>
<tr><td class="k">脱靶提醒</td><td>⌇ 竖抖注,跟在指派后</td></tr>
<tr><td class="k">认知基础</td><td>底座纹与"真机验收"章</td></tr>
<tr><td class="k">死原则</td><td>无锁:状态=推荐,卡永远可入</td></tr>
</table>
</div>
<div style="position:absolute; top: 470px; left: 948px; width: 292px;" class="panel">
<h3>组合规则</h3>
<div class="note" style="margin-bottom:6px;"><span class="idx">1</span><span class="txt"><b>撞色在框内</b>:章节色只进 16:9 相框,卡面纸色。</span></div>
<div class="note" style="margin-bottom:6px;"><span class="idx">2</span><span class="txt"><b>站点贴边</b>:左贴描边、右骑硬投影外缘;虚线/点线无站点。</span></div>
<div class="note" style="margin-bottom:6px;"><span class="idx">3</span><span class="txt"><b>入口徽章</b> ①②③:推荐起点,非强制。</span></div>
<div class="note" style="margin-bottom:0;"><span class="idx">4</span><span class="txt"><b>形状不压内容</b>:只在空白,密度 ≤ 8/屏。</span></div>
</div>
<div class="footline">设计系统 · 04 样例 · stack idealjs</div>
<div class="pagenum">04 / 04</div>
</div>
</body>
</html>