목업(/s/stay)이 참조하는 스타일시트가 서버에서 사라져(404) 그 화면을 기준으로 삼을 수
없었다. 브라우저 캐시에 남아 있던 규칙을 꺼내 레포에 되돌리고, 섹션 마크업을 목업 HTML
에서 그대로 옮겼다. Playwright 대조로 섹션 래퍼·제목 16/17, 안쪽 구조 14/17 일치.
- index.css: --fs-display~--fs-xs(유동 타이포 7) · --section-space · --color-line/muted ·
.h2 .h3 .panel .paper .measure .border-line .text-muted .divide-line .slider-viewport/track
★ 이 토큰이 없던 동안 컴포넌트가 var(--fs-display)를 써도 브라우저가 조용히 무시했다 —
히어로 제목이 본문 크기로 나오던 원인
- HeroSection: 가운데 → 좌하단. 사진 위에 글자를 한가운데 얹으면 피사체를 정확히 가린다
- AnswerBlock·EssentialInfo·Units·Gallery·Location·Faq·LocalGuide·Weather·About:
목업 마크업 그대로. embla 를 scroll-snap 으로 바꿔 스크립트 없이도 레일이 밀린다
- FestivalSection(계절 탭) · StorySection(이야기 탭 래퍼) · items/TripMap(OSM 타일 지도) 신설
★ 지도는 iframe 이 아니라 타일을 직접 깐다 — iframe 은 핀을 하나밖에 못 찍어
"어떤 순서로 도는가" 를 그릴 수 없다
- items: itinerary·event·video kind 추가(파서에 없어 payload 까지 실려 오고도 화면에서
사라지던 것) · Rail 을 slider-viewport/track 으로 · SongsSection 을 턴테이블로
- color.ts: 선 색을 secondary → mix(bg, text, .2). secondary 는 '본문 다음으로 진한
글자색' 이라 선으로 쓰면 표와 카드가 격자무늬처럼 새까맣게 그어진다
- seo/head.ts: --tpl-texture. 없으면 색만 갱지고 면은 매끈해서 인쇄물로 안 보인다
- seo/verify.ts: unitCode·numberOfRooms 를 화면 대조에서 뺀다
★ unitCode 는 ㎡의 ISO 코드로 priceCurrency 와 같은 성격인데 예외에 없었다. 그래서
room_size 가 있는 사업장은 발행 게이트가 전부 막았다(실측: 가은채 객실 12개).
stay 는 객실 2개 + room_size 없음이라 우연히 통과했다
- shared: LocalPlace.imageUrl/distanceMeters · FestivalEntry.imageUrl ·
ItineraryStop 좌표 · TemplateLook.texture · people/chronicle/postcard imageUrl
★ 좌표·사진은 모델이 만드는 칸이 아니다. 공식 API 로 조회해 채운다
검증: tsc 통과 · Playwright 대조(목업 CSS 주입) 섹션 래퍼·제목 16/17, 안쪽 14/17.
남은 차이는 데이터 한계다 — people 사진은 위키에 원본이 없고(original:false),
weather.note 는 정적 페이지에 날씨 문장을 박는 문제라 보류.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KP1ykMnWZFtLFpm2mow1Sw
181 lines
6.1 KiB
CSS
181 lines
6.1 KiB
CSS
@import "tailwindcss";
|
|
@import "@o2o/shared/styles/base.css";
|
|
|
|
/*
|
|
* 발행 사이트의 색은 사장님이 고른 템플릿에서 온다.
|
|
* 프리렌더가 <head> 에 --tpl-* 를 심고(`seo/head.ts` themeStyle), 여기서 Tailwind 색으로 연결한다.
|
|
* 관리자 토큰(tokens.css)은 이 앱에 들어오지 않는다 — 두 색 체계를 섞지 않는다.
|
|
*
|
|
* 개발 서버에서는 <head> 주입이 없으므로 아래 :root 기본값이 쓰인다.
|
|
*/
|
|
:root {
|
|
--tpl-primary: #18181b;
|
|
--tpl-secondary: #52525b;
|
|
--tpl-bg: #ffffff;
|
|
--tpl-card: #fafafa;
|
|
--tpl-text: #09090b;
|
|
--tpl-accent: #2563eb;
|
|
|
|
/*
|
|
* 유동 타이포 — 화면 폭에 따라 자라는 글자 크기.
|
|
*
|
|
* ★ 이 토큰이 없던 동안 히어로 제목이 본문과 같은 크기로 나왔다. 섹션 컴포넌트들이
|
|
* var(--fs-display) 를 쓰는데 정의가 어디에도 없어 그냥 무시됐다(브라우저는 조용히 넘어간다).
|
|
* ★ 값은 목업(/s/stay)이 쓰던 것을 그대로 옮겼다 — 화면이 달라지면 목업과 어긋난다.
|
|
*/
|
|
--fs-display: clamp(1.75rem, 1.25rem + 2.2vw, 3rem);
|
|
--fs-h2: clamp(1.3125rem, 1.15rem + 0.7vw, 1.75rem);
|
|
--fs-h3: clamp(1.0625rem, 1rem + 0.3vw, 1.25rem);
|
|
--fs-lead: clamp(0.9375rem, 0.9rem + 0.22vw, 1.0625rem);
|
|
--fs-body: clamp(0.9375rem, 0.91rem + 0.15vw, 1rem);
|
|
--fs-sm: clamp(0.8125rem, 0.8rem + 0.1vw, 0.875rem);
|
|
--fs-xs: clamp(0.75rem, 0.74rem + 0.06vw, 0.78125rem);
|
|
|
|
/* 섹션 세로 여백. 템플릿의 sectionSpace 를 상한으로 두고 좁은 화면에서만 줄인다. */
|
|
--section-space: clamp(2.25rem, 5vw, var(--tpl-section-space, 3.5rem));
|
|
|
|
/* 선·흐린 글자 — 템플릿 색에서 유도한다. 고정 회색을 쓰면 갱지 바탕에서 뜬다. */
|
|
--color-line: var(--tpl-border, color-mix(in oklab, var(--tpl-text, #09090b) 14%, transparent));
|
|
--color-muted: color-mix(in oklab, var(--tpl-text, #09090b) 60%, transparent);
|
|
}
|
|
|
|
@theme inline {
|
|
--color-brand: var(--tpl-primary);
|
|
--color-brand-soft: var(--tpl-secondary);
|
|
--color-surface: var(--tpl-bg);
|
|
--color-surface-alt: var(--tpl-card);
|
|
--color-ink: var(--tpl-text);
|
|
--color-accent: var(--tpl-accent);
|
|
|
|
--font-sans: 'Pretendard Variable', 'Noto Sans KR', system-ui, sans-serif;
|
|
--font-serif: 'Noto Serif KR', 'Batang', 'Times New Roman', serif;
|
|
}
|
|
|
|
html {
|
|
scroll-behavior: smooth;
|
|
/* 고정 헤더에 앵커가 가리지 않게. */
|
|
scroll-padding-top: 5rem;
|
|
}
|
|
|
|
body {
|
|
background-color: var(--color-surface);
|
|
color: var(--color-ink);
|
|
/* ★ 본문 서체도 템플릿이 정한다(theme.look → seo/head.ts). 토큰이 없는 옛 payload 에서는
|
|
지금까지와 똑같이 Noto Sans KR 로 떨어진다. */
|
|
font-family: var(--tpl-font-body, var(--font-sans));
|
|
font-feature-settings: "tnum" 1;
|
|
}
|
|
|
|
@layer components {
|
|
/* 제목 서체. 이름은 'serif' 로 남아 있지만 값은 템플릿이 정한다 —
|
|
레트로면 간판체, 심플이면 고딕이다. 토큰이 없으면 예전처럼 명조로 떨어진다. */
|
|
.serif {
|
|
font-family: var(--tpl-font-heading, var(--font-serif));
|
|
letter-spacing: var(--tpl-heading-tracking, normal);
|
|
}
|
|
/* 카드·패널 테두리 두께도 템플릿이 정한다. 레트로는 2px 라야 인쇄물처럼 보인다. */
|
|
.tpl-border {
|
|
border-width: var(--tpl-border-width, 1px);
|
|
}
|
|
|
|
/* 섹션 공통 폭 — 본문이 한 줄에 너무 길어지지 않게. */
|
|
.shell {
|
|
width: 100%;
|
|
max-width: 1120px;
|
|
margin-inline: auto;
|
|
padding-inline: 1rem;
|
|
}
|
|
@media (min-width: 640px) {
|
|
.shell {
|
|
padding-inline: 1.5rem;
|
|
}
|
|
}
|
|
|
|
/* 본문 한 줄 길이 상한. 68자를 넘기면 눈이 다음 줄을 못 찾는다. */
|
|
.measure {
|
|
max-width: 68ch;
|
|
}
|
|
|
|
/* 종이 질감 — 템플릿이 texture 를 주면 깔린다(레트로 갱지). 없으면 아무것도 안 깔린다. */
|
|
.paper {
|
|
background-image: var(--tpl-texture, none);
|
|
}
|
|
|
|
/* 카드·패널. 바탕보다 한 겹 앞으로 나온 면. */
|
|
.panel {
|
|
background-color: color-mix(in oklab, currentcolor 5%, transparent);
|
|
border: var(--tpl-border-width, 1px) solid var(--color-line);
|
|
border-radius: var(--tpl-radius, 0.75rem);
|
|
box-shadow: var(--tpl-shadow, none);
|
|
}
|
|
.panel-sunken {
|
|
background-color: color-mix(in oklab, currentcolor 6%, transparent);
|
|
}
|
|
|
|
.border-line {
|
|
border-color: var(--color-line);
|
|
}
|
|
/* divide-y 의 사이 선도 같은 색으로. Tailwind 기본은 회색이라 갱지 위에서 뜬다. */
|
|
.divide-line > :not([hidden]) ~ :not([hidden]) {
|
|
border-color: var(--color-line);
|
|
}
|
|
.text-muted {
|
|
color: var(--color-muted);
|
|
}
|
|
|
|
/* 소제목. h1 은 히어로가 인라인으로 쓰고, 그 아래 단계는 이 두 클래스가 맡는다. */
|
|
.h2 {
|
|
font-family: var(--tpl-font-heading, var(--font-serif));
|
|
font-size: var(--fs-h2);
|
|
font-weight: var(--tpl-heading-weight, 700);
|
|
letter-spacing: var(--tpl-heading-tracking, -0.01em);
|
|
line-height: 1.2;
|
|
}
|
|
.h3 {
|
|
font-family: var(--tpl-font-heading, var(--font-serif));
|
|
font-size: var(--fs-h3);
|
|
font-weight: var(--tpl-heading-weight, 700);
|
|
letter-spacing: var(--tpl-heading-tracking, -0.005em);
|
|
line-height: 1.35;
|
|
}
|
|
/* 간판체처럼 굵기가 한 벌뿐인 서체에 가짜 볼드가 씌워지는 것을 막는다. */
|
|
.serif,
|
|
.h2,
|
|
.h3 {
|
|
font-synthesis-weight: none;
|
|
}
|
|
|
|
.label {
|
|
font-size: var(--fs-xs);
|
|
color: var(--color-muted);
|
|
font-weight: 600;
|
|
}
|
|
|
|
.tpl-shadow {
|
|
box-shadow: var(--tpl-shadow, none);
|
|
}
|
|
}
|
|
|
|
@layer components {
|
|
/*
|
|
* 가로 레일 — 목업과 같은 클래스 이름. 캐러셀 라이브러리 없이 스크롤 스냅으로만 만든다.
|
|
* ★ 스크립트가 없어도 손가락·트랙패드로 밀린다. 라이브러리를 얹으면 그게 죽었을 때
|
|
* 레일 전체가 한 줄로 굳는다.
|
|
*/
|
|
.slider-viewport {
|
|
overflow-x: auto;
|
|
scrollbar-width: none;
|
|
padding-bottom: 0.75rem;
|
|
}
|
|
.slider-viewport::-webkit-scrollbar {
|
|
display: none;
|
|
}
|
|
.slider-track {
|
|
display: flex;
|
|
scroll-snap-type: x mandatory;
|
|
}
|
|
.slider-track > * {
|
|
scroll-snap-align: center;
|
|
}
|
|
}
|