import {useSite} from '@site/lib/site-context'; import {primaryImage} from '@site/seo/meta'; import {bookingActionLabel, bookingLinks, essentialRows, heroFacts, lowestPrice} from '@site/lib/derive'; /** * oasi 첫 화면 — 사진 한 장과 아주 작은 글씨. * * ★ 사진 위에 글자를 얹지 않는다. 이 안은 폭을 제한한 사진을 가운데 한 장 놓고 * **바깥 여백에 세로쓰기 캡션**을 세우는 편집형이다 — 사진을 화면 끝까지 늘리면 * 그 여백이 사라져 안 자체가 성립하지 않는다. * ★ 상호는 `

` 이지만 크게 쓰지 않는다. 크기는 왼쪽 워드마크가 이미 맡았고, * 여기서 큰 활자를 한 번 더 쓰면 화면에 큰 글자가 둘이 된다. * ★ 세로쓰기 캡션은 좁은 화면에서 감춘다 — 390px 에서는 사진 밖 여백이 없어 * 그대로 두면 가로 스크롤이 생긴다. * ★ 사진 틀의 **높이를 고정한다**. 자연 비율로 두면 소스가 세로 사진일 때 첫 화면을 * 사진 하나가 통째로 먹는다 — 실측(stay3, 1000×1333): 544×725px. * 사장님이 어떤 사진을 올리든 첫 화면 높이가 같아야 한다. */ export function Hero() { const payload = useSite(); const {place, narrative} = payload; const image = primaryImage(payload); const price = lowestPrice(payload); const links = bookingLinks(payload); /* 첫 화면 우선순위 key(체크인·영업시간…)가 하나도 없는 업종이 있다 — 그때 띠를 비우지 않고 확인된 이용 정보 앞 넷으로 채운다. */ const priority = heroFacts(payload); const facts = priority.length > 0 ? priority : essentialRows(payload).slice(0, 4); const caption = image?.caption ?? place.name; return ( /* data-oasi: 껍데기의 판 지우개(Shell PLATE_CSS)를 건너뛴다 — 여기는 이미 투명하고 위 여백도 스스로 정한다(첫 섹션이라 다른 섹션보다 좁다). */

{place.name}

{narrative.heroHeadline && (

{narrative.heroHeadline}

)} {image && (
{image.alt} {/* 캡션 높이를 액자에 묶고(max-h-full) 한 줄로 묶는다(nowrap). 22rem 로 박아 두면 액자보다 캡션이 길어져 사진 아래로 흘러내리고, 긴 캡션은 세로쓰기가 여러 단으로 갈려 액자 옆이 글자 벽이 된다. */}
{caption}
)} {(price || facts.length > 0) && (
{price && (
최저가
{price}
)} {facts.map((row) => (
{row.label}
{row.value}
))}
)} {/* 확정된 예약 채널만. 버튼 상자를 만들지 않는다 — 이 안에는 면이 없다. */} {links.length > 0 && ( )}
); }