- 핵심 규칙 6: 완료의 정의는 게이트 통과. 사용자를 QA로 쓰지 않는다 - 5단계 기계 검사 4번째: design-gate 실행 의무화 - references/audit-gate.md: 사고-검사 매핑, SEO/meta 체크리스트, OS/브라우저 특성, 하니스 규칙 - tools/design-gate.mjs: 범용 게이트(메타/SEO·대비·수축·리듬·트랙·스케일×폭 + 옵션 L0/L3/L4, checks 깊은 병합) - 리듬·트랙 불변식: 숫자 라벨 등폭·빈 셀 트랙 균일·등간격 — 시간표 자동배치 결함 재현 픽스처 검출, 앱 15뷰 통과(오탐 0) feat(site): 관리 앱 2종 프로덕션 콘솔(v6→v18) - 가온 학적부 9뷰·두레 수강신청 6뷰: shadcn 문법, Pretendard/Noto Serif/IBM Plex 폰트 전략, 볼드 금지(400/500/600), WCAG AA 대비 전면 교정, 한글 keep-all 조판 - LMS 필수 요소(알림 센터·공지·진도·평가 유형·출결 사유·학점 경고), 12명 기준 데이터 정합, SEO 구조(h1 유일·OG/twitter·og.png) - 시간표 자동배치 결함 수리(명시적 격자 좌표) - QA 게이트: L0 stylelint/html-validate · L1 단위 30 · L2 감사 61+불변식 · L3 시각회귀 30화면 · L4 WebKit · L5 키보드 탐색 — npm run verify 실패 시 배포 금지 체인
This commit is contained in:
parent
78ddc8b61a
commit
72337b7ee0
226 changed files with 18212 additions and 380 deletions
333
apps/site/public/work/muwol-coffee/index.html
Normal file
333
apps/site/public/work/muwol-coffee/index.html
Normal file
|
|
@ -0,0 +1,333 @@
|
|||
<!doctype html>
|
||||
<html lang="ko">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>무월 (霧月) · 싱글오리진 원두 정기구독</title>
|
||||
<meta
|
||||
name="description"
|
||||
content="원두마다 산미·단맛·바디를 같은 척도로 측정해 적고, 생두 매입가를 공개합니다. 격주 화요일 로스팅, 서울 서촌."
|
||||
/>
|
||||
<meta property="og:title" content="무월 (霧月) · 싱글오리진 원두 정기구독" />
|
||||
<meta
|
||||
property="og:description"
|
||||
content="측정된 좌표로 원두를 고르는 격주 구독. 생두 매입 원장 공개."
|
||||
/>
|
||||
<meta property="og:type" content="website" />
|
||||
<meta name="theme-color" content="#F4F4F0" />
|
||||
|
||||
<link rel="preconnect" href="https://cdn.jsdelivr.net" crossorigin />
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="https://cdn.jsdelivr.net/gh/webfontworld/naver/MaruBuri.css"
|
||||
/>
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.9/dist/web/variable/pretendardvariable-dynamic-subset.min.css"
|
||||
/>
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;500&display=swap"
|
||||
/>
|
||||
<link rel="stylesheet" href="./styles/main.css?v=2" />
|
||||
<link
|
||||
rel="icon"
|
||||
href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Crect width='32' height='32' fill='%23F4F4F0'/%3E%3Cpath d='M16 7a7 7 0 0 1 7 7h-7z' fill='%237A3E1D'/%3E%3Cpath d='M16 9a7 7 0 0 0-7 7h7z' fill='%23181B18'/%3E%3Ccircle cx='16' cy='16' r='9' fill='none' stroke='%23181B18' stroke-width='1.5'/%3E%3C/svg%3E"
|
||||
/>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<a class="skip" href="#main">본문으로 건너뛰기</a>
|
||||
|
||||
<header class="site-head">
|
||||
<div class="wrap head-inner">
|
||||
<a class="wordmark" href="#main">
|
||||
무월 <span class="wordmark-han">霧月</span>
|
||||
</a>
|
||||
<nav class="nav" aria-label="섹션">
|
||||
<a href="#scale">척도</a>
|
||||
<a href="#ledger">원장</a>
|
||||
<a href="#recipe">레시피</a>
|
||||
<a href="#plan">구독</a>
|
||||
</nav>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main id="main">
|
||||
<!--
|
||||
히어로 — R1(coffeecollective.dk): 가격을 첫 화면에서 숨기지 않는다.
|
||||
문구만으로 시작하는 대신 이번 주 로스 사진 한 장과 원두 둘(값 포함)을 같이 둔다.
|
||||
-->
|
||||
<section class="hero" aria-labelledby="hero-h">
|
||||
<div class="wrap hero-grid">
|
||||
<div class="hero-text">
|
||||
<p class="hero-label reveal">싱글오리진 로스터리 · 서울 서촌</p>
|
||||
<h1 id="hero-h" class="reveal" style="--delay: 60ms">
|
||||
취향은 형용사가 아니라<br />측정된 좌표입니다
|
||||
</h1>
|
||||
<p class="lead reveal" style="--delay: 120ms">
|
||||
과일 향이 난다는 말로는 추출 온도를 정할 수 없습니다. 무월은 원두마다
|
||||
산미와 단맛, 바디를 같은 척도로 측정해 적고, 생두를 얼마에 들였는지까지
|
||||
공개합니다. 마셔보기 전에 판단할 수 있어야 원두 고르는 즐거움이 시작됩니다.
|
||||
</p>
|
||||
<div class="hero-actions reveal" style="--delay: 180ms">
|
||||
<a class="btn" href="#plan">격주 구독 시작하기</a>
|
||||
<p class="hero-note">격주 화요일 로스팅 출고 · 언제든 해지</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<figure class="hero-photo reveal" style="--delay: 100ms">
|
||||
<img
|
||||
src="./assets/beans-hero.webp"
|
||||
alt="따뜻한 회색 리넨 위 질도기 그릇에 담긴 갓 볶은 원두와 놋쇠 스쿱"
|
||||
width="900"
|
||||
height="1200"
|
||||
loading="eager"
|
||||
fetchpriority="high"
|
||||
/>
|
||||
<figcaption>이번 주 첫 로스 · 8월 19일</figcaption>
|
||||
</figure>
|
||||
|
||||
<!-- 이번 주 원두 — 카드가 아니라 원장의 첫 두 줄 -->
|
||||
<dl class="hero-beans reveal" style="--delay: 240ms">
|
||||
<div class="bean-row">
|
||||
<div>
|
||||
<dt>에티오피아 구지 우라가</dt>
|
||||
<dd class="bean-origin">워시드 · 해발 2,150m · 커핑 88.75</dd>
|
||||
</div>
|
||||
<dd class="bean-price"><span>100g</span> 8,500원</dd>
|
||||
</div>
|
||||
<div class="bean-row">
|
||||
<div>
|
||||
<dt>콜롬비아 엘 파라이소</dt>
|
||||
<dd class="bean-origin">혐기발효 · 해발 1,930m · 커핑 91.20</dd>
|
||||
</div>
|
||||
<dd class="bean-price"><span>100g</span> 11,000원</dd>
|
||||
</div>
|
||||
</dl>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!--
|
||||
척도 — 향미 좌표계. 히어로의 계기판 노릇을 내려놓고
|
||||
본문의 척도로 옮긴다. 눈금과 점만 남긴다.
|
||||
-->
|
||||
<section id="scale" class="section" aria-labelledby="scale-h">
|
||||
<div class="wrap scale-grid">
|
||||
<div class="scale-text">
|
||||
<h2 id="scale-h">같은 척도로 잰<br />향미 좌표</h2>
|
||||
<p>
|
||||
같은 밝기로 볶아도 생두가 머금은 수분과 밀도에 따라 열은 다르게
|
||||
들어갑니다. 그래서 무월은 색이 아니라 1차 팝핑 후 감률과 커핑 점수로
|
||||
로트를 기록합니다.
|
||||
</p>
|
||||
<p class="muted">
|
||||
좌표는 로트마다 다시 측정해 옮겨 적습니다. 지난 로트의 좌표와 지금이
|
||||
같다고 말하지 않습니다.
|
||||
</p>
|
||||
<ul class="scale-legend" aria-label="좌표 범례">
|
||||
<li><span class="key" aria-hidden="true"></span>우라가 G1 워시드</li>
|
||||
<li><span class="key key-b" aria-hidden="true"></span>엘 파라이소 혐기발효</li>
|
||||
<li><span class="key key-c" aria-hidden="true"></span>엘 소코로 마라카투라</li>
|
||||
</ul>
|
||||
</div>
|
||||
<figure class="scale-plot reveal">
|
||||
<svg
|
||||
viewBox="0 0 520 340"
|
||||
role="img"
|
||||
aria-label="산미-바디 2차원 좌표. 우라가는 산미 높음, 엘 파라이소는 단맛 높음, 엘 소코로는 바디 높음."
|
||||
>
|
||||
<!-- 눈금 격자 -->
|
||||
<g class="grid">
|
||||
<line x1="56" y1="40" x2="56" y2="280" />
|
||||
<line x1="56" y1="280" x2="500" y2="280" />
|
||||
<line x1="56" y1="160" x2="500" y2="160" />
|
||||
<line x1="278" y1="40" x2="278" y2="280" />
|
||||
<line x1="167" y1="40" x2="167" y2="280" stroke-dasharray="2 6" />
|
||||
<line x1="389" y1="40" x2="389" y2="280" stroke-dasharray="2 6" />
|
||||
<line x1="56" y1="100" x2="500" y2="100" stroke-dasharray="2 6" />
|
||||
<line x1="56" y1="220" x2="500" y2="220" stroke-dasharray="2 6" />
|
||||
</g>
|
||||
<!-- 축 이름 -->
|
||||
<g class="axis-labels">
|
||||
<text x="56" y="302">산미 →</text>
|
||||
<text x="500" y="302" text-anchor="end">바디 →</text>
|
||||
<text x="46" y="46" text-anchor="end">10.0</text>
|
||||
<text x="46" y="286" text-anchor="end">0</text>
|
||||
</g>
|
||||
<!-- 로트 점 -->
|
||||
<g class="points">
|
||||
<circle cx="140" cy="62" r="5" />
|
||||
<text x="140" y="46" text-anchor="middle">우라가 8.8</text>
|
||||
<circle cx="252" cy="92" r="5" class="pt-b" />
|
||||
<text x="252" y="76" text-anchor="middle">엘 파라이소 9.0</text>
|
||||
<circle cx="430" cy="196" r="5" class="pt-c" />
|
||||
<text x="430" y="180" text-anchor="middle">엘 소코로 8.6</text>
|
||||
</g>
|
||||
</svg>
|
||||
<figcaption>8월 3주차 로트 실측 · 좌표는 주마다 다시 놓입니다</figcaption>
|
||||
</figure>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!--
|
||||
원장 — 이 페이지의 신뢰 장치 (R1: 거래 내역 공개가 이 업종의 스펙).
|
||||
밴드를 살짝 눌러 표가 페이지의 중심임을 알린다.
|
||||
-->
|
||||
<section id="ledger" class="section band" aria-labelledby="ledger-h">
|
||||
<div class="wrap">
|
||||
<div class="ledger-head">
|
||||
<h2 id="ledger-h">생두 매입 원장</h2>
|
||||
<p class="muted">
|
||||
농장에 돌아가는 돈이 얼마인지 보여주는 일이 스페셜티의 조건이라
|
||||
생각합니다. 1kg당 매입가와 가공 방식까지 로트 단위로 남깁니다.
|
||||
</p>
|
||||
</div>
|
||||
<div class="table-wrap reveal">
|
||||
<table>
|
||||
<caption class="sr-only">
|
||||
원두별 생두 매입 원장 — 원두명, 생산자, 가공 방식, 매입가, 커핑 점수
|
||||
</caption>
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col">원두</th>
|
||||
<th scope="col">생산자</th>
|
||||
<th scope="col">가공</th>
|
||||
<th scope="col" class="num">매입가 (FOB/kg)</th>
|
||||
<th scope="col" class="num">커핑</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<th scope="row">에티오피아 구지 우라가</th>
|
||||
<td>하르소 콜루 세척장</td>
|
||||
<td>워시드 · 72시간 발효</td>
|
||||
<td class="num">$14.20</td>
|
||||
<td class="num">88.75</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">콜롬비아 엘 파라이소</th>
|
||||
<td>디에고 사무엘 베르무데스</td>
|
||||
<td>혐기발효 · 열충격 2회</td>
|
||||
<td class="num">$26.50</td>
|
||||
<td class="num">91.20</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th scope="row">과테말라 엘 소코로</th>
|
||||
<td>후안 디에고 데 라 세르다</td>
|
||||
<td>전량 워시드</td>
|
||||
<td class="num">$16.80</td>
|
||||
<td class="num">89.00</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<p class="ledger-note muted">
|
||||
운임·통관·관세는 포함하지 않은 현지 출하가이며, 환율은 매입일 기준입니다.
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!--
|
||||
레시피 — 사진과 사양. 사양은 목록의 주인공이 아니라 사진의 각주다.
|
||||
-->
|
||||
<section id="recipe" class="section" aria-labelledby="recipe-h">
|
||||
<div class="wrap recipe-grid">
|
||||
<figure class="recipe-photo reveal">
|
||||
<img
|
||||
src="./assets/pourover.webp"
|
||||
alt="고핫물이 필터 백에 담긴 도자기 드리퍼로 얇은 물줄기로 들어가는 중"
|
||||
width="900"
|
||||
height="1200"
|
||||
loading="lazy"
|
||||
/>
|
||||
<figcaption>서촌 매장 · 오후 첫 잔</figcaption>
|
||||
</figure>
|
||||
<div class="recipe-text">
|
||||
<h2 id="recipe-h">원두 18g, 물 288g</h2>
|
||||
<p>
|
||||
구독 패키지에는 원두 밀도에 맞춘 분쇄도와 주수 간격을 적은 카드 한 장이
|
||||
들어갑니다. 드립의 변주는 그 다음 문제입니다.
|
||||
</p>
|
||||
<dl class="spec">
|
||||
<div>
|
||||
<dt>물 온도</dt>
|
||||
<dd>93°C</dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt>분쇄도</dt>
|
||||
<dd>코만단테 24딸</dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt>뜸 들이기</dt>
|
||||
<dd>40초 · 물 40g</dd>
|
||||
</div>
|
||||
<div>
|
||||
<dt>주수</dt>
|
||||
<dd>3회 · 116g씩</dd>
|
||||
</div>
|
||||
</dl>
|
||||
<p class="muted">
|
||||
추출 시간은 2분 30초에서 3분 사이가 기준입니다. 그보다 빨리 흘러내리면
|
||||
곱게 갈고, 늦으면 굵게 갑니다.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!--
|
||||
구독 — 회색조에서 가장 어두운 블록. 이 페이지의 유일한 강한 면.
|
||||
(1단계 회색조 위계 계획의 실행: CTA가 1위 덩어리)
|
||||
-->
|
||||
<section id="plan" class="section plan" aria-labelledby="plan-h">
|
||||
<div class="wrap plan-grid">
|
||||
<div class="plan-text">
|
||||
<h2 id="plan-h">격주, 서로 다른 좌표의<br />원두 두 종</h2>
|
||||
<p>
|
||||
2주마다 화요일 아침, 산미형 한 종과 밸런스형 한 종(각 100g)을 볶어
|
||||
보냅니다. 원두는 시음 후 남는 양이 없어 다음 주에 같은 로트를 못 드릴 수
|
||||
있습니다.
|
||||
</p>
|
||||
<ul class="plan-list">
|
||||
<li>원두별 추출 카드 동봉 — 분쇄도·온도·주수</li>
|
||||
<li>아로마 밸브 틴케이스 첫 회 증정</li>
|
||||
<li>출장·휴가 주는 앱에서 건너뛰기</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="plan-box">
|
||||
<p class="plan-price">
|
||||
<span>28,000원</span><span class="plan-unit">회당 · 배송비 포함</span>
|
||||
</p>
|
||||
<a class="btn btn-inverse" href="#plan">격주 구독 시작하기</a>
|
||||
<p class="plan-note">200g(100g×2) · 첫 회는 다음 화요일에 출고됩니다</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<footer class="site-foot">
|
||||
<div class="wrap foot-inner">
|
||||
<p>무월 로스터리 · 서울 종로구 옥인길 18</p>
|
||||
<p class="muted">화요일 로스팅 · 목요일부터 토요일까지 문을 엽니다</p>
|
||||
<p class="muted">roastery@muwol.kr</p>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<script>
|
||||
/* 목요일의 화원과 같은 문법 — 한 번 보이면 유지, 스크롤 이벤트 없음 */
|
||||
const io = new IntersectionObserver(
|
||||
(entries) => {
|
||||
for (const e of entries) {
|
||||
if (!e.isIntersecting) continue;
|
||||
e.target.classList.add("is-in");
|
||||
io.unobserve(e.target);
|
||||
}
|
||||
},
|
||||
{ rootMargin: "0px 0px -8% 0px", threshold: 0.05 },
|
||||
);
|
||||
for (const el of document.querySelectorAll(".reveal")) io.observe(el);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Loading…
Add table
Add a link
Reference in a new issue