@import url("./tokens.css?v=20261006"); /* ========================================================================== 무월 — 타이포 단독 히어로 + 탭 + 연락처 카드 푸터. 레이아웃 → (재질 없음) → 모션 순서로 읽힌다. 이펙트를 전부 꺼도 완성된 페이지다. ========================================================================== */ *, *::before, *::after { box-sizing: border-box; } * { margin: 0; } html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; background: var(--surface); /* Gowun Dodum은 400 하나, Gothic A1은 900 하나만 싣는다. 없는 웨이트·사체를 브라우저가 만들지 않게 한다 */ font-synthesis-weight: none; font-synthesis-style: none; } @media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } } body { background: var(--surface); color: var(--ink); font-family: var(--font-body); font-weight: var(--weight-body); font-size: var(--step-0); line-height: var(--leading-normal); -webkit-font-smoothing: antialiased; word-break: keep-all; overflow-wrap: anywhere; line-break: strict; } :where(h1, h2, h3) { font-family: var(--font-display); font-weight: var(--weight-display); line-height: var(--leading-heading); letter-spacing: -0.01em; text-wrap: balance; } :where(p, li, dd, dt, th, td, figcaption) { text-wrap: pretty; } :lang(ko) :is(em, i, cite, dfn, var, address) { font-style: normal; } :lang(ko) a { text-underline-position: under; } h2 { font-size: var(--step-2); } .muted { color: var(--ink-muted); } a { color: inherit; } :focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; } .skip { position: absolute; left: -9999px; top: 0; background: var(--accent); color: var(--accent-ink); font-family: var(--font-display); font-weight: var(--weight-display); padding: var(--space-3) var(--space-4); z-index: 100; } .skip:focus { left: 0; } .sr-only { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; } .wrap { width: min(100% - 2 * var(--pad-inline), var(--container)); margin-inline: auto; } /* placeholder — 사용자만 아는 값의 자리. 표식은 점선 밑줄 하나다 */ .ph { border-bottom: var(--ph-line); color: var(--ink-muted); } /* ── 헤더: 워드마크 + 한 문장. 고정하지 않는다(화면 서너 개 길이, 바탕이 단색) ─── */ .site-head { border-bottom: 1px solid var(--line); } .head-inner { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-3) var(--space-6); padding-block: var(--space-4); } .wordmark { font-family: var(--font-display); font-weight: var(--weight-display); font-size: 1.5rem; letter-spacing: -0.02em; white-space: nowrap; } .tagline { font-size: var(--step--1); color: var(--ink-muted); max-width: 34em; text-align: right; } /* ── 히어로: 글자만. 원두 이름(h1) → 로스팅 날짜 → 사실 네 개 ──────────────── */ .hero { padding-block: var(--space-8) var(--space-6); } .hero h1 { font-size: var(--step-4); line-height: var(--leading-tight); letter-spacing: -0.03em; max-width: 12em; /* 1440에서 한 줄, 390에서 두 줄. 줄 수를 맞추려고 문구를 줄이지 않는다 */ } .roast-date { font-family: var(--font-display); font-weight: var(--weight-display); font-size: var(--step-3); line-height: var(--leading-tight); letter-spacing: -0.02em; color: var(--accent); margin-top: var(--space-2); } .facts { display: flex; flex-wrap: wrap; gap: var(--space-2) var(--space-6); margin-top: var(--space-6); padding-top: var(--space-4); border-top: 1px solid var(--line); } .facts > div { display: flex; align-items: baseline; gap: var(--space-2); } .facts dt { font-size: var(--step--1); color: var(--ink-muted); } .facts dd { font-family: var(--font-display); font-weight: var(--weight-display); font-size: var(--step-1); font-variant-numeric: tabular-nums; } /* ── 마퀴: 로스팅 날짜. 사본 넷이 -25%(목록 하나 길이)까지 이동해 이어진다 ──────── */ .marquee { border-block: 1px solid var(--line); background: var(--surface-raised); display: grid; grid-template-columns: auto minmax(0, 1fr); align-items: center; } /* 흐름은 가로 스크롤 상자 안에서 돈다 — 기다리지 않고 손·키보드로 넘길 수 있고(A22), 감사 도구도 "스크롤되는 상자 속 넓은 내용"으로 본다 */ .marquee-viewport { overflow-x: auto; overflow-y: hidden; scrollbar-width: none; min-width: 0; } .marquee-viewport::-webkit-scrollbar { display: none; } .marquee-viewport:focus-visible { outline-offset: -3px; } .marquee-track { display: flex; width: max-content; animation: marquee var(--marquee-dur) linear infinite; } .marquee-track.is-paused, .marquee:focus-within .marquee-track { animation-play-state: paused; } .marquee-list { display: flex; flex: 0 0 auto; list-style: none; margin: 0; padding: var(--space-3) 0; font-family: var(--font-display); font-weight: var(--weight-display); font-size: var(--step-1); white-space: nowrap; } .marquee-list li { padding-inline: var(--space-5); position: relative; } .marquee-list li::before { content: ""; position: absolute; left: -4px; top: 50%; width: 8px; height: 8px; border-radius: 50%; background: var(--accent); translate: 0 -50%; } /* 정지 버튼은 흐름 앞(왼쪽)에 둔다 — 탭 순서가 "멈춤 → 목록"이고, 흐르는 글자가 화면 왼쪽 가장자리에 붙지 않는다 */ .marquee-toggle { min-width: 44px; min-height: 44px; margin-inline: var(--pad-inline) var(--space-3); padding: 0 var(--space-3); border: 1px solid var(--line-strong); border-radius: var(--radius); background: var(--surface); color: var(--ink); font: inherit; font-size: var(--step--1); cursor: pointer; } .marquee-toggle:hover { border-color: var(--accent); } @keyframes marquee { from { transform: translateX(0); } to { transform: translateX(-25%); /* 사본 넷 가운데 하나 길이 */ } } /* 감소 모션: 움직이지 않는 목록. 폭이 모자라면 줄을 바꾼다 */ @media (prefers-reduced-motion: reduce) { .marquee { grid-template-columns: minmax(0, 1fr); } .marquee-viewport { padding-inline: var(--pad-inline); } .marquee-track { animation: none; width: auto; } .marquee-list { flex: 1 1 auto; flex-wrap: wrap; white-space: normal; gap: var(--space-2) var(--space-5); } .marquee-list li { padding-inline: 0; } .marquee-list li::before { display: none; } .marquee-list[aria-hidden="true"], .marquee-toggle { display: none; } } /* ── 탭: 원두 / 구독 / 매장. 같은 로스터리의 보기 전환이지 페이지 이동이 아니다 ── */ .tabs { border-bottom: 1px solid var(--line); } .tablist { display: flex; gap: var(--space-5); overflow-x: auto; scrollbar-width: none; } .tablist a { display: inline-flex; align-items: center; min-height: 56px; padding: var(--space-2) 0; font-family: var(--font-display); font-weight: var(--weight-display); font-size: var(--step-1); text-decoration: none; color: var(--ink-muted); border-bottom: 3px solid transparent; margin-bottom: -1px; white-space: nowrap; transition: color var(--dur-quick) ease-out, border-color var(--dur-quick) ease-out; } .tablist a:hover { color: var(--ink); } .tablist a[aria-selected="true"] { color: var(--ink); border-color: var(--accent); } .tablist a:focus-visible { outline-offset: -2px; } .panel { padding-block: var(--space-7); } /* JS가 있을 때만 hidden 패널을 숨긴다. 없으면 셋이 다 보여 앵커 링크로 이동한다 */ html:not(.js) .panel[hidden] { display: block; } .panel[id] { scroll-margin-top: var(--space-5); } /* ── 원두: 차트 + 원형 사진 / 생두 기록 표 ─────────────────────────────── */ .scale-grid, .plan-grid, .recipe-grid { display: grid; gap: var(--space-6) var(--space-7); align-items: start; } .scale-grid > *, .plan-grid > *, .recipe-grid > * { min-width: 0; } .scale-grid { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); } .scale-text p, .recipe-text p, .plan-text p { max-width: var(--measure); } .panel h2 + p, .panel p + p, .spec + p { margin-top: var(--space-3); } .scale-legend { list-style: none; padding: 0; margin-top: var(--space-4); display: flex; flex-wrap: wrap; gap: var(--space-2) var(--space-4); font-size: var(--step--1); color: var(--ink-muted); } .key { display: inline-block; width: 8px; height: 8px; border-radius: 50%; background: var(--ink); margin-right: var(--space-2); vertical-align: baseline; } .key-b { background: var(--accent); } .key-c { background: var(--ink-faint); } /* 원형 크롭 — 피사체(그릇·드리퍼)가 중앙에 있어 clip 없이 object-position으로 맞춘다 */ .photo { margin-top: var(--space-5); display: grid; gap: var(--space-2); justify-items: start; } .photo img { display: block; width: var(--photo); height: var(--photo); border-radius: 50%; object-fit: cover; object-position: 50% 42%; } .photo-pour img { object-position: 50% 58%; } .photo figcaption, .scale-plot figcaption { font-size: var(--step--1); color: var(--ink-faint); } .scale-plot { padding: clamp(1rem, 3vw, 2rem); border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface-raised); } .scale-plot svg { display: block; width: 100%; height: auto; } .scale-plot .grid line { stroke: var(--line-strong); stroke-width: 1; } .scale-plot .grid line:first-child, .scale-plot .grid line:nth-child(2) { stroke: var(--ink-faint); stroke-width: 1.25; } .axis-labels text, .points text { font-family: var(--font-body); font-size: 15px; fill: var(--ink-muted); } .points circle { fill: var(--ink); } .points .pt-b { fill: var(--accent); } .points .pt-c { fill: var(--ink-faint); } .plot-note { margin-bottom: var(--space-3); color: var(--ink-muted); font-size: var(--step--1); } .scale-plot figcaption { margin-top: var(--space-2); } .ledger { margin-top: var(--space-7); padding-top: var(--space-6); border-top: 1px solid var(--line); } .ledger-head { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: var(--space-3) var(--space-6); align-items: end; margin-bottom: var(--space-5); } .ledger-head p { max-width: var(--measure); } .table-wrap { overflow-x: auto; border: 1px solid var(--line); border-radius: var(--radius); } /* 좁은 폭에서는 열을 쥐어짜지 않고 상자 안에서 가로로 민다(typography §6-5 표 셀 예외: anywhere 대신 break-word) */ table { width: 100%; min-width: 42rem; border-collapse: collapse; font-size: var(--step-0); overflow-wrap: break-word; } thead th { text-align: left; font-weight: inherit; font-size: var(--step--1); color: var(--ink-muted); padding: var(--space-2) var(--space-3); border-bottom: 1px solid var(--line-strong); white-space: nowrap; } tbody th { text-align: left; font-family: var(--font-display); font-weight: var(--weight-display); } tbody td, tbody th { padding: var(--space-3); border-bottom: 1px solid var(--line); vertical-align: baseline; } tbody tr:last-child :is(td, th) { border-bottom: 0; } .num { font-family: var(--font-display); font-weight: var(--weight-display); font-variant-numeric: tabular-nums; text-align: right; white-space: nowrap; } .date { white-space: nowrap; } .table-wrap:focus-visible { outline-offset: -3px; } thead .num { font-family: var(--font-body); font-weight: inherit; } /* ── 구독 ──────────────────────────────────────────────────────────────── */ .plan-grid { grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); } .plan-list { margin-top: var(--space-4); padding: 0; list-style: none; max-width: var(--measure); } .plan-list li { padding-left: 1.25em; position: relative; } .plan-list li::before { content: ""; position: absolute; left: 0; top: 0.78em; width: 8px; height: 2px; background: var(--accent); } .plan-list li + li { margin-top: var(--space-2); } .plan-box { border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface-raised); padding: var(--space-5); display: grid; gap: var(--space-4); } .plan-amount { display: block; font-family: var(--font-display); font-weight: var(--weight-display); font-size: var(--step-3); line-height: var(--leading-tight); letter-spacing: -0.02em; } .plan-unit { display: block; font-size: var(--step--1); margin-top: var(--space-2); color: var(--ink-muted); } .plan-spec div, .spec div, .contact-card div { display: grid; grid-template-columns: 6em minmax(0, 1fr); gap: var(--space-3); align-items: baseline; } .plan-spec div + div, .spec div + div, .contact-card div + div { margin-top: var(--space-2); } .plan-spec dt, .spec dt, .contact-card dt { font-size: var(--step--1); color: var(--ink-muted); } .plan-note { font-size: var(--step--1); color: var(--ink-muted); } /* ── 매장: 원형 사진 + 레시피 ─────────────────────────────────────────── */ .recipe-grid { grid-template-columns: minmax(0, 4fr) minmax(0, 8fr); } .recipe-grid .photo { margin-top: 0; } .spec { margin-top: var(--space-4); max-width: var(--measure); } .spec dd { font-family: var(--font-display); font-weight: var(--weight-display); font-size: var(--step-1); font-variant-numeric: tabular-nums; } .recipe-text p:last-child { margin-top: var(--space-4); } .plan-side { display: grid; gap: var(--space-5); } .plan-side .photo { margin-top: 0; } .inline-link { color: var(--accent); text-decoration-thickness: 1px; text-underline-offset: 0.2em; } .inline-link:hover { color: var(--accent-hover); } /* ── 푸터: 연락처·영업시간 카드 ────────────────────────────────────────── */ .site-foot { border-top: 1px solid var(--line); background: var(--surface-sunken); padding-block: var(--space-7); } .contact-card { margin-top: var(--space-5); padding: var(--space-5); border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface-raised); max-width: 40em; } .contact-card dd { font-family: var(--font-display); font-weight: var(--weight-display); font-size: var(--step-1); } .foot-note { margin-top: var(--space-5); font-size: var(--step--1); color: var(--ink-muted); max-width: var(--measure); } /* ── 모션: 첫 화면 스태거 등장(로드 1회, 시간 기반). 스크롤 리빌은 없다 ─────── */ @keyframes rise-in { from { opacity: 0; translate: 0 var(--rise-shift); } to { opacity: 1; translate: 0 0; } } .rise { animation: rise-in var(--dur-rise) var(--ease-out) both; animation-delay: calc(var(--i, 0) * var(--stagger)); } @media (prefers-reduced-motion: reduce) { .rise { animation: none; } } /* ── 반응형 ───────────────────────────────────────────────────────────── */ @media (max-width: 900px) { .scale-grid, .plan-grid, .recipe-grid, .ledger-head { grid-template-columns: 1fr; gap: var(--space-5); } .ledger-head { gap: var(--space-3); } .head-inner { flex-direction: column; align-items: flex-start; gap: var(--space-2); } .tagline { text-align: left; } .panel { padding-block: var(--space-6); } } @media (max-width: 560px) { .hero { padding-block: var(--space-6) var(--space-5); } .facts { gap: var(--space-2) var(--space-4); } .tablist { gap: var(--space-4); } .plan-box, .contact-card { padding: var(--space-4); } .plan-spec div, .spec div, .contact-card div { grid-template-columns: 1fr; gap: var(--space-1); } } @media (min-width: 120rem) { .scale-grid, .plan-grid, .recipe-grid { gap: var(--space-6) var(--space-8); } }