feat(site): rework 19 marketing showcases for composition diversity
Some checks are pending
ci / build (push) Waiting to run
Some checks are pending
ci / build (push) Waiting to run
Measured convergence before: split hero 13/19, top-bar nav 19/19, one-line notice footer 14/19, body Pretendard 17/21, 10 similarity pairs above 0.78. Each showcase got a pre-assigned hero family, nav form, footer form, type pair, background, accent hue, radius, motion grammar and material from outputs/rework-2026-10-06/plan.md; direction cards and the chosen reason are recorded in every design.md. After: 0 similarity warnings, 19 distinct display faces, 7 hero families, 5 nav forms, 5 footer forms, no scroll reveals, 5 showcases with SVG filter materials. Example contact values replace bracket placeholders under the existing fictional-brand notices. Thumbnails, OG images, card copy and three e2e assertions updated; dead CSS in dure-enrollment and hannam-jari removed; similarity.mjs learns the new font families.
This commit is contained in:
parent
88c11682b1
commit
8e3cdb0d3b
296 changed files with 19131 additions and 17538 deletions
|
|
@ -1,77 +1,75 @@
|
|||
# design.md — 한성활자연구소
|
||||
|
||||
## 진행 상태
|
||||
|
||||
- 2026-10-06 재작업(전체·리디자인 경로, 방향 위임): 0 감사 → 1 레퍼런스 → 2 카드 A 선택 → 3 토큰 → 4 구현 → 5 검증 통과 → 6 이 문서. 작업 노트 `outputs/rework-2026-10-06/font-foundry.md`.
|
||||
|
||||
## 브리프
|
||||
|
||||
- **무엇을**: 가상 서체 기획을 정직하게 밝히면서, 실제 마루 부리와 Pretendard로 문장 조판의 형태 차이를 즉시 체험하는 한국어 타입 스튜디오.
|
||||
- **누구에게**: 활자를 고르거나 본문 조판 값을 결정해야 하는 편집자·디자이너·개발자.
|
||||
- **제약**: ko-KR 한국어, 밝은 아이보리·검정 본문·버밀리언 정체성 유지. 가상 서체를 판매하거나 가짜 스펙을 제시하지 않으며, 본문은 최대 42rem. 320px부터 가로 넘침이 없어야 한다.
|
||||
- **무엇을**: 한글 본문 서체 두 종(마루 부리·Pretendard)을 글자 하나의 굵기 축에서 보고, 같은 문장을 크기·자간·행간을 바꿔 조판해 보는 가상 서체 연구소 한 장.
|
||||
- **누구에게**: 본문 서체와 조판 값을 정해야 하는 편집자·디자이너·개발자. 목표 행동은 굵기 슬라이더와 조판 시험대를 직접 움직이는 것(문의·구매 없음).
|
||||
- **제약**: ko-KR. 정적 HTML/CSS/인라인 JS. 가상 기획이라 실제 주문으로 이어지지 않으며 가격은 예시. 마루 부리는 공식 배포본 그대로(서브셋 금지). 320px부터 가로 넘침 없음. 화면: `index.html` 한 장.
|
||||
- 확정 슬롯: 업종 서체 연구소 / 톤 "글자 자체가 이미지, 설명은 작게" / 자산 마루 부리 WOFF2 2종·견본 문장·예시 가격 / 좁은 화면 내비 탭 2개 그대로.
|
||||
|
||||
## 리디자인 감사와 레퍼런스
|
||||
## 미확정
|
||||
|
||||
이전 판은 한 글자 표본과 실제 렌더 서체의 관계가 멀고, 11,172자·1000 UPM 같은 가상 수치가 체험보다 앞섰다. 실제 사용자가 판단할 수 있는 것은 문장 안의 폭·획·간격이므로 그 역할을 첫 화면으로 올렸다.
|
||||
- 가격 140,000·220,000원 — 예시(order 섹션에 "예시" 명시).
|
||||
- 글리프 기본 글자 `활` — 브랜드 연상으로 정했고 사용자가 바꿀 수 있다.
|
||||
- 방향 카드 선택 — 위임으로 A를 골랐다(아래).
|
||||
|
||||
| 출처 ID · 슬롯 | 출처 | 관찰 | 채택한 원리와 검증 |
|
||||
| --- | --- | --- | --- |
|
||||
| `KLIM-FONTS` · R1 구조 | https://klim.co.nz/fonts/ | Display, Text, Narrow, Condensed처럼 같은 계열의 역할과 폭을 나란히 제시한다. | 글꼴을 사양 표가 아니라 읽는 역할로 비교한다. 같은 문장을 두 역할로 렌더해 비교한다. |
|
||||
| `CHIPPERFIELD-PROJECTS` · R2 톤 | https://davidchipperfield.com/projects | 프로젝트명·연도·필터가 정렬선과 짧은 메타 안에서 읽힌다. | 큰 표본 아래에 기준선, 짧은 메타, 한 가지 행동을 정렬한다. 1440px 첫 화면에서 표본·상태·CTA의 순서를 확인한다. |
|
||||
| `SANDOLL-TYPELAB` · R3 디테일 | https://typelab.sandoll.co.kr/experience | 권장규격과 맞춤규격, 한글 범위를 선택하며 표본을 실제 작업으로 연결한다. | 버튼과 조판 슬라이더가 즉시 보이는 결과를 바꾸게 한다. 키보드·range·리셋으로 값을 바꾸어 검증한다. |
|
||||
| `WCAG-READ` · 접근성 | 200% 텍스트 확대와 320 CSS px reflow를 핵심 화면에서 별도로 시험한다. | 큰 활자 장면은 접근성 제목을 대신하지 않는다. | 이전 판에서 320px·200% 확대와 `aria-hidden` 표본을 관찰했다. Round 4 현재 결과는 최종 proof를 참조한다. |
|
||||
## 레퍼런스
|
||||
|
||||
| 슬롯 | 출처 | 가져온 원리 |
|
||||
|---|---|---|
|
||||
| R1 구조 | https://abcdinamo.com/typefaces/favorit (2026-10-06 텍스트 페처) | 첫 화면이 타입 테스터, 변종·보기를 탭으로 바꾼다 |
|
||||
| R2 톤 | https://rsms.me/inter/ (2026-10-06 텍스트 페처) | 글자 표본이 곧 첫 화면, 설명은 아래 작게 |
|
||||
| R3 디테일 | https://typelab.sandoll.co.kr/experience (이전 판 기록 재사용, 미재검증) | 조작이 즉시 표본을 바꾼다 |
|
||||
| 푸터 | https://pangrampangram.com/ 확인 — 워드마크 한 줄 푸터 아님. 배정값으로 감(미검증) | — |
|
||||
|
||||
## 방향
|
||||
|
||||
- **컨셉**: 문장이 보여 주는 활자의 차이.
|
||||
- **프리셋**: `editorial` — 읽는 시간이 주제이므로 따뜻한 바탕, 제한된 색, 좁은 본문 폭, 세리프 표제를 쓴다.
|
||||
- **감수한 리스크**: 이미지를 히어로에서 빼고 버밀리언 세 글자 표본 하나를 가장 큰 장면으로 사용한다. 제목과 설명은 별도 DOM으로 남겨 접근성 판단을 표본에 기대지 않는다.
|
||||
**지문**: 히어로 타이포 단독(글자 하나 거대 + 굵기 슬라이더) · 표제 Noto Serif KR 900 / 본문 Noto Sans KR 400 · 바탕 밝은 쿨 중립 #f1f2f4 · 강조 240° 남색 잉크 #22235a · radius 0 · 흐름 글리프 → 같은 문장 비교 → 조판 시험대 → 옆면 여백과 자간 → 가격(예시) → 워드마크 · 내비 탭·세그먼트(서체별 보기, 상단 바 없음, sticky 없음) · 푸터 큰 워드마크 한 줄 · 이미지 없음(글자가 이미지) · 모션 탭 전환 View Transitions + 글리프 크기 scroll-driven.
|
||||
|
||||
## 토큰과 구현
|
||||
- **컨셉**: 본문 서체를 고르는 편집자가 한 글자를 굵기 축으로 밀어 보며 마루 부리(정적 2굵기)와 Pretendard(가변 45~920)의 성격을 판단하고, 같은 문장 조판으로 확인한다.
|
||||
- **프리셋**: swiss-minimal 지배(격자·침묵·쿨 중립), 보조 없음. 서체·명도·hue·radius는 plan.md 배정값.
|
||||
- **표현 리스크**: 글자 하나가 첫 화면 56svh를 차지해 "무엇을 하는 곳"이 h1·리드에만 있다. 검증: 1440·390 첫 화면에 h1·리드·슬라이더가 함께 들어오는지(둘 다 들어옴, 390 하단 821px).
|
||||
- **카드**: A 글자 하나의 굵기(선택) / B 문장 폭포(문장 다섯 크기, 자간 슬라이더) / C 자모 분해(초·중·종성 세 칸). A를 고른 이유 — 브리프의 사실(정적 2굵기 vs 가변 축)이 굵기 축에서 가장 분명하고, R1·R2 둘 다 글자 표본이 첫 화면이었다. B는 비교 섹션과 역할이 겹치고 C는 글자 교체가 어렵다.
|
||||
- **반사실**: 고유 요소 — 마루 부리 거대 글리프 + 서체별로 바뀌는 굵기 축(400↔600 / 100~900), 서체 이름 탭, 네이버·OFL·굵기 수 사실. 세무사무소로 치환하면 슬라이더·탭이 성립하지 않는다. 수렴(muwol-coffee 대비 6축): 히어로 패밀리·탭 내비 같음, 나머지 4축 다름.
|
||||
- **보존 자산**: 상호, 견본 문장, 시험대 기본값 17px/0em/1.8과 `display/body` 값, 마루 부리 파일, 예시 가격, 가상 고지.
|
||||
|
||||
- **폰트**: 마루 부리는 공식 로컬 WOFF2 Regular 400·SemiBold 600으로 제목·조판 시험대·표본의 제목 상태를 맡고, Pretendard CDN은 본문·기본 표본 상태를 맡는다. `font-synthesis-weight: none`으로 합성 굵기를 막는다.
|
||||
- **색**: `--surface #f5f1e8`, `--ink #26221d`, `--accent #a63d2f`. 버밀리언은 표본과 행동에만 쓴다.
|
||||
- **크기**: h1 `clamp(40px, 1.6rem + 3vw, 60px)`, 표본 `clamp(96px, 11vw, 180px)`, 본문 폭 최대 `42rem`.
|
||||
- **레이아웃**: 데스크톱 첫 화면은 5:7 두 칼럼으로, 종이색 소개면과 적갈색 표본면을 맞물린다. 900px 미만에서는 소개면 다음에 표본면을 한 칼럼으로 둔다.
|
||||
- **상호작용**: native 버튼 두 개의 `aria-pressed`가 표본 폰트와 상태 문구를 바꾼다. 조판 시험대는 실제 마루 부리·Pretendard 선택과 크기·자간·행간 range를 제공하고, 리셋은 네 값을 함께 복원한다.
|
||||
- **성능**: 새 JavaScript 라이브러리·이미지·애니메이션 없음. 초기 체험은 인라인 DOM 코드만 사용한다. 활자 케이스의 두 장면은 생성 이미지임을 캡션으로 밝힌다.
|
||||
## 토큰과 예산
|
||||
|
||||
## 의도적으로 하지 않은 것
|
||||
값은 `styles/tokens.css`. 역할: `--font-display` 표제·h3·워드마크, `--font-body` 본문·UI, `--face-buri`·`--face-godic` 표본·시험대 전용(UI에 쓰지 않는다). `--accent`는 거대 글리프·활성 탭·슬라이더·버튼에만. `--line-strong`은 컨트롤 테두리(3.98:1). Noto Sans KR은 400 한 굵기만 싣고 강조는 서체·색으로 낸다.
|
||||
|
||||
- 마루 부리·Pretendard를 가상의 한성 서체로 속여 판매하지 않는다. 가상 기획과 실제 구현 폰트를 표본 바로 위와 푸터에 밝힌다.
|
||||
- 인장·붓글씨·세로쓰기·종이결처럼 한국 활자를 이국화하는 장식을 사용하지 않는다. 활자의 형태와 조판만으로 분위기를 만든다.
|
||||
- 움직임으로 활자의 차이를 설명하지 않는다. reduced motion에서도 같은 표본과 모든 조작이 남는다.
|
||||
예산(tokens §5 데모): JS 150KB — 실측 인라인 4KB. LCP 2.5s — 로컬 308ms(`#glyph`), CLS 0.000. 폰트 전송 200KB — **실측 ≈939KB 초과**(마루 부리 424KB + Pretendard 동적 서브셋 229KB + Noto 286KB). 표본 서체가 제품이고 마루 부리는 공식 배포본 그대로라 이번 작업에서 줄이지 않았다. 별도 작업 제안: OFL 범위의 한글 서브셋.
|
||||
|
||||
## 이전 판 검증 기록 · 2026-09-12
|
||||
## 이펙트와 폴백
|
||||
|
||||
아래는 이전 판에서 남긴 역사적 관찰이며 Round 4의 현재 통과 결과가 아니다. Round 4 결과는 최종 proof를 참조한다.
|
||||
- 탭 전환: `document.startViewTransition` 래퍼. 미지원·감소 모션은 즉시 교체. `::view-transition-*(glyph|face-status)`만 저자 키프레임.
|
||||
- 글리프 축소: `animation-timeline: scroll(root block)` 0~80vh, scale 1→0.55. `@media (prefers-reduced-motion: no-preference)`와 `@supports` 안에 둬 Firefox·감소 모션은 고정 크기.
|
||||
- 재질 없음. 이펙트 전부 끄고 JS를 꺼도 글리프·비교·시험대가 그대로 남는다(검증 참조).
|
||||
|
||||
- `outputs/design-expertise-20260912/font/font-redesign-e2e.mjs`가 독립 정적 서버에서 320·390·768·1440·1920·2560px를 열었다. 각 폭의 문서 `scrollWidth`는 뷰포트 폭과 같고, 내비는 한 줄, 버튼은 최소 44px이었다.
|
||||
- 320px에서 200% 텍스트 확대 후 문서 폭은 320px, 서술형 h1은 80px으로 실제 확대됐다. 장식 표본은 `aria-hidden="true"`로 남았다.
|
||||
- `prefers-reduced-motion: reduce`에서 `scroll-behavior`는 `auto`였다. 키보드 Space로 제목 버튼을 선택하면 `aria-pressed`와 상태 문구가 마루 부리로 바뀌었다.
|
||||
- 세 range는 24px·0.05em·2.2를 표본과 캡션에 적용했고, 리셋은 17px·0em·1.8을 둘 다 복원했다.
|
||||
- 지연 이미지 두 장은 scrollIntoView 뒤 `decode()`를 통과했고, `metaltype.webp` 응답은 HTTP 200·naturalWidth 900이었다. `font-foundry-1440-first.png`, `font-foundry-390-first.png`, 전체 캡처와 JSON 보고서는 같은 outputs 폴더에 있다.
|
||||
## 하지 않기로 한 것
|
||||
|
||||
## Round 4 판단표 · 2026-09-12
|
||||
- 사진 2장(`metaltype.webp`·`inkstone.webp`)을 화면에서 뺐다 — 같은 생성 이미지를 두 번 싣던 자리였고 배정이 "글자가 이미지"다. 파일은 디스크에 남긴다.
|
||||
- 상단 바·앵커 내비·sticky·backdrop-filter를 두지 않았다 — 한 장짜리 4화면 길이, 내비는 서체 탭 하나로 충분하다.
|
||||
- 마루 부리·Pretendard를 UI 서체로 쓰지 않았다(6-6 하우스 룩). 표본으로만 남긴다.
|
||||
- 가운뎃점 메타 문자열(`A · B`)을 가시 텍스트에서 없앴다. 시험대 캡션은 쉼표.
|
||||
- 스크롤 리빌 없음. 눈썹 라벨 없음.
|
||||
|
||||
| 축 | 참고 범위와 현재 질문 | 채택과 기각 조건 | 구현 |
|
||||
| --- | --- | --- | --- |
|
||||
| 구도 | Arnheim·Hofmann의 균형·대비·구도 관점을 참고해 소개와 표본의 관계, 5:7 대안, 작은 폭에서의 순서 유지를 살핀다. | 소개와 표본의 관계가 읽히고 작은 폭에서 순서가 유지되면 채택한다. CTA가 밀리면 기각한다. | `--container-wide`, `--pad-wide` |
|
||||
| 타입 | Ruder의 구조·리듬·비례와 Wallace의 개인·성능·선호 분리 범위를 참고해 같은 문장·22px·1.8·동일 폭 두 칼럼과 가족 선택을 살핀다. | 조절과 reset이 깨지지 않을 때만 채택한다. 읽기 성능의 보편 효과는 주장하지 않는다. | `--font-display`, `--font-body` |
|
||||
| 색 | Albers의 색 맥락 관점을 참고해 작은 accent와 큰 stage의 관계를 비교한다. | 역할 경계와 대비가 유지되고 상태가 묻히지 않을 때 채택한다. | `--stage-ink`, `--accent` |
|
||||
## 검증
|
||||
|
||||
## Round 4 실증 기록 · 2026-09-12
|
||||
- 자동(2026-10-06, apps/site): html-validate 0오류 · stylelint 통과 · no-hanja PASS · showcase-audit PASS 6/FAIL 0 · design-gate 충족 13/미검증 0/실패 0(static·visual·webkit 꺼짐) · 상호작용 스크립트 34/34(탭 키보드 패턴, 슬라이더·지연 로드, 기존 E2E 3단언, 200%+1.4.12 간격 재정의 가로 넘침 0, 감소 모션, 이펙트·JS 끔, 표제 마지막 줄 어절 ≥2) · 기존 `archive-showcases-e2e.mjs` font-foundry 14/14.
|
||||
- 시각 루브릭(약한 축부터): R7 1(h1이 범용) · R9 1(390 글자 입력이 한 줄 독점) · R1 2 · R2 2 · R3 2 · R4 2 · R5 2 · R8 2 · R10 2 · R6 N/A — 16/18, 통과. 근거와 캡처 경로는 작업 노트.
|
||||
- 대비: 본문 15.96:1, 보조 6.21:1(띠 위 5.62:1), 남색 면 위 글자 12.88:1.
|
||||
- 미검증: WebKit 실렌더(게이트 webkit=false), 실기기 INP, Firefox 폴백은 코드 가드만 확인.
|
||||
|
||||
- **방향과 원리**: 한성활자연구소의 종이색·적갈색·금속 활자 이미지는 유지하고, 첫 화면을 5:7 종이 소개면과 적갈색 표본면으로 재배치했다. 표본면의 큰 흰 글자, 기준선, 선택 상태는 같은 시선 안에서 글꼴 전환을 읽게 한다.
|
||||
- **비교 조건**: Ruder의 구조·리듬·비례를 현재 화면의 검증 질문으로만 번역했다. 비교 두 칼럼은 같은 원문, 동일 폭, 기본 22px(`1.375rem`)와 `1.8` 행간을 공유하며 글꼴 가족만 다르다. 서체마다 글자가 보이는 크기는 다를 수 있다는 안내를 함께 둔다.
|
||||
- **채택과 측정 한계**: 조판 시험대는 실제 웹폰트 선택을 문장에 적용하고 네 제어값을 리셋한다. 화면 비교는 형태·폭·줄바꿈의 관찰을 돕지만, 읽기 속도·이해도 향상은 사용자 과업 측정 전까지 주장하지 않는다. 역사처럼 보일 수 있는 견본 문단은 견본글임을 명시했다.
|
||||
- **동일 브리프 보존**: 가상 기획·예시 가격·라이선스 안내, 네 개의 내비와 앵커, 기존 CTA, 금속 이미지와 생성 이미지 표기, 버튼의 `aria-pressed`·상태 문구, 기존 조판 range와 reset 기능을 보존한다.
|
||||
## 피드백 기록 · 보존 목록
|
||||
|
||||
### Round 4 최종 판정
|
||||
- 보존: 같은 문장 22px/1.8 동일 폭 비교, 시험대 네 컨트롤과 리셋, 가상 고지 위치(가격 섹션 + 푸터).
|
||||
|
||||
2026-09-12 원본 담당자 판정: 수용. 소개와 표본의 면 구분, 표본과 제어의 군집, 같은 조건의 문장 비교를 실제 데스크톱·모바일 캡처에서 확인했다. 작은 폭의 확대에서 발견한 내비·가격·제목의 넘침과 앵커 가림을 수정했다.
|
||||
## 변경 기록
|
||||
|
||||
`outputs/design-expertise-20260912/round4/browser-proof/root-final-v3/feature-check-results.json`: 수정본 320·390·1440·1920px 4개 행 통과, 실패 0. 글꼴 실제 로딩, 키보드 선택·range·초기화, 앵커, 감소 모션, 이미지 decode, 문서 가로 넘침을 검사했다. 확대 검사는 루트 글자 크기 200% 및 자간 0.12em·행간 2의 조합이며, 브라우저 확대나 WCAG 전체 적합성 인증을 대신하지 않는다. 표본면의 설명·상태·선택/비선택 버튼 텍스트 대비는 6.07:1이었다. 사용자 읽기 속도·이해도·전환은 미측정이다.
|
||||
|
||||
## 2026-09-12 전체 쇼케이스 점검
|
||||
|
||||
- 기존 글꼴 선택·range·reset, 22px·1.8·동일 폭 비교 계약과 캡션·앵커 구도를 유지했다. 로컬 MaruBuri 경로는 `fonts.css?v=20260912all`로 명시했다.
|
||||
- `verify-final` 18개 묶음은 16개가 즉시 통과했다. 전체 묶음의 invariant·visual 검사는 Gaon·Dure를 대상으로 하며, 나머지 2개는 수정 뒤 release 독립 재실행에서 ALL PASS·ALL MATCH였다.
|
||||
- root는 28개 모바일, 21개 데스크톱, 7개 하위 경로와 30개 앱 상태를 직접 검토해 수용했다. stress 112건은 hard failure 0이며, 가로 넘침 4건은 targeted fix 뒤 390px 재측정에서 0이다.
|
||||
- 이 기록은 렌더·계약 범위의 현재 결과다. 모든 폭·키보드 경로·인쇄 등 개별 기능을 완전 재실행했다는 뜻이 아니며, 참여자 과업 효과도 미측정이다.
|
||||
- 2026-09-12 Round 4: 5:7 종이 소개면 + 적갈색 표본면, 마루 부리·Pretendard 비교 계약, 320·200% 확대 검사(옛 기록).
|
||||
- 2026-10-02 레드팀 06: 헤더 정렬·가격 "예시" 표기 정리.
|
||||
- 2026-10-06 재작업: 타이포 단독 히어로(거대 글리프 + 굵기 축), 서체 탭 내비, 큰 워드마크 푸터, Noto Serif KR 900/Noto Sans KR, #f1f2f4·#22235a·radius 0, View Transitions·scroll-driven, 사진 제거, og.png 추가. 이유: 19종 구성 수렴 해소(plan.md 배정).
|
||||
|
|
|
|||
|
|
@ -3,169 +3,232 @@
|
|||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>한성활자연구소 · 읽는 리듬을 만드는 활자</title>
|
||||
<meta name="description" content="문장으로 확인하는 한글 조판. 마루 부리와 Pretendard의 역할을 비교하고 글자 크기·자간·행간을 직접 조절해 보세요." />
|
||||
<meta property="og:title" content="한성활자연구소 · 읽는 리듬을 만드는 활자" />
|
||||
<meta property="og:description" content="문장으로 확인하는 한글 조판과 즉시 체험 시험대." />
|
||||
<title>한성활자연구소 — 한글 본문 서체 시험대</title>
|
||||
<meta name="description" content="마루 부리와 Pretendard 두 한글 본문 서체를 글자 하나의 굵기 축에서 비교하고, 같은 문장을 글자 크기·자간·행간을 바꿔 가며 조판해 보는 가상 서체 연구소." />
|
||||
<meta property="og:title" content="한성활자연구소 — 한글 본문 서체 시험대" />
|
||||
<meta property="og:description" content="마루 부리와 Pretendard를 글자 하나의 굵기 축에서 비교하고, 같은 문장을 크기·자간·행간을 바꿔 조판해 봅니다." />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta name="theme-color" content="#F5F1E8" />
|
||||
<meta property="og:image" content="./og.png" />
|
||||
<meta name="twitter:card" content="summary_large_image" />
|
||||
<meta name="theme-color" content="#f1f2f4" />
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link rel="preconnect" href="https://cdn.jsdelivr.net" crossorigin />
|
||||
<link rel="stylesheet" href="./styles/fonts.css?v=20260912all" />
|
||||
<link rel="preload" href="./assets/fonts/MaruBuri-Regular.woff2" as="font" type="font/woff2" crossorigin />
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Noto+Sans+KR&family=Noto+Serif+KR:wght@900&display=swap" />
|
||||
<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=20260912all" />
|
||||
<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" />
|
||||
<link rel="stylesheet" href="./styles/fonts.css?v=20261006" />
|
||||
<link rel="stylesheet" href="./styles/main.css?v=20261006" />
|
||||
<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='%23f1f2f4'/%3E%3Crect x='7' y='7' width='18' height='18' fill='%2322235a'/%3E%3C/svg%3E" />
|
||||
</head>
|
||||
<body>
|
||||
<body data-face="buri">
|
||||
<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 class="face-nav" aria-label="서체 보기">
|
||||
<div class="tabs" role="tablist" aria-label="보는 서체">
|
||||
<button type="button" class="tab" role="tab" id="tab-buri" data-face="buri" aria-selected="true" aria-controls="face-panel" tabindex="0">마루 부리</button>
|
||||
<button type="button" class="tab" role="tab" id="tab-godic" data-face="godic" aria-selected="false" aria-controls="face-panel" tabindex="-1">Pretendard</button>
|
||||
</div>
|
||||
</nav>
|
||||
</div>
|
||||
</header>
|
||||
<main id="main">
|
||||
<section class="hero" aria-labelledby="hero-h">
|
||||
<div class="hero-rail">
|
||||
<div class="hero-intro">
|
||||
<div>
|
||||
<p class="eyebrow">한글 타입 스튜디오</p>
|
||||
<h1 id="hero-h">읽는 리듬을<br />만드는 활자.</h1>
|
||||
</div>
|
||||
<div class="hero-note">
|
||||
<p>글자는 모양만으로 읽히지 않습니다. 문장 안에서 어떤 폭으로 서고, 얼마나 가까이 호흡하는지 직접 관찰해 보세요.</p>
|
||||
<a class="text-link" href="#bench">조판해 보기 <span aria-hidden="true">↓</span></a>
|
||||
</div>
|
||||
<div class="wrap hero-grid">
|
||||
<div class="hero-title">
|
||||
<h1 id="hero-h">서체 시험대</h1>
|
||||
<p class="hero-lead">한글 본문 서체 두 종을 글자 하나의 굵기 축에서 보고, 같은 문장을 크기·자간·행간을 바꿔 가며 조판합니다.</p>
|
||||
</div>
|
||||
<div class="specimen-stage" data-kind="body">
|
||||
<p class="stage-label">가상 서체 기획 · 화면은 마루 부리와 Pretendard로 구현</p>
|
||||
<p class="hero-specimen" aria-hidden="true">글의 결</p>
|
||||
<div class="baseline" aria-hidden="true"></div>
|
||||
<div class="stage-footer">
|
||||
<div class="type-switch" role="group" aria-label="표본 글꼴 선택">
|
||||
<button type="button" class="type-choice" data-kind="body" aria-pressed="true">본문</button>
|
||||
<button type="button" class="type-choice" data-kind="title" aria-pressed="false">제목</button>
|
||||
<div class="stage" id="face-panel" role="tabpanel" aria-labelledby="tab-buri">
|
||||
<p class="glyph" id="glyph" aria-hidden="true">활</p>
|
||||
<div class="axis">
|
||||
<div class="control">
|
||||
<div class="control-head"><label for="ctl-weight">굵기</label><output id="out-weight" for="ctl-weight">400</output></div>
|
||||
<input type="range" id="ctl-weight" name="weight" min="400" max="600" step="200" value="400" />
|
||||
</div>
|
||||
<p id="type-status" class="type-status" aria-live="polite">본문 표본 · Pretendard · 또렷한 문장 폭</p>
|
||||
<div class="control control-glyph">
|
||||
<label for="ctl-glyph">글자</label>
|
||||
<input type="text" id="ctl-glyph" name="glyph" value="활" maxlength="1" autocomplete="off" spellcheck="false" />
|
||||
</div>
|
||||
<p id="type-status" class="type-status" aria-live="polite">마루 부리 400. 네이버가 배포한 부리 서체이며 정적 굵기 가운데 Regular와 SemiBold 두 종을 실었습니다.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="typefaces" class="section" aria-labelledby="typefaces-h">
|
||||
<div class="wrap">
|
||||
<div class="section-head">
|
||||
<p class="eyebrow">두 가지 읽기 방식</p>
|
||||
<h2 id="typefaces-h">같은 문장, 서로 다른 결.</h2>
|
||||
<h2 id="typefaces-h">같은 문장을 22px, 행간 1.8, 같은 폭으로 두 서체에 조판했습니다.</h2>
|
||||
<p class="section-note">서체마다 글자가 보이는 크기는 다를 수 있습니다. 줄 길이와 줄바꿈 자리를 비교해 보세요.</p>
|
||||
</div>
|
||||
<p class="comparison-note">크기·행간·폭을 맞췄습니다. 서체마다 글자가 보이는 크기는 다를 수 있습니다.</p>
|
||||
<div class="comparison">
|
||||
<article class="typeface">
|
||||
<article class="typeface" data-face="buri">
|
||||
<header class="typeface-head">
|
||||
<h3>마루 부리</h3>
|
||||
<p class="muted">부리 계열. 네이버 배포, SIL 오픈 폰트 라이선스. 이 화면에는 정적 굵기 400·600 두 종을 실었습니다.</p>
|
||||
</header>
|
||||
<p class="specimen specimen-buri">아침 안개가 걷히기 전에 도랑물 소리가 먼저 들렸다. 마을 어귀 느티나무 아래에서는 할머니 두 분이 멍석에 고추를 널고 있었다.</p>
|
||||
</article>
|
||||
<article class="typeface" data-face="godic">
|
||||
<header class="typeface-head">
|
||||
<h3>Pretendard</h3>
|
||||
<p class="muted">본문용 산세리프</p>
|
||||
<p class="muted">민부리 계열. 가변 서체라 굵기 축을 45부터 920까지 연속으로 바꿀 수 있습니다. SIL 오픈 폰트 라이선스.</p>
|
||||
</header>
|
||||
<p class="specimen specimen-body">아침 안개가 걷히기 전에 도랑물 소리가 먼저 들렸다. 글자는 종이 위에서 소리를 내지 않지만, 잘 짜인 활자는 소리 내어 읽게 만든다.</p>
|
||||
</article>
|
||||
<article class="typeface typeface-title">
|
||||
<header class="typeface-head">
|
||||
<h3>MaruBuri</h3>
|
||||
<p class="muted">명조 계열 세리프</p>
|
||||
</header>
|
||||
<p class="specimen specimen-display">아침 안개가 걷히기 전에 도랑물 소리가 먼저 들렸다. 글자는 종이 위에서 소리를 내지 않지만, 잘 짜인 활자는 소리 내어 읽게 만든다.</p>
|
||||
<p class="specimen specimen-godic">아침 안개가 걷히기 전에 도랑물 소리가 먼저 들렸다. 마을 어귀 느티나무 아래에서는 할머니 두 분이 멍석에 고추를 널고 있었다.</p>
|
||||
</article>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="bench" class="section band" aria-labelledby="bench-h">
|
||||
<div class="wrap">
|
||||
<div class="bench-heading">
|
||||
<div>
|
||||
<p class="eyebrow">조판 시험대</p>
|
||||
<h2 id="bench-h">읽는 호흡을<br />직접 맞춰 보세요.</h2>
|
||||
</div>
|
||||
<p class="muted bench-lead">크기·자간·행간을 바꾸며 문장 폭, 줄바꿈, 글자 형태의 차이가 어떻게 보이는지 비교해 보세요.</p>
|
||||
<div class="section-head">
|
||||
<h2 id="bench-h">글자 크기 13~26px, 자간, 행간 1.4~2.4를 바꾸면 줄바꿈이 바로 달라집니다.</h2>
|
||||
<p class="section-note">웹 본문은 보통 16~18px, 한글 행간은 1.6~1.8배에서 시작합니다. 기본값으로 되돌리면 17px, 자간 0em, 행간 1.8로 돌아갑니다.</p>
|
||||
</div>
|
||||
<div class="bench">
|
||||
<form class="bench-controls" aria-label="조판 설정">
|
||||
<div class="control"><label for="ctl-font">글꼴</label><select id="ctl-font" name="font"><option value="display">마루부리</option><option value="body">Pretendard</option></select></div>
|
||||
<div class="control"><label for="ctl-font">글꼴</label><select id="ctl-font" name="font"><option value="display">마루 부리</option><option value="body">Pretendard</option></select></div>
|
||||
<div class="control"><div class="control-head"><label for="ctl-size">글자 크기</label><output id="out-size" for="ctl-size">17px</output></div><input type="range" id="ctl-size" name="size" min="13" max="26" step="1" value="17" /></div>
|
||||
<div class="control"><div class="control-head"><label for="ctl-tracking">자간</label><output id="out-tracking" for="ctl-tracking">0em</output></div><input type="range" id="ctl-tracking" name="tracking" min="-5" max="10" step="1" value="0" /></div>
|
||||
<div class="control"><div class="control-head"><label for="ctl-leading">행간</label><output id="out-leading" for="ctl-leading">1.8</output></div><input type="range" id="ctl-leading" name="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-reading">
|
||||
<p id="bench-caption" class="bench-caption">마루 부리 · 17px · 자간 0em · 행간 1.8</p>
|
||||
<p class="bench-disclaimer">아래 문단은 역사 사실을 설명하는 글이 아닌 조판 견본글입니다.</p>
|
||||
<div class="bench-sample" id="bench-sample" aria-live="polite">활자의 역사는 글자를 찍는 기계의 역사가 아니라, 글자를 읽는 눈의 역사였다. 활자소의 식자공들은 하루에 만 글자를 짜면서 어느 글꼴이 눈을 덜 아프게 하는지 알고 있었다. 그 지식은 문서로 남지 않았고 손끝으로만 전해졌다. 이 미리보기는 그 판단을 눈으로 비교할 수 있게 옮긴 것입니다. 자간을 0에서 5로 바꾸면 문단의 호흡과 줄 길이가 어떻게 달라지는지 확인할 수 있습니다.</div>
|
||||
<p id="bench-caption" class="bench-caption">마루 부리, 17px, 자간 0em, 행간 1.8</p>
|
||||
<p class="bench-disclaimer">아래 문단은 조판 견본글입니다.</p>
|
||||
<div class="bench-sample" id="bench-sample" aria-live="polite">웹 본문 글자는 보통 16~18px로 정하고, 한글 행간은 글자 크기의 1.6~1.8배 정도로 잡습니다. 자간은 0을 기준으로 큰 제목에서는 조금 좁히고, 작은 글자에서는 조금 넓히기도 합니다. 같은 문단이라도 서체에 따라 한 줄에 들어가는 글자 수가 달라집니다. 자간을 0em에서 0.05em으로 바꾸면 줄 길이와 줄바꿈 위치가 어떻게 달라지는지 확인해 보세요.</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<section id="case" class="section" aria-labelledby="case-h">
|
||||
<div class="wrap case-grid">
|
||||
<figure class="case-photo">
|
||||
<img src="./assets/metaltype.webp" alt="나무 활자 케이스에 골라 담긴 금속 활자들 — 활자면이 위에서 빛을 받아 결이 보인다" width="900" height="1200" loading="lazy" />
|
||||
<figcaption>생성 이미지 · 금속 활자 케이스의 관찰 장면</figcaption>
|
||||
</figure>
|
||||
<div class="case-text">
|
||||
<p class="eyebrow">활자 케이스</p>
|
||||
<h2 id="case-h">금속에서 시작해<br />화면에서 읽힌다.</h2>
|
||||
<p>이 가상 기획은 금속 활자의 옆면 여백을 관찰의 출발점으로 삼습니다. 납활자는 글자 바로 옆에 살이 붙어 있어, 찍히는 글자 사이가 일정했습니다. 이 화면에서는 그 일정함이 문장 안의 자간과 행간에 어떤 리듬을 만드는지 살펴봅니다.</p>
|
||||
<figure class="case-photo-b">
|
||||
<img src="./assets/metaltype.webp" alt="빛을 받은 금속 활자와 정렬된 활자 케이스" width="1100" height="825" loading="lazy" />
|
||||
<figcaption>생성 이미지 · 활자 폭과 여백을 보는 편집 장면</figcaption>
|
||||
</figure>
|
||||
|
||||
<section id="spacing" class="section" aria-labelledby="spacing-h">
|
||||
<div class="wrap spacing-grid">
|
||||
<div class="spacing-text">
|
||||
<h2 id="spacing-h">납활자 옆면의 여백이 화면에서는 자간 값이 됩니다.</h2>
|
||||
<p>납활자는 글자 몸통 양옆에 일정한 여백이 있어 찍힌 글자 사이 간격이 고르게 나왔습니다. 디지털 서체도 글자마다 옆면 여백을 갖고 있고, 자간은 그 여백에 더하거나 빼는 값입니다. 아래는 같은 네 글자를 자간 -0.05em과 0.1em으로 놓은 것입니다. 한글은 자간을 넓히면 낱글자로 흩어지기 쉬워 본문에서는 0 근처에서 시작합니다.</p>
|
||||
</div>
|
||||
<figure class="track-demo" aria-labelledby="track-caption">
|
||||
<p class="track-line track-tight" aria-hidden="true">활자연구</p>
|
||||
<p class="track-line track-loose" aria-hidden="true">활자연구</p>
|
||||
<figcaption id="track-caption">위는 자간 -0.05em, 아래는 0.1em. 보는 서체의 굵기 400으로 그렸습니다.</figcaption>
|
||||
</figure>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section id="order" class="section band" aria-labelledby="order-h">
|
||||
<div class="wrap order-grid">
|
||||
<div>
|
||||
<p class="eyebrow">가상 서체 기획</p>
|
||||
<h2 id="order-h">라이선스 안내</h2>
|
||||
<p class="muted">아래 라이선스 종류와 가격은 서체 판매 정보를 구성하는 방식을 보여 주는 예시입니다. 실제 주문·결제·문의로 이어지지 않습니다.</p>
|
||||
<div class="order-text">
|
||||
<h2 id="order-h">라이선스 가격은 웨이트 전종 기준의 예시입니다.</h2>
|
||||
<p class="muted">한성활자연구소는 가상 서체 기획입니다. 실제 주문·결제·문의로 이어지지 않으며, 화면의 서체는 네이버 마루 부리와 Pretendard로 구현했습니다.</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 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="#bench">조판해 보기</a>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
<footer class="site-foot"><div class="wrap foot-inner"><p>한성활자연구소 · 가상 서체 기획</p><p class="muted">화면의 글꼴은 마루 부리와 Pretendard로 구현했습니다.</p></div></footer>
|
||||
<footer class="site-foot">
|
||||
<div class="wrap">
|
||||
<p class="foot-mark" aria-hidden="true">한성활자연구소</p>
|
||||
<p class="foot-note">한성활자연구소는 가상 서체 기획 쇼케이스입니다. 서체와 가격은 예시이며, 화면의 글꼴은 마루 부리와 Pretendard(둘 다 SIL 오픈 폰트 라이선스)로 구현했습니다.</p>
|
||||
</div>
|
||||
</footer>
|
||||
<script>
|
||||
const specimenStage = document.querySelector(".specimen-stage");
|
||||
const choices = document.querySelectorAll(".type-choice");
|
||||
const faces = {
|
||||
buri: {
|
||||
name: "마루 부리",
|
||||
benchValue: "display",
|
||||
axis: { min: 400, max: 600, step: 200, value: 400 },
|
||||
note: "네이버가 배포한 부리 서체이며 정적 굵기 가운데 Regular와 SemiBold 두 종을 실었습니다.",
|
||||
},
|
||||
godic: {
|
||||
name: "Pretendard",
|
||||
benchValue: "body",
|
||||
axis: { min: 100, max: 900, step: 10, value: 400 },
|
||||
note: "가변 서체라 굵기 축을 100부터 900까지 10 단위로 움직입니다.",
|
||||
},
|
||||
};
|
||||
const panel = document.getElementById("face-panel");
|
||||
const glyph = document.getElementById("glyph");
|
||||
const tabs = [...document.querySelectorAll('[role="tab"]')];
|
||||
const weight = document.getElementById("ctl-weight");
|
||||
const outWeight = document.getElementById("out-weight");
|
||||
const glyphInput = document.getElementById("ctl-glyph");
|
||||
const typeStatus = document.getElementById("type-status");
|
||||
const typeMessages = { body: "본문 표본 · Pretendard · 또렷한 문장 폭", title: "제목 표본 · 마루 부리 · 여백이 보이는 획의 대비" };
|
||||
choices.forEach((choice) => choice.addEventListener("click", () => {
|
||||
const kind = choice.dataset.kind;
|
||||
specimenStage.dataset.kind = kind;
|
||||
choices.forEach((button) => button.setAttribute("aria-pressed", String(button === choice)));
|
||||
typeStatus.textContent = typeMessages[kind];
|
||||
}));
|
||||
const reducedMotion = matchMedia("(prefers-reduced-motion: reduce)");
|
||||
|
||||
function transition(update) {
|
||||
if (!document.startViewTransition || reducedMotion.matches) { update(); return; }
|
||||
document.startViewTransition(update);
|
||||
}
|
||||
function currentFace() { return document.body.dataset.face; }
|
||||
function describe() {
|
||||
const face = faces[currentFace()];
|
||||
typeStatus.textContent = `${face.name} ${weight.value}. ${face.note}`;
|
||||
outWeight.textContent = weight.value;
|
||||
}
|
||||
function applyWeight() {
|
||||
glyph.style.fontWeight = weight.value;
|
||||
describe();
|
||||
}
|
||||
function setFace(key, { syncBench = true } = {}) {
|
||||
const face = faces[key];
|
||||
document.body.dataset.face = key;
|
||||
tabs.forEach((tab) => {
|
||||
const on = tab.dataset.face === key;
|
||||
tab.setAttribute("aria-selected", String(on));
|
||||
tab.tabIndex = on ? 0 : -1;
|
||||
if (on) panel.setAttribute("aria-labelledby", tab.id);
|
||||
});
|
||||
weight.min = face.axis.min; weight.max = face.axis.max; weight.step = face.axis.step; weight.value = face.axis.value;
|
||||
applyWeight();
|
||||
if (syncBench) { ctl.font.value = face.benchValue; apply(); }
|
||||
}
|
||||
tabs.forEach((tab, index) => {
|
||||
tab.addEventListener("click", () => { if (tab.dataset.face !== currentFace()) transition(() => setFace(tab.dataset.face)); });
|
||||
tab.addEventListener("keydown", (event) => {
|
||||
const delta = event.key === "ArrowRight" ? 1 : event.key === "ArrowLeft" ? -1 : 0;
|
||||
let next = null;
|
||||
if (delta) next = (index + delta + tabs.length) % tabs.length;
|
||||
if (event.key === "Home") next = 0;
|
||||
if (event.key === "End") next = tabs.length - 1;
|
||||
if (next === null) return;
|
||||
event.preventDefault();
|
||||
tabs[next].focus();
|
||||
tabs[next].click();
|
||||
});
|
||||
});
|
||||
weight.addEventListener("input", applyWeight);
|
||||
glyphInput.addEventListener("input", () => {
|
||||
const chars = [...glyphInput.value.trim()];
|
||||
glyph.textContent = chars.length ? chars[0] : "활";
|
||||
});
|
||||
|
||||
const sample = document.getElementById("bench-sample");
|
||||
const ctl = { font: document.getElementById("ctl-font"), 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 = { font: "display", size: 17, tracking: 0, leading: 1.8 };
|
||||
const fontNames = { display: "마루 부리", body: "Pretendard" };
|
||||
function apply() {
|
||||
sample.style.fontFamily = ctl.font.value === "display" ? "var(--font-display)" : "var(--font-body)";
|
||||
sample.style.fontFamily = ctl.font.value === "display" ? "var(--face-buri)" : "var(--face-godic)";
|
||||
sample.style.fontSize = ctl.size.value + "px";
|
||||
sample.style.letterSpacing = ctl.tracking.value / 100 + "em";
|
||||
sample.style.lineHeight = ctl.leading.value;
|
||||
out.size.textContent = ctl.size.value + "px";
|
||||
out.tracking.textContent = ctl.tracking.value / 100 + "em";
|
||||
out.leading.textContent = Number(ctl.leading.value).toFixed(1);
|
||||
document.getElementById("bench-caption").textContent = `${fontNames[ctl.font.value]} · ${ctl.size.value}px · 자간 ${ctl.tracking.value / 100}em · 행간 ${Number(ctl.leading.value).toFixed(1)}`;
|
||||
document.getElementById("bench-caption").textContent = `${fontNames[ctl.font.value]}, ${ctl.size.value}px, 자간 ${ctl.tracking.value / 100}em, 행간 ${Number(ctl.leading.value).toFixed(1)}`;
|
||||
}
|
||||
Object.values(ctl).forEach((input) => { input.addEventListener("input", apply); input.addEventListener("change", apply); });
|
||||
document.getElementById("ctl-reset").addEventListener("click", () => { ctl.font.value = defaults.font; ctl.size.value = defaults.size; ctl.tracking.value = defaults.tracking; ctl.leading.value = defaults.leading; apply(); });
|
||||
setFace("buri", { syncBench: false });
|
||||
apply();
|
||||
</script>
|
||||
</body>
|
||||
|
|
|
|||
BIN
apps/site/public/work/font-foundry/og.png
Normal file
BIN
apps/site/public/work/font-foundry/og.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 51 KiB |
|
|
@ -1,3 +1,4 @@
|
|||
/* 마루 부리 — 표본 서체 전용(자체 호스팅, 네이버 공식 배포본 그대로, SOURCES.md). UI 서체는 tokens.css의 Noto Serif KR·Noto Sans KR이다. */
|
||||
@font-face {
|
||||
font-family: "MaruBuri";
|
||||
src: url("../assets/fonts/MaruBuri-Regular.woff2") format("woff2");
|
||||
|
|
|
|||
|
|
@ -1,125 +1,144 @@
|
|||
@import url("./tokens.css?v=20260912all");
|
||||
@import url("./tokens.css?v=20261006");
|
||||
|
||||
/* ── 기본 ── */
|
||||
*, *::before, *::after { box-sizing: border-box; }
|
||||
* { margin: 0; }
|
||||
html { background: var(--surface); scroll-behavior: smooth; -webkit-text-size-adjust: 100%; }
|
||||
body { background: var(--surface); color: var(--ink); font-family: var(--font-body); font-size: var(--step-0); line-height: var(--leading-normal); font-synthesis-weight: none; -webkit-font-smoothing: antialiased; }
|
||||
:where(h1, h2, h3) { font-family: var(--font-display); font-weight: 600; line-height: var(--leading-tight); text-wrap: balance; word-break: keep-all; overflow-wrap: break-word; }
|
||||
h2 { font-size: var(--step-3); }
|
||||
h3 { font-family: var(--font-body); font-size: var(--step-1); font-weight: 600; }
|
||||
:where(p, li, dd, dt, th, td, figcaption) { overflow-wrap: break-word; word-break: keep-all; text-wrap: pretty; }
|
||||
a { color: inherit; }
|
||||
body { background: var(--surface); color: var(--ink); font-family: var(--font-body); font-size: var(--step-0); line-height: var(--leading-normal); font-synthesis: none; -webkit-font-smoothing: antialiased; word-break: keep-all; overflow-wrap: anywhere; }
|
||||
:where(h1, h2) { font-family: var(--font-display); font-weight: var(--weight-display); line-height: var(--leading-tight); letter-spacing: -0.02em; text-wrap: balance; }
|
||||
h2 { font-size: var(--step-2); }
|
||||
h3 { font-family: var(--font-display); font-size: var(--step-1); font-weight: var(--weight-display); line-height: 1.35; letter-spacing: -0.01em; }
|
||||
:where(p, li, dd, dt, figcaption) { text-wrap: pretty; }
|
||||
a { color: inherit; text-underline-position: under; }
|
||||
.muted { color: var(--ink-muted); }
|
||||
.eyebrow, .stage-label, .bench-caption { color: var(--ink-muted); font-size: var(--step--1); letter-spacing: 0.04em; }
|
||||
:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
|
||||
.skip { position: absolute; z-index: 100; top: 0; left: -9999px; padding: var(--space-3) var(--space-4); background: var(--ink); color: var(--surface); }
|
||||
.skip { position: absolute; z-index: 100; top: 0; left: -9999px; padding: var(--space-3) var(--space-4); background: var(--accent); color: var(--accent-ink); }
|
||||
.skip:focus { left: 0; }
|
||||
.wrap { width: min(100% - 2 * var(--pad-inline), var(--container)); margin-inline: auto; }
|
||||
|
||||
.site-head { position: sticky; z-index: 10; top: 0; border-bottom: 1px solid var(--line); background: color-mix(in srgb, var(--surface) 94%, transparent); backdrop-filter: blur(6px); }
|
||||
.head-inner { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-4); min-block-size: 4.25rem; }
|
||||
.wordmark { font-family: var(--font-display); font-size: var(--step-1); font-weight: 600; text-decoration: none; }
|
||||
.nav { display: flex; flex-wrap: wrap; gap: clamp(var(--space-3), 2vw, var(--space-5)); font-size: var(--step--1); }
|
||||
.nav a { padding-block: var(--space-2); color: var(--ink-muted); text-decoration: none; }
|
||||
.nav a:hover { color: var(--accent); }
|
||||
/* ── 머리: 워드마크 + 서체 탭(내비는 탭 하나뿐) ── */
|
||||
.site-head { border-bottom: 1px solid var(--line); }
|
||||
.head-inner { display: flex; align-items: center; justify-content: space-between; gap: var(--space-4); min-block-size: var(--head-height); }
|
||||
.wordmark { font-family: var(--font-display); font-size: var(--step-1); font-weight: var(--weight-display); text-decoration: none; white-space: nowrap; }
|
||||
.tabs { display: flex; }
|
||||
.tab { min-block-size: 2.75rem; white-space: nowrap; padding-inline: var(--space-4); border: 1px solid var(--line-strong); border-inline-start-width: 0; border-radius: var(--radius); background: transparent; color: var(--ink); cursor: pointer; font: inherit; }
|
||||
.tab:first-child { border-inline-start-width: 1px; }
|
||||
.tab:hover { background: var(--accent-soft); }
|
||||
.tab[aria-selected="true"] { border-color: var(--accent); background: var(--accent); color: var(--accent-ink); }
|
||||
.tab[aria-selected="true"] + .tab { border-inline-start-color: var(--accent); }
|
||||
|
||||
.hero { padding-block: clamp(var(--space-5), 5vw, var(--space-7)) var(--space-7); }
|
||||
.hero-rail { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: clamp(var(--space-5), 5vw, var(--space-8)); width: min(100% - 2 * var(--pad-wide), var(--container-wide)); margin-inline: auto; align-items: stretch; }
|
||||
.hero-rail > *, .hero-intro > * { min-inline-size: 0; }
|
||||
.hero-intro { display: flex; flex-direction: column; justify-content: space-between; gap: var(--space-6); min-block-size: clamp(32rem, 52vw, 44rem); padding: clamp(var(--space-5), 4vw, var(--space-7)); border: 1px solid var(--line); background: var(--surface-raised); }
|
||||
.hero h1 { margin-top: var(--space-3); font-size: clamp(2.5rem, 1.6rem + 3vw, 3.75rem); max-inline-size: 10ch; }
|
||||
.hero-note { max-inline-size: 29rem; }
|
||||
.text-link { display: inline-flex; gap: var(--space-2); margin-top: var(--space-4); color: var(--accent); font-weight: 600; text-decoration-thickness: 1px; text-underline-offset: 0.25em; }
|
||||
.specimen-stage { display: flex; flex-direction: column; justify-content: space-between; min-inline-size: 0; min-block-size: clamp(32rem, 52vw, 44rem); padding: clamp(var(--space-5), 4vw, var(--space-7)); background: var(--accent); color: var(--stage-ink); }
|
||||
.stage-label { color: var(--stage-ink); }
|
||||
.hero-specimen { min-inline-size: 0; margin-block: var(--space-5); font-family: var(--font-body); font-size: clamp(6rem, 11vw, 11.25rem); font-weight: 650; letter-spacing: -0.09em; line-height: 0.82; overflow-wrap: anywhere; white-space: normal; }
|
||||
.specimen-stage[data-kind="title"] .hero-specimen { font-family: var(--font-display); font-weight: 600; letter-spacing: -0.11em; }
|
||||
.baseline { block-size: 1px; margin-top: var(--space-3); background: color-mix(in srgb, var(--stage-ink) 75%, transparent); }
|
||||
.stage-footer { display: flex; align-items: center; justify-content: space-between; gap: var(--space-4); padding-top: var(--space-3); }
|
||||
.type-switch { display: flex; flex-wrap: wrap; gap: var(--space-2); }
|
||||
.type-choice, .btn-reset { min-block-size: 2.75rem; border: 1px solid var(--line); border-radius: var(--radius); background: transparent; color: var(--ink); cursor: pointer; font: inherit; padding-inline: 0.9rem; }
|
||||
.type-choice { border-color: color-mix(in srgb, var(--stage-ink) 72%, transparent); color: var(--stage-ink); }
|
||||
.type-choice[aria-pressed="true"] { border-color: var(--stage-ink); background: var(--stage-ink); color: var(--accent); }
|
||||
.type-choice:focus-visible { outline-color: var(--stage-ink); }
|
||||
.type-status { color: var(--stage-ink); font-size: var(--step--1); text-align: end; }
|
||||
|
||||
.section { padding-block: var(--space-8); }
|
||||
.section[id] { scroll-margin-block-start: 5rem; }
|
||||
.band { border-block: 1px solid var(--line); background: var(--surface-raised); }
|
||||
.section-head { display: grid; grid-template-columns: minmax(0, 4fr) minmax(0, 8fr); gap: var(--space-5); align-items: baseline; }
|
||||
.comparison-note { max-inline-size: 42rem; margin-top: var(--space-5); color: var(--ink-muted); }
|
||||
.comparison { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-6); margin-top: var(--space-6); border-top: 1px solid var(--line); }
|
||||
.typeface { min-inline-size: 0; padding-block: var(--space-6); border-bottom: 1px solid var(--line); }
|
||||
.typeface-head .muted { margin-top: var(--space-2); font-size: var(--step--1); }
|
||||
.specimen { margin-top: var(--space-5); inline-size: 100%; font-size: 1.375rem; line-height: 1.8; }
|
||||
.specimen-body { font-family: var(--font-body); }
|
||||
.specimen-display { font-family: var(--font-display); }
|
||||
|
||||
.bench-heading { display: grid; grid-template-columns: minmax(0, 7fr) minmax(0, 4fr); gap: var(--space-6); align-items: end; }
|
||||
.bench-lead { max-inline-size: 28rem; }
|
||||
.bench { display: grid; grid-template-columns: minmax(13rem, 3fr) minmax(0, 7fr); gap: var(--space-6) var(--space-7); margin-top: var(--space-6); padding-top: var(--space-5); border-top: 1px solid var(--line); }
|
||||
.bench-controls { display: grid; align-content: start; gap: var(--space-4); }
|
||||
/* ── 첫 화면: 글자 하나가 이미지다 ── */
|
||||
.hero { padding-block: 0 var(--space-6); }
|
||||
.hero-grid { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); grid-template-rows: minmax(0, 1fr) auto; gap: var(--space-5) var(--space-6); min-block-size: calc(100svh - var(--head-height) - var(--space-5)); }
|
||||
.hero-grid > * { min-inline-size: 0; }
|
||||
.hero-title { grid-column: 1; grid-row: 2; align-self: end; }
|
||||
.hero h1 { font-size: var(--step-3); white-space: nowrap; }
|
||||
.hero-lead { max-inline-size: 28em; margin-top: var(--space-3); color: var(--ink-muted); }
|
||||
.stage { grid-column: 1 / -1; grid-row: 1 / 3; display: grid; grid-template-columns: subgrid; grid-template-rows: subgrid; }
|
||||
.glyph { grid-column: 1 / -1; grid-row: 1; justify-self: center; align-self: center; font-family: var(--face-buri); font-size: var(--glyph-size); font-weight: 400; line-height: 1; color: var(--accent); transform-origin: center bottom; view-transition-name: glyph; }
|
||||
[data-face="godic"] .glyph { font-family: var(--face-godic); }
|
||||
.axis { grid-column: 2; grid-row: 2; display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: var(--space-3) var(--space-5); align-items: end; align-self: end; }
|
||||
.type-status { grid-column: 1 / -1; color: var(--ink-muted); font-size: var(--step--1); max-inline-size: 40em; view-transition-name: face-status; }
|
||||
.control { display: grid; gap: var(--space-2); }
|
||||
.control-head { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-3); }
|
||||
.control label, .control output { color: var(--ink-muted); font-size: var(--step--1); }
|
||||
.control output, .order-price { font-variant-numeric: tabular-nums; }
|
||||
.control-glyph input { inline-size: 3.25rem; min-block-size: 2.75rem; border: 1px solid var(--line-strong); border-radius: var(--radius); background: var(--surface); color: var(--ink); font-family: inherit; font-size: var(--step-1); text-align: center; }
|
||||
input[type="range"], select { inline-size: 100%; accent-color: var(--accent); }
|
||||
select { min-block-size: 2.75rem; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); color: var(--ink); font: inherit; padding-inline: var(--space-3); }
|
||||
.btn-reset { justify-self: start; margin-top: var(--space-2); }
|
||||
.btn-reset:hover { border-color: var(--accent); }
|
||||
.type-choice:hover { border-color: var(--stage-ink); }
|
||||
.bench-caption { margin-bottom: var(--space-3); }
|
||||
.bench-disclaimer { margin-bottom: var(--space-3); color: var(--ink-muted); font-size: var(--step--1); }
|
||||
.bench-sample { max-inline-size: 42rem; border: 1px solid var(--line); background: var(--surface); padding: clamp(var(--space-4), 3vw, var(--space-6)); font-family: var(--font-display); font-size: 1.0625rem; line-height: 1.8; }
|
||||
input[type="range"] { min-block-size: 2.75rem; margin: 0; }
|
||||
select { min-block-size: 2.75rem; border: 1px solid var(--line-strong); border-radius: var(--radius); background: var(--surface); color: var(--ink); font: inherit; padding-inline: var(--space-3); }
|
||||
|
||||
.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, .case-text { min-inline-size: 0; }
|
||||
.case-photo img, .case-photo-b img { display: block; max-inline-size: 100%; inline-size: 100%; block-size: auto; border-radius: var(--radius); }
|
||||
.case-photo figcaption, .case-photo-b figcaption { margin-top: var(--space-2); color: var(--ink-faint); font-size: var(--step--1); }
|
||||
.case-text { max-inline-size: 42rem; }
|
||||
.case-text h2 { margin-top: var(--space-3); margin-bottom: var(--space-4); }
|
||||
.case-photo-b { max-inline-size: 34rem; margin-top: var(--space-5); }
|
||||
/* ── 섹션 공통 ── */
|
||||
.section { padding-block: var(--space-8); }
|
||||
.section[id] { scroll-margin-block-start: var(--space-4); }
|
||||
.band { border-block: 1px solid var(--line); background: var(--surface-raised); }
|
||||
.section-head { display: grid; grid-template-columns: minmax(0, 7fr) minmax(0, 4fr); gap: var(--space-4) var(--space-6); align-items: end; }
|
||||
.section-head h2 { max-inline-size: 22em; }
|
||||
.section-note { color: var(--ink-muted); max-inline-size: 28em; }
|
||||
|
||||
/* ── 비교: 같은 문장, 같은 폭 ── */
|
||||
.comparison { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-6); margin-top: var(--space-6); border-top: 1px solid var(--line); }
|
||||
.typeface { min-inline-size: 0; padding-block: var(--space-5) var(--space-6); border-top: 3px solid transparent; margin-top: -2px; }
|
||||
[data-face="buri"] .typeface[data-face="buri"], [data-face="godic"] .typeface[data-face="godic"] { border-top-color: var(--accent); }
|
||||
.typeface-head .muted { margin-top: var(--space-2); font-size: var(--step--1); max-inline-size: 30em; }
|
||||
.specimen { margin-top: var(--space-5); inline-size: 100%; font-size: 1.375rem; line-height: 1.8; }
|
||||
.specimen-buri { font-family: var(--face-buri); }
|
||||
.specimen-godic { font-family: var(--face-godic); }
|
||||
|
||||
/* ── 조판 시험대 ── */
|
||||
.bench { display: grid; grid-template-columns: minmax(13rem, 3fr) minmax(0, 7fr); gap: var(--space-6) var(--space-7); margin-top: var(--space-6); padding-top: var(--space-5); border-top: 1px solid var(--line); }
|
||||
.bench-controls { display: grid; align-content: start; gap: var(--space-4); }
|
||||
.btn-reset { justify-self: start; min-block-size: 2.75rem; margin-top: var(--space-2); padding-inline: 0.9rem; border: 1px solid var(--line-strong); border-radius: var(--radius); background: transparent; color: var(--ink); cursor: pointer; font: inherit; }
|
||||
.btn-reset:hover { border-color: var(--accent); color: var(--accent); }
|
||||
.bench-caption { margin-bottom: var(--space-2); color: var(--ink-muted); font-size: var(--step--1); }
|
||||
.bench-disclaimer { margin-bottom: var(--space-3); color: var(--ink-muted); font-size: var(--step--1); }
|
||||
.bench-sample { max-inline-size: 42rem; border: 1px solid var(--line); background: var(--surface); padding: clamp(var(--space-4), 3vw, var(--space-6)); font-family: var(--face-buri); font-size: 1.0625rem; line-height: 1.8; }
|
||||
|
||||
/* ── 옆면 여백과 자간: 글자가 그림이다 ── */
|
||||
.spacing-grid { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: var(--space-6) var(--space-7); align-items: center; }
|
||||
.spacing-grid > * { min-inline-size: 0; }
|
||||
.spacing-text p { margin-top: var(--space-4); max-inline-size: var(--measure); }
|
||||
.track-demo { border-block: 1px solid var(--line); padding-block: var(--space-4); overflow: hidden; }
|
||||
.track-line { font-family: var(--face-buri); font-size: clamp(2.5rem, 1rem + 6vw, 6rem); font-weight: 400; line-height: 1.2; color: var(--accent); white-space: nowrap; }
|
||||
[data-face="godic"] .track-line { font-family: var(--face-godic); }
|
||||
.track-tight { letter-spacing: -0.05em; }
|
||||
.track-loose { letter-spacing: 0.1em; }
|
||||
.track-demo figcaption { margin-top: var(--space-3); color: var(--ink-muted); font-size: var(--step--1); }
|
||||
|
||||
/* ── 라이선스(예시) ── */
|
||||
.order-grid { display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 6fr) auto; gap: var(--space-5) var(--space-7); align-items: center; }
|
||||
.order-grid > * { min-inline-size: 0; }
|
||||
.order-grid h2 { margin-top: var(--space-3); }
|
||||
.order-grid .muted { max-inline-size: 28rem; margin-top: var(--space-3); }
|
||||
.order-text .muted { max-inline-size: 28em; margin-top: var(--space-3); }
|
||||
.order-rows { border-top: 1px solid var(--line); }
|
||||
.order-row { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-4); padding-block: var(--space-3); border-bottom: 1px solid var(--line); }
|
||||
.order-row p { margin-top: var(--space-1); color: var(--ink-muted); font-size: var(--step--1); }
|
||||
.order-price { flex: 0 0 auto; color: var(--ink) !important; font-family: var(--font-display); font-size: var(--step-1) !important; white-space: nowrap; }
|
||||
.btn { display: inline-flex; align-items: center; justify-content: center; min-block-size: 2.75rem; border: 1px solid var(--accent); border-radius: var(--radius); background: var(--accent); color: var(--accent-ink); font-weight: 600; padding-inline: 1.25rem; text-decoration: none; }
|
||||
.order-price { flex: 0 0 auto; color: var(--ink); font-family: var(--font-display); font-weight: var(--weight-display); font-size: var(--step-1); white-space: nowrap; }
|
||||
.btn { display: inline-flex; align-items: center; justify-content: center; min-block-size: 2.75rem; border: 1px solid var(--accent); border-radius: var(--radius); background: var(--accent); color: var(--accent-ink); padding-inline: 1.25rem; text-decoration: none; }
|
||||
.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; flex-wrap: wrap; justify-content: space-between; gap: var(--space-3) var(--space-5); }
|
||||
|
||||
/* ── 푸터: 큰 워드마크 한 줄 ── */
|
||||
.site-foot { border-top: 1px solid var(--line); padding-block: var(--space-6) var(--space-5); overflow: hidden; }
|
||||
.foot-mark { font-family: var(--font-display); font-weight: var(--weight-display); font-size: var(--wordmark-size); line-height: 1; letter-spacing: -0.03em; color: var(--accent); white-space: nowrap; }
|
||||
.foot-note { margin-top: var(--space-4); color: var(--ink-muted); font-size: var(--step--1); max-inline-size: 44em; }
|
||||
|
||||
/* ── 모션: 탭 전환은 View Transitions, 표본 크기는 스크롤이 움직인다 ── */
|
||||
::view-transition-old(glyph), ::view-transition-old(face-status) { animation: calc(var(--dur-slow) * 0.65) var(--ease-in) both vt-out; }
|
||||
::view-transition-new(glyph), ::view-transition-new(face-status) { animation: var(--dur-slow) var(--ease-soft) both vt-in; }
|
||||
@keyframes vt-out { to { opacity: 0; translate: 0 -0.5rem; } }
|
||||
@keyframes vt-in { from { opacity: 0; translate: 0 0.5rem; } }
|
||||
@media (prefers-reduced-motion: no-preference) {
|
||||
@supports (animation-timeline: scroll()) {
|
||||
.glyph { animation: glyph-shrink 1ms linear both; animation-timeline: scroll(root block); animation-range: 0 80vh; }
|
||||
@keyframes glyph-shrink { to { scale: 0.55; } }
|
||||
}
|
||||
}
|
||||
|
||||
/* ── 반응형 ── */
|
||||
@media (max-width: 900px) {
|
||||
.hero-rail, .section-head, .comparison, .bench-heading, .bench, .case-grid, .order-grid { grid-template-columns: 1fr; }
|
||||
.hero-intro, .specimen-stage { min-block-size: 0; }
|
||||
.hero-intro, .bench-heading { gap: var(--space-4); }
|
||||
.hero-note { max-inline-size: 34rem; }
|
||||
.hero-grid { grid-template-columns: 1fr; grid-template-rows: minmax(0, 1fr) auto auto; gap: var(--space-4); }
|
||||
.hero-title { grid-row: 2; }
|
||||
.stage { grid-row: 1 / 4; }
|
||||
.glyph { grid-column: 1; }
|
||||
.axis { grid-column: 1; grid-row: 3; grid-template-columns: 1fr; }
|
||||
.control-glyph { grid-template-columns: auto 1fr; align-items: center; }
|
||||
.hero-lead { max-inline-size: 34em; }
|
||||
.section-head, .comparison, .bench, .spacing-grid, .order-grid { grid-template-columns: 1fr; }
|
||||
.bench { gap: var(--space-5); }
|
||||
.case-photo { max-inline-size: 30rem; }
|
||||
}
|
||||
@media (max-width: 560px) {
|
||||
.head-inner { display: grid; gap: 0; min-block-size: 0; padding-block: var(--space-3); }
|
||||
.nav { justify-content: space-between; gap: var(--space-2); max-inline-size: 100%; margin-top: var(--space-1); }
|
||||
.nav a { flex: 0 0 auto; padding-block: var(--space-1); }
|
||||
.hero { padding-block: var(--space-5); }
|
||||
.hero-rail { gap: var(--space-4); }
|
||||
.hero-intro, .specimen-stage { padding: var(--space-4); }
|
||||
.hero-intro :where(p, h1), .stage-label, .type-status { overflow-wrap: anywhere; }
|
||||
.hero h1 { font-size: clamp(2.5rem, 11vw, 4rem); overflow-wrap: anywhere; word-break: normal; }
|
||||
.hero-specimen { font-size: min(30vw, 9.5rem); letter-spacing: -0.12em; }
|
||||
.bench-heading > * { min-inline-size: 0; }
|
||||
.bench-heading h2 { overflow-wrap: anywhere; }
|
||||
.order-row > * { min-inline-size: 0; max-inline-size: 100%; }
|
||||
.order-price { white-space: normal; overflow-wrap: anywhere; }
|
||||
.stage-footer, .order-row { align-items: flex-start; flex-direction: column; }
|
||||
.type-status { text-align: start; }
|
||||
:root { --glyph-size: min(72vw, 42svh); --head-height: 7.5rem; }
|
||||
.head-inner { flex-wrap: wrap; gap: var(--space-2) var(--space-3); padding-block: var(--space-3); }
|
||||
.face-nav { flex: 1 0 100%; }
|
||||
.tabs { display: grid; grid-template-columns: 1fr 1fr; }
|
||||
.tab { padding-inline: var(--space-3); white-space: normal; }
|
||||
.hero { padding-block: 0 var(--space-5); }
|
||||
.hero-grid { min-block-size: calc(100svh - var(--head-height) - var(--space-4)); }
|
||||
.hero h1, .wordmark { white-space: normal; }
|
||||
.section { padding-block: var(--space-7); }
|
||||
.section[id] { scroll-margin-block-start: calc(7rem + 1rem); }
|
||||
.order-row { align-items: flex-start; flex-direction: column; }
|
||||
.order-price { white-space: normal; }
|
||||
}
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
html { scroll-behavior: auto; }
|
||||
*, *::before, *::after { transition-duration: 0.01ms !important; }
|
||||
::view-transition-group(*), ::view-transition-old(*), ::view-transition-new(*) { animation: none !important; }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,23 +1,39 @@
|
|||
/* 한성활자연구소 토큰 — 값은 여기서만 정의한다(05 Q-25). 다른 CSS는 var()로만 쓴다. */
|
||||
:root {
|
||||
/* 타입 스케일: 본문 17px, 보조 13px, 표제는 한 줄 큰 낱말 */
|
||||
--step--1: 0.8125rem;
|
||||
--step-0: 1.0625rem;
|
||||
--step-1: 1.25rem;
|
||||
--step-2: clamp(1.75rem, 1.3rem + 1.5vw, 2.5rem);
|
||||
--step-3: clamp(2.5rem, 1.6rem + 4vw, 5rem);
|
||||
--leading-tight: 1.08;
|
||||
--leading-normal: 1.8;
|
||||
--font-display: "MaruBuri", Georgia, serif;
|
||||
--font-body: "Pretendard Variable", Pretendard, -apple-system, BlinkMacSystemFont, sans-serif;
|
||||
--surface: #f5f1e8;
|
||||
--surface-raised: #ede7d9;
|
||||
--ink: #26221d;
|
||||
--ink-muted: #625b52;
|
||||
--ink-faint: #756c60;
|
||||
--line: #d9d1bf;
|
||||
--accent: #a63d2f;
|
||||
--accent-ink: #f5f1e8;
|
||||
--stage-ink: #fffaf1;
|
||||
--accent-hover: #8a3225;
|
||||
--step-2: clamp(1.5rem, 1.15rem + 1.3vw, 2.125rem);
|
||||
--step-3: clamp(2.75rem, 1.4rem + 4.5vw, 5.75rem);
|
||||
--glyph-size: min(56svh, 50vw);
|
||||
--wordmark-size: clamp(2.5rem, 12vw, 11rem);
|
||||
--leading-tight: 1.25;
|
||||
--leading-normal: 1.7;
|
||||
--measure: 36em;
|
||||
|
||||
/* UI 서체: 표제 Noto Serif KR 900 / 본문 Noto Sans KR. 표본 서체는 UI에 쓰지 않는다 */
|
||||
--font-display: "Noto Serif KR", "Apple SD Gothic Neo", "Malgun Gothic", serif;
|
||||
--font-body: "Noto Sans KR", "Apple SD Gothic Neo", "Malgun Gothic", sans-serif;
|
||||
--weight-display: 900;
|
||||
--weight-strong: 400; /* Noto Sans KR은 400 한 굵기만 싣는다(전송량). 강조는 색·서체로 낸다 */
|
||||
|
||||
/* 표본 서체: 마루 부리(자체 호스팅, 정적 400·600)와 Pretendard(가변 45~920). 표본·시험대에만 쓴다 */
|
||||
--face-buri: "MaruBuri", "Noto Serif KR", serif;
|
||||
--face-godic: "Pretendard Variable", Pretendard, "Noto Sans KR", sans-serif;
|
||||
|
||||
/* 색: 밝은 쿨 중립 바탕, 240° 남색 잉크 강조. 강조는 거대 글자·슬라이더·선택 상태에만 */
|
||||
--surface: #f1f2f4;
|
||||
--surface-raised: #e5e7eb;
|
||||
--ink: #16171d;
|
||||
--ink-muted: #565966;
|
||||
--line: #c3c6cf;
|
||||
--line-strong: #737786;
|
||||
--accent: #22235a;
|
||||
--accent-hover: #15163f;
|
||||
--accent-ink: #f1f2f4;
|
||||
--accent-soft: #d8daea;
|
||||
|
||||
--space-1: 0.25rem;
|
||||
--space-2: 0.5rem;
|
||||
--space-3: 1rem;
|
||||
|
|
@ -26,11 +42,14 @@
|
|||
--space-6: 4rem;
|
||||
--space-7: 6rem;
|
||||
--space-8: clamp(5rem, 3rem + 7vw, 10rem);
|
||||
--radius: 2px;
|
||||
--container: 76rem;
|
||||
--container-wide: 106.25rem;
|
||||
|
||||
--radius: 0;
|
||||
--container: 80rem;
|
||||
--pad-inline: clamp(1.25rem, 1rem + 2.5vw, 4.5rem);
|
||||
--pad-wide: clamp(1.25rem, 1vw + 1rem, 4rem);
|
||||
--head-height: 4.25rem;
|
||||
|
||||
--dur-quick: 160ms;
|
||||
--dur-slow: 320ms;
|
||||
--ease-soft: cubic-bezier(0.25, 1, 0.35, 1);
|
||||
--ease-in: cubic-bezier(0.5, 0, 0.9, 0.4);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue