소개 페이지 — 스킬을 스스로 적용해 만든 첫 사례
designpaca 파이프라인 0~6단계를 실제로 돌려 만들었다. 근거는 research/site-brief.md, 결정 기록은 apps/site/design.md 에 있다. 한 문장 컨셉 - 이 페이지는 designpaca 를 거쳐 만들어졌고, 절차와 형태 수치를 한국어 기준으로 전부 공개한다 번호 없이 순서 표현 (C-07 회피) - 파이프라인 6단계를 번호로 매기면 검출률 3위 슬롭 지문에 걸린다 - 시각: 스파인 위 위치가 순서를 만든다 / 내용: 같은 브리프가 단계마다 변한다 - 의미: <ol role="list"> — 화면에 번호 0개, 보조기술에는 "6개 중 n번째" 멀티링구얼 - / = 한국어, /en/ = 영어. 번역이 아니라 각 판을 따로 썼다 - 언어별 레이아웃이 자기 폰트만 로드한다 (판당 2개) - 조판 섹션은 한국어판에서 주장이고 영어판에서 사례다 실측 - JS 314B (gzip, 예산 50KB) / CSS 3.0KB / HTML 4.4~4.8KB - radius 2종 · backdrop-filter 0개 · 타입 5단계 · 강조색 1개 - 슬롭 지문 grep 9패턴 0건, 정적 하드 게이트 8개 전부 통과 감사에서 걸려 고친 것 - eyebrow 6개 → 상한 ceil(7/3)=3 위반 → 3개로 - clip-path 리빌 → 게이트 #8 위반 → transform 으로 교정 - 구분선 대비 1.30:1 → 입력 테두리용 별칭 분리 (WCAG 1.4.11) - 본문 컬럼 960px → --measure 로. layout.md 예시 코드도 같이 수정
This commit is contained in:
parent
8808c672dc
commit
6103700d38
18 changed files with 1497 additions and 20 deletions
116
apps/site/src/layouts/Base.astro
Normal file
116
apps/site/src/layouts/Base.astro
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
---
|
||||
import "../styles/tokens.css";
|
||||
import "../styles/base.css";
|
||||
|
||||
interface Props {
|
||||
lang: "ko" | "en";
|
||||
title: string;
|
||||
description: string;
|
||||
}
|
||||
const { lang, title, description } = Astro.props;
|
||||
|
||||
// 언어별로 자기 폰트만 받는다. 두 벌을 한 페이지에 로드하면 예산을 넘긴다.
|
||||
const FONT_CSS = {
|
||||
ko: "https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css",
|
||||
en: "https://api.fontshare.com/v2/css?f%5B%5D=switzer@400,500,600&display=swap",
|
||||
} as const;
|
||||
|
||||
const alt = lang === "ko" ? "/en/" : "/";
|
||||
---
|
||||
|
||||
<!doctype html>
|
||||
<html lang={lang}>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>{title}</title>
|
||||
<meta name="description" content={description} />
|
||||
|
||||
<link rel="canonical" href={new URL(Astro.url.pathname, Astro.site)} />
|
||||
<link rel="alternate" hreflang="ko" href={new URL("/", Astro.site)} />
|
||||
<link rel="alternate" hreflang="en" href={new URL("/en/", Astro.site)} />
|
||||
<link rel="alternate" hreflang="x-default" href={new URL("/", Astro.site)} />
|
||||
|
||||
{/* 본문 폰트만 preconnect·preload 한다. 모노는 코드 블록에만 쓰인다 */}
|
||||
<link rel="preconnect" href={lang === "ko" ? "https://cdn.jsdelivr.net" : "https://api.fontshare.com"} crossorigin />
|
||||
<link rel="stylesheet" href={FONT_CSS[lang]} />
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500&display=swap"
|
||||
media="print"
|
||||
onload="this.media='all'"
|
||||
/>
|
||||
|
||||
<meta property="og:title" content={title} />
|
||||
<meta property="og:description" content={description} />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta name="color-scheme" content="light dark" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<a class="skip" href="#main">{lang === "ko" ? "본문으로 건너뛰기" : "Skip to content"}</a>
|
||||
|
||||
<header class="page site-header">
|
||||
<a class="wordmark" href={lang === "ko" ? "/" : "/en/"}>designpaca</a>
|
||||
<nav aria-label={lang === "ko" ? "언어" : "Language"}>
|
||||
{/* 언어는 국가가 아니다 — 국기 아이콘을 쓰지 않는다 */}
|
||||
<a href={alt} hreflang={lang === "ko" ? "en" : "ko"} lang={lang === "ko" ? "en" : "ko"}>
|
||||
{lang === "ko" ? "English" : "한국어"}
|
||||
</a>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<main id="main" class="page">
|
||||
<slot />
|
||||
</main>
|
||||
|
||||
<footer class="page site-footer">
|
||||
<slot name="footer" />
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
<style>
|
||||
.skip {
|
||||
position: absolute;
|
||||
left: var(--space-3);
|
||||
top: calc(var(--space-3) * -4);
|
||||
padding: var(--space-2) var(--space-3);
|
||||
background: var(--accent);
|
||||
color: var(--accent-ink);
|
||||
border-radius: var(--radius-sm);
|
||||
z-index: 10;
|
||||
transition: transform var(--dur-quick) var(--ease-out);
|
||||
}
|
||||
.skip:focus {
|
||||
transform: translateY(calc(var(--space-3) * 5));
|
||||
}
|
||||
|
||||
.site-header {
|
||||
padding-block: var(--space-4);
|
||||
}
|
||||
.site-header > * {
|
||||
grid-column: main;
|
||||
}
|
||||
.site-header {
|
||||
align-items: baseline;
|
||||
}
|
||||
.wordmark {
|
||||
font-weight: 600;
|
||||
letter-spacing: -0.01em;
|
||||
text-decoration: none;
|
||||
}
|
||||
.site-header nav {
|
||||
justify-self: end;
|
||||
grid-row: 1;
|
||||
grid-column: main;
|
||||
font-size: var(--step-0);
|
||||
color: var(--ink-muted);
|
||||
}
|
||||
|
||||
.site-footer {
|
||||
padding-block: var(--space-6);
|
||||
border-top: 1px solid var(--line);
|
||||
color: var(--ink-muted);
|
||||
}
|
||||
</style>
|
||||
Loading…
Add table
Add a link
Reference in a new issue