049bc5e2cf
홈 확정안과 디자인 시스템을 아트보드로 정리한다. 후보 셋(HomeA/B/C)은 확정안 Main 으로 합치고 지운다. 디자인 시스템 페이지 - Logo: 워드마크를 글꼴 대신 획으로 그려 내보내기에서도 모양이 유지된다 - Brand: 탄피 오렌지 확정. 면 #FF6A00(흰 글자) / 글자 #C24A00 로 값이 갈린다 - Foundations: 홈에서 굳어진 글자 아홉 단계·색·컴포넌트·치수 - Blocks: 실패 · 비어 있음 블록 규격과 섹션별 문구 홈 페이지 - Main: 검색 히어로를 최상단으로, 그 아래 균등 3열 밀도 그리드 - Loading / States: 스켈레톤과 섹션별로 섞인 네 가지 상태 - Search: 헤더 돋보기 + 검색 시트 - Tablet(768) / Mobile(390): 기준점 두 개로 2열 · 1열 전환 랭크전 랭킹에 티어 이미지 자리를 추가한다. 티어와 RP 는 한 몸으로 읽혀야 해서 한 칸(72px)에 묶고 그 안에서만 4px 로 붙였다. 계급·티어·클랜 표장을 막대/육각/방패로 갈라 한 줄에 놓여도 구분된다. Pretendard 는 아트보드가 실제로 쓰는 글자만 서브셋(fonts/mini)해 아트보드마다 복사되는 용량을 줄인다. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DNo7LSAWohdk6vpEhmtqLY
47 lines
2.1 KiB
JavaScript
47 lines
2.1 KiB
JavaScript
// 아트보드가 실제로 쓰는 글자만 남긴 Pretendard 서브셋을 만든다.
|
|
// 아트보드마다 폰트가 통째로 들어가므로(각 아트보드는 독립 문서), 글자 수를 줄이는 것이 곧 캔버스 용량이다.
|
|
import { readFileSync, writeFileSync, readdirSync, mkdirSync } from 'node:fs';
|
|
import { join } from 'node:path';
|
|
import subsetFont from 'subset-font';
|
|
import { decompress } from 'wawoff2';
|
|
|
|
const DIR = process.argv[2]; // .design/surinz
|
|
const TPL = join(DIR, 'templates');
|
|
const SRC = join(DIR, 'fonts');
|
|
const OUT = join(DIR, 'fonts', 'mini');
|
|
|
|
// 1) 아트보드 텍스트에서 쓰이는 글자를 모은다 (style 블록과 태그는 제외)
|
|
const used = new Set();
|
|
for (const name of readdirSync(TPL).filter((n) => n.endsWith('.dc.html'))) {
|
|
const src = readFileSync(join(TPL, name), 'utf8')
|
|
.replace(/<style[\s\S]*?<\/style>/g, '')
|
|
.replace(/<[^>]+>/g, ' ');
|
|
for (const c of src) used.add(c);
|
|
}
|
|
|
|
// 2) 안전 여유 — 아스키 인쇄 가능 문자와 자주 쓰는 기호는 항상 포함
|
|
for (let i = 0x20; i <= 0x7e; i += 1) used.add(String.fromCharCode(i));
|
|
for (const c of '·…—–‘’“”「」『』〈〉《》±×÷≤≥→←↑↓★☆※℃%㎏㎜㎝가나다라마바사아자차카타파하') used.add(c);
|
|
|
|
const text = [...used].filter((c) => c.charCodeAt(0) > 0x1f).join('');
|
|
console.log(`서브셋 글자 수 ${text.length}`);
|
|
|
|
mkdirSync(OUT, { recursive: true });
|
|
writeFileSync(join(OUT, 'charset.txt'), text, 'utf8');
|
|
|
|
const WEIGHTS = ['Regular', 'SemiBold', 'Bold'];
|
|
let before = 0;
|
|
let after = 0;
|
|
|
|
for (const w of WEIGHTS) {
|
|
const woff2 = readFileSync(join(SRC, `Pretendard-${w}.subset.woff2`));
|
|
before += woff2.length;
|
|
const ttf = Buffer.from(await decompress(woff2));
|
|
const out = await subsetFont(ttf, text, { targetFormat: 'woff2' });
|
|
after += out.length;
|
|
writeFileSync(join(OUT, `Pretendard-${w}.mini.woff2`), out);
|
|
console.log(`${w.padEnd(9)} ${(woff2.length / 1024).toFixed(0).padStart(4)} KB → ${(out.length / 1024).toFixed(0).padStart(3)} KB`);
|
|
}
|
|
|
|
console.log(`합계 ${(before / 1024).toFixed(0)} KB → ${(after / 1024).toFixed(0)} KB (아트보드 1개당)`);
|