designpaca/apps/site/public/work/cask-archive/index.html
Yun Chan 8e3cdb0d3b
Some checks are pending
ci / build (push) Waiting to run
feat(site): rework 19 marketing showcases for composition diversity
Measured convergence before: split hero 13/19, top-bar nav 19/19,
one-line notice footer 14/19, body Pretendard 17/21, 10 similarity
pairs above 0.78. Each showcase got a pre-assigned hero family, nav
form, footer form, type pair, background, accent hue, radius, motion
grammar and material from outputs/rework-2026-10-06/plan.md; direction
cards and the chosen reason are recorded in every design.md.

After: 0 similarity warnings, 19 distinct display faces, 7 hero
families, 5 nav forms, 5 footer forms, no scroll reveals, 5 showcases
with SVG filter materials. Example contact values replace bracket
placeholders under the existing fictional-brand notices. Thumbnails,
OG images, card copy and three e2e assertions updated; dead CSS in
dure-enrollment and hannam-jari removed; similarity.mjs learns the new
font families.
2026-10-06 16:55:50 +09:00

490 lines
26 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!doctype html>
<html lang="ko">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
<title>캐스크 아카이브 — 독립병입 싱글 캐스크 5통</title>
<meta
name="description"
content="독립병입 싱글 캐스크 위스키 5통의 캐스크 번호, 숙성 배럴과 연수, 도수, 병 수를 번호 순으로 적은 가상 위스키 바 안내. 도슨트 1:1 시음 코스와 시음회 일정을 함께 싣습니다."
/>
<meta property="og:title" content="캐스크 아카이브 — 독립병입 싱글 캐스크 5통" />
<meta property="og:description" content="캐스크 번호, 숙성 배럴과 연수, 도수, 병 수를 번호 순으로 적은 독립병입 위스키 바 안내." />
<meta property="og:type" content="website" />
<meta property="og:image" content="https://designpaca.chanpaca.net/work/cask-archive/assets/whisky-hero.webp" />
<meta property="og:image:alt" content="그을린 오크 배럴 상판 위에 놓인 싱글 캐스크 위스키 한 병과 테이스팅 글라스" />
<meta name="twitter:card" content="summary_large_image" />
<meta name="theme-color" content="#1a1512" />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
rel="stylesheet"
href="https://fonts.googleapis.com/css2?family=IBM+Plex+Sans+KR:wght@400;600&family=Nanum+Myeongjo:wght@400;700&display=swap"
/>
<link rel="stylesheet" href="./styles/main.css?v=20261006" />
<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' rx='2' fill='%231A1512'/%3E%3Ccircle cx='16' cy='16' r='10' stroke='%23D18147' stroke-width='2' fill='none'/%3E%3Cpath d='M16 8v16M8 16h16' stroke='%23D18147' stroke-width='1.5'/%3E%3C/svg%3E"
/>
</head>
<body>
<a class="skip-link" href="#mainContent">본문으로 건너뛰기</a>
<div class="shell">
<!-- 측면 색인 — 두 페이지가 같은 셸을 쓴다 -->
<header class="index">
<a class="wordmark" href="./index.html" aria-label="캐스크 아카이브 홈">
캐스크 아카이브
<span class="wordmark-sub">독립병입 위스키 바, 한남동</span>
</a>
<details class="toc" open>
<summary></summary>
<nav aria-label="차례">
<ol>
<li><a href="#ledger">캐스크 목록</a></li>
<li><a href="#bottlers">병입자</a></li>
<li><a href="#docent">도슨트 세션</a></li>
<li><a href="#events">시음회 일정</a></li>
<li><a href="#subscribe">입고 알림</a></li>
<li><a href="./docent/index.html">도슨트 상세 페이지</a></li>
</ol>
</nav>
</details>
<div class="index-foot">
<p>캐스크 5통, 코스 2개, 9월 시음회 2회</p>
<a href="#docent" class="btn-outline">도슨트 세션 고르기</a>
</div>
</header>
<main id="mainContent" class="content">
<!-- 첫 화면: 캐스크 번호 목록 -->
<section class="section" id="ledger" aria-labelledby="ledgerHeading">
<div class="ledger-head">
<h1 id="ledgerHeading">독립병입 싱글 캐스크 5통, 도슨트와 1:1로 시음합니다</h1>
<p>행 끝의 병입 정보 버튼을 누르면 통관 번호까지 보입니다.</p>
</div>
<div class="ledger-filter-bar">
<div class="filter-btn-group" role="group" aria-label="캐스크 분류">
<button type="button" class="filter-btn is-active" data-filter="all">전체 5통</button>
<button type="button" class="filter-btn" data-filter="sherry">셰리 캐스크</button>
<button type="button" class="filter-btn" data-filter="peat">피트</button>
<button type="button" class="filter-btn" data-filter="bourbon">버번 배럴</button>
<button type="button" class="filter-btn" data-filter="cs">캐스크 스트렝스</button>
</div>
<input
type="search"
id="caskSearch"
class="search-input"
placeholder="증류소 또는 캐스크 번호"
aria-label="캐스크 검색"
/>
</div>
<div class="ledger-table-wrap">
<table class="ledger-table">
<thead>
<tr>
<th scope="col">번호</th>
<th scope="col">증류소</th>
<th scope="col">병입자</th>
<th scope="col">배럴, 연수</th>
<th scope="col">도수</th>
<th scope="col">병 수</th>
<th scope="col">향미</th>
<th scope="col"><span class="sr-only">병입 정보</span></th>
</tr>
</thead>
<tbody id="caskTableBody">
<tr data-cat="sherry cs" id="cask-6512">
<td class="cask-no num">#6512</td>
<td class="distillery" data-label="증류소"><span class="cask-name">Clynelish 1996</span><span class="cask-sub">하이랜드, 왁시한 꿀과 린덴</span></td>
<td class="bottler" data-label="병입자">Signatory Vintage</td>
<td class="cask-type" data-label="배럴, 연수">1st Fill Sherry Butt, 24년</td>
<td class="abv num" data-label="도수">54.2%</td>
<td class="bottles num" data-label="병 수">180병</td>
<td class="notes" data-label="향미">말린 무화과, 밀랍, 시나몬, 다크초콜릿</td>
<td class="act"><button type="button" class="btn-outline" data-cert data-name="Clynelish 1996 #6512" data-bottler="Signatory Vintage" data-age="24년 (1996 증류, 2020 병입)" data-abv="54.2% 캐스크 스트렝스" data-customs="식약처 정식통관 제2024-IB-0982호">병입 정보</button></td>
</tr>
<tr data-cat="peat cs" id="cask-29-281">
<td class="cask-no num">#29.281</td>
<td class="distillery" data-label="증류소"><span class="cask-name">Laphroaig 2005</span><span class="cask-sub">아일라, 약용 피트와 해풍</span></td>
<td class="bottler" data-label="병입자">SMWS</td>
<td class="cask-type" data-label="배럴, 연수">1st Fill Ex-Bourbon, 15년</td>
<td class="abv num" data-label="도수">57.8%</td>
<td class="bottles num" data-label="병 수">214병</td>
<td class="notes" data-label="향미">모닥불 연기, 바다 소금, 레몬 제스트, 피트 45ppm</td>
<td class="act"><button type="button" class="btn-outline" data-cert data-name="Laphroaig 2005 (SMWS 29.281)" data-bottler="The Scotch Malt Whisky Society" data-age="15년 (2005 증류)" data-abv="57.8% 캐스크 스트렝스" data-customs="식약처 정식통관 제2025-IB-1102호">병입 정보</button></td>
</tr>
<tr data-cat="sherry" id="cask-93-41">
<td class="cask-no num">#93/41</td>
<td class="distillery" data-label="증류소"><span class="cask-name">Springbank 1993</span><span class="cask-sub">캠벨타운, 미네랄과 오일</span></td>
<td class="bottler" data-label="병입자">Gordon &amp; MacPhail</td>
<td class="cask-type" data-label="배럴, 연수">Refill Sherry Hogshead, 27년</td>
<td class="abv num" data-label="도수">51.6%</td>
<td class="bottles num" data-label="병 수">142병</td>
<td class="notes" data-label="향미">열대 과일 잼, 가죽, 부드러운 유황, 정향</td>
<td class="act"><button type="button" class="btn-outline" data-cert data-name="Springbank 1993 #93/41" data-bottler="Gordon &amp; MacPhail Reserve" data-age="27년 (1993 증류)" data-abv="51.6%" data-customs="식약처 정식통관 제2024-IB-0419호">병입 정보</button></td>
</tr>
<tr data-cat="peat cs" id="cask-px-88">
<td class="cask-no num">#PX-88</td>
<td class="distillery" data-label="증류소"><span class="cask-name">Caol Ila 2008</span><span class="cask-sub">아일라, 달콤한 훈연</span></td>
<td class="bottler" data-label="병입자">Cadenhead's</td>
<td class="cask-type" data-label="배럴, 연수">Pedro Ximenez Finish, 14년</td>
<td class="abv num" data-label="도수">56.4%</td>
<td class="bottles num" data-label="병 수">260병</td>
<td class="notes" data-label="향미">스모크 베이컨, 건포도, 블랙베리, 훈제 파프리카</td>
<td class="act"><button type="button" class="btn-outline" data-cert data-name="Caol Ila 2008 #PX-88" data-bottler="Cadenhead's Authentic Collection" data-age="14년" data-abv="56.4% 캐스크 스트렝스" data-customs="식약처 정식통관 제2025-IB-0831호">병입 정보</button></td>
</tr>
<tr data-cat="bourbon cs" id="cask-98-12">
<td class="cask-no num">#98/12</td>
<td class="distillery" data-label="증류소"><span class="cask-name">Ben Nevis 1998</span><span class="cask-sub">서부 하이랜드, 묵직한 바디</span></td>
<td class="bottler" data-label="병입자">Adelphi Distillery</td>
<td class="cask-type" data-label="배럴, 연수">Ex-Bourbon Cask, 22년</td>
<td class="abv num" data-label="도수">58.1%</td>
<td class="bottles num" data-label="병 수">195병</td>
<td class="notes" data-label="향미">바닐라 커스터드, 구운 코코넛, 청사과, 후추</td>
<td class="act"><button type="button" class="btn-outline" data-cert data-name="Ben Nevis 1998 #98/12" data-bottler="Adelphi Selection" data-age="22년" data-abv="58.1%" data-customs="식약처 정식통관 제2024-IB-0771호">병입 정보</button></td>
</tr>
</tbody>
</table>
</div>
</section>
<!-- 병입자 -->
<section class="section" id="bottlers" aria-labelledby="bottlersHeading">
<div class="section-head">
<h2 id="bottlersHeading">병입자 네 곳의 라벨 정보를 그대로 옮겨 적습니다</h2>
<p>캐스크 번호, 숙성 배럴, 연수, 도수는 병 라벨에 적힌 값입니다. 향미는 도슨트가 시음한 메모입니다.</p>
</div>
<div class="two-col">
<figure class="figure-aside is-portrait">
<img
src="./assets/whisky-hero.webp"
alt="그을린 오크 배럴 상판 위에 놓인 싱글 캐스크 위스키 한 병과 테이스팅 글라스"
width="896"
height="1200"
loading="eager"
fetchpriority="high"
/>
<figcaption>
<strong>#8821, 58.4%</strong>
<span>Signatory Vintage 1997</span>
<span>186병 가운데 42번째 병</span>
<span>사진은 896×1200 원본 비율 그대로입니다.</span>
</figcaption>
</figure>
<ul class="bottler-list">
<li>
<strong>Gordon &amp; MacPhail</strong>
<p>라벨의 병입자 정보를 목록에 함께 적습니다.</p>
</li>
<li>
<strong>Signatory Vintage</strong>
<p>숙성 배럴, 연수, 도수를 한 줄에 적습니다.</p>
</li>
<li>
<strong>The Scotch Malt Whisky Society</strong>
<p>캐스크 번호별 향미 메모를 싣습니다.</p>
</li>
<li>
<strong>Cadenhead's</strong>
<p>1842년 설립, 스코틀랜드에서 가장 오래된 독립병입자입니다.</p>
</li>
</ul>
</div>
</section>
<!-- 도슨트 세션 -->
<section class="section" id="docent" aria-labelledby="docentHeading">
<div class="section-head">
<h2 id="docentHeading">도슨트 한 명이 한 팀만 맡아 3잔 또는 5잔을 설명합니다</h2>
<p>좋아하는 향을 먼저 여쭙고, 그에 맞는 캐스크를 골라 잔마다 숙성 배럴과 도수의 차이를 짚습니다. 자세한 라인업은 <a href="./docent/index.html">도슨트 상세 페이지</a>에 있습니다.</p>
</div>
<div class="two-col">
<ul class="course-list">
<li class="course-card">
<div class="course-header">
<h3 class="course-title">코스 A. 독립병입자 입문 플라이트, 3잔</h3>
<span class="course-price">65,000원</span>
</div>
<p>같은 증류소의 오피셜 보틀과 독립병입 싱글 캐스크를 나란히 마셔 보며 숙성 배럴에 따른 차이를 비교합니다.</p>
<ul class="course-meta">
<li>45분</li>
<li>도슨트 1:1</li>
<li>글렌캐런 글라스</li>
</ul>
</li>
<li class="course-card">
<div class="course-header">
<h3 class="course-title">코스 B. 캐스크 스트렝스와 빈티지 플라이트, 5잔</h3>
<span class="course-price">120,000원</span>
</div>
<p>1990년대 빈티지와 도수 55% 이상 캐스크 스트렝스 5종을 테이스팅 휠로 하나씩 짚어 보는 심화 코스입니다.</p>
<ul class="course-meta">
<li>75분</li>
<li>수제 초콜릿과 샤퀴테리 페어링</li>
</ul>
</li>
</ul>
<div class="form-panel">
<h3>도슨트 세션 선택</h3>
<form id="docentForm" onsubmit="return false;">
<div class="form-group">
<label class="form-label" for="bookingCourse">코스</label>
<select id="bookingCourse" name="bookingCourse" class="form-input">
<option value="A">코스 A. 입문 플라이트 3잔 (65,000원)</option>
<option value="B" selected>코스 B. 캐스크 스트렝스 플라이트 5잔 (120,000원)</option>
</select>
</div>
<div class="form-group">
<label class="form-label" for="bookingTime">시간</label>
<select id="bookingTime" name="bookingTime" class="form-input">
<option>19:00 (1부)</option>
<option selected>20:30 (2부)</option>
<option>22:00 (3부 심야)</option>
</select>
</div>
<div class="form-group">
<label class="form-label" for="bookingDate">날짜</label>
<input type="date" id="bookingDate" name="bookingDate" autocomplete="off" class="form-input" />
</div>
<div class="form-group">
<label class="form-label" for="guestName">이름</label>
<input type="text" id="guestName" name="guestName" autocomplete="name" class="form-input" required />
</div>
<div class="form-group">
<label class="form-label" for="guestPhone">연락처</label>
<input type="tel" id="guestPhone" name="guestPhone" autocomplete="tel" class="form-input" required />
</div>
<div class="form-group">
<label class="form-label" for="guestPref">좋아하는 향 (선택)</label>
<input type="text" id="guestPref" name="guestPreference" autocomplete="off" class="form-input" placeholder="예: 셰리, 피트" />
</div>
<button type="button" class="btn-fill" id="btnBookDocent">선택한 세션 내용 확인</button>
</form>
<p class="demo-notice" role="note">가상 브랜드 쇼케이스입니다. 입력 정보는 저장하거나 전송하지 않으며 실제 예약으로 이어지지 않습니다.</p>
</div>
</div>
</section>
<!-- 시음회 일정 -->
<section class="section" id="events" aria-labelledby="eventHeading">
<div class="section-head">
<h2 id="eventHeading">9월 12일과 26일 저녁에 시음회를 엽니다</h2>
<p>매달 새로 들어오는 독립병입 캐스크로 시음회를 엽니다. 정원은 회마다 8명입니다.</p>
</div>
<ul class="event-list">
<li class="event-item">
<div class="event-date">9월 12일<small>금요일 20:00</small></div>
<div>
<h3>1990년대 올드 셰리 버트 4종 버티컬 시음회</h3>
<p>Signatory와 Gordon &amp; MacPhail의 90년대 빈티지 셰리 캐스크 4종을 비교합니다.</p>
</div>
</li>
<li class="event-item">
<div class="event-date">9월 26일<small>토요일 21:00</small></div>
<div>
<h3>옥토모어와 아일라 피트 위스키 심야 시음회</h3>
<p>페놀 수치 80ppm 이상, 피트 향이 강한 독립병입 위스키를 블라인드로 마십니다.</p>
</div>
</li>
</ul>
<div class="newsletter" id="subscribe">
<h3>새 캐스크가 들어오면 이메일로 알립니다</h3>
<p>입고 소식과 시음회 일정만 보냅니다.</p>
<form class="newsletter-form" onsubmit="return false;">
<label class="sr-only" for="newsEmail">이메일 주소</label>
<input
type="email"
id="newsEmail"
name="newsletterEmail"
autocomplete="email"
class="form-input"
placeholder="이메일 주소"
required
/>
<button type="button" class="btn-fill" id="btnSubscribe">입력 내용 확인</button>
</form>
<p class="demo-notice" role="note">이메일은 이 화면에 저장되지 않으며 실제 구독으로 등록되지 않습니다.</p>
</div>
</section>
</main>
<!-- 푸터: 다열 색인 -->
<footer class="site-foot">
<div class="foot-grid">
<div>
<h2>차례</h2>
<ul>
<li><a href="#ledger">캐스크 목록</a></li>
<li><a href="#bottlers">병입자</a></li>
<li><a href="#docent">도슨트 세션</a></li>
<li><a href="#events">시음회 일정</a></li>
<li><a href="#subscribe">입고 알림</a></li>
</ul>
</div>
<div>
<h2>캐스크 번호</h2>
<ul>
<li><a href="#cask-6512">#6512 Clynelish 1996</a></li>
<li><a href="#cask-29-281">#29.281 Laphroaig 2005</a></li>
<li><a href="#cask-93-41">#93/41 Springbank 1993</a></li>
<li><a href="#cask-px-88">#PX-88 Caol Ila 2008</a></li>
<li><a href="#cask-98-12">#98/12 Ben Nevis 1998</a></li>
</ul>
</div>
<div>
<h2>도슨트</h2>
<ul>
<li><a href="./docent/index.html#courses">코스 A, 3잔 65,000원</a></li>
<li><a href="./docent/index.html#courses">코스 B, 5잔 120,000원</a></li>
<li><a href="./docent/index.html#aroma">향 계열 네 가지</a></li>
<li><a href="./docent/index.html#pairing">페어링 플레이트</a></li>
<li><a href="./docent/index.html#reservation-section">세션 선택</a></li>
</ul>
</div>
<div>
<h2>찾아오기</h2>
<p>캐스크 룸, 서울 한남동 한남 27길</p>
<p>1부 19:00, 2부 20:30, 3부 22:00</p>
<p>한 세션 최대 2인</p>
</div>
</div>
<p class="foot-note">캐스크 아카이브는 가상 브랜드 쇼케이스입니다. 캐스크 정보, 통관 번호, 가격, 세션은 예시이며 입력 정보는 저장하거나 전송하지 않습니다.</p>
</footer>
</div>
<!-- 병입 정보 모달 -->
<dialog id="certModal" class="cert-dialog" aria-labelledby="certTitle">
<div class="cert-head">
<h3 id="certTitle">병입 정보</h3>
<button type="button" class="cert-close" data-close aria-label="닫기">닫기</button>
</div>
<dl class="cert-list">
<dt>증류소</dt>
<dd id="mWhiskyName"></dd>
<dt>병입자</dt>
<dd id="mBottler"></dd>
<dt>숙성</dt>
<dd id="mAge"></dd>
<dt>도수</dt>
<dd id="mAbv"></dd>
<dt>통관 번호</dt>
<dd id="mCustoms"></dd>
</dl>
<div class="cert-foot">
<button type="button" class="btn-fill" data-close>확인</button>
</div>
</dialog>
<script>
(function () {
// 1. 캐스크 목록 검색·분류
const filterBtns = document.querySelectorAll(".filter-btn");
const searchInput = document.getElementById("caskSearch");
const rows = document.querySelectorAll("#caskTableBody tr");
function filterLedger() {
const activeFilter = document.querySelector(".filter-btn.is-active")?.getAttribute("data-filter") || "all";
const query = searchInput.value.toLowerCase().trim();
rows.forEach((row) => {
const cat = row.getAttribute("data-cat") || "";
const text = row.textContent.toLowerCase();
const matchCat = activeFilter === "all" || cat.includes(activeFilter);
const matchQuery = !query || text.includes(query);
row.style.display = matchCat && matchQuery ? "" : "none";
});
}
filterBtns.forEach((btn) => {
btn.addEventListener("click", () => {
filterBtns.forEach((b) => {
b.classList.remove("is-active");
b.removeAttribute("aria-pressed");
});
btn.classList.add("is-active");
btn.setAttribute("aria-pressed", "true");
filterLedger();
});
});
if (searchInput) searchInput.addEventListener("input", filterLedger);
// 2. 병입 정보 모달
const modal = document.getElementById("certModal");
document.querySelectorAll("[data-cert]").forEach((btn) => {
btn.addEventListener("click", () => {
document.getElementById("mWhiskyName").textContent = btn.dataset.name;
document.getElementById("mBottler").textContent = btn.dataset.bottler;
document.getElementById("mAge").textContent = btn.dataset.age;
document.getElementById("mAbv").textContent = btn.dataset.abv;
document.getElementById("mCustoms").textContent = btn.dataset.customs;
modal.showModal();
});
});
modal.querySelectorAll("[data-close]").forEach((btn) => btn.addEventListener("click", () => modal.close()));
// 3. 도슨트 세션 선택
const btnBook = document.getElementById("btnBookDocent");
if (btnBook) {
btnBook.addEventListener("click", () => {
const name = document.getElementById("guestName").value || "고객님";
const course = document.getElementById("bookingCourse").value;
alert(`${name}님이 선택한 도슨트 세션(코스 ${course})을 확인했습니다.\n실제 예약은 접수되지 않았으며 입력 정보는 저장하거나 전송하지 않습니다.`);
});
}
// 4. 입고 알림
const btnSub = document.getElementById("btnSubscribe");
if (btnSub) {
btnSub.addEventListener("click", () => {
const field = document.getElementById("newsEmail");
if (!field.value || !field.value.includes("@")) {
alert("이메일 주소를 정확히 입력해 주세요.");
return;
}
alert(`${field.value} 주소는 이 화면에 저장되지 않으며 실제 구독으로 등록되지 않습니다.`);
field.value = "";
});
}
// 5. 측면 색인 — 좁은 화면에서는 접고, 현재 위치를 표시한다(모션 없음)
const toc = document.querySelector(".toc");
const narrow = window.matchMedia("(max-width: 1023px)");
const syncToc = () => { toc.open = !narrow.matches; };
syncToc();
narrow.addEventListener("change", syncToc);
toc.querySelectorAll("a[href^='#']").forEach((a) => a.addEventListener("click", () => { if (narrow.matches) toc.open = false; }));
const links = [...toc.querySelectorAll("a[href^='#']")];
const targets = links.map((a) => document.querySelector(a.getAttribute("href"))).filter(Boolean);
if ("IntersectionObserver" in window && targets.length) {
const io = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (!entry.isIntersecting) return;
links.forEach((a) => a.removeAttribute("aria-current"));
const link = links.find((a) => a.getAttribute("href") === `#${entry.target.id}`);
if (link) link.setAttribute("aria-current", "true");
});
}, { rootMargin: "-20% 0px -70% 0px" });
targets.forEach((t) => io.observe(t));
}
})();
</script>
</body>
</html>