/* ============================================================================= * ui_template_public_layout.ts * 공개 화면 틀 `public-frame`(552-4 틀) — 로그인 전 공개 페이지(A01 ~ A09) 몸통: 머리 띠(hero) · 구역 · 본문. * 꼴 = 머리 띠(제목 · 설명 · 주 단추 줄 · 가운데 / 왼쪽 맞춤) · 구역(제목 + 몸) 여럿 * 공개 머리(로고 · 메뉴)와 바닥글(`.app-footer`)은 앱 셸 몫 — 이 틀은 그 사이 본문만 * 크기 = 폭 = --page-max-width · 제목 = --text-heading-lg(좁으면 --text-heading · `wide` = 18 자) · 구역 제목 = --text-heading-sm(가운데) * 상태 = 없음 * 쓰는 법 = const f = createPublicFrame({ title: "임도 설계", lead: "…", actions: [btn] }); f.addSection("기능").append(grid) * 대신하는 옛 변종 = A01 ~ A05 `.a0N-hero` · `__inner` · `__title` · `__subtitle` · `__ctas` 다섯 벌 · `.a0N-section(__title)` * ========================================================================== */ import "./ui_template_public_layout.css"; export interface PublicFrameOptions { title: string; lead?: string; actions?: HTMLElement[]; /** 머리 띠 맞춤 — 기본 가운데 */ align?: "center" | "start"; /** 제목 18 자 · 설명 56 자 폭(기본 14 · 52) */ wide?: boolean; } export interface PublicFrame { root: HTMLElement; hero: HTMLElement; /** 구역 하나 더함 → 그 구역 몸(여기에 내용을 담음) */ addSection: (title?: string) => HTMLElement; } function node( tag: K, className: string, text?: string, ): HTMLElementTagNameMap[K] { const n = document.createElement(tag); n.className = className; if (text !== undefined) n.textContent = text; return n; } export function createPublicFrame(opts: PublicFrameOptions): PublicFrame { const root = node("div", "ui-public-frame"); const hero = node("section", "ui-public-frame__hero"); hero.dataset.align = opts.align ?? "center"; if (opts.wide) hero.dataset.wide = ""; const inner = node("div", "ui-public-frame__hero-inner"); inner.append(node("h1", "ui-public-frame__title", opts.title)); if (opts.lead) inner.append(node("p", "ui-public-frame__lead", opts.lead)); if (opts.actions?.length) { const ctas = node("div", "ui-public-frame__actions"); ctas.append(...opts.actions); inner.append(ctas); } hero.append(inner); root.append(hero); const addSection = (title?: string): HTMLElement => { const section = node("section", "ui-public-frame__section"); if (title) section.append(node("h2", "ui-public-frame__section-title", title)); const body = node("div", "ui-public-frame__section-body"); section.append(body); root.append(section); return body; }; return { root, hero, addSection }; }