- 핵심 규칙 6: 완료의 정의는 게이트 통과. 사용자를 QA로 쓰지 않는다 - 5단계 기계 검사 4번째: design-gate 실행 의무화 - references/audit-gate.md: 사고-검사 매핑, SEO/meta 체크리스트, OS/브라우저 특성, 하니스 규칙 - tools/design-gate.mjs: 범용 게이트(메타/SEO·대비·수축·리듬·트랙·스케일×폭 + 옵션 L0/L3/L4, checks 깊은 병합) - 리듬·트랙 불변식: 숫자 라벨 등폭·빈 셀 트랙 균일·등간격 — 시간표 자동배치 결함 재현 픽스처 검출, 앱 15뷰 통과(오탐 0) feat(site): 관리 앱 2종 프로덕션 콘솔(v6→v18) - 가온 학적부 9뷰·두레 수강신청 6뷰: shadcn 문법, Pretendard/Noto Serif/IBM Plex 폰트 전략, 볼드 금지(400/500/600), WCAG AA 대비 전면 교정, 한글 keep-all 조판 - LMS 필수 요소(알림 센터·공지·진도·평가 유형·출결 사유·학점 경고), 12명 기준 데이터 정합, SEO 구조(h1 유일·OG/twitter·og.png) - 시간표 자동배치 결함 수리(명시적 격자 좌표) - QA 게이트: L0 stylelint/html-validate · L1 단위 30 · L2 감사 61+불변식 · L3 시각회귀 30화면 · L4 WebKit · L5 키보드 탐색 — npm run verify 실패 시 배포 금지 체인
This commit is contained in:
parent
78ddc8b61a
commit
72337b7ee0
226 changed files with 18212 additions and 380 deletions
BIN
apps/site/public/work/font-foundry/assets/inkstone.webp
Normal file
BIN
apps/site/public/work/font-foundry/assets/inkstone.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 56 KiB |
BIN
apps/site/public/work/font-foundry/assets/metaltype.webp
Normal file
BIN
apps/site/public/work/font-foundry/assets/metaltype.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 86 KiB |
289
apps/site/public/work/font-foundry/index.html
Normal file
289
apps/site/public/work/font-foundry/index.html
Normal file
|
|
@ -0,0 +1,289 @@
|
|||
<!doctype html>
|
||||
<html lang="ko">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>한성활자연구소 · 본문용 한글 활자</title>
|
||||
<meta
|
||||
name="description"
|
||||
content="획의 장력과 여백의 비례. 본문 조판을 위해 설계한 한글 활자 두 종과 조판 시험대. 1000 UPM, 측정 가능한 자간과 행간."
|
||||
/>
|
||||
<meta property="og:title" content="한성활자연구소 · 본문용 한글 활자" />
|
||||
<meta
|
||||
property="og:description"
|
||||
content="본문 조판을 위해 설계한 한글 활자와 조판 시험대."
|
||||
/>
|
||||
<meta property="og:type" content="website" />
|
||||
<meta name="theme-color" content="#F5F1E8" />
|
||||
|
||||
<link rel="preconnect" href="https://cdn.jsdelivr.net" crossorigin />
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="https://cdn.jsdelivr.net/gh/webfontworld/naver/MaruBuri.css"
|
||||
/>
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css"
|
||||
/>
|
||||
<link rel="stylesheet" href="./styles/main.css?v=2" />
|
||||
<link
|
||||
rel="icon"
|
||||
href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Crect width='32' height='32' fill='%23F5F1E8'/%3E%3Crect x='8' y='8' width='16' height='16' fill='%23A63D2F'/%3E%3C/svg%3E"
|
||||
/>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<a class="skip" href="#main">본문으로 건너뛰기</a>
|
||||
|
||||
<header class="site-head">
|
||||
<div class="wrap head-inner">
|
||||
<a class="wordmark" href="#main">한성활자연구소</a>
|
||||
<nav class="nav" aria-label="섹션">
|
||||
<a href="#typefaces">활자</a>
|
||||
<a href="#bench">시험대</a>
|
||||
<a href="#case">활자 케이스</a>
|
||||
<a href="#order">구입</a>
|
||||
</nav>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main id="main">
|
||||
<!--
|
||||
스페시멘 히어로 — 파운드리의 첫 화면은 설명이 아니라 글자다.
|
||||
'한' 한 글자를 페이지에서 가장 크게, 인주각과 함께.
|
||||
-->
|
||||
<section class="hero" aria-labelledby="hero-h">
|
||||
<div class="wrap">
|
||||
<p class="hero-kicker reveal">본문용 한글 활자 · 1000 UPM · 2018년 창립</p>
|
||||
<h1 id="hero-h" class="hero-glyph reveal" style="--delay: 60ms" lang="ko" aria-label="한">한</h1>
|
||||
<div class="hero-side">
|
||||
<p class="hero-statement">
|
||||
이 글자가 어디에 쓰이는지는 이 페이지 전체가 증명합니다. 우리는
|
||||
제목용 활자를 만들지 않습니다 — 오래 읽어야 하는 본문의 활자만
|
||||
만듭니다. 획의 장력, 자간의 균형, 행간의 숨을 그 단위(UPM)로
|
||||
측정합니다.
|
||||
</p>
|
||||
<dl class="hero-facts reveal" style="--delay: 120ms">
|
||||
<div>
|
||||
<dt>서체</dt>
|
||||
<dd>한성본문 · 한성제목</dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt>글자 수</dt>
|
||||
<dd>11,172자 완성</dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt>단위</dt>
|
||||
<dd>1000 UPM · 가변 웨이트 3종</dd>
|
||||
</div>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!--
|
||||
활자 두 종 — 스페시멘은 실제 문장으로. Lorem ipsum 은 활자시험의 반대다.
|
||||
-->
|
||||
<section id="typefaces" class="section" aria-labelledby="typefaces-h">
|
||||
<div class="wrap">
|
||||
<h2 id="typefaces-h">활자 두 종</h2>
|
||||
|
||||
<article class="typeface reveal">
|
||||
<header class="typeface-head">
|
||||
<h3>한성본문</h3>
|
||||
<p class="muted">본문용 · 웨이트 400 · 16px에서 행간 1.8</p>
|
||||
</header>
|
||||
<p class="specimen" style="font-family: 'MaruBuri', serif">
|
||||
아침 안개가 걷히기 전에 도랑물 소리가 먼저 들렸다. 글자는 종이 위에서
|
||||
소리를 내지 않지만, 잘 짜인 활자는 소리 내어 읽게 만든다. 획이 닿는
|
||||
각도와 글자가 서로 미는 힘을 천 번쯤 고쳐 썼다. 그 결과 이 문장이
|
||||
밤늦게도 읽히는 것이다.
|
||||
</p>
|
||||
</article>
|
||||
|
||||
<article class="typeface reveal" style="--delay: 80ms">
|
||||
<header class="typeface-head">
|
||||
<h3>한성제목</h3>
|
||||
<p class="muted">제목·표제용 · 웨이트 600 · 큰 짝에서 벌어짐 0</p>
|
||||
</header>
|
||||
<p class="specimen specimen-display" style="font-family: 'MaruBuri', serif">
|
||||
활자는 붓의 속도를 기억한다
|
||||
</p>
|
||||
</article>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!--
|
||||
조판 시험대 — 이 페이지의 리스크이자 유일한 인터랙션.
|
||||
슬라이더 세 개가 실제 본문에 즉시 반영된다. 라벨은 한국어, 값은 숫자로.
|
||||
-->
|
||||
<section id="bench" class="section band" aria-labelledby="bench-h">
|
||||
<div class="wrap">
|
||||
<h2 id="bench-h">조판 시험대</h2>
|
||||
<p class="muted bench-lead">
|
||||
자간과 행간, 글자 크기가 가독성을 어떻게 바꾸는지 직접 움직여 보세요.
|
||||
아래 값은 권장값이 아니라 출발점입니다 — 용지 규격과 본문 길이에 따라
|
||||
정답은 달라집니다.
|
||||
</p>
|
||||
|
||||
<div class="bench">
|
||||
<form class="bench-controls" aria-label="조판 설정">
|
||||
<div class="control">
|
||||
<label for="ctl-size">글자 크기 <output id="out-size" for="ctl-size">17</output></label>
|
||||
<input type="range" id="ctl-size" min="13" max="26" step="1" value="17" />
|
||||
</div>
|
||||
<div class="control">
|
||||
<label for="ctl-tracking">자간 <output id="out-tracking" for="ctl-tracking">0</output></label>
|
||||
<input type="range" id="ctl-tracking" min="-5" max="10" step="1" value="0" />
|
||||
</div>
|
||||
<div class="control">
|
||||
<label for="ctl-leading">행간 <output id="out-leading" for="ctl-leading">1.8</output></label>
|
||||
<input type="range" id="ctl-leading" min="1.4" max="2.4" step="0.1" value="1.8" />
|
||||
</div>
|
||||
<button type="button" class="btn-reset" id="ctl-reset">권장값으로</button>
|
||||
</form>
|
||||
<div
|
||||
class="bench-sample"
|
||||
id="bench-sample"
|
||||
style="font-family: 'MaruBuri', serif"
|
||||
aria-live="polite"
|
||||
>
|
||||
활자의 역사는 글자를 찍는 기계의 역사가 아니라, 글자를 읽는 눈의
|
||||
역사였다. 활자소의 식자공들은 하루에 만 글자를 짜면서 어느 글꼴이
|
||||
눈을 덜 아프게 하는지 알고 있었다. 그 지식은 문서로 남지 않았고
|
||||
손끝으로만 전해졌다. 이 시험대는 그 손끝의 판단을 누구나 해볼 수
|
||||
있는 눈금으로 옮긴 것이다. 자간을 0에서 5로 옮겨 보라 — 문장이
|
||||
늘어지는 것이 아니라 숨이 가빠지는 것을 느낄 것이다.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!--
|
||||
활자 케이스 — 연구소의 물성. 금속 활자와 인주.
|
||||
-->
|
||||
<section id="case" class="section" aria-labelledby="case-h">
|
||||
<div class="wrap case-grid">
|
||||
<figure class="case-photo reveal">
|
||||
<img
|
||||
src="./assets/metaltype.webp"
|
||||
alt="나무 활자 케이스에 골라 담긴 금속 활자들 — 활자면이 위에서 빛을 받아 결이 보인다"
|
||||
width="900"
|
||||
height="1200"
|
||||
loading="lazy"
|
||||
/>
|
||||
<figcaption>연구소 2층 · 금속 활자 케이스</figcaption>
|
||||
</figure>
|
||||
<div class="case-text">
|
||||
<h2 id="case-h">금속에서 시작해<br />화면으로 끝난다</h2>
|
||||
<p>
|
||||
한성본문의 자간 규칙은 금속 활자의 '옆면 여백'에서 왔습니다. 납활자는
|
||||
글자 바로 옆에 살이 붙어 있어서, 찍히는 글자 사이는 언제나 일정했고
|
||||
그 일정함이 읽는 리듬이었습니다. 화면용 폰트는 그 살을 지울 수
|
||||
있지만, 우리는 지우지 않았습니다.
|
||||
</p>
|
||||
<figure class="case-photo-b reveal" style="--delay: 80ms">
|
||||
<img
|
||||
src="./assets/inkstone.webp"
|
||||
alt="연구한 먹이 고인 연적과 옆에 놓인 인주 연판"
|
||||
width="1100"
|
||||
height="825"
|
||||
loading="lazy"
|
||||
/>
|
||||
<figcaption>먹을 갈고 인주를 찍는 자리 — 시험 인쇄 전</figcaption>
|
||||
</figure>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!--
|
||||
구입 — 라이선스는 조판 단위로. 조용한 두 줄.
|
||||
-->
|
||||
<section id="order" class="section" aria-labelledby="order-h">
|
||||
<div class="wrap order-grid">
|
||||
<div>
|
||||
<h2 id="order-h">구입</h2>
|
||||
<p class="muted">
|
||||
웹·출판·임베드 세 가지 라이선스만 있습니다. 사용 수를 세지 않습니다 —
|
||||
조판되는 단위(도서 권수, 사이트 도메인, 기기)로 셉니다.
|
||||
</p>
|
||||
</div>
|
||||
<div class="order-rows">
|
||||
<div class="order-row">
|
||||
<div>
|
||||
<h3>웹</h3>
|
||||
<p>도메인당 · 웨이트 전종 · 자체 호스팅 WOFF2</p>
|
||||
</div>
|
||||
<p class="order-price">140,000원</p>
|
||||
</div>
|
||||
<div class="order-row">
|
||||
<div>
|
||||
<h3>출판</h3>
|
||||
<p>도서 권수당 · 인쇄+전자 동시</p>
|
||||
</div>
|
||||
<p class="order-price">220,000원</p>
|
||||
</div>
|
||||
</div>
|
||||
<a class="btn" href="mailto:foundry@hanseong.kr">견적 문의</a>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<footer class="site-foot">
|
||||
<div class="wrap foot-inner">
|
||||
<p>한성활자연구소 · 서울 마포</p>
|
||||
<p class="muted">foundry@hanseong.kr</p>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script>
|
||||
/* 시험대 — 슬라이더 세 개가 본문 스타일을 직접 쓴다. 프레임당 레이아웃 없음. */
|
||||
const sample = document.getElementById("bench-sample");
|
||||
const ctl = {
|
||||
size: document.getElementById("ctl-size"),
|
||||
tracking: document.getElementById("ctl-tracking"),
|
||||
leading: document.getElementById("ctl-leading"),
|
||||
};
|
||||
const out = {
|
||||
size: document.getElementById("out-size"),
|
||||
tracking: document.getElementById("out-tracking"),
|
||||
leading: document.getElementById("out-leading"),
|
||||
};
|
||||
const defaults = { size: 17, tracking: 0, leading: 1.8 };
|
||||
|
||||
function apply() {
|
||||
const px = ctl.size.value + "px";
|
||||
const em = ctl.tracking.value / 100 + "em";
|
||||
const lh = ctl.leading.value;
|
||||
sample.style.fontSize = px;
|
||||
sample.style.letterSpacing = em;
|
||||
sample.style.lineHeight = lh;
|
||||
out.size.textContent = ctl.size.value;
|
||||
out.tracking.textContent = ctl.tracking.value;
|
||||
out.leading.textContent = Number(ctl.leading.value).toFixed(1);
|
||||
}
|
||||
for (const input of Object.values(ctl)) {
|
||||
input.addEventListener("input", apply);
|
||||
}
|
||||
document.getElementById("ctl-reset").addEventListener("click", () => {
|
||||
ctl.size.value = defaults.size;
|
||||
ctl.tracking.value = defaults.tracking;
|
||||
ctl.leading.value = defaults.leading;
|
||||
apply();
|
||||
});
|
||||
apply();
|
||||
|
||||
const io = new IntersectionObserver(
|
||||
(entries) => {
|
||||
for (const e of entries) {
|
||||
if (!e.isIntersecting) continue;
|
||||
e.target.classList.add("is-in");
|
||||
io.unobserve(e.target);
|
||||
}
|
||||
},
|
||||
{ rootMargin: "0px 0px -8% 0px", threshold: 0.05 },
|
||||
);
|
||||
for (const el of document.querySelectorAll(".reveal")) io.observe(el);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
420
apps/site/public/work/font-foundry/styles/main.css
Normal file
420
apps/site/public/work/font-foundry/styles/main.css
Normal file
|
|
@ -0,0 +1,420 @@
|
|||
@import url("./tokens.css");
|
||||
|
||||
/* ==========================================================================
|
||||
한성활자연구소 — editorial-archival. 글자가 상품.
|
||||
========================================================================== */
|
||||
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
* {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
html {
|
||||
-webkit-text-size-adjust: 100%;
|
||||
scroll-behavior: smooth;
|
||||
background: var(--surface);
|
||||
}
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
html {
|
||||
scroll-behavior: auto;
|
||||
}
|
||||
}
|
||||
|
||||
body {
|
||||
background: var(--surface);
|
||||
color: var(--ink);
|
||||
font-family: var(--font-body);
|
||||
font-size: var(--step-0);
|
||||
line-height: var(--leading-normal);
|
||||
-webkit-font-smoothing: antialiased;
|
||||
}
|
||||
|
||||
:where(h1, h2, h3) {
|
||||
font-family: var(--font-display);
|
||||
font-weight: 600;
|
||||
line-height: var(--leading-tight);
|
||||
word-break: keep-all;
|
||||
overflow-wrap: break-word;
|
||||
text-wrap: balance;
|
||||
}
|
||||
h2 {
|
||||
font-size: var(--step-2);
|
||||
}
|
||||
h3 {
|
||||
font-family: var(--font-body);
|
||||
font-weight: 600;
|
||||
font-size: var(--step-1);
|
||||
}
|
||||
:where(p, li, dd, dt, th, td, figcaption) {
|
||||
word-break: keep-all;
|
||||
overflow-wrap: break-word;
|
||||
line-height: var(--leading-normal);
|
||||
text-wrap: pretty;
|
||||
}
|
||||
|
||||
.muted {
|
||||
color: var(--ink-muted);
|
||||
}
|
||||
a {
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
:focus-visible {
|
||||
outline: 2px solid var(--accent);
|
||||
outline-offset: 3px;
|
||||
}
|
||||
|
||||
.skip {
|
||||
position: absolute;
|
||||
left: -9999px;
|
||||
top: 0;
|
||||
background: var(--ink);
|
||||
color: var(--surface);
|
||||
padding: var(--space-3) var(--space-4);
|
||||
z-index: 100;
|
||||
}
|
||||
.skip:focus {
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.wrap {
|
||||
width: min(100% - 2 * var(--pad-inline), var(--container));
|
||||
margin-inline: auto;
|
||||
}
|
||||
|
||||
/* ── 헤더 ─────────────────────────────────────────────────────────────── */
|
||||
|
||||
.site-head {
|
||||
position: sticky;
|
||||
top: 0;
|
||||
z-index: 50;
|
||||
background: color-mix(in srgb, var(--surface) 90%, transparent);
|
||||
backdrop-filter: blur(6px);
|
||||
border-bottom: 1px solid var(--line);
|
||||
}
|
||||
.head-inner {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
justify-content: space-between;
|
||||
gap: var(--space-4);
|
||||
padding-block: var(--space-3);
|
||||
}
|
||||
.wordmark {
|
||||
font-family: var(--font-display);
|
||||
font-size: var(--step-1);
|
||||
font-weight: 600;
|
||||
text-decoration: none;
|
||||
}
|
||||
.nav {
|
||||
display: flex;
|
||||
gap: clamp(var(--space-3), 2vw, var(--space-5));
|
||||
font-size: var(--step--1);
|
||||
}
|
||||
.nav a {
|
||||
text-decoration: none;
|
||||
color: var(--ink-muted);
|
||||
padding-block: 2px;
|
||||
border-bottom: 1px solid transparent;
|
||||
transition: color var(--dur-quick) var(--ease-soft),
|
||||
border-color var(--dur-quick) var(--ease-soft);
|
||||
}
|
||||
.nav a:hover {
|
||||
color: var(--ink);
|
||||
border-color: var(--accent);
|
||||
}
|
||||
|
||||
/* ── 스페시멘 히어로 ──────────────────────────────────────────────────── */
|
||||
|
||||
.hero {
|
||||
padding-block: var(--space-7) var(--space-8);
|
||||
}
|
||||
.hero-kicker {
|
||||
font-size: var(--step--1);
|
||||
color: var(--ink-muted);
|
||||
letter-spacing: 0.06em;
|
||||
}
|
||||
.hero-glyph {
|
||||
font-size: clamp(11rem, 24vw, 22rem);
|
||||
line-height: 0.95;
|
||||
margin-top: var(--space-4);
|
||||
position: relative;
|
||||
}
|
||||
/* 인주각 — 글리프 옆에 찍히는 도장 */
|
||||
.hero-glyph::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
right: 0.12em;
|
||||
bottom: 0.18em;
|
||||
width: 0.11em;
|
||||
height: 0.11em;
|
||||
background: var(--accent);
|
||||
}
|
||||
.hero-side {
|
||||
margin-top: var(--space-5);
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
|
||||
gap: var(--space-5) var(--space-7);
|
||||
align-items: start;
|
||||
}
|
||||
.hero-statement {
|
||||
max-width: 32em;
|
||||
}
|
||||
.hero-facts {
|
||||
display: grid;
|
||||
gap: var(--space-3);
|
||||
border-left: 1px solid var(--line);
|
||||
padding-left: var(--space-5);
|
||||
}
|
||||
.hero-facts dt {
|
||||
font-size: var(--step--1);
|
||||
color: var(--ink-faint);
|
||||
}
|
||||
.hero-facts dd {
|
||||
margin-top: 2px;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/* ── 섹션 공통 ────────────────────────────────────────────────────────── */
|
||||
|
||||
.section {
|
||||
padding-block: var(--space-8);
|
||||
}
|
||||
.band {
|
||||
background: var(--surface-raised);
|
||||
border-block: 1px solid var(--line);
|
||||
}
|
||||
|
||||
/* ── 활자 두 종 ───────────────────────────────────────────────────────── */
|
||||
|
||||
.typeface + .typeface {
|
||||
margin-top: var(--space-6);
|
||||
}
|
||||
.typeface-head {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: baseline;
|
||||
gap: var(--space-4);
|
||||
flex-wrap: wrap;
|
||||
border-top: 1px solid var(--line);
|
||||
padding-top: var(--space-3);
|
||||
}
|
||||
.typeface-head .muted {
|
||||
font-size: var(--step--1);
|
||||
}
|
||||
.specimen {
|
||||
margin-top: var(--space-4);
|
||||
font-size: 1.1875rem;
|
||||
line-height: 1.9;
|
||||
max-width: 46em;
|
||||
}
|
||||
.specimen-display {
|
||||
font-size: clamp(1.75rem, 1.2rem + 3vw, 3.25rem);
|
||||
line-height: 1.45;
|
||||
max-width: 22em;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* ── 조판 시험대 ──────────────────────────────────────────────────────── */
|
||||
|
||||
.bench-lead {
|
||||
max-width: 36em;
|
||||
margin-top: var(--space-3);
|
||||
}
|
||||
.bench {
|
||||
margin-top: var(--space-5);
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 4fr) minmax(0, 8fr);
|
||||
gap: var(--space-5) var(--space-7);
|
||||
align-items: start;
|
||||
}
|
||||
.bench-controls {
|
||||
display: grid;
|
||||
gap: var(--space-4);
|
||||
}
|
||||
.control label {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
font-size: var(--step--1);
|
||||
color: var(--ink-muted);
|
||||
}
|
||||
.control output {
|
||||
font-variant-numeric: tabular-nums;
|
||||
color: var(--ink);
|
||||
}
|
||||
input[type="range"] {
|
||||
width: 100%;
|
||||
accent-color: var(--accent);
|
||||
}
|
||||
.btn-reset {
|
||||
justify-self: start;
|
||||
background: none;
|
||||
border: 1px solid var(--line);
|
||||
border-radius: var(--radius);
|
||||
color: var(--ink-muted);
|
||||
font-size: var(--step--1);
|
||||
padding: 0.4rem 0.9rem;
|
||||
cursor: pointer;
|
||||
transition: border-color var(--dur-quick) var(--ease-soft),
|
||||
color var(--dur-quick) var(--ease-soft);
|
||||
}
|
||||
.btn-reset:hover {
|
||||
border-color: var(--accent);
|
||||
color: var(--ink);
|
||||
}
|
||||
.bench-sample {
|
||||
border: 1px solid var(--line);
|
||||
background: var(--surface);
|
||||
border-radius: var(--radius);
|
||||
padding: var(--space-5);
|
||||
max-width: 46em;
|
||||
}
|
||||
|
||||
/* ── 활자 케이스 ──────────────────────────────────────────────────────── */
|
||||
|
||||
.case-grid {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
|
||||
gap: var(--space-6) var(--space-7);
|
||||
align-items: start;
|
||||
}
|
||||
.case-photo img,
|
||||
.case-photo-b img {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: auto;
|
||||
border-radius: var(--radius);
|
||||
}
|
||||
.case-photo figcaption,
|
||||
.case-photo-b figcaption {
|
||||
font-size: var(--step--1);
|
||||
color: var(--ink-faint);
|
||||
margin-top: var(--space-2);
|
||||
}
|
||||
.case-text h2 {
|
||||
margin-bottom: var(--space-4);
|
||||
}
|
||||
.case-photo-b {
|
||||
margin-top: var(--space-5);
|
||||
max-width: 34rem;
|
||||
}
|
||||
|
||||
/* ── 구입 ─────────────────────────────────────────────────────────────── */
|
||||
|
||||
.order-grid {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 5fr) minmax(0, 6fr) auto;
|
||||
gap: var(--space-5) var(--space-7);
|
||||
align-items: start;
|
||||
}
|
||||
.order-grid .muted {
|
||||
margin-top: var(--space-3);
|
||||
max-width: 26em;
|
||||
}
|
||||
.order-rows {
|
||||
border-top: 1px solid var(--line);
|
||||
}
|
||||
.order-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: baseline;
|
||||
gap: var(--space-4);
|
||||
padding-block: var(--space-3);
|
||||
border-bottom: 1px solid var(--line);
|
||||
}
|
||||
.order-row p {
|
||||
font-size: var(--step--1);
|
||||
color: var(--ink-muted);
|
||||
margin-top: 2px;
|
||||
}
|
||||
.order-price {
|
||||
font-family: var(--font-display);
|
||||
font-size: var(--step-1);
|
||||
white-space: nowrap;
|
||||
}
|
||||
.btn {
|
||||
display: inline-block;
|
||||
background: var(--accent);
|
||||
color: var(--accent-ink);
|
||||
font-weight: 500;
|
||||
text-decoration: none;
|
||||
padding: 0.75rem 1.5rem;
|
||||
border-radius: var(--radius);
|
||||
transition: background var(--dur-quick) var(--ease-soft);
|
||||
}
|
||||
.btn:hover {
|
||||
background: var(--accent-hover);
|
||||
}
|
||||
|
||||
/* ── 푸터 ─────────────────────────────────────────────────────────────── */
|
||||
|
||||
.site-foot {
|
||||
border-top: 1px solid var(--line);
|
||||
padding-block: var(--space-5);
|
||||
font-size: var(--step--1);
|
||||
}
|
||||
.foot-inner {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
gap: var(--space-3) var(--space-5);
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
/* ── 등장 모션 ────────────────────────────────────────────────────────── */
|
||||
|
||||
.reveal {
|
||||
opacity: 0;
|
||||
translate: 0 12px;
|
||||
transition: opacity var(--dur-normal) var(--ease-soft),
|
||||
translate var(--dur-normal) var(--ease-soft);
|
||||
transition-delay: var(--delay, 0ms);
|
||||
}
|
||||
.reveal.is-in {
|
||||
opacity: 1;
|
||||
translate: 0 0;
|
||||
}
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.reveal {
|
||||
opacity: 1;
|
||||
translate: 0 0;
|
||||
transition: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* ── 반응형 ───────────────────────────────────────────────────────────── */
|
||||
|
||||
@media (max-width: 900px) {
|
||||
.hero-side,
|
||||
.bench,
|
||||
.case-grid,
|
||||
.order-grid {
|
||||
grid-template-columns: 1fr;
|
||||
gap: var(--space-5);
|
||||
}
|
||||
.case-photo {
|
||||
max-width: 24rem;
|
||||
}
|
||||
.hero,
|
||||
.section {
|
||||
padding-block: var(--space-6);
|
||||
}
|
||||
}
|
||||
@media (max-width: 560px) {
|
||||
.head-inner {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
gap: var(--space-1);
|
||||
}
|
||||
.nav {
|
||||
width: 100%;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.order-row {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
gap: var(--space-1);
|
||||
}
|
||||
}
|
||||
53
apps/site/public/work/font-foundry/styles/tokens.css
Normal file
53
apps/site/public/work/font-foundry/styles/tokens.css
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
/* ==========================================================================
|
||||
한성활자연구소 — 디자인 토큰
|
||||
프리셋: editorial-archival
|
||||
컨셉 한 문장: 글자가 상품이다 — 첫 화면부터 스페시멘, 나머지는 물성과 눈금.
|
||||
레퍼런스: dogfood-foundry(파운드리 계열 구조 관찰 — 별도 파일). 방향:
|
||||
스페시멘은 Lorem 이 아니라 실제 문장, 테스터는 즉시 반영.
|
||||
하지 않은 것: Lorem ipsum, 서체 카드 3열, '구독하면 웨이트 전부' 마케팅,
|
||||
책등 세로 내비. 이유: 활자는 보여주는 것이지 포장하는 게 아니다.
|
||||
강조 인주빨강 #A63D2F — 인장·CTA에만. 배경 채움은 버튼 하나 뿐.
|
||||
========================================================================== */
|
||||
|
||||
:root {
|
||||
/* 타입 — 스페시멘 글리프는 스케일 밖(20vw). 본문 17px. */
|
||||
--step--1: 0.8125rem; /* 13px */
|
||||
--step-0: 1.0625rem; /* 17px — 본문 (조판을 파는 페이지) */
|
||||
--step-1: 1.25rem; /* 20px */
|
||||
--step-2: clamp(1.375rem, 1.2rem + 0.9vw, 1.75rem); /* 28px */
|
||||
--step-3: clamp(2rem, 1.4rem + 3vw, 3.25rem); /* 52px */
|
||||
|
||||
--leading-tight: 1.3;
|
||||
--leading-normal: 1.85;
|
||||
|
||||
--font-display: "MaruBuri", serif;
|
||||
--font-body: "Pretendard Variable", Pretendard, -apple-system, sans-serif;
|
||||
|
||||
--surface: #f5f1e8; /* 한지 */
|
||||
--surface-raised: #ede7d9;
|
||||
--ink: #26221d;
|
||||
--ink-muted: #6a635a;
|
||||
--ink-faint: #948b7c;
|
||||
--line: #d9d1bf;
|
||||
--accent: #a63d2f; /* 인주 */
|
||||
--accent-ink: #f5f1e8;
|
||||
--accent-hover: #8a3225; /* 인주 눌린 단계 */
|
||||
|
||||
--space-1: 0.25rem;
|
||||
--space-2: 0.5rem;
|
||||
--space-3: 1rem;
|
||||
--space-4: 1.5rem;
|
||||
--space-5: 2.5rem;
|
||||
--space-6: 4rem;
|
||||
--space-7: 6rem;
|
||||
--space-8: clamp(4.5rem, 3rem + 6vw, 8.5rem);
|
||||
|
||||
--radius: 2px;
|
||||
|
||||
--container: 1120px;
|
||||
--pad-inline: clamp(1.25rem, 1rem + 2.5vw, 4rem);
|
||||
|
||||
--dur-quick: 160ms;
|
||||
--dur-normal: 420ms;
|
||||
--ease-soft: cubic-bezier(0.25, 1, 0.35, 1);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue