- 黑顶栏/米白底/统计卡行/双列课程卡/高亮媒体播放卡/右侧彩色事件栏 - hover 态 = 白卡翻淡彩媒体卡 + 黑色圆形播放钮 + ⏱ 胶囊(复刻原稿播放器) - tokens 更新:骨架色 + 淡彩底 + 课程色→淡彩映射 - visual-judge 验收 5/5(P2 卡区溢出经数值定位后修复)
587 lines
31 KiB
HTML
587 lines
31 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="zh-CN">
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<title>课程书架 设计稿 v2 · 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);
|
||
}
|
||
}
|
||
|
||
/* ====== 通用元素 ====== */
|
||
.kicker { font-size: 15px; letter-spacing: 4px; font-weight: 500; color: #6b6b6b; text-transform: uppercase; }
|
||
.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; }
|
||
|
||
.pagehead { position: absolute; top: 40px; left: 40px; right: 40px; display: flex; align-items: baseline; justify-content: space-between; }
|
||
.pagehead h2 { margin: 0; font-size: 30px; font-weight: 800; color: #1a1a1a; }
|
||
.pagehead .sub { font-size: 15px; color: #6b6b6b; }
|
||
|
||
.note { display: flex; gap: 10px; align-items: flex-start; margin-bottom: 10px; }
|
||
.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: 14px; line-height: 1.55; color: #3d3d3d; }
|
||
.note .txt b { color: #1a1a1a; }
|
||
.panel { background: #ffffff; border-radius: 18px; padding: 20px 22px; box-shadow: 0 1px 2px rgba(26,26,26,0.06); }
|
||
.panel h3 { margin: 0 0 12px; font-size: 17px; font-weight: 700; color: #1a1a1a; }
|
||
.pin {
|
||
position: absolute; width: 24px; height: 24px; border-radius: 50%;
|
||
background: #1a1a1a; color: #fff; font-size: 13px; font-weight: 700;
|
||
display: flex; align-items: center; justify-content: center;
|
||
box-shadow: 0 0 0 4px rgba(26,26,26,0.12); z-index: 5;
|
||
}
|
||
|
||
/* ====== 复刻组件:黑色顶栏 ====== */
|
||
.topbar {
|
||
height: 46px;
|
||
background: #111111;
|
||
color: #b9b9b9;
|
||
border-radius: 12px 12px 0 0;
|
||
display: flex;
|
||
align-items: center;
|
||
padding: 0 16px;
|
||
gap: 22px;
|
||
font-size: 12.5px;
|
||
}
|
||
.topbar .logo { color: #ffffff; font-weight: 800; letter-spacing: 0.5px; font-size: 13.5px; }
|
||
.topbar .menu { display: flex; gap: 20px; margin: 0 auto; }
|
||
.topbar .menu span.active { color: #ffffff; font-weight: 600; }
|
||
.topbar .ava {
|
||
width: 24px; height: 24px; border-radius: 50%;
|
||
background: linear-gradient(135deg, #6366f1, #ec4899);
|
||
display: flex; align-items: center; justify-content: center;
|
||
color: #fff; font-size: 11px; font-weight: 700;
|
||
}
|
||
.topbar .bell { font-size: 14px; }
|
||
|
||
/* ====== 复刻组件:统计卡 ====== */
|
||
.stats { display: flex; gap: 14px; }
|
||
.stat {
|
||
flex: 1; border-radius: 16px; padding: 10px 14px 8px;
|
||
display: flex; flex-direction: column; gap: 2px;
|
||
}
|
||
.stat .num { font-size: 24px; font-weight: 800; color: #1a1a1a; }
|
||
.stat .lab { font-size: 11px; color: #6b6b6b; letter-spacing: 0.5px; }
|
||
|
||
/* ====== 复刻组件:课程卡(白卡 / 高亮媒体卡) ====== */
|
||
.course-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; position: relative; }
|
||
.ccard {
|
||
background: #ffffff;
|
||
border-radius: 16px;
|
||
padding: 10px 12px 10px 14px;
|
||
box-shadow: 0 1px 2px rgba(26,26,26,0.06);
|
||
position: relative;
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 5px;
|
||
}
|
||
.ccard .icorow { display: flex; justify-content: space-between; align-items: flex-start; }
|
||
.ccard .ico {
|
||
width: 26px; height: 26px; border-radius: 9px;
|
||
display: flex; align-items: center; justify-content: center;
|
||
font-size: 15px;
|
||
}
|
||
.ccard .ttl { font-size: 13.5px; font-weight: 700; color: #1a1a1a; margin: 0; }
|
||
.ccard .dsc { font-size: 11px; line-height: 1.4; color: #8a8a8a; margin: 0; flex: 1; }
|
||
.ccard .btm { display: flex; align-items: center; justify-content: space-between; }
|
||
.pill {
|
||
font-size: 10.5px; padding: 3px 11px; border-radius: 999px; font-weight: 600;
|
||
}
|
||
.pill.done { background: #efe6fb; color: #6d28d9; }
|
||
.pill.wip { background: #ffffff; color: #6b6b6b; border: 1px solid #d5d5d3; }
|
||
.pill.time { background: #ffffff; color: #1a1a1a; border: 1px solid #d5d5d3; }
|
||
.cbtn {
|
||
width: 26px; height: 26px; border-radius: 50%;
|
||
background: #1a1a1a; color: #ffffff;
|
||
display: flex; align-items: center; justify-content: center;
|
||
font-size: 12px;
|
||
}
|
||
.chips { display: flex; gap: 6px; flex-wrap: wrap; }
|
||
.chip { font-size: 10px; color: #555; border: 1px solid #cfcfcd; border-radius: 999px; padding: 1px 8px; }
|
||
|
||
/* 高亮媒体卡(hover 态复刻:原稿粉紫卡 → 我们用各章淡彩) */
|
||
.ccard.media { background: var(--tint, #e0e7ff); box-shadow: none; }
|
||
.ccard.media .player {
|
||
flex: 1; min-height: 54px; border-radius: 12px;
|
||
background: var(--tint, #e0e7ff);
|
||
display: flex; align-items: center; justify-content: center;
|
||
position: relative;
|
||
}
|
||
.playbtn {
|
||
width: 44px; height: 44px; border-radius: 50%;
|
||
background: #111111; color: #ffffff;
|
||
display: flex; align-items: center; justify-content: center;
|
||
font-size: 16px;
|
||
box-shadow: 0 4px 14px rgba(17,17,17,0.28);
|
||
}
|
||
|
||
/* ====== 复刻组件:左窄图标栏 ====== */
|
||
.rail {
|
||
width: 40px;
|
||
background: #ffffff;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
gap: 14px;
|
||
padding: 14px 0;
|
||
font-size: 14px;
|
||
color: #8a8a8a;
|
||
}
|
||
|
||
/* ====== 复刻组件:右侧事件栏 ====== */
|
||
.events { display: flex; flex-direction: column; gap: 10px; }
|
||
.events .hd { font-size: 14px; font-weight: 700; color: #1a1a1a; }
|
||
.ev {
|
||
border-radius: 14px; padding: 10px 12px;
|
||
display: flex; flex-direction: column; gap: 3px;
|
||
}
|
||
.ev .r1 { display: flex; justify-content: space-between; align-items: center; font-size: 10.5px; font-weight: 700; color: #1a1a1a; }
|
||
.ev .date { font-size: 9.5px; color: #6b6b6b; font-weight: 600; }
|
||
.ev .r2 { font-size: 10.5px; color: #555; line-height: 1.45; }
|
||
.ev .r3 { font-size: 9.5px; color: #6b6b6b; }
|
||
|
||
/* ====== P3 解剖大卡 ====== */
|
||
.bigcard {
|
||
position: absolute;
|
||
width: 396px;
|
||
background: #ffffff;
|
||
border-radius: 20px;
|
||
box-shadow: 0 1px 2px rgba(26,26,26,0.08);
|
||
padding: 20px 22px;
|
||
display: flex;
|
||
flex-direction: column;
|
||
gap: 10px;
|
||
}
|
||
.bigcard.media-card { background: #e0e7ff; box-shadow: none; }
|
||
.bigcard .m-player {
|
||
height: 190px; border-radius: 14px; background: #e0e7ff;
|
||
display: flex; align-items: center; justify-content: center; position: relative;
|
||
}
|
||
.bigcard .m-playbtn { width: 56px; height: 56px; border-radius: 50%; background: #111; color: #fff; display: flex; align-items: center; justify-content: center; font-size: 20px; box-shadow: 0 6px 18px rgba(17,17,17,0.3); }
|
||
.bigcard .m-time { position: absolute; left: 12px; bottom: 10px; background: #ffffff; border-radius: 999px; padding: 3px 12px; font-size: 12px; color: #1a1a1a; border: 1px solid #d5d5d3; }
|
||
.legendbox { position: absolute; width: 396px; }
|
||
|
||
/* ====== P4 流程 ====== */
|
||
.flow { display: flex; align-items: stretch; }
|
||
.flow .step {
|
||
flex: 1; background: #ffffff; border-radius: 14px; padding: 13px 14px 11px;
|
||
position: relative; margin-right: 26px;
|
||
box-shadow: 0 1px 2px rgba(26,26,26,0.06);
|
||
}
|
||
.flow .step:last-child { margin-right: 0; }
|
||
.flow .step::after {
|
||
content: ""; position: absolute; right: -20px; top: 50%;
|
||
width: 13px; height: 13px; border-top: 2px solid #8a8a8a; border-right: 2px solid #8a8a8a;
|
||
transform: translateY(-50%) rotate(45deg);
|
||
}
|
||
.flow .step:last-child::after { display: none; }
|
||
.flow .s-no { font-size: 11.5px; color: #6d28d9; font-weight: 700; letter-spacing: 1px; }
|
||
.flow .s-t { font-size: 15px; font-weight: 700; color: #1a1a1a; margin: 3px 0 5px; }
|
||
.flow .s-d { font-size: 12.5px; line-height: 1.55; color: #555; }
|
||
table.spec { width: 100%; border-collapse: collapse; font-size: 13.5px; color: #3d3d3d; }
|
||
table.spec th { text-align: left; font-weight: 700; color: #1a1a1a; border-bottom: 2px solid #d5d5d3; padding: 7px 10px 7px 0; }
|
||
table.spec td { border-bottom: 1px solid #ececea; padding: 8px 10px 8px 0; vertical-align: top; }
|
||
table.spec td.k { color: #1a1a1a; font-weight: 600; white-space: nowrap; }
|
||
|
||
/* ====== P5 tokens ====== */
|
||
.swatches { display: flex; gap: 12px; flex-wrap: wrap; }
|
||
.swatch { width: 104px; }
|
||
.swatch .c { height: 50px; border-radius: 12px; border: 1px solid rgba(26,26,26,0.08); }
|
||
.swatch .n { font-size: 12px; font-weight: 700; color: #1a1a1a; margin-top: 6px; }
|
||
.swatch .h { font-size: 11px; color: #8a8a8a; }
|
||
.statecard { width: 208px; border-radius: 14px; padding: 10px 12px; background: #fff; box-shadow: 0 1px 2px rgba(26,26,26,0.06); }
|
||
.statecard.hov { background: #e0e7ff; box-shadow: none; }
|
||
.statecard .m { height: 58px; border-radius: 10px; background: #ececea; display:flex; align-items:center; justify-content:center; color:#8a8a8a; font-size: 11px; }
|
||
.statecard.hov .m { background: #e0e7ff; color: #1a1a1a; }
|
||
.statecard .t { font-size: 12.5px; font-weight: 700; color: #1a1a1a; margin-top: 7px; }
|
||
|
||
/* ====== P1 封面 ====== */
|
||
.cover .bandtop { position: absolute; top: 0; left: 0; right: 0; height: 46px; background: #111; color: #b9b9b9; display: flex; align-items: center; padding: 0 40px; gap: 26px; font-size: 13px; }
|
||
.cover .bandtop .logo { color: #fff; font-weight: 800; font-size: 15px; }
|
||
.cover .bandtop .menu { display: flex; gap: 24px; margin: 0 auto; }
|
||
.cover .bandtop .menu .active { color: #fff; }
|
||
.cover .bandtop .ava { width: 26px; height: 26px; border-radius: 50%; background: linear-gradient(135deg,#6366f1,#ec4899); }
|
||
</style>
|
||
</head>
|
||
<body>
|
||
|
||
<!-- ================= P1 封面 ================= -->
|
||
<div class="page cover">
|
||
<div class="bandtop">
|
||
<span class="logo">stack·idealjs</span>
|
||
<span class="menu"><span class="active">全栈教程 🎓</span><span>工具使用</span><span>博客</span></span>
|
||
<span class="ava"></span>
|
||
</div>
|
||
<div style="position:absolute; top: 118px; left: 80px;" class="kicker-box">
|
||
<div class="kicker">STACK IDEALJS · 全栈工程师教程</div>
|
||
</div>
|
||
<h1 style="position:absolute; top: 208px; left: 80px; margin:0; font-size:92px; line-height:1.12; font-weight:800; color:#1a1a1a; letter-spacing:2px;">课程书架<br>设计稿 v2</h1>
|
||
<div style="position:absolute; top: 448px; left: 80px; font-size:21px; color:#555; line-height:1.65;">
|
||
课程预览从目录树改为卡片书架 · 复刻 Learning Plan Dashboard 视觉语言<br>
|
||
每卡承载 title / desc / done / relations,悬停即在卡内循环播放预期成果 GIF
|
||
</div>
|
||
<div style="position:absolute; top: 586px; left: 80px; width: 560px;" class="stats">
|
||
<div class="stat" style="background:#c9e7f7;"><span class="num">6</span><span class="lab">Total Sections · 教程部分</span></div>
|
||
<div class="stat" style="background:#d2f5df;"><span class="num">5</span><span class="lab">Completed · 已完成 🎉</span></div>
|
||
<div class="stat" style="background:#efe6fb;"><span class="num">1</span><span class="lab">Upcoming · 写作中</span></div>
|
||
</div>
|
||
<div style="position:absolute; bottom: 40px; right: 80px; text-align:right; font-size:14.5px; color:#8a8a8a; line-height:1.9;">
|
||
v2.0 · 2026-10 · 分支 feat/course-shelf<br>
|
||
视觉复刻自 00 · E-learning Learning Plan Dashboard(Dribbble,仅风格参考)
|
||
</div>
|
||
<div class="pagenum">01 / 05</div>
|
||
</div>
|
||
|
||
<!-- ================= P2 整体布局(核心复刻页) ================= -->
|
||
<div class="page">
|
||
<div class="pagehead">
|
||
<h2>01 整体布局 · Learning Plan 式课程书架</h2>
|
||
<span class="sub">复刻要素:黑顶栏 · 统计卡行 · 双列课程卡 · 高亮媒体卡 · 右侧事件栏</span>
|
||
</div>
|
||
|
||
<!-- Dashboard 框 -->
|
||
<div style="position:absolute; top: 106px; left: 40px; width: 852px; height: 640px; background:#f0f0ef; border-radius:12px; box-shadow:0 8px 26px rgba(26,26,26,0.14);">
|
||
<div class="topbar">
|
||
<span class="logo">stack·idealjs</span>
|
||
<span class="menu"><span class="active">全栈教程 🎓</span><span>工具使用</span><span>实践经历</span><span>博客</span></span>
|
||
<span class="bell">🔔</span>
|
||
<span class="ava">初</span>
|
||
</div>
|
||
<div style="display:flex; height: 594px;">
|
||
<!-- 左窄图标栏 -->
|
||
<div class="rail" style="height:100%;">
|
||
<span>🏠</span><span>📚</span><span>🧩</span><span>⚙️</span>
|
||
</div>
|
||
<!-- 主区 -->
|
||
<div style="flex:1; padding: 14px 14px 10px 12px; display:flex; flex-direction:column; gap:10px;">
|
||
<div style="display:flex; align-items:center; justify-content:space-between;">
|
||
<div style="font-size:19px; font-weight:800; color:#1a1a1a;">全栈工程师教程 📚</div>
|
||
<div style="font-size:12px; color:#8a8a8a; background:#fff; border-radius:999px; padding:5px 16px; border:1px solid #d5d5d3;">Search…</div>
|
||
</div>
|
||
<div class="stats">
|
||
<div class="stat" style="background:#c9e7f7;"><span class="num">6</span><span class="lab">Total Sections</span></div>
|
||
<div class="stat" style="background:#d2f5df;"><span class="num">5</span><span class="lab">Completed 🎉</span></div>
|
||
<div class="stat" style="background:#efe6fb;"><span class="num">1</span><span class="lab">Upcoming</span></div>
|
||
</div>
|
||
<div class="course-grid" style="flex:1;">
|
||
<!-- 1 高亮媒体卡 = hover 态 -->
|
||
<div class="ccard media" style="--tint:#e0e7ff;">
|
||
<div class="player">
|
||
<div class="playbtn">▶</div>
|
||
<div class="pill time" style="position:absolute; right:10px; top:8px;">⏱ GIF loop</div>
|
||
</div>
|
||
<div>
|
||
<div class="ttl">快速开始</div>
|
||
<div class="dsc">悬停态:预期成果在卡内循环播放</div>
|
||
</div>
|
||
</div>
|
||
<!-- 2 -->
|
||
<div class="ccard">
|
||
<div class="icorow"><span class="ico" style="background:#fce7f3;">⚛️</span></div>
|
||
<div class="ttl">快速开始 React</div>
|
||
<div class="dsc">用脚手架创建 React 应用,亲手拼出第一个 Todo List。</div>
|
||
<div class="btm"><span class="pill done">✓ Completed 🎉</span><span class="cbtn">✓</span></div>
|
||
</div>
|
||
<!-- 3 -->
|
||
<div class="ccard">
|
||
<div class="icorow"><span class="ico" style="background:#fef3c7;">🧱</span></div>
|
||
<div class="ttl">更多示例</div>
|
||
<div class="dsc">浮动布局等补充示例,巩固前面攒下的积木。</div>
|
||
<div class="btm"><span class="pill done">✓ Completed 🎉</span><span class="cbtn">✓</span></div>
|
||
</div>
|
||
<!-- 4 -->
|
||
<div class="ccard">
|
||
<div class="icorow"><span class="ico" style="background:#d1fae5;">📦</span></div>
|
||
<div class="ttl">更多</div>
|
||
<div class="dsc">把示例工程构建为可发布产物,看清 build 做了什么。</div>
|
||
<div class="btm"><span class="pill done">✓ Completed 🎉</span><span class="cbtn">✓</span></div>
|
||
</div>
|
||
<!-- 5 -->
|
||
<div class="ccard">
|
||
<div class="icorow"><span class="ico" style="background:#e0f2fe;">🔗</span></div>
|
||
<div class="ttl">全栈基础</div>
|
||
<div class="dsc">从网页到服务与数据库,串起最小全栈闭环。</div>
|
||
<div class="btm"><span class="pill wip">Upcoming</span><span class="cbtn">→</span></div>
|
||
</div>
|
||
<!-- 6 -->
|
||
<div class="ccard">
|
||
<div class="icorow"><span class="ico" style="background:#ede9fe;">🧠</span></div>
|
||
<div class="ttl">高级教程</div>
|
||
<div class="dsc">数据流、纯函数、CAP——工程上的心智模型。</div>
|
||
<div class="btm"><span class="pill done">✓ Completed 🎉</span><span class="cbtn">✓</span></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<!-- 右侧事件栏 -->
|
||
<div style="width: 224px; padding: 16px 16px 12px 6px;">
|
||
<div class="events" style="height:100%;">
|
||
<div class="hd">最近更新 😊</div>
|
||
<div class="ev" style="background:#c9e7f7;">
|
||
<div class="r1"><span>新增 · Web</span><span class="date">OCT 02</span></div>
|
||
<div class="r2">「更多示例」补充浮动布局一文</div>
|
||
<div class="r3">09:00</div>
|
||
</div>
|
||
<div class="ev" style="background:#e9c8f5;">
|
||
<div class="r1"><span>章节 · 高级</span><span class="date">SEP 28</span></div>
|
||
<div class="r2">CAP 一讲更新配图与示例</div>
|
||
<div class="r3">14:30</div>
|
||
</div>
|
||
<div class="ev" style="background:#f5e6c4;">
|
||
<div class="r1"><span>计划 · 全栈</span><span class="date">SOON</span></div>
|
||
<div class="r2">「全栈基础」章节开写,占位卡已上架</div>
|
||
<div class="r3">即将开始</div>
|
||
</div>
|
||
<div class="ev" style="background:#d2f5df;">
|
||
<div class="r1"><span>讨论</span><span class="date">OCT 01</span></div>
|
||
<div class="r2">讨论区新增 3 帖,欢迎踩场</div>
|
||
<div class="r3">20:00</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 框外右侧标注 pin(走廊不压内容) -->
|
||
<span class="pin" style="top: 122px; left: 902px;">1</span>
|
||
<span class="pin" style="top: 262px; left: 902px;">2</span>
|
||
<span class="pin" style="top: 330px; left: 902px;">3</span>
|
||
<span class="pin" style="top: 388px; left: 902px;">4</span>
|
||
|
||
<!-- 右侧说明面板 -->
|
||
<div style="position:absolute; top: 106px; left: 948px; width: 292px;">
|
||
<div class="panel">
|
||
<h3>复刻要素对照</h3>
|
||
<div class="note"><span class="idx">1</span><span class="txt"><b>黑色顶栏</b>:白 logo + 居中菜单(当前项白色高亮)+ 🔔 与头像。</span></div>
|
||
<div class="note"><span class="idx">2</span><span class="txt"><b>统计卡行</b>:大数字 + 小灰标签,淡蓝/淡绿/淡紫底。</span></div>
|
||
<div class="note"><span class="idx">3</span><span class="txt"><b>双列课程卡</b>:白卡大圆角,彩色圆角图标、状态胶囊、黑圆确认钮。</span></div>
|
||
<div class="note"><span class="idx">4</span><span class="txt"><b>高亮媒体卡</b>:淡彩底 + 黑色圆形播放钮 + ⏱ 胶囊——即 hover 预览态。</span></div>
|
||
<div class="note"><span class="idx">5</span><span class="txt"><b>右侧事件栏</b>:彩色条目卡承载章节动态(类型 + 日期 + 描述 + 时间)。</span></div>
|
||
</div>
|
||
<div class="panel" style="margin-top: 14px;">
|
||
<h3>与 v1 的差异</h3>
|
||
<div class="note"><span class="idx">A</span><span class="txt">Docusaurus 浅蓝 hero 退场,骨架改为 Learning Plan 仪表盘;卡片语言从「书脊 + 媒体区」改为「图标 + 状态胶囊 + 黑圆按钮」。</span></div>
|
||
<div class="note"><span class="idx">B</span><span class="txt">新增统计行与事件栏,分别对应「积木清单规模」与「章节动态」。</span></div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="footline">课程书架设计稿 v2 · stack idealjs</div>
|
||
<div class="pagenum">02 / 05</div>
|
||
</div>
|
||
|
||
<!-- ================= P3 卡片解剖 · 默认态 vs 悬停态 ================= -->
|
||
<div class="page">
|
||
<div class="pagehead">
|
||
<h2>02 卡片解剖 · 默认白卡 → 悬停媒体卡</h2>
|
||
<span class="sub">悬停 = 卡内嵌播放器,GIF 循环预期成果</span>
|
||
</div>
|
||
|
||
<!-- 左:默认白卡 -->
|
||
<div class="bigcard" style="left: 56px; top: 118px;">
|
||
<div style="display:flex; justify-content:space-between; align-items:flex-start;">
|
||
<span style="width:38px;height:38px;border-radius:12px;background:#e0e7ff;display:flex;align-items:center;justify-content:center;font-size:18px;">🌐</span>
|
||
</div>
|
||
<div>
|
||
<div style="font-size:20px; font-weight:800; color:#1a1a1a;">快速开始</div>
|
||
<div style="font-size:13.5px; color:#8a8a8a; margin-top:4px;">写出第一个网页并在浏览器打开,跑起你的第一个 HTTP 服务器。</div>
|
||
</div>
|
||
<div class="chips"><span class="chip">前置:无</span><span class="chip">关联:快速开始 React</span></div>
|
||
<div style="display:flex; align-items:center; justify-content:space-between;">
|
||
<span class="pill done" style="font-size:12px; padding:4px 14px;">✓ Completed 🎉</span>
|
||
<span class="cbtn" style="width:32px;height:32px;font-size:14px;">✓</span>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 右:悬停媒体卡 -->
|
||
<div class="bigcard media-card" style="left: 700px; top: 118px;">
|
||
<div class="m-player">
|
||
<div class="m-playbtn">▶</div>
|
||
<div class="m-time">⏱ Preview · GIF loop</div>
|
||
</div>
|
||
<div>
|
||
<div style="font-size:20px; font-weight:800; color:#1a1a1a;">快速开始</div>
|
||
<div style="font-size:13.5px; color:#555; margin-top:4px;">预期成果正在卡内循环播放:浏览器打开第一个网页。</div>
|
||
</div>
|
||
<div style="display:flex; align-items:center; justify-content:space-between;">
|
||
<span class="pill time" style="font-size:12px; padding:4px 14px;">⏱ Watching</span>
|
||
<span class="cbtn" style="width:32px;height:32px;font-size:14px;">▶</span>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- pin 标注 -->
|
||
<span class="pin" style="top: 142px; left: 470px;">1</span>
|
||
<span class="pin" style="top: 252px; left: 470px;">2</span>
|
||
<span class="pin" style="top: 335px; left: 470px;">3</span>
|
||
<span class="pin" style="top: 382px; left: 470px;">4</span>
|
||
<span class="pin" style="top: 142px; left: 1114px;">5</span>
|
||
<span class="pin" style="top: 224px; left: 1114px;">6</span>
|
||
<span class="pin" style="top: 392px; left: 1114px;">7</span>
|
||
|
||
<!-- 底部两说明面板 -->
|
||
<div class="legendbox" style="top: 530px; left: 56px;">
|
||
<div class="panel" style="padding: 14px 18px;">
|
||
<h3 style="margin-bottom: 8px;">默认白卡要素</h3>
|
||
<div class="note" style="margin-bottom: 5px;"><span class="idx">1</span><span class="txt"><b>彩色圆角图标</b>:每章一个 emoji 图标,淡彩圆角底。</span></div>
|
||
<div class="note" style="margin-bottom: 5px;"><span class="idx">2</span><span class="txt"><b>标题 + 预期结果一句话</b>:desc 写「学完能做出什么」。</span></div>
|
||
<div class="note" style="margin-bottom: 0;"><span class="idx">3</span><span class="txt"><b>关系 chips</b>:前置 / 关联章节(关系待列,示例为占位)。</span></div>
|
||
</div>
|
||
</div>
|
||
<div class="legendbox" style="top: 530px; left: 700px;">
|
||
<div class="panel" style="padding: 14px 18px;">
|
||
<h3 style="margin-bottom: 8px;">悬停媒体卡(复刻播放器)</h3>
|
||
<div class="note" style="margin-bottom: 5px;"><span class="idx">4</span><span class="txt"><b>状态胶囊 + 黑圆确认钮</b>:✓ Completed 🎉 / Upcoming,点击进入章节。</span></div>
|
||
<div class="note" style="margin-bottom: 5px;"><span class="idx">5</span><span class="txt"><b>淡彩整卡</b>:白卡变为该章主题淡彩底,视觉即「进入预览」。</span></div>
|
||
<div class="note" style="margin-bottom: 0;"><span class="idx">6</span><span class="txt"><b>黑色圆形播放钮 + ⏱ 胶囊</b>:复刻原稿标志元素;此刻才挂载 GIF,移出还原白卡。</span></div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="footline">课程书架设计稿 v2 · stack idealjs</div>
|
||
<div class="pagenum">03 / 05</div>
|
||
</div>
|
||
|
||
<!-- ================= P4 交互与资产 ================= -->
|
||
<div class="page">
|
||
<div class="pagehead">
|
||
<h2>03 交互流程 · 触发矩阵 · GIF 资产规范</h2>
|
||
<span class="sub">预期成果 GIF = 靶子「预期结果」的非文字化</span>
|
||
</div>
|
||
|
||
<div style="position:absolute; top: 118px; left: 40px; right: 40px;">
|
||
<div class="panel" style="padding-bottom: 18px;">
|
||
<h3>悬停播放时序</h3>
|
||
<div class="flow">
|
||
<div class="step"><div class="s-no">STEP 1</div><div class="s-t">指针进入</div><div class="s-d">mouseenter / focus-visible 触发,白卡翻为淡彩媒体卡。</div></div>
|
||
<div class="step"><div class="s-no">STEP 2</div><div class="s-t">挂载播放器</div><div class="s-d">此刻才渲染 GIF,浏览器按需拉取,首屏零动图流量。</div></div>
|
||
<div class="step"><div class="s-no">STEP 3</div><div class="s-t">循环播放</div><div class="s-d">GIF loop=0 自动循环,卡内嵌播放,无控件无声音。</div></div>
|
||
<div class="step"><div class="s-no">STEP 4</div><div class="s-t">移出还原</div><div class="s-d">mouseleave 还原白卡;HTTP 缓存保留,再悬停瞬时恢复。</div></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div style="position:absolute; top: 372px; left: 40px; width: 590px;">
|
||
<div class="panel">
|
||
<h3>触发矩阵</h3>
|
||
<table class="spec">
|
||
<tr><th>设备 / 输入</th><th>行为</th></tr>
|
||
<tr><td class="k">桌面 · 鼠标 hover</td><td>白卡 → 媒体卡播放预览;点击卡片进入章节。</td></tr>
|
||
<tr><td class="k">键盘 · Tab focus</td><td>与 hover 同态(可访问性),Enter 进入章节。</td></tr>
|
||
<tr><td class="k">触屏 · 无 hover</td><td>不做预览态;首次点击直接进入章节,避免误触耗流量。</td></tr>
|
||
<tr><td class="k">减弱动效偏好</td><td>prefers-reduced-motion 时显示静帧,不自动播放。</td></tr>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
|
||
<div style="position:absolute; top: 372px; left: 662px; width: 578px;">
|
||
<div class="panel">
|
||
<h3>GIF 资产规范(6 张占位已入库)</h3>
|
||
<table class="spec">
|
||
<tr><th>项</th><th>约定</th></tr>
|
||
<tr><td class="k">尺寸 / 画幅</td><td>640 × 360 · 16:9 覆盖媒体区,object-fit: cover。</td></tr>
|
||
<tr><td class="k">时长与循环</td><td>3–8s · 无限循环(loop=0)· 无声。</td></tr>
|
||
<tr><td class="k">体积</td><td>单张 ≤ 300KB(当前占位 72–101KB)。</td></tr>
|
||
<tr><td class="k">命名替换</td><td>static/gifs/<id>.gif 同名覆盖即换片,零代码改动。</td></tr>
|
||
<tr><td class="k">内容口径</td><td>拍「学完后的真实产物」:跑起来的页面、终端输出、可核对结果。</td></tr>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="footline">课程书架设计稿 v2 · stack idealjs</div>
|
||
<div class="pagenum">04 / 05</div>
|
||
</div>
|
||
|
||
<!-- ================= P5 设计 Tokens ================= -->
|
||
<div class="page">
|
||
<div class="pagehead">
|
||
<h2>04 设计 Tokens · 复刻配色 / 课程色 / 状态</h2>
|
||
<span class="sub">骨架色取自 Learning Plan Dashboard,课程色沿用六章映射</span>
|
||
</div>
|
||
|
||
<div style="position:absolute; top: 118px; left: 40px; width: 566px;">
|
||
<div class="panel">
|
||
<h3>骨架色(复刻)</h3>
|
||
<div class="swatches">
|
||
<div class="swatch"><div class="c" style="background:#111111"></div><div class="n">顶栏黑</div><div class="h">#111111</div></div>
|
||
<div class="swatch"><div class="c" style="background:#f0f0ef; border:1px solid #d5d5d3;"></div><div class="n">页面米白</div><div class="h">#F0F0EF</div></div>
|
||
<div class="swatch"><div class="c" style="background:#ffffff; border:1px solid #d5d5d3;"></div><div class="n">卡白</div><div class="h">#FFFFFF</div></div>
|
||
<div class="swatch"><div class="c" style="background:#1a1a1a"></div><div class="n">文字主黑</div><div class="h">#1A1A1A</div></div>
|
||
<div class="swatch"><div class="c" style="background:#8a8a8a"></div><div class="n">文字次灰</div><div class="h">#8A8A8A</div></div>
|
||
</div>
|
||
<h3 style="margin-top:16px;">淡彩底(统计卡 / 媒体卡 / 事件栏)</h3>
|
||
<div class="swatches">
|
||
<div class="swatch"><div class="c" style="background:#c9e7f7"></div><div class="n">事件蓝</div><div class="h">#C9E7F7</div></div>
|
||
<div class="swatch"><div class="c" style="background:#e9c8f5"></div><div class="n">事件紫</div><div class="h">#E9C8F5</div></div>
|
||
<div class="swatch"><div class="c" style="background:#f5e6c4"></div><div class="n">事件黄</div><div class="h">#F5E6C4</div></div>
|
||
<div class="swatch"><div class="c" style="background:#d2f5df"></div><div class="n">事件绿</div><div class="h">#D2F5DF</div></div>
|
||
<div class="swatch"><div class="c" style="background:#e0e7ff"></div><div class="n">媒体卡 indigo</div><div class="h">#E0E7FF</div></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div style="position:absolute; top: 118px; left: 646px; width: 594px;">
|
||
<div class="panel">
|
||
<h3>课程色 → 淡彩底映射(图标底 / 媒体卡底)</h3>
|
||
<table class="spec">
|
||
<tr><th>章节</th><th>图标底(淡彩)</th><th>强调色</th></tr>
|
||
<tr><td class="k">快速开始</td><td>#E0E7FF</td><td>#6366F1</td></tr>
|
||
<tr><td class="k">快速开始 React</td><td>#FCE7F3</td><td>#EC4899</td></tr>
|
||
<tr><td class="k">更多示例</td><td>#FEF3C7</td><td>#F59E0B</td></tr>
|
||
<tr><td class="k">更多</td><td>#D1FAE5</td><td>#10B981</td></tr>
|
||
<tr><td class="k">全栈基础</td><td>#E0F2FE</td><td>#0EA5E9</td></tr>
|
||
<tr><td class="k">高级教程</td><td>#EDE9FE</td><td>#8B5CF6</td></tr>
|
||
</table>
|
||
</div>
|
||
<div class="panel" style="margin-top: 14px;">
|
||
<h3>状态示意</h3>
|
||
<div style="display:flex; gap: 24px; align-items:flex-start;">
|
||
<div class="statecard">
|
||
<div class="m">白卡 · 静止</div>
|
||
<div class="t">default</div>
|
||
</div>
|
||
<div class="statecard hov">
|
||
<div class="m">▶ 播放中</div>
|
||
<div class="t">hover / focus</div>
|
||
</div>
|
||
</div>
|
||
<div style="margin-top: 12px; font-size:12.5px; color:#555; line-height:1.7;">
|
||
hover:白卡翻为该章淡彩媒体卡,黑色圆形播放钮与 ⏱ 胶囊出现;键盘 Tab 与鼠标悬停共享同一态。圆角 14–20px,阴影仅 0 1px 2px 极轻一级。
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="footline">课程书架设计稿 v2 · stack idealjs · relations 待产品列出后填充</div>
|
||
<div class="pagenum">05 / 05</div>
|
||
</div>
|
||
|
||
</body>
|
||
</html>
|