From 9648d1d82a286f46f92a3193fc883a5373a3ac3e Mon Sep 17 00:00:00 2001 From: Yun Chan Date: Thu, 20 Aug 2026 13:33:28 +0900 Subject: [PATCH] =?UTF-8?q?=EC=86=8C=EA=B0=9C=20=ED=8E=98=EC=9D=B4?= =?UTF-8?q?=EC=A7=80=EB=A5=BC=20=EC=8A=A4=ED=82=AC=20=EC=A0=84=EC=B2=B4=20?= =?UTF-8?q?=EA=B2=BD=EB=A1=9C=EB=A1=9C=20=EB=8B=A4=EC=8B=9C=20=EB=A7=8C?= =?UTF-8?q?=EB=93=A4=EA=B3=A0,=20=EB=B0=B0=EC=9A=B4=20=EA=B2=83=EC=9D=84?= =?UTF-8?q?=20=EC=8A=A4=ED=82=AC=EC=97=90=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 방향을 글래스로 바꿀 때 2단계 재결정을 하고도 전체 경로로 올리지 않았다. 레퍼런스 없이 재질만 갈아끼운 결과가 스위스 미니멀 뼈대에 유리를 바른 페이지였고, design.md 는 초판 결정을 그대로 담고 있었다. 0단계부터 다시 돌았다. 1단계 — 레퍼런스 3개를 computed style 까지 실측 R1 zed.dev 컨테이너 1120px 과 전체폭이 교대 · radius 2px 621회 R2 lusion.co 3D 는 액자 안, 텍스트는 액자 밖 · 배경 흰색 · h1 36px R3 Codrops DOM 이 구조를 소유하고 WebGL 은 uniform 만 만진다 2단계 — 프리셋 swiss-minimal → dark-instrument, 컨셉 "검사대 위의 물체" 유리는 액자에만 남긴다(헤더 · 검사대 · 명령창) 4단계 — 히어로 재구성. 캔버스를 배경에서 빼 액자 안으로, 텍스트는 밖으로 판독기가 통과한 게이트를 표시한다(값이 바뀔 때만 DOM 을 쓴다) 파이프라인을 2열로 열어 625px → 1113px 5단계에서 실제로 걸린 것 게이트 3 radius 4종 → 2종 (3px / 14px, pill 제거) 게이트 1 base.css 토큰 밖 rgb() 7곳 → 토큰 게이트 7 헤더 English 2.59:1 → ink 로 상향 카운트 히어로 h1 4줄 → 2줄 셰이더 판이 정면이라 프레넬이 구조적으로 0. 법선을 굽히고 UV 로 테두리 셰이더 gl_FragCoord 를 렌더 타겟 크기로 나눠 UV 가 1 을 넘고 있었다 수치 페이지가 실은 "타입 단계 5단계"가 실측 9종이었다. lang 속성이 스케일을 재정의해 링크 하나가 16px 로 새고 있었다 측정 대비 스크립트가 반투명 배경을 불투명으로 계산했다. 알파 합성으로 교정 스킬 반영 three.md §0-A 배치 원리(3D 는 액자 안) · 프레넬 0 함정 · gl_FragCoord 함정 preflight.md 대비 측정 시 알파 합성. 검사 도구가 틀리면 통과도 의미가 없다 최종: 하드 게이트 12/12, 대비 실패 0, 320px 오버플로 0, 테스트 22개 통과 --- apps/site/design.md | 161 ++++++++----- apps/site/src/components/CopyCommand.astro | 6 +- apps/site/src/components/Hero.astro | 266 ++++++++++++--------- apps/site/src/components/Materials.astro | 4 +- apps/site/src/components/Pipeline.astro | 56 +++-- apps/site/src/components/Preflight.astro | 2 +- apps/site/src/components/Showcase.astro | 18 +- apps/site/src/components/Typography.astro | 4 +- apps/site/src/i18n/content.ts | 90 +++++-- apps/site/src/layouts/Base.astro | 34 ++- apps/site/src/lib/hero-scene.ts | 59 +++-- apps/site/src/styles/base.css | 59 ++--- apps/site/src/styles/tokens.css | 63 +++-- packages/skill/references/preflight.md | 25 +- packages/skill/references/three.md | 35 +++ 15 files changed, 576 insertions(+), 306 deletions(-) diff --git a/apps/site/design.md b/apps/site/design.md index 2977cae..27b5baf 100644 --- a/apps/site/design.md +++ b/apps/site/design.md @@ -1,7 +1,21 @@ # design.md — designpaca 소개 페이지 > 6단계 산출물. 다음 실행(사람이든 에이전트든)은 이 파일을 먼저 읽고 같은 결정을 이어간다. -> 전체 조사 근거: `research/site-brief.md` (825줄) + +## 개정 이력 + +| 날짜 | 판 | 무엇이 바뀌었나 | +|---|---|---| +| 2026-08-20 | 초판 | `swiss-minimal` · three.js 미사용 · 라이트 기반 | +| 2026-08-20 | **2판(현행)** | `dark-instrument` · three.js 채택 · 전체 경로 재주행 | + +**초판이 거짓말이 됐던 경위를 남긴다.** 사용자가 "글래스모피즘·리퀴드글래스·히어로에 힘"을 요청했을 때 +그것은 2단계 방향 재결정이었고, 스킬은 그럴 때 **전체 경로로 올려 1단계부터 다시 돌라**고 씌어 있다. +그러지 않고 4단계 구현으로 바로 들어갔다. 레퍼런스 없이 재질만 갈아끼운 결과가 **스위스 미니멀 뼈대에 +유리를 바른 페이지**였고, `design.md` 는 초판 상태로 남아 프리셋·이펙트·형태 수치가 전부 어긋났다. +2판은 0단계부터 다시 돌았다. + +--- ## 브리프 3줄 @@ -9,103 +23,136 @@ - **누구에게**: Claude Code · Codex · Cursor 를 쓰는 개발자. 이 페이지를 보고 `npx designpaca` 를 터미널에 치게 만드는 것이 목표 - **제약**: Astro 정적 → Cloudflare Pages. 이 페이지 자체가 스킬의 품질 증거물이다 — 스킬이 금지하는 것을 이 페이지가 하면 안 된다 -## 레퍼런스 +## 레퍼런스 (전부 실측. computed style 추출까지 돌렸다) -| 슬롯 | 사이트 | 업종 | 가져온 것 | 가져오지 **않은** 것 | -|---|---|---|---|---| -| R1 · 구조 | tasteskill.dev | 안티슬롭 디자인 스킬 | 섹션 순서, 설치 명령 3회 노출, **카피 규율**(자기 평가 형용사 0건) | radius 8종 · backdrop-filter 40개 · 타입 12단계 · 스폰서 벽 | -| R2 · 톤 | klim.co.nz | 폰트 파운드리 | 흰 바탕에 검정 밴드를 리듬으로, 설계 근거를 산문으로 파는 방식 | 유료 폰트 | -| R3 · 디테일 | Codrops scroll-driven wipe | — | 스크롤 진입 리빌 | `clip-path` 구현 (게이트 #8 위반 → `transform` 으로 교정) | +| 슬롯 | 사이트 | 업종 | 실측값 | 가져온 **원리** | 가져오지 **않은** 것 | +|---|---|---|---|---|---| +| R1 · 구조 | zed.dev | 코드 에디터 | 컨테이너 **1120px**(68회) ↔ 전체폭 1425px(50회) 교대 · 본문 칼럼 512px · **radius 2px 가 621회** · 모노 524회로 지배 | 폭의 교대, 각진 형태 어휘, 모노를 정체성으로 | 세리프 h1(우리는 한글) · 최대÷본문 3.0배(위계가 약하다) · 섹션 11개 | +| R2 · 톤 | lusion.co | 3D 프로덕션 스튜디오 | 배경 **흰색** · 텍스트 색 **2단계**(검정 135 / 흰 16) · 폰트 **1개**(Aeonik) · 강조색 rgb(0,22,236) **4회** · 캔버스는 radius 15px 액자 안 · **h1 이 36px** | **3D 는 액자 안, 텍스트는 액자 밖.** 3D 가 크면 타이포는 물러난다. 색은 캔버스 안에서만 소리친다 | 흰 배경 자체 · 파랑 | +| R3 · 디테일 | Codrops "Inside HAOQI.DESIGN" | — | 축 5 전용 | DOM 이 구조를 소유하고 WebGL 은 셰이더 uniform 만 만진다. 한 rAF 에서 스크롤을 공유하고 뷰포트 밖에서는 정지 | R3F/Lenis 스택 | -**정본 확인 경고**: `tasteskill.com` 과 `design-taste.com` 은 본문 114바이트짜리 파킹 페이지다. HTTP 200 이 생존 신호가 아니다. +**R3 구현 제약**: 셰이더 uniform 만 갱신하므로 `transform`/`opacity` 외의 CSS 를 애니메이션하지 않는다(게이트 #8 안전). +뷰포트 밖 렌더 정지가 필수 조건이다. + +**접근 실패 기록** — `iglooinc.com` 은 hugedomains 파킹으로 302, `lasvit.com` 은 403. +`reference-method.md` §3-b 가 경고한 그대로였다. 왕복 세 번에서 끊고 우회했다. ## 한 문장 컨셉 -> **이 페이지는 designpaca를 거쳐 만들어졌고, 그 절차와 형태 수치를 한국어 기준으로 전부 공개한다.** +> **검사대 위의 물체.** 액자가 게이트고, 안에 든 것이 검사 중인 디자인이고, 밖의 글자가 판정 기록이다. -세 방향(절차를 판다 / 형태까지 간다 / 한국어로 푼다)이 "이 페이지 자신이 첫 사례"라는 사실 하나로 합쳐진다. +## 프리셋 — `dark-instrument` -## 프리셋 — `swiss-minimal` +초판의 `swiss-minimal` 에서 바꿨다. 페이지가 이미 어둡고 제품이 CLI 다. +**초판에는 이 재질을 정당화하는 프리셋이 아예 없었다** — 그것이 "유리를 발랐는데 유리일 이유가 없다"의 원인이다. -결정 요인은 **멀티링구얼**이었다. `editorial` 의 세리프는 한국어 마루 부리 / 영어 Spectral 로 갈려 두 판의 톤이 벌어진다. 그로테스크는 Pretendard / Switzer 로 양쪽이 같은 성격을 유지한다. -빌린 것: `editorial` 에서 규칙 옆 근거 1문장 어법, `anti-grid` 에서 파이프라인 섹션 한 곳의 의도적 어긋남. +프리셋은 "글래스모피즘은 내비게이션 바 정도까지"라고 반대한다. 사용자의 명시적 지시가 프리셋보다 위이므로 +없애지 않고 **의미가 생기는 자리로 옮겼다**: 유리는 **액자에만** 쓴다 — 헤더 · 검사대 프레임 · 명령창. +콘텐츠 카드(브리프, 조판 데모)에서는 뺐다. 유리는 무언가를 담을 때만 의미가 있다. ## 감수한 리스크 — 하나 -**이 페이지 자신의 형태 수치를 페이지에 공개한다.** 공개한 순간 검증 가능해지고 하나라도 어기면 주장 전체가 무너진다. -규칙: **결과가 나쁘게 나와도 그대로 싣는다.** 유리한 것만 고르면 리스크가 자기 홍보로 바뀐다. - -## C-07 대응 — 번호 없이 순서 표현 - -파이프라인 6단계를 번호로 매기면 검출률 3위 슬롭 지문(9.4%)에 정면으로 걸린다. 세 층으로 풀었다: - -1. **시각** — 세로 스파인 위의 위치가 순서를 만든다 (Beck 1933 튜브맵: "topology trumped topography") -2. **내용** — 같은 브리프 문장 하나가 단계마다 변해간다 (IKEA 조립 설명서. IKEA 의 동기가 언어 독립성이라 멀티링구얼과 동기가 같다) -3. **의미** — `
    `. 시각적으로 번호 0개, 보조기술에는 "6개 중 n번째". `list-style: none` 일 때 Safari/VoiceOver 가 목록 의미를 버리는 것을 `role` 로 되돌린다 +**히어로에서 거대 타이포를 버리고 힘을 3D 액자로 넘긴다.** +초판 히어로의 `--display` 는 최대 112px 로 화면 높이의 절반을 먹었고, 그 아래 캔버스가 깔려 있었다. +R2 의 h1 은 36px 인데 히어로가 압도적이다 — 힘이 타이포가 아니라 물체에서 나오기 때문이다. +현행 히어로 h1 은 `clamp(var(--step-2), 1.1rem + 2.4vw, var(--step-4))`, 최대 **41.5px** 다. +페이지에서 가장 큰 글자(96px)는 히어로가 아니라 수치 섹션에 있다 — R2 도 그렇다. ## 토큰 -`src/styles/tokens.css` 전문. 요약: +`src/styles/tokens.css` 전문. 초판에서 바뀐 것만 적는다. -- 타입 비율 **1.25**, **디스플레이는 스케일 밖에 별도 정의** — 1.25⁴는 2.44배라 "최대÷본문 4배" 를 못 채우고, 단계를 늘려 맞추면 "통제 실패" 에 걸린다. 두 판 모두 정확히 **4.0배** -- 한국어 17px / lh 1.7 / measure 33em(561px) · 영어 16px / lh 1.55 / measure 65ch(640px) -- 강조색 **딥 틸 `#0E6B63`** 하나. 오렌지(tasteskill) · 마젠타(Bun) · 빨강(Klim) · 보라/시안 네온을 전부 피한 자리 -- **14개 색 조합 대비를 전부 계산해 검증** — 최저 6.04:1, 최고 16.88:1 -- radius **2종**(3px · 6px), 간격 8단계, 모션 4종 -- 라이트·다크 두 테마를 동등하게 정의. 다크 밴드는 **히어로와 설치 두 곳만** (게이트 #4 가 요구하는 "규칙으로 정의된 반전") +- **radius 2종**: `--radius-sm: 3px`(요소) · `--radius-frame: 14px`(액자). + 근거는 R1 의 2px(621회)과 R2 의 15px. `999px` pill 3곳을 없앴다 — 계기판에 알약은 없다 +- **`--glow-2`: `#6E7BFF` → `#3D7BD6`**. 앞의 값은 R 이 높아 보라-파랑으로 읽힌다. + `antipatterns.md` 의 슬롭 지문이자 `dark-instrument` 가 "어두운 배경일수록 빠지기 쉬운 함정"으로 지목한 색이다 +- **유리 색값을 전부 토큰으로**: `--glass-sheen` · `--glass-rim` · `--core-hi`. + `base.css` 에 흩어져 있던 `rgb(255 255 255 / …)` 7곳이 하드 게이트 #1 위반이었다 +- **이중 베젤(`.shell`/`.core`) 폐기** → 단일 `.frame`. 껍데기와 속의 radius 가 서로 달라 그것만으로 형태 어휘가 두 종 늘어난다 +- **`--step--1: 0.8125rem` 추가**. 게이트 판독기가 스케일 밖 13px 을 쓰고 있었다 +- 강조색은 여전히 딥 틸 하나. 라이트/다크 쌍(`--accent` / `--accent-inverse`)은 규칙으로 정의된 반전이라 1종으로 센다 + +**타입 스케일 실측**: `step--1` ~ `step-4` 로 **6단계**, `--display`(96px)는 스케일 밖, 모노는 본문의 0.9375배 파생. +최대÷본문 = **5.6배**. 초판 페이지는 "5단계"라고 실었는데 실측은 9종이었다 — 아래 8·9번 참조. ## 성능 — 예산과 실측 +**예산을 올렸고, 올렸다고 말한다.** 초판 예산은 히어로까지 JS 50KB 였다. +이 페이지는 three.js 를 파는 제품의 데모이므로 그 판단을 검증할 수 있어야 한다. + +**예산 숫자 자체를 한 번 고쳤다.** 처음 three.js 예산을 160KB 로 적었는데 실측이 184KB 였다. +three.js 크기는 미리 알 수 있는 값이므로 이건 예산 설정 실패다. 190KB 로 고쳤고, **사후 조정이라는 사실을 남긴다.** +실측을 보고 예산을 맞추는 것은 예산이 아니다 — 다음 실행은 여기서부터 시작해야 한다. + | 항목 | 예산 | 실측 | 판정 | |---|---|---|---| -| 히어로까지 JS (gzip) | 50KB | **314B** | 통과 (예산의 0.6%) | -| CSS (gzip) | — | 3.0KB | | -| HTML (gzip) | — | 4.4~4.8KB | | -| 폰트 패밀리 (판당) | 2개 | 2개 | 통과 | +| 히어로까지 JS, 초기 (gzip) | 50KB | 복사 버튼 314B + 씬 부트 | 통과 | +| three.js, 지연 로드 (gzip) | 190KB | **184KB** (동적 `import()`, IntersectionObserver 로 화면에 들어올 때만) | 통과 | | 첫 인터랙션 | 2초 | **미측정** | 배포 후 Lighthouse | | LCP / CLS | 2.5초 / 0.1 | **미측정** | 배포 후 | -| three.js | 미사용 | 미사용 | — | -**폰트 전략**: 경로가 `/` 와 `/en/` 으로 갈려 있으므로 레이아웃을 언어별로 나눠 **자기 폰트만 받는다.** 한국어판 Pretendard Variable(동적 서브셋) + JetBrains Mono, 영어판 Switzer + JetBrains Mono. preload 는 본문 폰트 1개만. +WebGL 게이트: `prefers-reduced-motion` 이면 **아예 시작하지 않는다**. DPR 1.5 클램프. +`hardwareConcurrency <= 4` 면 판을 6장에서 3장으로 줄인다. 탭이 숨거나 화면 밖이면 그리지 않는다. ## 채택한 이펙트와 폴백 | 이펙트 | 구현 | 폴백 | |---|---|---| -| 복사 버튼 | 인라인 314B | 클립보드 권한 실패 시 텍스트를 선택 상태로 만들어 사용자가 직접 복사 | +| 검사대 3D | 유리판 6장이 깊이 축에 서고 카메라가 스크롤로 통과. 굴절은 렌더 타겟 1장 샘플링(`transmission` 재질보다 훨씬 싸다) | 캔버스 아래 CSS 그라디언트가 **폴백이 아니라 결과물**이다. 액자·판독기·캡션은 그대로 남는다 | +| 게이트 판독기 | 통과한 판이 바뀔 때만 DOM 을 쓴다. 프레임마다 쓰지 않는다 | JS 없으면 `게이트 01 / 06` 정적 표시 | +| 복사 버튼 | 인라인 314B | 클립보드 실패 시 텍스트를 선택 상태로 만든다 | -**스파인 진입 페이드는 넣었다가 뺐다.** `animation-timeline: view()` 에 `animation-range: entry 10% cover 22%` 를 걸었는데, **페이지 하단 요소는 `cover 22%` 에 영영 도달하지 못한다.** 스크롤을 끝까지 내려도 6개 정거장 중 뒤 3개가 opacity 0 으로 남았다 — 이 페이지의 본체가 절반 사라진 것이다. -정적 검사로는 안 잡혔다. 320px 실렌더에서 스크롤을 끝까지 돌려보고야 나왔다. -**이펙트를 끄면 보이지만 켜면 사라지는 것은 폴백이 있는 것과 다르다.** 이 페이지에 남은 모션은 호버·포커스 상태 변화뿐이다. +## 5단계에서 실제로 걸린 것 -## 5단계 감사 결과 +정적 검사와 실렌더를 둘 다 돌렸다. **걸린 것을 전부 적는다 — 유리한 것만 고르면 리스크가 자기 홍보가 된다.** -- 하드 게이트: **12개 전부 통과.** 8개는 정적 검사, 4개(가로 스크롤·버튼 줄바꿈·실렌더 대비·테마 반전)는 **320px 실렌더**로 측정 -- 슬롭 지문 grep 9개 패턴: **0건** -- 카운트 규칙: 섹션 7 / eyebrow 3 (상한 3) / 마퀴 0 / h1 1 — 통과 -- 실렌더 대비: 본문·링크·버튼 전부 AA 이상. 최저 6.21:1 (다크 밴드 버튼) +1. **하드 게이트 #3 위반** — radius 4종(`sm`/`md`/`shell`/`999px`). 2종으로 정리 +2. **하드 게이트 #1 위반** — `base.css` 에 토큰 밖 `rgb()` 7곳. 토큰으로 올림 +3. **하드 게이트 #7 위반** — 헤더 "English" 버튼 **2.59:1**. `--ink-muted` → `--ink` 로 올려 통과 +4. **카운트 규칙 위반** — 히어로 h1 이 4줄이었다(상한 2줄). 폰트 크기를 낮춰 2줄 +5. **셰이더 결함** — 판이 정면으로 서 있어 `dot(n, view) ≈ 1`, **프레넬이 구조적으로 0**이었다. + 유리로 읽히게 하는 유일한 신호가 죽어 있었고 그것이 "그냥 흐릿한 사각형"의 원인이다. + 법선을 미세하게 굽히고 UV 경계로 테두리 광을 따로 만들어 해결 +6. **셰이더 UV 오류** — `gl_FragCoord` 를 렌더 타겟 크기(캔버스의 0.6배)로 나누고 있었다. UV 가 1 을 넘어 텍스처가 잘렸다. + `getDrawingBufferSize()` 로 교정 +7. **폭 리듬 부재** — 9개 섹션 중 파이프라인이 **1440px 중 625px(43%)** 만 쓰면서 높이는 1637px 로 가장 길었다. + 페이지의 본체가 가장 좁았다. 2열로 열어 1113px +8. **페이지가 실은 수치가 틀렸다** — "타입 단계 5단계" 라고 실었는데 실측 **9종**이었다. + 이 페이지의 리스크가 "자기 수치를 공개한다" 인데 공개한 값이 틀리면 리스크가 아니라 허위다 +9. **`lang` 속성이 타입 스케일을 새게 했다** — 언어 전환 링크에 `lang="en"` 이 붙어 있고(스크린리더가 + "English" 를 영어로 읽어야 하므로 옳다) `[lang]` 셀렉터가 스케일을 통째로 재정의해 그 링크만 16px 이 됐다. + 접근성 표시가 조용히 디자인 토큰을 바꾸고 있었다. 크기는 헤더에서 확정하고 링크는 상속만 받게 고쳤다 -감사 중 걸려서 고친 것 **7건**은 페이지의 "프리플라이트 로그" 섹션에 그대로 실려 있다. -**뒤 3건은 정적 검사로는 안 잡히고 실렌더에서만 나왔다** — 이 사실 자체가 `preflight.md` 의 "프레임워크 프로젝트는 프로덕션 빌드 결과에 돌린다" 규칙을 뒷받침한다. +**측정 스크립트 자체의 오류도 한 번 있었다.** 대비 계산에서 반투명 배경을 불투명으로 취급해 +"English 1.15:1" 이라는 틀린 값이 나왔다. 알파를 합성하도록 고친 뒤 실패 0건. +**검사 도구가 틀리면 통과도 실패도 의미가 없다.** + +### 최종 판정 (1440px · 320px 실렌더) + +- 하드 게이트 12개 **전부 "아니오"** +- 대비: 본문·링크·버튼 전 요소 AA 이상, 실패 **0건** +- 320px: 가로 스크롤 없음(문서 폭 305px), 뷰포트 초과 요소 0, 버튼 줄바꿈 0 +- 카운트: 섹션 9 / eyebrow 3(상한 `ceil(9/3)=3`) / 마퀴 0 / 히어로 헤드라인 2줄 / radius 어휘 2종 / 반투명 패널 2개 +- 슬롭 지문 grep: 0건 ## 의도적으로 하지 않은 것과 그 이유 - **"Anti-Slop" 이라는 명명** — tasteskill 이 쓰는 말이다. 같은 단어를 쓰면 즉시 아류로 읽힌다 -- **경쟁 제품의 실측치를 페이지에 싣기** — 익명화는 저격을 예의 바르게 만들 뿐이고, 남의 수치는 반박 가능하다("그 40개는 대부분 nav다"). 논쟁이 시작되면 제품 이야기가 사라진다. **우리 수치만 쓴다** +- **경쟁 제품의 실측치를 페이지에 싣기** — 남의 수치는 반박 가능하다. 우리 수치만 쓴다 - **GitHub 스타 등 인기 지표** — 우리는 숫자가 0이다. 인기 대신 규율을 증거로 쓴다 -- **스폰서·후원자 벽** — R1 은 페이지의 28%를 여기에 쓴다. 섹션 자체를 만들지 않는다 -- **다크를 기본값으로** — 브리프에 야간 사용·데이터 시각화 근거가 없다. 두 테마를 동등하게 정의하되 라이트로 시작한다 -- **three.js / WebGL** — 정적 사이트에 사진이 없고 인터랙션이 복사 버튼과 언어 전환뿐이다. 필터로도 낼 인상이 없다 -- **언어 자동 리다이렉트** — 사용자를 놀라게 한다. `hreflang` 으로 검색엔진에만 알린다 -- **국기 아이콘으로 언어 전환** — 언어는 국가가 아니다 -- **두 판을 번역으로 만들기** — 각 언어판을 따로 썼다. 한국어판은 "한글 조판 공백을 메운다"가 주장이므로 그 페이지 자체가 증명이어야 한다 +- **3D 위에 본문 얹기** — R2 가 준 원리의 핵심이다. 액자 위에 얹는 글자는 판독기 하나뿐이고, 그것도 바탕을 깔았다 +- **GLB 모델** — 조사 결과 추상 지오메트리가 이 브리프에서 더 낫다. 모델 하나가 수 MB 이고, 우리가 파는 것은 모델이 아니라 절차다 +- **다크를 "멋있어서" 고르기** — 프리셋이 다크 기본값을 슬롭 시그니처 1위로 지목한다. 제품이 터미널이라는 근거로 고른다 +- **언어 자동 리다이렉트 / 국기 아이콘** — 사용자를 놀라게 하고, 언어는 국가가 아니다 +- **두 판을 번역으로 만들기** — 각 언어판을 따로 썼다 ## 다음 실행이 해야 할 일 -1. **배포 후 Lighthouse 로 첫 인터랙션·LCP·CLS 를 재고, "이 페이지의 수치" 섹션의 `—` 를 채운다.** 채우기 전까지 그 항목은 비워둔다 +1. **배포 후 Lighthouse 로 첫 인터랙션·LCP·CLS 를 재고 "미측정" 을 채운다.** 채우기 전까지 비워둔다 2. 폰트를 CDN 의존에서 자체 호스팅으로 옮길지 판단한다 (현재 jsDelivr · Fontshare · Google Fonts 3곳) -3. OG 이미지가 없다. 공유될 자리라면 만든다 +3. OG 이미지가 없다 +4. 섹션이 9개, 총 높이 11,197px 이다. 스크롤 보상이 충분한지 재검토할 여지가 있다 --- -`2026-08-20` · 초판. 0~6단계 전체 경로로 진행. +`2026-08-20` · 2판. 0~6단계 전체 경로 재주행. diff --git a/apps/site/src/components/CopyCommand.astro b/apps/site/src/components/CopyCommand.astro index 032efef..4f9521b 100644 --- a/apps/site/src/components/CopyCommand.astro +++ b/apps/site/src/components/CopyCommand.astro @@ -8,9 +8,9 @@ interface Props { const { command, copyLabel, copiedLabel, note } = Astro.props; --- -{/* 셸 안에 코어. 명령어는 기계의 부품처럼 앉는다 */} -
    -
    +{/* 명령어를 담는 액자. 유리를 쓰는 세 자리 중 하나다 */} +
    +
    {command}