/* Densetsu sample — structure shared by all three directions. Each direction's theme.css sets the tokens, the
   fonts and where the text sits on each photo plate (desktop). Layout concept: one photo plate per scene;
   ≥1024px the text floats in the plate's quiet area, below that the text follows the picture. */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-padding-top: 76px; background: var(--bg); }
body { margin: 0; background: var(--bg); color: var(--fg); font: 400 1rem/1.6 var(--sans); -webkit-font-smoothing: antialiased; }
img { display: block; max-width: 100%; height: auto; }
a { color: inherit; }
a:focus-visible, button:focus-visible { outline: 2px solid var(--focus); outline-offset: 3px; }
p { margin: 0; }

.skip { position: absolute; left: 16px; top: -80px; z-index: 20; padding: 12px 16px; background: var(--fg); color: var(--bg); text-decoration: none; }
.skip:focus { top: 12px; }

/* Header: transparent over the first plate, the page colour once the page moves. */
.site-header {
  position: fixed; inset: 0 0 auto 0; z-index: 10;
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  padding: calc(env(safe-area-inset-top, 0px) + 12px) clamp(16px, 5.5vw, 84px) 12px;
  transition: background-color .5s ease, color .4s ease;
}
.site-header.is-scrolled { background: var(--bar); }
/* Below the overlay layout the pictures run to the top edge, so the bar always carries the page colour. */
@media (max-width: 1023px) { .site-header { background: var(--bar); } }
.brand { display: inline-flex; align-items: center; gap: 12px; min-height: 44px; text-decoration: none; }
.brand img { width: 30px; height: 30px; }
.word { font: var(--word-font); letter-spacing: .34em; text-transform: uppercase; }
.nav { display: flex; align-items: center; gap: clamp(14px, 2.6vw, 38px); }
.nav-link { display: inline-flex; align-items: center; min-height: 44px; font-size: .9rem; text-decoration: none; }
.nav-link:hover { text-decoration: underline; text-underline-offset: 6px; }

.btn {
  display: inline-flex; align-items: center; justify-content: center; min-height: 46px; padding: 0 24px;
  font: 500 .9rem/1 var(--sans); letter-spacing: .01em; text-decoration: none;
  border-radius: var(--radius); background: var(--btn-bg); color: var(--btn-fg); transition: filter .2s ease;
}
.btn:hover { filter: brightness(1.08); }
.btn-sm { min-height: 44px; padding: 0 18px; font-size: .85rem; }
.text-link { display: inline-flex; align-items: center; gap: .55em; min-height: 44px; font-size: .92rem; text-decoration: none; }
.text-link span { border-bottom: 1px solid currentColor; padding-bottom: 3px; }
.text-link::after { content: "→"; }
.text-link:hover span { border-bottom-width: 2px; }

/* Scenes */
.scene { position: relative; background: var(--bg); }
.stage { position: relative; }
.plate { position: relative; display: block; overflow: hidden; }
.plate img { width: 100%; height: auto; }
.copy { padding: 30px clamp(20px, 6vw, 48px) 64px; max-width: 36rem; }
.label { margin-bottom: 14px; font: 500 .7rem/1.4 var(--sans); letter-spacing: .26em; text-transform: uppercase; color: var(--label); }
.title { margin: 0 0 12px; font: var(--title-font); letter-spacing: var(--title-track, 0); text-wrap: balance; }
.scene-hero .title { font-size: var(--h1); }
.line { color: var(--muted); font-size: .95rem; max-width: 36ch; }
.line + .line { margin-top: 2px; }
.tel { display: inline-flex; align-items: center; min-height: 44px; text-decoration: none; }
.tel:hover { text-decoration: underline; }
.actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 30px; margin-top: 22px; }
.prices { list-style: none; padding: 0; margin: 18px 0 14px; display: grid; gap: 6px; font-size: .95rem; font-variant-numeric: tabular-nums; }
.prices li { display: flex; justify-content: space-between; gap: 28px; }
.copy-1 { padding-bottom: 0; }
.copy-2 { padding-top: 14px; }

/* Desktop: the text sits on the plate. Each theme.css places .copy per scene with left/right/top/bottom. */
@media (min-width: 1024px) {
  .stage { aspect-ratio: 16 / 9; overflow: hidden; }
  .plate, .plate img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
  .copy { position: absolute; padding: 0; max-width: 34%; }
  .copy-1, .copy-2 { padding: 0; }
}
/* Tablet (준 09-28: "use the space big, but keep enough negative space"): the 4:3 framing fills the width, and
   the words get a larger scale and a lot of room around them. */
@media (min-width: 701px) and (max-width: 1023px) {
  .copy { padding: clamp(56px, 8vw, 80px) 9vw clamp(96px, 13vw, 132px); max-width: 44rem; }
  .label { font-size: .8rem; margin-bottom: 18px; }
  .title { font-size: clamp(2.4rem, 5.4vw, 3.3rem); margin-bottom: 16px; }
  .scene-hero .title { font-size: clamp(2.8rem, 6.4vw, 3.9rem); }
  .line { font-size: 1.1rem; max-width: 40ch; }
  .prices { font-size: 1.05rem; gap: 10px; }
  .actions { margin-top: 32px; }
  .btn { min-height: 52px; padding: 0 30px; font-size: 1rem; }
  .text-link { font-size: 1rem; }
}
@media (max-width: 480px) {
  .nav-visit { display: none; } /* Menu stays: it is its own page; Visit is a scroll away on the home page */
}
@media (max-width: 340px) {
  .word { display: none; }
}
.nav-link[aria-current="page"] { text-decoration: underline; text-underline-offset: 6px; }

/* Continuous-background pages (.flow): every plate fades into the page field at its top and bottom edges (the plates
   are also colour-matched to that field in tools/optimize.py), so the scenes read as one surface. */
.flow .plate img, .flow .plate canvas.heat {
  -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 9%, #000 91%, transparent 100%);
  mask-image: linear-gradient(to bottom, transparent 0, #000 9%, #000 91%, transparent 100%);
}
/* A scene whose picture must show whole (A · Sumi 2 hero: the full omakase board, 준 09-28). Its plate is
   colour-matched to the field, so no fade is needed to hide an edge. */
.flow .scene-nofade .plate img { -webkit-mask-image: none; mask-image: none; }

/* Steam and heat shimmer (a scene with data-heat): steam.js redraws the photo in WebGL on this canvas, prepared
   before the scene scrolls in. The canvas takes the photo's own entrance (see Motion below), so the udon and its
   steam arrive together. The photo underneath stays the no-JS, no-WebGL and reduced-motion picture. */
.plate canvas.heat { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }
@media (prefers-reduced-motion: reduce) { .plate canvas.heat { display: none; } }

/* "Out of the dark" (a scene with data-reveal): a scroll-linked unveiling, like a product film. site.js writes
   --a (the light comes up) and --t (the words arrive), each 0→1, while the stage is pinned. The defaults are 1, so
   without JS, with reduced motion, or before site.js runs, the settled scene is what shows. */
.scene-reveal { --a: 1; --t: 1; }
@media (prefers-reduced-motion: no-preference) {
  html .scene-reveal.is-live .plate img {
    transition: none;
    transform: scale(calc(1.14 - .14 * var(--a)));
    filter: brightness(calc(.02 + .98 * var(--a))) blur(calc((1 - var(--a)) * 12px));
    will-change: transform, filter;
  }
  .scene-reveal.is-live .plate {
    -webkit-mask-image: radial-gradient(ellipse calc(10% + 82% * var(--a)) calc(8% + 88% * var(--a)) at 50% 42%, #000 52%, transparent 100%);
    mask-image: radial-gradient(ellipse calc(10% + 82% * var(--a)) calc(8% + 88% * var(--a)) at 50% 42%, #000 52%, transparent 100%);
  }
  .scene-reveal.is-live .stage { background: var(--bg); }
  .scene-reveal.is-live .copy > * { opacity: var(--t); transform: translateY(calc((1 - var(--t)) * 20px)); }
}
/* Desktop: the stage pins for 40vh of scrolling while the scene plays out (120vh → 75vh → 40vh as 준 asked for a
   shorter reveal). Phones scrub the same timeline as the scene travels up the screen, without pinning. */
@media (min-width: 1024px) and (prefers-reduced-motion: no-preference) {
  .scene-reveal.is-live { height: calc(56.25vw + 40vh); }
  .scene-reveal.is-live .stage { position: sticky; top: max(0px, calc((100vh - 56.25vw) / 2)); }
}

/* ── Menu page ───────────────────────────────────────────────────────────────────────────────────────────
   Text-led opening, a sticky chapter bar, chapters with room around them. Items in two columns on desktop.
   No leaders, rules or boxes; hierarchy comes from type and space. */
html.page-menu { scroll-padding-top: 132px; }
.page-menu .site-header { background: var(--bar); }
.menu { --measure: min(1160px, 100% - 2 * clamp(20px, 6vw, 96px)); --spicy: var(--accent-spicy, #B03A2E); }
.menu-intro { width: var(--measure); margin: 0 auto; padding: clamp(140px, 16vw, 220px) 0 clamp(56px, 7vw, 96px); }
.menu-intro .title { font-size: var(--h1); }
.menu-intro .line { max-width: 52ch; }
.menu-key { display: flex; flex-wrap: wrap; gap: 6px 28px; margin-top: 18px; font-size: .85rem; color: var(--muted); }
.raw { text-decoration: none; margin-left: .15em; color: var(--spicy); font-weight: 600; cursor: help; }
.spicy { display: inline-block; margin-left: .6em; font: 600 .62rem/1 var(--sans); letter-spacing: .16em; text-transform: uppercase; color: var(--spicy); vertical-align: .18em; }
.menu-key .spicy { margin-left: 0; margin-right: .4em; }
.menu-key .raw { margin: 0 .35em 0 0; }

.menu-nav { position: sticky; top: calc(env(safe-area-inset-top, 0px) + 68px); z-index: 5; background: var(--bar); }
.menu-nav ul { display: flex; gap: clamp(18px, 3vw, 44px); width: var(--measure); margin: 0 auto; padding: 0; list-style: none; overflow-x: auto; scrollbar-width: none; }
.menu-nav ul::-webkit-scrollbar { display: none; }
.menu-nav a { display: inline-flex; align-items: center; min-height: 48px; white-space: nowrap; font-size: .88rem; color: var(--muted); text-decoration: none; }
.menu-nav a:hover, .menu-nav a[aria-current] { color: var(--fg); text-decoration: underline; text-underline-offset: 7px; }

.chapter { padding-bottom: clamp(72px, 9vw, 140px); }
.chapter-plate { position: relative; margin-bottom: clamp(48px, 6vw, 88px); }
.chapter-plate .plate img { width: 100%; height: auto; }
.chapter-body { width: var(--measure); margin: 0 auto; }
.chapter:not(:has(.chapter-plate)) .chapter-body { padding-top: clamp(24px, 3vw, 40px); }
.chapter-title { margin: 0; font: var(--title-font); font-size: clamp(2.1rem, 3.3vw, 3.1rem); letter-spacing: var(--title-track, 0); text-wrap: balance; }
.chapter-note { margin-top: 10px; color: var(--muted); font-size: .95rem; }
.groups { display: grid; gap: clamp(56px, 6vw, 88px); margin-top: clamp(40px, 5vw, 64px); }
.group-title { margin: 0; font: var(--title-font); font-size: clamp(1.25rem, 1.6vw, 1.5rem); letter-spacing: var(--title-track, 0); }
.group-note { margin-top: 6px; color: var(--muted); font-size: .88rem; }
.items { display: grid; grid-template-columns: minmax(0, 1fr); gap: 26px clamp(40px, 6vw, 96px); margin: 26px 0 0; padding: 0; list-style: none; }
.item-head { display: flex; justify-content: space-between; align-items: baseline; gap: 20px; }
.item-name { font-weight: 500; font-size: 1rem; }
.item-price { flex: none; font-variant-numeric: tabular-nums; font-size: .95rem; }
.item-price.multi { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 2px 16px; }
.item-price small { font-size: .72rem; color: var(--muted); margin-right: .25em; }
.mkt { font-size: .82rem; color: var(--muted); }
.item-desc { margin-top: 4px; color: var(--muted); font-size: .9rem; line-height: 1.5; max-width: 60ch; }

.table-wrap { overflow-x: auto; margin-top: 22px; }
.sushi-table { width: 100%; max-width: 720px; border-collapse: collapse; font-variant-numeric: tabular-nums; }
.sushi-table th, .sushi-table td { padding: 9px 0; text-align: right; font-weight: 400; font-size: .95rem; }
.sushi-table thead th { font: 500 .7rem/1.4 var(--sans); letter-spacing: .2em; text-transform: uppercase; color: var(--label); padding-bottom: 14px; }
.sushi-table th[scope="row"], .sushi-table thead th:first-child { text-align: left; font-weight: 500; padding-right: 24px; }
.sushi-table td { width: 8.5em; }
.sushi-table .na { color: var(--muted); }

.menu-fine { width: var(--measure); margin: 0 auto; padding-bottom: 64px; font-size: .78rem; color: var(--muted); max-width: none; }
@media (min-width: 1024px) {
  .items { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  /* the desktop plate fills its box absolutely (see Scenes), so the chapter picture needs a box of its own */
  .chapter-plate { aspect-ratio: 16 / 9; overflow: hidden; }
}
@media (max-width: 700px) {
  html.page-menu { scroll-padding-top: 124px; }
  .item-head { gap: 14px; }
}
/* Narrow fold covers: keep glass/bottle prices below the full wine name. */
@media (max-width: 340px) {
  .item-head:has(.item-price.multi) { display: block; }
  .item-price.multi { justify-content: flex-start; margin-top: 6px; }
}

/* Footer: one quiet line and the sample note. */
.site-footer {
  display: flex; flex-wrap: wrap; align-items: center; gap: 8px 18px;
  padding: 28px clamp(20px, 5.5vw, 84px) calc(env(safe-area-inset-bottom, 0px) + 32px);
  background: var(--bg); color: var(--muted); font-size: .8rem;
}
.foot-mark { width: 26px; height: 26px; }
.foot-addr { flex: 1 1 auto; }
.foot-addr a { display: inline-flex; align-items: center; min-height: 44px; text-decoration: none; }
.sample-note { flex: 1 1 100%; font-size: .72rem; opacity: .8; }

/* Motion: pictures only, never the words. The resting state is always readable; with scripting on, each plate
   starts in the direction's "before" state and settles when its scene enters (site.js adds .is-in). */
@media (scripting: enabled) and (prefers-reduced-motion: no-preference) {
  .plate img, .plate canvas.heat { transition: var(--enter-transition); }
  .scene:not(.is-in) .plate img, .scene:not(.is-in) .plate canvas.heat { filter: var(--enter-filter, none); transform: var(--enter-transform, none); }
}
