언제 쓰는가
모든 손님 화면. 위성 앱의 페이지는 예외 없이 <x-gujo::shell> 하나로 감싼다. 헤더·푸터·앱 스위처·플래시 메시지·head 자산은 shell 이 그리고, 앱은 메뉴 슬롯과 본문만 채운다.
구조
<x-gujo::shell :title="__('store.catalog_title')" :description="__('store.catalog_lead')">
<x-slot:nav>@include('partials.nav')</x-slot:nav>
<section class="gj-hero gj-container">
<h1>{{ __('store.hero_title') }}</h1>
<p class="gj-lead">{{ __('store.hero_lead') }}</p>
<div class="gj-hero-cta">
<x-gujo::btn :href="route('catalog.index')">{{ __('store.cta_primary') }}</x-gujo::btn>
<x-gujo::btn :href="route('support')" variant="ghost">{{ __('store.cta_support') }}</x-gujo::btn>
</div>
</section>
<div class="gj-container gj-section">
<div class="gj-section-head">
<h2>{{ __('store.section_title') }}</h2>
<p>{{ __('store.section_lead') }}</p>
</div>
…
</div>
</x-gujo::shell>
- 첫 화면(랜딩)은
.gj-hero로 시작한다. 제목 한 줄,.gj-lead한두 문장,.gj-hero-cta에 버튼 둘까지. - 히어로 아래 특징 밴드가 필요하면
.gj-strip+.gj-strip-inner+.gj-strip-item3칸. - 본문 블록은
.gj-container안에서.gj-section으로 나누고, 각 블록은.gj-section-head(h2 + p) 로 시작한다. 촘촘한 구간은.gj-section--tight. - 헤더 메뉴는
partials/nav.blade.php한 곳에 두고<x-gujo::nav-link :active="request()->routeIs(...)">로 현재 위치를 표시한다.
쓰는 .gj-* 클래스와 Blade 컴포넌트
- 컴포넌트:
<x-gujo::shell>,<x-gujo::nav-link>,<x-gujo::btn> - 클래스:
.gj-container,.gj-hero,.gj-lead,.gj-hero-cta,.gj-strip,.gj-strip-inner,.gj-strip-item,.gj-section,.gj-section--tight,.gj-section-head,.gj-section-head--center,.gj-eyebrow - 라우트 이름 계약:
landing,support,login,logout(+선택mypage,legal.*). shell 의 헤더·푸터가Route::has()로 감지해 자동 노출한다.
하지 말 것
- 앱 안에
<style>블록이나style="…"로 여백·색을 손보지 않는다. 필요한 모양이 없으면 이 패키지의components.css에 클래스를 추가한다. - 앱별 레이아웃 파일(
layouts/app.blade.php)을 따로 만들지 않는다. 골격은 shell 하나다. - 카피를 템플릿에 직접 적지 않는다.
lang/ko/*.php의__()키만 쓴다. - 히어로에 버튼을 셋 이상 두지 않는다. 주 행동 하나, 보조 하나.
- 화면 카피에 한글 리터럴을 넣지 않는다.
__('store.hero_title')처럼 키만 쓴다.
