chore(supporters): 통합 뒤 템플릿 재생성 (주변 안내 포함, 영어 홈 안전 기본값)
정본 supporters/ 와 템플릿의 페이지 집합이 같아졌다. /stay·/en/stay·/en·/plan·/en/plan 이 양쪽에 모두 있다. 검증 - 뷰 34페이지, 게이트 41/41, check.mjs 오류 0건. - 빈 데이터 템플릿 16페이지, 영어 홈에 병원 고유 사실 0건, 문장 성립. - 내보내기 종료코드 0, tsc 0 에러. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
0a0f64c29e
commit
82aa56fa40
@ -24,5 +24,9 @@
|
||||
"sponsorNotice": "",
|
||||
"ga4MeasurementId": "",
|
||||
"_comment_ga4": "GA4 측정 ID(G-XXXX). 비우면 태그를 넣지 않는다. 키 이벤트 이름은 data/ai_channels.json conversion_events 와 같다.",
|
||||
"heroImageAltEn": ""
|
||||
"heroImageAltEn": "",
|
||||
"indexNowKey": "",
|
||||
"googleSiteVerification": "",
|
||||
"naverSiteVerification": "",
|
||||
"_comment_publish": "indexNowKey 는 워커 data 단계가 자동 생성(public/<key>.txt). googleSiteVerification·naverSiteVerification 은 각 콘솔의 HTML 태그 content 값을 사람이 넣는다(briefs/<clinic>/clinic.json site 로 전달 가능). 발행 단계는 scripts/publish_site.mjs."
|
||||
}
|
||||
|
||||
@ -75,6 +75,7 @@ document.addEventListener('click',function(e){var a=e.target.closest&&e.target.c
|
||||
<a href="/posts">{u.nav_posts}</a>
|
||||
<a href="/videos">{u.nav_videos}</a>
|
||||
<a href="/newsroom">{u.nav_news}</a>
|
||||
<a href="/stay">{u.nav_stay}</a>
|
||||
<a href="/visit">{u.nav_visit}</a>
|
||||
<a href="/plan">{u.nav_plan}</a>
|
||||
<a href="/about">{u.nav_about}</a>
|
||||
@ -82,6 +83,7 @@ document.addEventListener('click',function(e){var a=e.target.closest&&e.target.c
|
||||
) : (
|
||||
<>
|
||||
<a href="/en">{u.nav_home}</a>
|
||||
<a href="/en/stay">{u.nav_stay}</a>
|
||||
<a href="/en/plan">{u.nav_plan}</a>
|
||||
<a href="/en#visit">{u.nav_visit}</a>
|
||||
<a href="/en#clinic">{u.nav_clinic}</a>
|
||||
|
||||
@ -6,6 +6,7 @@ export type Lang = 'ko' | 'en';
|
||||
const PAIRS: [string, string][] = [
|
||||
['/', '/en'],
|
||||
['/plan', '/en/plan'],
|
||||
['/stay', '/en/stay'],
|
||||
];
|
||||
export function switchHref(pathname: string, to: Lang): string {
|
||||
const p = pathname.replace(/\/index\.html$/, '/').replace(/\.html$/, '').replace(/\/$/, '') || '/';
|
||||
@ -21,7 +22,7 @@ export const UI: Record<Lang, Record<string, string>> = {
|
||||
ko: {
|
||||
sample: '샘플 사이트입니다. 정식 공개 전입니다.',
|
||||
brand: '서포터즈',
|
||||
nav_posts: '상담 전 질문', nav_videos: '의료진 영상', nav_news: '뉴스룸', nav_visit: '방문 안내', nav_plan: '회복 일정', nav_about: '매체 소개',
|
||||
nav_posts: '상담 전 질문', nav_videos: '의료진 영상', nav_news: '뉴스룸', nav_stay: '주변 안내', nav_visit: '방문 안내', nav_plan: '회복 일정', nav_about: '매체 소개',
|
||||
cta: '상담 예약',
|
||||
back: '이전 페이지', backAria: '이전 페이지로 돌아가기', totop: '맨 위로',
|
||||
switchLabel: 'EN', switchAria: 'Switch to English',
|
||||
@ -33,7 +34,7 @@ export const UI: Record<Lang, Record<string, string>> = {
|
||||
en: {
|
||||
sample: 'Sample site. Not yet public.',
|
||||
brand: 'Supporters',
|
||||
nav_home: 'Home', nav_plan: 'Recovery Planner', nav_visit: 'Getting Here', nav_clinic: 'Clinic Facts', nav_korean: '한국어 전체 보기',
|
||||
nav_home: 'Home', nav_stay: 'Nearby', nav_plan: 'Recovery Planner', nav_visit: 'Getting Here', nav_clinic: 'Clinic Facts', nav_korean: '한국어 전체 보기',
|
||||
cta: 'Book a consultation',
|
||||
back: 'Back', backAria: 'Go back to the previous page', totop: 'Back to top',
|
||||
switchLabel: 'KO', switchAria: '한국어로 보기',
|
||||
|
||||
@ -12,6 +12,8 @@ export const GET: APIRoute = async ({ site }) => {
|
||||
{ loc: `${base}/clinic`, lastmod: today },
|
||||
{ loc: `${base}/visit`, lastmod: today },
|
||||
{ loc: `${base}/en`, lastmod: today },
|
||||
{ loc: `${base}/stay`, lastmod: today },
|
||||
{ loc: `${base}/en/stay`, lastmod: today },
|
||||
{ loc: `${base}/plan`, lastmod: today },
|
||||
{ loc: `${base}/en/plan`, lastmod: today },
|
||||
{ loc: `${base}/newsroom`, lastmod: today },
|
||||
|
||||
@ -280,3 +280,180 @@ td { color: var(--slate-700); }
|
||||
.site-header .nav a { margin-left: 0; flex: none; font-size: 0.9rem; }
|
||||
}
|
||||
|
||||
/* ── /en/stay ── */
|
||||
.stay { padding-bottom: 4rem; }
|
||||
.stay .lede { color: var(--slate-600, #475569); margin-top: 0.6rem; }
|
||||
.stay section { margin-top: 3.4rem; }
|
||||
.stay .sec-head { display: flex; align-items: baseline; justify-content: space-between; gap: 1rem; flex-wrap: wrap; }
|
||||
.stay .sec-head h2 { margin: 0; }
|
||||
.stay .upd { font-size: 0.8rem; color: var(--slate-500, #64748B); }
|
||||
.stay .sub { color: var(--slate-600, #475569); margin: 0.4rem 0 1rem; }
|
||||
.stay .src { font-size: 0.84rem; color: var(--slate-500, #64748B); margin-top: 1rem; }
|
||||
.stay .chips { display: flex; flex-wrap: wrap; gap: 0.5rem; margin: 0.2rem 0 1.6rem; }
|
||||
.stay .chip {
|
||||
border: 1px solid var(--line, #E2E8F0); background: #fff; border-radius: 999px;
|
||||
padding: 0.36rem 0.85rem; font: inherit; font-size: 0.86rem; color: var(--slate-600, #475569);
|
||||
cursor: pointer; transition: background 0.15s, color 0.15s, border-color 0.15s;
|
||||
}
|
||||
.stay .chip b { font-weight: 700; opacity: 0.55; margin-left: 0.25em; }
|
||||
.stay .chip:hover { border-color: var(--primary-900, #0A1128); }
|
||||
.stay .chip.on { background: var(--primary-900, #0A1128); border-color: var(--primary-900, #0A1128); color: #fff; }
|
||||
.stay .chip.on b { opacity: 0.7; }
|
||||
.stay .grp { margin-bottom: 2.2rem; }
|
||||
.stay .grp h3 { margin: 0 0 0.9rem; }
|
||||
.stay .grp h3 small { font-weight: 400; font-size: 0.82rem; color: var(--slate-500, #64748B); margin-left: 0.45em; }
|
||||
.stay .cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(248px, 1fr)); gap: 1rem; }
|
||||
.stay .card {
|
||||
background: #fff; border: 1px solid var(--line, #E2E8F0); border-radius: 14px;
|
||||
overflow: hidden; display: flex; flex-direction: column;
|
||||
box-shadow: 3px 4px 12px rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
.stay .card .thumb { position: relative; height: 148px; background: #EEF1F6; display: flex; align-items: center; justify-content: center; }
|
||||
.stay .card .thumb img { width: 100%; height: 148px; object-fit: cover; display: block; }
|
||||
.stay .card .nophoto {
|
||||
font-size: 1.02rem; font-weight: 700; color: var(--slate-500, #64748B);
|
||||
padding: 0 1rem; text-align: center; line-height: 1.35; word-break: keep-all;
|
||||
}
|
||||
.stay .card .badge {
|
||||
position: absolute; left: 0.6rem; bottom: 0.6rem;
|
||||
background: rgba(10, 17, 40, 0.82); color: #fff; border-radius: 6px;
|
||||
padding: 0.18rem 0.45rem; font-size: 0.74rem; font-weight: 600;
|
||||
}
|
||||
.stay .card .badge em { font-style: normal; opacity: 0.7; margin-left: 0.25em; }
|
||||
.stay .card .badge.mono { letter-spacing: 0.06em; }
|
||||
.stay .card .body { padding: 0.85rem 0.95rem 1rem; display: flex; flex-direction: column; flex: 1; }
|
||||
.stay .card h4 { margin: 0 0 0.35rem; font-size: 0.98rem; }
|
||||
.stay .card .when { font-size: 0.8rem; color: var(--slate-600, #475569); margin: 0 0 0.4rem; }
|
||||
.stay .card .desc { font-size: 0.86rem; color: var(--slate-600, #475569); margin: 0 0 0.5rem; }
|
||||
.stay .card .addr { font-size: 0.78rem; color: var(--slate-500, #64748B); margin: 0 0 0.6rem; }
|
||||
.stay .card .go { font-size: 0.82rem; margin-top: auto; }
|
||||
.stay .route { border: 1px solid var(--line, #E2E8F0); border-radius: 16px; padding: 1.3rem 1.4rem; margin-bottom: 1.4rem; background: #fff; }
|
||||
.stay .route-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 1rem; flex-wrap: wrap; }
|
||||
.stay .route-head h3 { margin: 0; }
|
||||
.stay .route .who { font-size: 0.84rem; color: var(--slate-500, #64748B); margin: 0.15rem 0 0; }
|
||||
.stay .route .clock { font-size: 0.86rem; font-weight: 600; color: var(--primary-900, #0A1128); white-space: nowrap; }
|
||||
.stay .route .blurb { color: var(--slate-600, #475569); margin: 0.7rem 0 1rem; }
|
||||
.stay .route .map { width: 100%; height: auto; display: block; border-radius: 12px; }
|
||||
.stay .route .maphint { font-size: 0.76rem; color: var(--slate-500, #64748B); margin: 0.4rem 0 1rem; }
|
||||
.stay .timeline { list-style: none; padding: 0; margin: 0; }
|
||||
.stay .timeline .move { font-size: 0.8rem; color: var(--slate-500, #64748B); margin: 0.35rem 0 0.35rem 1.05rem; }
|
||||
.stay .timeline .stop { display: flex; gap: 0.8rem; align-items: flex-start; }
|
||||
.stay .timeline .n {
|
||||
flex: none; width: 26px; height: 26px; border-radius: 50%;
|
||||
background: var(--primary-900, #0A1128); color: #fff;
|
||||
font-size: 0.8rem; font-weight: 700; display: grid; place-items: center; margin-top: 0.1rem;
|
||||
}
|
||||
.stay .timeline .stop-t { font-size: 0.8rem; color: var(--slate-500, #64748B); }
|
||||
.stay .timeline h4 { margin: 0.1rem 0 0.2rem; font-size: 0.98rem; }
|
||||
.stay .timeline p { margin: 0; font-size: 0.86rem; color: var(--slate-600, #475569); }
|
||||
.stay .botnote { margin-top: 1.6rem; }
|
||||
/* 시술 후 관리 안내(병원 원문 인용). 동선 카드(.route)·정차(.stop) 룩을 그대로 쓰고 접이식 동작만 더한다. 새 색·크기 없음. */
|
||||
.stay details.recovery > summary.btn { list-style: none; cursor: pointer; }
|
||||
.stay details.recovery > summary.btn::-webkit-details-marker { display: none; }
|
||||
.stay details.recovery > summary.btn .hide { display: none; }
|
||||
.stay details.recovery[open] > summary.btn .show { display: none; }
|
||||
.stay details.recovery[open] > summary.btn .hide { display: inline; }
|
||||
.stay details.recovery[open] > summary.btn { margin-bottom: 1.1rem; }
|
||||
.stay details.recovery > .timeline { margin-top: 0.2rem; }
|
||||
.stay .recovery .timeline > li { border-top: 1px solid var(--line, #E2E8F0); padding: 0.7rem 0; }
|
||||
.stay .recovery .timeline > li:first-child { border-top: 0; padding-top: 0; }
|
||||
.stay .recovery summary { cursor: pointer; list-style: none; }
|
||||
.stay .recovery summary::-webkit-details-marker { display: none; }
|
||||
.stay .recovery summary .stop { display: flex; }
|
||||
.stay .recovery summary h4 { margin: 0.1rem 0 0; }
|
||||
.stay .recovery details[open] summary h4 { text-decoration: underline; text-underline-offset: 0.2em; text-decoration-color: var(--slate-200, #E2E8F0); }
|
||||
.stay .recovery details > ul { margin: 0.7rem 0 0.5rem 2.2rem; padding-left: 1.1rem; }
|
||||
.stay .recovery details > ul li { font-size: 0.9rem; color: var(--slate-700, #334155); margin-bottom: 0.35rem; }
|
||||
.stay .recovery details > p { margin: 0 0 0 2.2rem; font-size: 0.84rem; color: var(--slate-500, #64748B); }
|
||||
@media (max-width: 640px) { .cards { grid-template-columns: 1fr; } }
|
||||
|
||||
/* 섹션 점프. 머리말 아래에 붙어 스크롤을 따라온다. 헤더(68px) 아래에 걸리게 top 을 맞춘다. */
|
||||
.stay .jump {
|
||||
position: sticky; top: 68px; z-index: 9;
|
||||
display: flex; flex-wrap: wrap; gap: 0.45rem;
|
||||
margin: 1.4rem 0 2.4rem;
|
||||
padding: 0.62rem 0.68rem;
|
||||
background: rgba(255, 255, 255, 0.58);
|
||||
backdrop-filter: blur(16px) saturate(1.5);
|
||||
-webkit-backdrop-filter: blur(16px) saturate(1.5);
|
||||
border: 1px solid rgba(255, 255, 255, 0.6);
|
||||
border-radius: 18px;
|
||||
box-shadow: 0 8px 28px rgba(10, 17, 40, 0.09), inset 0 1px 0 rgba(255, 255, 255, 0.7);
|
||||
}
|
||||
.stay .jump a {
|
||||
display: inline-flex; align-items: center; gap: 0.42rem;
|
||||
padding: 0.46rem 0.9rem;
|
||||
border-radius: 999px;
|
||||
font-size: 0.86rem; font-weight: 600; letter-spacing: -0.005em;
|
||||
color: var(--primary-900, #0A1128);
|
||||
text-decoration: none; white-space: nowrap;
|
||||
background: #fff;
|
||||
border: 1px solid var(--line, #E2E8F0);
|
||||
box-shadow: 0 1px 2px rgba(10, 17, 40, 0.06);
|
||||
transition: transform 0.14s ease, box-shadow 0.14s ease, background 0.14s, border-color 0.14s, color 0.14s;
|
||||
}
|
||||
.stay .jump a:hover {
|
||||
text-decoration: none;
|
||||
transform: translateY(-1px);
|
||||
border-color: #C5CBF5;
|
||||
box-shadow: 0 4px 12px rgba(10, 17, 40, 0.12);
|
||||
}
|
||||
.stay .jump a:active { transform: translateY(0); box-shadow: 0 1px 2px rgba(10, 17, 40, 0.08); }
|
||||
.stay .jump a b {
|
||||
font-weight: 700; font-size: 0.72rem; line-height: 1;
|
||||
padding: 0.2rem 0.4rem; border-radius: 999px;
|
||||
background: #EFF0FF; color: #3A3F7C;
|
||||
}
|
||||
/* 지금 보고 있는 섹션 */
|
||||
.stay .jump a.on {
|
||||
background: linear-gradient(to right, #4F1DA1, #021341);
|
||||
border-color: transparent; color: #fff;
|
||||
box-shadow: 0 4px 14px rgba(79, 29, 161, 0.32);
|
||||
}
|
||||
.stay .jump a.on b { background: rgba(255, 255, 255, 0.22); color: #fff; }
|
||||
/* 점프로 이동했을 때 제목이 스티키 바에 가리지 않게 */
|
||||
.stay section, .stay .grp { scroll-margin-top: 152px; }
|
||||
@media (max-width: 640px) {
|
||||
.stay .jump { top: 60px; gap: 0.35rem; padding: 0.5rem; border-radius: 14px; }
|
||||
.stay .jump a { padding: 0.4rem 0.72rem; font-size: 0.8rem; }
|
||||
}
|
||||
|
||||
/* 필터 칩도 눌리는 것처럼 보이게 */
|
||||
.stay .chip {
|
||||
box-shadow: 0 1px 2px rgba(10, 17, 40, 0.05);
|
||||
transition: transform 0.14s ease, box-shadow 0.14s ease, background 0.15s, color 0.15s, border-color 0.15s;
|
||||
}
|
||||
.stay .chip:hover { transform: translateY(-1px); box-shadow: 0 4px 12px rgba(10, 17, 40, 0.1); }
|
||||
.stay .chip:active { transform: translateY(0); }
|
||||
.stay .chip.on { box-shadow: 0 4px 14px rgba(10, 17, 40, 0.22); }
|
||||
|
||||
/* 오늘 날씨. 값을 못 받으면 hidden 이라 아예 그려지지 않는다. */
|
||||
.stay .wx {
|
||||
display: flex; align-items: center; justify-content: space-between;
|
||||
gap: 1.2rem; flex-wrap: wrap;
|
||||
margin-top: 1.6rem; padding: 1rem 1.2rem;
|
||||
background: linear-gradient(to right, #fff3eb, #e4cfff, #f5f9ff);
|
||||
border-radius: 16px;
|
||||
}
|
||||
.stay .wx-now { display: flex; align-items: center; gap: 0.9rem; }
|
||||
.stay .wx-temp { font-family: 'Playfair Display', serif; font-size: 2.5rem; font-weight: 700; line-height: 1; color: var(--primary-900, #0A1128); }
|
||||
.stay .wx-unit { font-size: 1.1rem; vertical-align: 0.9rem; margin-left: 0.06em; opacity: 0.6; }
|
||||
.stay .wx-cond { font-weight: 700; color: var(--primary-900, #0A1128); }
|
||||
.stay .wx-meta { font-size: 0.8rem; color: var(--slate-600, #475569); margin-top: 0.15rem; }
|
||||
.stay .wx-note { margin: 0; font-size: 0.88rem; color: var(--slate-700, #334155); max-width: 30rem; }
|
||||
|
||||
/* 동선 지도. OSM 타일을 좌표로 깔고 그 위에 핀을 얹는다. 출처 표기는 OSM 정책상 필수다. */
|
||||
.stay .route .map {
|
||||
position: relative; width: 100%; max-width: 680px; height: 340px;
|
||||
border-radius: 12px; overflow: hidden; background: #E8EDF3;
|
||||
border: 1px solid var(--line, #E2E8F0);
|
||||
}
|
||||
.stay .route .map-tiles { position: absolute; inset: 0; }
|
||||
.stay .route .map-tiles .tile { position: absolute; width: 256px; height: 256px; background-size: 256px 256px; background-repeat: no-repeat; }
|
||||
.stay .route .map-pins { position: absolute; inset: 0; width: 100%; height: 100%; }
|
||||
.stay .route .map-credit {
|
||||
position: absolute; right: 0; bottom: 0;
|
||||
background: rgba(255, 255, 255, 0.82); color: var(--slate-600, #475569);
|
||||
font-size: 0.66rem; padding: 0.1rem 0.35rem; border-top-left-radius: 6px;
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user