업종마다 템플릿이 다섯인데 넷이 "흰 바탕 + 고딕 + 둥근 모서리"에 색조만 달랐다. 고르는 화면의 미리보기도 회색 막대 세 줄 + 색 동그라미라 다섯 장이 전부 같은 그림이었다 — 뭐가 다른지 알 수 없으니 아무거나 골랐다. - shared/TemplateItem.look: 제목·본문 서체, 모서리, 테두리 두께, 그림자, 제목 자간·굵기, 섹션 여백. CSS 에 그대로 들어가는 문자열로 들고 있다 — 숫자로 두면 쓰는 쪽에서 단위를 빠뜨린 곳이 조용히 0 이 된다 - CanvasView: Tailwind v4 의 --radius-* · --shadow-* 를 캔버스 안에서만 덮는다. 변이 파일 40여 개에 흩어진 rounded-* · shadow-* 를 한 줄도 안 고치고 전부 템플릿을 따르게 된다. 배수는 Tailwind 기본 비율 그대로라 기준값 0.75rem 이면 지금까지와 픽셀 단위로 같다 - index.css: .site-canvas 는 --tpl-font-heading/body 를 이미 읽고 있었는데 아무도 넣지 않았다. 서체가 안 갈리던 진짜 이유가 이 빠진 고리다. 제목 굵기도 토큰으로 뺐다 — 간판체(Gugi)는 굵기가 한 벌뿐이라 700 을 주면 브라우저가 가짜 볼드를 씌워 획이 뭉갠다 - industryData: templatesFor() 팩토리 하나로 심플·매거진·레트로 셋. 업종은 accent 하나만 바꾼다 — 생김새는 업종이 아니라 취향의 문제다. 537줄 → 237줄 - Step4Template: 미리보기를 그 템플릿의 서체·모서리·테두리·그림자로 실제로 그린다 - index.html: Noto Serif KR 추가. 매거진 제목이 Batang 으로 떨어지는데 맥에는 그 서체가 없다 - SectionFrame: 세로 여백을 --tpl-section-space 로. 이 값 하나로 페이지의 호흡이 바뀐다 옛 템플릿 id 가 DB 에 남아 있어도 resolveTemplate 이 첫 템플릿으로 떨어뜨린다. tsc·eslint·vite build 통과(frontend·admin·site), 템플릿 12벌 look 전량 대조 + 폴백 확인
94 lines
3.7 KiB
CSS
94 lines
3.7 KiB
CSS
@import "tailwindcss";
|
|
@import "tw-animate-css";
|
|
|
|
/* 디자인 토큰(색상·폰트·radius)은 shared 단일 소스에서 관리. site 와 공유 가능. */
|
|
@import "@o2o/shared/styles/tokens.css";
|
|
@import "@o2o/shared/styles/base.css";
|
|
|
|
body {
|
|
background-color: var(--background);
|
|
color: var(--foreground);
|
|
font-family: var(--font-sans);
|
|
transition: background-color 0.2s ease, color 0.2s ease;
|
|
}
|
|
|
|
@layer base {
|
|
* {
|
|
@apply border-border outline-ring/50;
|
|
}
|
|
body {
|
|
@apply bg-background text-foreground;
|
|
}
|
|
html {
|
|
@apply font-sans;
|
|
}
|
|
}
|
|
|
|
/* 캔버스(발행 사이트 미리보기)는 관리자 토큰이 아니라 템플릿 색을 쓴다.
|
|
.site-canvas 안쪽은 --tpl-* 변수로만 색을 잡는다 — 관리자 크롬 색이 새어 들어오지 않게. */
|
|
@layer components {
|
|
.site-canvas {
|
|
color-scheme: light;
|
|
background-color: var(--tpl-bg, #ffffff);
|
|
color: var(--tpl-text, #09090b);
|
|
/* 본문 서체도 토큰이다. 변수가 없으면(빌더 캔버스 등) 지금까지처럼 관리자 본문 서체를 쓴다. */
|
|
font-family: var(--tpl-font-body, var(--font-sans));
|
|
}
|
|
.site-canvas .serif-title {
|
|
font-family: var(--tpl-font-heading, 'Noto Serif KR', 'Batang', 'Times New Roman', serif);
|
|
}
|
|
/* 캔버스 안의 '면'(카드·패널)과 테두리도 토큰을 따른다.
|
|
★ bg-white / bg-stone-* 이 캔버스 안에만 82곳 흩어져 있어 파일마다 고치는 대신 여기서 덮는다.
|
|
폴백이 원래 Tailwind 값이라, --tpl-* 이 없는 곳에서는 지금까지와 완전히 동일하다.
|
|
★ 팔레트를 바꿔도 화면이 안 변하는 원인의 절반이 이 면들이었다(나머지 절반은 섹션 바탕). */
|
|
.site-canvas .bg-white {
|
|
background-color: var(--tpl-card, #ffffff);
|
|
}
|
|
.site-canvas .bg-stone-50 {
|
|
background-color: var(--tpl-card, var(--color-stone-50));
|
|
}
|
|
.site-canvas .bg-stone-100 {
|
|
background-color: var(--tpl-surface-alt, var(--color-stone-100));
|
|
}
|
|
/* 테두리는 팔레트 색을 그대로 쓰면 너무 세다 — 30% 만 섞는다. */
|
|
.site-canvas .border-stone-200,
|
|
.site-canvas .border-stone-300 {
|
|
border-color: color-mix(in oklab, var(--tpl-border, var(--color-stone-200)) 30%, transparent);
|
|
}
|
|
|
|
/* serif-title 을 안 쓰는 제목도 제목 서체를 따르게 한다.
|
|
★ 폴백이 inherit 이라 --tpl-font-heading 이 없으면 예전과 똑같이 본문 서체를 그대로 물려받는다. */
|
|
.site-canvas h1,
|
|
.site-canvas h2,
|
|
.site-canvas h3,
|
|
.site-canvas h4 {
|
|
font-family: var(--tpl-font-heading, inherit);
|
|
letter-spacing: var(--tpl-heading-tracking, normal);
|
|
}
|
|
/* ★ 굵기는 폴백을 inherit 로 두지 않는다. 간판체(Gugi)는 굵기가 한 벌뿐이라 700 을 주면
|
|
브라우저가 가짜 볼드를 씌워 획이 뭉갠다 — 템플릿이 400 을 지정할 수 있어야 한다. */
|
|
.site-canvas :is(h1, h2, h3, h4).tpl-title {
|
|
font-weight: var(--tpl-heading-weight, 700);
|
|
}
|
|
/* 카드·패널 테두리 두께도 템플릿이 정한다. 레트로는 2px 라야 인쇄물처럼 보인다. */
|
|
.site-canvas .border {
|
|
border-width: var(--tpl-border-width, 1px);
|
|
}
|
|
}
|
|
|
|
/* 수집 진행바 shimmer — 0%(빈 트랙) 구간에서도 '진행 중'이 보이게 한다. */
|
|
@keyframes o2o-shimmer {
|
|
from { transform: translateX(-100%); }
|
|
to { transform: translateX(500%); }
|
|
}
|
|
.o2o-progress-shimmer {
|
|
animation: o2o-shimmer 1.8s ease-in-out infinite;
|
|
}
|
|
|
|
/* 노치/홈 인디케이터 회피 (viewport-fit=cover 와 짝).
|
|
화면 맨 위/맨 아래에 붙는 바에만 붙인다 — 스크롤되는 본문에는 쓰지 않는다. */
|
|
@layer components {
|
|
.safe-t { padding-top: env(safe-area-inset-top); }
|
|
.safe-b { padding-bottom: env(safe-area-inset-bottom); }
|
|
}
|