feat: 布局三修——navbar 下方统一 32px 间距(章节页横幅零间距修复);选中项背景=章节色(与章头横幅统一,书架选中 ink);字体系统(16px 基准=正文 / t1-t3 三级标题 / 小字两态 mute·strong / 大字两态 t1·幽灵 display 章号)全站应用
This commit is contained in:
1 parent
8454a7abab
commit
a65a6d96b1
4 files changed
+74
-26
No files matched your search
@@ -23,15 +23,18 @@ export function ChapterPage({ id }: { id: ChapterId }) {
|
||||
<Page active={id}>
|
||||
{/* 章头:与书架相框共享 view-transition-name —— 点卡片进来时相框飞进来变成章头 */}
|
||||
<div
|
||||
className="flex items-center gap-4 rounded-2xl border-2 border-ink p-5 shadow-hard"
|
||||
className="relative flex items-center gap-4 overflow-hidden rounded-2xl border-2 border-ink p-5 shadow-hard"
|
||||
style={{ background: ch.color, viewTransitionName: `ch-${id}` } as CSSProperties}
|
||||
>
|
||||
<span className="t-display pointer-events-none absolute -right-2 -top-3 select-none" aria-hidden>
|
||||
0{id}
|
||||
</span>
|
||||
<span className="text-[44px] leading-none">{ch.emoji}</span>
|
||||
<div className="flex-1">
|
||||
<h1 className="m-0 text-[24px] font-extrabold text-ink">
|
||||
<h1 className="m-0 text-t1 font-extrabold text-ink">
|
||||
第 {id} 章 · {ch.title}
|
||||
</h1>
|
||||
<div className="mt-1.5 flex flex-wrap gap-x-6 gap-y-1 text-[12px] font-semibold text-ink">
|
||||
<div className="mt-2 flex flex-wrap gap-x-6 gap-y-1 t-small-strong">
|
||||
<span>▲ 目标:{ch.target.goal}</span>
|
||||
<span>○ 预期:{ch.target.expectation}</span>
|
||||
<span className="flex items-center gap-1.5">
|
||||
@@ -52,18 +55,20 @@ export function ChapterPage({ id }: { id: ChapterId }) {
|
||||
{i + 1}
|
||||
</span>
|
||||
{s.kind === 'value' ? (
|
||||
<Mark className="text-[13.5px]">{s.title}</Mark>
|
||||
<Mark className="text-t3">{s.title}</Mark>
|
||||
) : (
|
||||
<span className="flex items-center gap-1.5 text-[13.5px] font-bold text-ink">
|
||||
<span className="flex items-center gap-1.5 text-t3 font-bold text-ink">
|
||||
<Wave size={30} />
|
||||
{s.title}
|
||||
<span className="rounded-full bg-clash3b/15 px-2 py-0.5 text-[10.5px]">代理区 · 交给 agent</span>
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
<p className="m-0 mt-2 text-[12.5px] leading-relaxed text-body">{s.what}</p>
|
||||
<p className="m-0 mt-1.5 text-[12px] text-ink">
|
||||
<b>验收</b>:{s.accept}
|
||||
<p className="m-0 mt-2.5 text-content text-body">{s.what}</p>
|
||||
<p className="m-0 mt-2 text-content text-body">
|
||||
<b className="t-small-strong">验收</b>
|
||||
<span className="mx-1.5 text-mute">·</span>
|
||||
{s.accept}
|
||||
</p>
|
||||
</li>
|
||||
))}
|
||||
@@ -76,9 +81,9 @@ export function ChapterPage({ id }: { id: ChapterId }) {
|
||||
<div key={b.name} className="rounded-xl border-2 border-ink bg-paper p-3.5 shadow-hard">
|
||||
<div className="flex items-center gap-2">
|
||||
<Tri size={13} />
|
||||
<b className="text-[13px]">{b.name}</b>
|
||||
<b className="text-t3">{b.name}</b>
|
||||
</div>
|
||||
<p className="m-0 mt-1.5 text-[11.5px] leading-relaxed text-body">
|
||||
<p className="m-0 mt-2 text-small leading-relaxed text-body">
|
||||
<b>是什么</b>:{b.what}
|
||||
<br />
|
||||
<b>为何在这</b>:{b.why}
|
||||
@@ -94,7 +99,7 @@ export function ChapterPage({ id }: { id: ChapterId }) {
|
||||
<Section label="认知基础" note="脚下的地(env/库/运行环境)——第一次用到就地露出">
|
||||
<div className="flex items-start gap-3 rounded-xl border-2 border-dashed border-ink/40 bg-clash3b/15 p-4">
|
||||
<Ring size={18} className="mt-0.5 shrink-0" />
|
||||
<p className="m-0 text-[12.5px] leading-relaxed text-body">{c.base}</p>
|
||||
<p className="m-0 text-content text-body">{c.base}</p>
|
||||
</div>
|
||||
</Section>
|
||||
)}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
/** 教程站页面骨架:站头导航跨页常驻(view-transition-name 共享元素,页间不闪烁) */
|
||||
/** 教程站页面骨架:站头导航跨页常驻(view-transition-name 共享元素,页间不闪烁)。
|
||||
* 选中项背景色=该章色(与章头 title 横幅统一);书架选中为 ink。 */
|
||||
import type { ReactNode } from 'react'
|
||||
import type { ChapterId } from './types'
|
||||
import { CHAPTERS } from './chapters'
|
||||
@@ -22,39 +23,43 @@ export function Page({
|
||||
/** 章节页标题在章头横幅里,可省 */
|
||||
title?: string
|
||||
desc?: string
|
||||
/** 站头高亮的章节;书架页不传 */
|
||||
active?: ChapterId
|
||||
/** 站头高亮:章节 id 或书架 'index' */
|
||||
active?: ChapterId | 'index'
|
||||
children: ReactNode
|
||||
}) {
|
||||
return (
|
||||
<main className="mx-auto max-w-[1200px] px-6 py-8">
|
||||
<main className="mx-auto max-w-[1200px] px-6 py-8 text-content text-body">
|
||||
<header
|
||||
className="flex flex-wrap items-center gap-1.5 rounded-2xl border-2 border-ink bg-paper p-2.5 shadow-hard"
|
||||
className="mb-8 flex flex-wrap items-center gap-1.5 rounded-2xl border-2 border-ink bg-paper p-2.5 shadow-hard"
|
||||
style={{ viewTransitionName: 'site-header' }}
|
||||
>
|
||||
<a href="/index.html" className="mr-2 rounded-lg bg-ink px-2.5 py-1 font-mono text-[13px] font-bold text-paper no-underline">
|
||||
stack·教程
|
||||
</a>
|
||||
{NAV.map((n) => (
|
||||
{NAV.map((n) => {
|
||||
const on = n.id ? n.id === active : active === 'index'
|
||||
return (
|
||||
<a
|
||||
key={n.href}
|
||||
href={n.href}
|
||||
className={`rounded-lg px-2.5 py-1 text-[12.5px] font-bold no-underline transition-colors ${
|
||||
n.id === active ? 'bg-clash2a text-ink' : 'text-body hover:bg-black/5'
|
||||
on ? (n.id ? 'text-ink' : 'bg-ink text-paper') : 'text-body hover:bg-black/5'
|
||||
}`}
|
||||
style={on && n.id ? { background: CHAPTERS[n.id].color } : undefined}
|
||||
>
|
||||
{n.label}
|
||||
</a>
|
||||
))}
|
||||
)
|
||||
})}
|
||||
</header>
|
||||
{(title || desc) && (
|
||||
<div className="mb-7 mt-7">
|
||||
{title && <h1 className="m-0 text-[28px] font-extrabold text-ink">{title}</h1>}
|
||||
{desc && <p className="m-0 mt-1 text-[14.5px] text-[#6b6b6b]">{desc}</p>}
|
||||
<div className="mb-7">
|
||||
{title && <h1 className="m-0 text-t1 font-extrabold text-ink">{title}</h1>}
|
||||
{desc && <p className="m-0 mt-2 max-w-[72ch] text-content text-mute">{desc}</p>}
|
||||
</div>
|
||||
)}
|
||||
{children}
|
||||
<footer className="mt-12 border-t-2 border-dashed border-ink/15 pt-3 text-[12px] text-[#8a8a8a]">
|
||||
<footer className="mt-12 border-t-2 border-dashed border-ink/15 pt-3 t-small-mute">
|
||||
stack·教程 · 孟菲斯 × 拟物卡 · 靶子先行,步骤=目标+验收
|
||||
</footer>
|
||||
</main>
|
||||
@@ -64,9 +69,9 @@ export function Page({
|
||||
export function Section({ label, note, children }: { label: string; note?: string; children: ReactNode }) {
|
||||
return (
|
||||
<section className="mb-8">
|
||||
<h2 className="mb-2 text-[13.5px] font-bold text-ink">
|
||||
{label}
|
||||
{note && <i className="ml-2 text-[11.5px] font-normal not-italic text-[#6b6b6b]">{note}</i>}
|
||||
<h2 className="mb-2.5 flex flex-wrap items-baseline gap-2">
|
||||
<span className="t-small-strong">{label}</span>
|
||||
{note && <i className="t-small-mute not-italic">{note}</i>}
|
||||
</h2>
|
||||
{children}
|
||||
</section>
|
||||
|
||||
@@ -26,6 +26,7 @@ const GRID: { id: ChapterId; entry?: 1 | 2 | 3 }[] = [
|
||||
export function App() {
|
||||
return (
|
||||
<Page
|
||||
active="index"
|
||||
title="全栈工程师教程 · 书架"
|
||||
desc="靶子先行:每章先给目标、预期结果、积木清单,步骤只写「产出什么+核对什么」;过程有没有学习价值,每步先分类。"
|
||||
>
|
||||
|
||||
@@ -82,3 +82,40 @@
|
||||
animation-duration: 0.01ms;
|
||||
}
|
||||
}
|
||||
|
||||
/* ===== 字体系统 =====
|
||||
* 基准=浏览器默认 16px=正文字号(content,不另设基准)。
|
||||
* 向上:t3 → t2 → t1 三级标题;再向上是大字。
|
||||
* 小字两态:t-small-mute 边缘可忽略(弱化灰)/ t-small-strong 缩小但加强(加粗收字距)。
|
||||
* 大字两态:t1 大而强(页面主标题)/ t-display 大而弱(幽灵背景字,可被忽略)。 */
|
||||
@theme {
|
||||
--text-content: 1rem;
|
||||
--text-content--line-height: 1.75;
|
||||
--text-t3: 1.125rem;
|
||||
--text-t3--line-height: 1.5;
|
||||
--text-t2: 1.375rem;
|
||||
--text-t2--line-height: 1.45;
|
||||
--text-t1: 1.75rem;
|
||||
--text-t1--line-height: 1.3;
|
||||
--text-small: 0.75rem;
|
||||
--text-small--line-height: 1.65;
|
||||
}
|
||||
|
||||
.t-small-mute {
|
||||
font-size: var(--text-small);
|
||||
line-height: var(--text-small--line-height);
|
||||
color: var(--color-mute);
|
||||
}
|
||||
.t-small-strong {
|
||||
font-size: var(--text-small);
|
||||
line-height: 1.5;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.02em;
|
||||
color: var(--color-ink);
|
||||
}
|
||||
.t-display {
|
||||
font-size: 4rem;
|
||||
line-height: 1;
|
||||
font-weight: 800;
|
||||
color: color-mix(in srgb, var(--color-ink) 10%, transparent);
|
||||
}
|
||||
Reference in new issue
Block a user