refactor(site): 섹션 순서를 성격별로 묶고 분량을 우선순위에 맞춘다
Some checks are pending
ci / build (push) Waiting to run
Some checks are pending
ci / build (push) Waiting to run
지적마다 그 섹션만 키운 결과 15.5 화면이 됐고, 기능 설명과 증거가 번갈아 나와 지금 무슨 이야기를 듣고 있는지 알 수 없었다. 순서를 네 묶음으로 정리했다. ① 무엇인가 히어로 · 파이프라인 ② 무엇을 아는가 SVG 필터 · 한글 조판 ③ 정말 그런가 사례 · 수치 · 자기 감사 · 규칙 ④ 행동 설치 분량: - SVG 필터 3.1 → 2.1 화면. 스킬 문서에 있을 구현 디테일을 페이지에 옮겨 적고 있었다. 데모는 넷 다 두고 설명만 줄였다. - .stage 의 padding 에 --wide-pad 를 쓰고 있었다. 이 토큰은 페이지 그리드의 바깥 칼럼용(최대 10rem)이라 1440px 에서 폭 320px 이 사라졌고, 그만큼 설명 칸이 170px 로 눌려 여덟 자마다 줄이 바뀌었다. - 자기 감사 항목 13개 → 6개. 나열이 밀도를 대신하고 있었다. 파이프라인 끝의 마무리 문장을 삭제했다. sticky 게이트가 끝까지 돌 스크롤 구간이 필요해서 만든 자리에 문장을 채운 것이라, 읽는 사람에게는 앞뒤 없이 튀어나온 문장이었다. 여백이 필요하면 여백을 만든다. 전체 15.5 → 13.5 화면.
This commit is contained in:
parent
9a09678dee
commit
3271a329af
5 changed files with 79 additions and 73 deletions
|
|
@ -50,7 +50,6 @@ const MAP_Y = map(true, "rgb(128,255,128)", "rgb(128,0,128)");
|
|||
c.demos.map((d, i) => (
|
||||
<li class="fdemo reveal" style={`--reveal-delay:${i * 70}ms`}>
|
||||
<h3 class="fd-name">{d.name}</h3>
|
||||
<p class="fd-problem">{d.problem}</p>
|
||||
|
||||
<div class="fd-pair">
|
||||
{[false, true].map((on) => (
|
||||
|
|
@ -63,8 +62,11 @@ const MAP_Y = map(true, "rgb(128,255,128)", "rgb(128,0,128)");
|
|||
))}
|
||||
</div>
|
||||
|
||||
<div class="fd-text">
|
||||
<p class="fd-problem">{d.problem}</p>
|
||||
<p class="fd-how muted">{d.how}</p>
|
||||
<p class="fd-verdict mono">{d.verdict}</p>
|
||||
</div>
|
||||
</li>
|
||||
))
|
||||
}
|
||||
|
|
@ -165,7 +167,10 @@ const MAP_Y = map(true, "rgb(128,255,128)", "rgb(128,0,128)");
|
|||
position: relative;
|
||||
max-width: 1180px;
|
||||
margin-inline: auto;
|
||||
padding: var(--wide-pad);
|
||||
/* --wide-pad 는 페이지 그리드의 바깥 칼럼을 정의하는 토큰이다(최대 10rem).
|
||||
여기에 그대로 쓰면 1440px 화면에서 좌우 160px 씩, 폭 320px 이 사라진다.
|
||||
그만큼 오른쪽 설명 칸이 170px 로 줄어 여덟 자마다 줄이 바뀌었다. */
|
||||
padding: var(--space-6);
|
||||
border-radius: var(--radius-frame);
|
||||
overflow: hidden;
|
||||
isolation: isolate;
|
||||
|
|
@ -197,14 +202,26 @@ const MAP_Y = map(true, "rgb(128,255,128)", "rgb(128,0,128)");
|
|||
}
|
||||
.fdemo + .fdemo { border-top: 1px solid var(--line); padding-top: var(--space-6); }
|
||||
|
||||
.fd-name { font-size: var(--step-1); }
|
||||
.fd-problem { max-width: 52ch; color: var(--ink-muted); }
|
||||
/* 데모와 설명을 세로로 쌓으면 한 항목이 320px 을 먹는다.
|
||||
넷이면 섹션이 3.1 화면 — 파이프라인 설명보다 길어졌다.
|
||||
그림은 왼쪽, 말은 오른쪽에 두면 같은 내용이 절반 높이에 들어간다. */
|
||||
.fdemo {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 584px) minmax(0, 1fr);
|
||||
column-gap: var(--space-6);
|
||||
align-items: start;
|
||||
}
|
||||
.fd-name {
|
||||
grid-column: 1 / -1;
|
||||
font-size: var(--step-1);
|
||||
margin-bottom: var(--space-4);
|
||||
}
|
||||
.fd-problem { color: var(--ink-muted); }
|
||||
|
||||
.fd-pair {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(0, 300px));
|
||||
gap: var(--space-4);
|
||||
margin-block: var(--space-4);
|
||||
grid-template-columns: repeat(2, minmax(0, 280px));
|
||||
gap: var(--space-3);
|
||||
}
|
||||
.fd-side { margin: 0; }
|
||||
.fd-tag {
|
||||
|
|
@ -215,13 +232,16 @@ const MAP_Y = map(true, "rgb(128,255,128)", "rgb(128,0,128)");
|
|||
.is-bad { color: var(--ink-muted); }
|
||||
.is-good { color: var(--accent); }
|
||||
|
||||
.fd-how { max-width: 60ch; }
|
||||
.fd-text > * + * { margin-top: var(--space-3); }
|
||||
.fd-verdict {
|
||||
margin: var(--space-2) 0 0;
|
||||
font-size: var(--mono-size);
|
||||
color: var(--accent);
|
||||
}
|
||||
|
||||
@media (max-width: 1080px) {
|
||||
.fdemo { grid-template-columns: 1fr; row-gap: var(--space-4); }
|
||||
}
|
||||
@media (max-width: 720px) {
|
||||
.fd-pair { grid-template-columns: 1fr; }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,7 +49,6 @@ const { c } = Astro.props;
|
|||
))
|
||||
}
|
||||
</ol>
|
||||
<p class="after muted reveal">{c.after}</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
|
@ -169,7 +168,7 @@ const { c } = Astro.props;
|
|||
space-7 까지 올렸더니 이번엔 정거장 사이가 224px 로 벌어져
|
||||
목록이 흩어져 보였다 — 여섯 개가 한 목록으로 안 읽힌다.
|
||||
읽기 간격과 스크롤 구간은 같은 손잡이가 아니다.
|
||||
간격은 읽기에 맞추고, 스크롤 구간은 스파인 뒤 여백(.after)에서 번다. */
|
||||
간격은 읽기에 맞추고, 스크롤 구간은 스파인 뒤 여백에서 번다. */
|
||||
padding-block: var(--stop-pad);
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 0.9fr) minmax(0, 1.1fr);
|
||||
|
|
@ -226,13 +225,11 @@ const { c } = Astro.props;
|
|||
overflow-wrap: anywhere;
|
||||
}
|
||||
|
||||
.after {
|
||||
margin-top: var(--space-7);
|
||||
max-width: var(--measure);
|
||||
/* 여기가 스크롤 구간을 버는 자리다. 정거장 간격을 벌리는 대신
|
||||
마지막 정거장 뒤에 여운을 둔다 — 스파인이 끝난 뒤라 빈 공간으로 읽히지 않는다 */
|
||||
padding-bottom: 62dvh;
|
||||
}
|
||||
/* sticky 게이트가 끝까지 돌려면 스파인 뒤에 스크롤 구간이 필요하다.
|
||||
한동안 여기에 마무리 문장을 한 줄 놓아 그 자리를 채웠는데,
|
||||
읽는 사람에게는 뜬금없는 문장이었다 — 여백이 필요하면 여백을 만든다.
|
||||
문장으로 여백을 대신하지 않는다. */
|
||||
.spine { padding-bottom: 62dvh; }
|
||||
|
||||
@media (max-width: 780px) {
|
||||
.stop {
|
||||
|
|
|
|||
|
|
@ -49,7 +49,6 @@ export interface Content {
|
|||
briefLabel: string;
|
||||
brief: string;
|
||||
stages: Stage[];
|
||||
after: string;
|
||||
};
|
||||
showcase: {
|
||||
h2: string;
|
||||
|
|
@ -208,8 +207,6 @@ export const ko: Content = {
|
|||
briefLabel: "들어온 브리프",
|
||||
brief: "수제 커피 로스터리의 원두 정기구독 랜딩 만들어줘",
|
||||
stages: STAGES_KO,
|
||||
after:
|
||||
"여섯 단계 끝에 남는 것은 페이지 하나와 design.md 하나다. 다음 사람이 그 파일을 읽고 같은 결정을 이어간다.",
|
||||
},
|
||||
showcase: {
|
||||
h2: "결과물은 서로 닮지 않는다",
|
||||
|
|
@ -237,38 +234,38 @@ export const ko: Content = {
|
|||
{
|
||||
id: "scrim",
|
||||
name: "글자 모양대로 생기는 스크림",
|
||||
problem: "사진 위 캡션이 대비 4.5:1 을 못 넘는다. 사진마다 밝기가 달라 반투명 박스를 손으로 맞춰야 한다.",
|
||||
problem: "사진 위 캡션이 대비를 못 넘긴다. 사진마다 밝기가 달라 반투명 박스를 손으로 맞추게 된다.",
|
||||
beforeLabel: "그냥 얹음",
|
||||
afterLabel: "filter: url(#scrim)",
|
||||
how: "feMorphology 로 글자 알파를 부풀리고 블러한 뒤, 그 모양대로만 feFlood 를 채운다. 박스가 아니라 글자를 따라가므로 사진을 가리지 않는다.",
|
||||
verdict: "흰 글자 대비 1.70:1 → 4.79:1 · 사진을 바꿔도 다시 맞출 것이 없다",
|
||||
how: "글자 알파를 부풀려 그 모양대로만 색을 채운다. 박스가 아니라 글자를 따라가므로 사진을 덜 가린다.",
|
||||
verdict: "흰 글자 대비 1.70:1 → 4.79:1",
|
||||
},
|
||||
{
|
||||
id: "cvd",
|
||||
name: "색각 이상 시뮬레이션",
|
||||
problem: "상태를 색으로만 구분하면 남성 12명 중 1명에게 같은 배지가 된다. 눈으로는 절대 못 잡는다.",
|
||||
problem: "상태를 색으로만 구분하면 남성 12명 중 1명에게 같은 배지가 된다. 내 화면만 봐서는 못 잡는다.",
|
||||
beforeLabel: "내가 보는 화면",
|
||||
afterLabel: "적록색약(2형)",
|
||||
how: "feColorMatrix 하나다. 이것만은 sRGB 로 두면 안 된다 — 색각 변환은 물리적 혼합이라 linearRGB 가 맞다. 필터 전체에서 유일한 예외다.",
|
||||
verdict: "세 배지의 최소 색거리 82 → 2 · 주의와 실패가 같은 색이 된다",
|
||||
how: "feColorMatrix 한 줄. 이것만은 linearRGB 로 둔다 — 색각 변환은 물리적인 빛의 혼합이다.",
|
||||
verdict: "배지 셋의 최소 색거리 82 → 2 · 주의와 실패가 같은 색",
|
||||
},
|
||||
{
|
||||
id: "goo",
|
||||
name: "떨어진 것이 하나로 뭉치기",
|
||||
problem: "조각이 서로 녹아 붙는 표현을 하려고 캔버스나 물리 라이브러리를 켠다. 로더, 메뉴 병합, 인디케이터 전환에서 반복된다.",
|
||||
problem: "조각이 녹아 붙는 표현에 캔버스나 물리 라이브러리를 켠다. 로더와 메뉴 전환에서 반복된다.",
|
||||
beforeLabel: "필터 없음 · 원 3개",
|
||||
afterLabel: "filter: url(#goo)",
|
||||
how: "크게 블러한 뒤 feColorMatrix 로 알파만 18배 세워 잘라낸다. 붙을지 말지는 눈대중이 아니라 산수다 — 두 원 사이 중간점의 블러 알파가 문턱(7÷18 ≒ 0.39)을 넘어야 한다. 간격 18px 에 블러 7 로는 0.2 근처라 못 넘었고, 12px 에 10 으로 넘겼다.",
|
||||
verdict: "가로로 세어 덩어리 3개 → 1개 · JS 0줄",
|
||||
how: "블러한 뒤 알파만 세워 잘라낸다. 붙을지 말지는 취향이 아니라 간격과 블러 반경의 비율로 정해진다.",
|
||||
verdict: "덩어리 3개 → 1개 · JS 0줄",
|
||||
},
|
||||
{
|
||||
id: "glass",
|
||||
name: "배경을 휘게 하는 오버레이",
|
||||
problem: "반투명 패널은 뒤를 흐리게만 만든다. 실제 유리는 빛을 휜다 — 그 차이가 패널을 화면 위가 아니라 화면 안에 놓는다.",
|
||||
problem: "반투명 패널은 뒤를 흐리게만 만든다. 실제 유리는 빛을 휜다.",
|
||||
beforeLabel: "backdrop-filter: blur",
|
||||
afterLabel: "blur + url(#lens)",
|
||||
how: "변위 지도를 backdrop-filter 에 넘긴다. R 이 X, G 가 Y 이동량이고 128 이 중립이다. 지도를 feTurbulence 로 만들면 값이 128 로 수렴해 아무 일도 일어나지 않는다 — 가장자리에서 안쪽으로 미는 그라디언트를 직접 그려야 한다.",
|
||||
verdict: "가장자리에서 격자가 눌린다 · 지도 크기가 요소와 다르면 조용히 아무 일도 안 일어난다 · Chromium 전용",
|
||||
how: "변위 지도를 backdrop-filter 에 넘긴다. 노이즈로 만들면 값이 중립으로 수렴해 아무 일도 안 일어난다.",
|
||||
verdict: "가장자리에서 격자가 눌린다 · Chromium 전용",
|
||||
},
|
||||
],
|
||||
},
|
||||
|
|
@ -296,6 +293,7 @@ export const ko: Content = {
|
|||
h2: "이 페이지를 만들며 실제로 걸린 것",
|
||||
lead: "남을 검사한 결과가 아니라 자신을 검사한 결과다.",
|
||||
items: [
|
||||
|
||||
{
|
||||
caught: "폰트가 교체되는 순간 글자 폭이 13% 튀고 있었다",
|
||||
fixed:
|
||||
|
|
@ -326,39 +324,6 @@ export const ko: Content = {
|
|||
fixed:
|
||||
"밴드가 강조색만 반전시키고 그 위 글자색은 흰색 그대로였다. 반전 대응 토큰을 하나 더 두고 함께 바꿨다.",
|
||||
},
|
||||
{
|
||||
caught: "320px 에서 가로로 13px 넘쳤다. 표를 스크롤 컨테이너로 감쌌는데도",
|
||||
fixed:
|
||||
"grid item 의 기본 min-width 는 auto 라 콘텐츠가 부모를 밀어낸다. min-width:0 을 걸어야 overflow 가 실제로 작동한다.",
|
||||
},
|
||||
{
|
||||
caught: "eyebrow 라벨이 6개. 카운트 규칙 상한은 3개",
|
||||
fixed: "세 섹션만 남기고 나머지는 헤드라인만으로 구분했다. 라벨이 없어도 섹션은 읽힌다.",
|
||||
},
|
||||
{
|
||||
caught: "본문 컬럼이 960px. 우리가 정한 한 줄 길이는 561px",
|
||||
fixed: "그리드의 본문 폭을 토큰에 묶었다. 스킬 문서의 예시 코드도 같이 고쳤다.",
|
||||
},
|
||||
{
|
||||
caught: "방향을 바꾸면서 이 스킬의 1단계를 건너뛰었다",
|
||||
fixed:
|
||||
"재질을 유리로 바꾸라는 요청은 2단계 방향 재결정이고, 그때는 전체 경로로 올려 레퍼런스부터 다시 봐야 한다. 그러지 않고 구현으로 바로 들어갔다. 결과는 이전 방향의 뼈대에 유리를 바른 페이지였고 design.md 는 옛 결정을 그대로 담고 있었다. 0단계부터 다시 돌았다.",
|
||||
},
|
||||
{
|
||||
caught: "유리판이 정면으로 서 있어 프레넬이 구조적으로 0이었다",
|
||||
fixed:
|
||||
"평면이 카메라를 정면으로 보면 법선과 시선의 내적이 1이라 가장자리 반사가 계산되지 않는다. 유리로 읽히게 하는 유일한 신호가 죽어 있었고, 그래서 판 여섯 장이 흐린 사각형으로 보였다. 법선을 미세하게 굽히고 테두리 광을 UV 경계에서 따로 만들었다.",
|
||||
},
|
||||
{
|
||||
caught: "페이지의 본체인 파이프라인이 화면의 43%만 쓰고 있었다",
|
||||
fixed:
|
||||
"1440px 중 625px. 아홉 섹션에서 가장 좁으면서 높이는 1637px 로 가장 길었다. 단계 설명과 산출물을 두 열로 열어 1113px 로 넓혔다.",
|
||||
},
|
||||
{
|
||||
caught: "대비를 재는 스크립트가 반투명 배경을 불투명으로 계산했다",
|
||||
fixed:
|
||||
"\"English 1.15:1\" 이라는 틀린 값이 나왔다. 알파를 아래에서 위로 합성하도록 고치자 실패 0건이었다. 검사 도구가 틀리면 통과도 실패도 의미가 없다.",
|
||||
},
|
||||
],
|
||||
note: "열세 건 모두 만들면서 걸린 것이고, 걸린 뒤에 고쳤다. 사람이 잡은 것이 셋이다. 카드가 전형적이라는 말, 폰트를 제대로 다루지 못한다는 말, 그리고 우리 스킬을 진짜로 쓴 게 맞냐는 말.",
|
||||
},
|
||||
|
|
@ -472,8 +437,6 @@ export const en: Content = {
|
|||
briefLabel: "The brief that came in",
|
||||
brief: "Build a subscription landing page for a small-batch coffee roastery",
|
||||
stages: STAGES_EN,
|
||||
after:
|
||||
"What remains after six stages is one page and one design.md. The next person reads that file and continues the same decisions.",
|
||||
},
|
||||
showcase: {
|
||||
h2: "The outputs do not resemble each other",
|
||||
|
|
|
|||
|
|
@ -13,14 +13,27 @@ import { en as c } from "../../i18n/content";
|
|||
---
|
||||
|
||||
<Base lang="en" title={c.meta.title} description={c.meta.description}>
|
||||
{/*
|
||||
순서는 세 묶음이다. 한동안 기능과 증거가 번갈아 나와서
|
||||
(사례 → 필터 → 수치 → 감사 → 조판 → 규칙) 읽는 사람이 지금 무슨 이야기를
|
||||
듣고 있는지 놓쳤다. 같은 성격끼리 붙인다.
|
||||
|
||||
① 무엇인가 히어로 · 파이프라인
|
||||
② 무엇을 아는가 SVG 필터 · 한글 조판
|
||||
③ 정말 그런가 사례 · 수치 · 자기 감사 · 규칙
|
||||
④ 행동 설치
|
||||
*/}
|
||||
<Hero c={c.hero} ui={c.ui} />
|
||||
<Pipeline c={c.pipeline} />
|
||||
<Showcase c={c.showcase} />
|
||||
|
||||
<Materials c={c.materials} />
|
||||
<Typography c={c.typography} />
|
||||
|
||||
<Showcase c={c.showcase} />
|
||||
<Metrics c={c.metrics} />
|
||||
<Preflight c={c.preflight} />
|
||||
<Typography c={c.typography} />
|
||||
<Rules c={c.rules} />
|
||||
|
||||
<Install c={c.install} ui={c.ui} />
|
||||
|
||||
</Base>
|
||||
|
|
|
|||
|
|
@ -13,14 +13,27 @@ import { ko as c } from "../i18n/content";
|
|||
---
|
||||
|
||||
<Base lang="ko" title={c.meta.title} description={c.meta.description}>
|
||||
{/*
|
||||
순서는 세 묶음이다. 한동안 기능과 증거가 번갈아 나와서
|
||||
(사례 → 필터 → 수치 → 감사 → 조판 → 규칙) 읽는 사람이 지금 무슨 이야기를
|
||||
듣고 있는지 놓쳤다. 같은 성격끼리 붙인다.
|
||||
|
||||
① 무엇인가 히어로 · 파이프라인
|
||||
② 무엇을 아는가 SVG 필터 · 한글 조판
|
||||
③ 정말 그런가 사례 · 수치 · 자기 감사 · 규칙
|
||||
④ 행동 설치
|
||||
*/}
|
||||
<Hero c={c.hero} ui={c.ui} />
|
||||
<Pipeline c={c.pipeline} />
|
||||
<Showcase c={c.showcase} />
|
||||
|
||||
<Materials c={c.materials} />
|
||||
<Typography c={c.typography} />
|
||||
|
||||
<Showcase c={c.showcase} />
|
||||
<Metrics c={c.metrics} />
|
||||
<Preflight c={c.preflight} />
|
||||
<Typography c={c.typography} />
|
||||
<Rules c={c.rules} />
|
||||
|
||||
<Install c={c.install} ui={c.ui} />
|
||||
|
||||
</Base>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue