/* ============================================================
   Eric Rose Cafe Tokyo - 08-eric-rose
   The only stylesheet written for this site. ds.css, booking.css and
   media.css load AFTER this file and are shared; nothing here forks
   them, and the two places where this file deliberately out-specifies
   booking.css are marked OVERRIDE and explained.

   THE READ. A Kita-Aoyama cafe that opens at nine and closes at eight,
   every day of the week, for people working nearby and for visitors
   crossing Aoyama. 3.8 from 304 reviews is the lowest rating and by far
   the largest sample of the eight Tokyo venues, and that combination is
   the brief: 304 people bothered to say something, so the useful answer
   is unambiguous information, not a trophy case. The page is therefore
   plain and information-first, and its signature layout family is a
   FLAT SEVEN-ROW WEEK in which every row says the same thing, because
   the most common question at a cafe is whether it is open and seven
   identical rows answer that faster than a sentence claiming "open
   daily". It is the only venue of the eight with no midnight crossing,
   no closed day and no 翌 label anywhere, and that plainness is the
   identity.

   PALETTE. Brick, timber and paper, with one petrol teal taken from the
   linen ground in g3. Ratios computed against WCAG 2.1, not guessed:
     --text    #22201C on --bg  #F7F3EC ....... 14.70:1
     --text    #22201C on --bg-2 #FFFDF8 ...... 16.00:1
     --muted   #5B564E on --bg ................  6.58:1
     --accent  #1F4E5A on --bg ................  8.27:1  (body text legal)
     --accent-ink #FFFDF8 on --accent .........  9.00:1  (.book-ref chip)
     --brick   #8A4E2C on --bg ................  5.92:1  (small type, rules)
     --error   #8E3120 on --bg ................  7.27:1
     --success #2E6152 on --bg ................  6.44:1
   The literal paving colour of the arcade in g1, #A8653F, measures
   4.13:1 and is therefore photographic only: it is nowhere in this file.

   TYPE. IBM Plex, because the multilingual requirement decides it
   rather than taste: Plex ships a real Japanese cut and a real Korean
   cut drawn to the same skeleton, so index.html, en.html and ko.html
   are typographically the same page in three scripts rather than three
   fonts pretending to be one. Plex has no Traditional Chinese cut, so
   zh-Hant takes Noto Sans TC. No serif anywhere on this site: it is a
   modern cafe with no documented heritage, and "it feels premium" is
   not a justification.
   ============================================================ */

:root {
  /* Paper and timber. */
  --bg: #F7F3EC;
  --bg-2: #FFFDF8;
  --bg-3: #EFEADF;

  --text: #22201C;
  --muted: #5B564E;
  --line: #E2DACE;

  /* The petrol teal of the linen in g3. The strongest accent contrast in
     the eight, which is right for a page whose whole argument is that it
     is legible. It carries words here, not only fills. */
  --accent: #1F4E5A;
  --accent-ink: #FFFDF8;

  /* The brick paving, darkened until it can legally carry small type.
     Rules and labels only. */
  --brick: #8A4E2C;

  --error: #8E3120;
  --success: #2E6152;

  /* One radius system, three steps. */
  --radius: 10px;
  --radius-sm: 6px;
  --radius-xs: 3px;

  --nav-h: 64px;
  --maxw: 1120px;
  --gutter: clamp(1rem, 0.6rem + 2vw, 2.5rem);
  --measure: 40rem;
  --ease: cubic-bezier(0.22, 0.75, 0.3, 1);

  /* IBM Plex Sans JP covers Latin as well as Japanese, drawn to one
     skeleton, so index.html loads a single family and the cafe's own
     Latin name and every clock time come from the same design. */
  --font-display: "IBM Plex Sans JP", "Hiragino Kaku Gothic ProN", "Hiragino Sans", "Yu Gothic", Meiryo, sans-serif;
  --font-body: "IBM Plex Sans JP", "Hiragino Kaku Gothic ProN", "Hiragino Sans", "Yu Gothic", Meiryo, sans-serif;
}

/* The per-language families REPLACE the Japanese ones rather than
   sitting behind them. A JP cut left at the head of the Chinese stack
   renders Chinese in Japanese glyph shapes, which is the typographic
   version of a machine translation and would undo the one thing these
   four pages are for. IBM Plex Sans is kept at the head of the zh stack
   on purpose: it carries no ideographs, so every Chinese character
   still falls through to Noto Sans TC. */
html[lang="en"] {
  --font-display: "IBM Plex Sans", system-ui, -apple-system, "Segoe UI", Helvetica, Arial, sans-serif;
  --font-body: "IBM Plex Sans", system-ui, -apple-system, "Segoe UI", Helvetica, Arial, sans-serif;
}
html[lang="zh-Hant"] {
  --font-display: "IBM Plex Sans", "Noto Sans TC", "PingFang TC", "Microsoft JhengHei", "Heiti TC", sans-serif;
  --font-body: "IBM Plex Sans", "Noto Sans TC", "PingFang TC", "Microsoft JhengHei", "Heiti TC", sans-serif;
}
html[lang="ko"] {
  --font-display: "IBM Plex Sans KR", "Apple SD Gothic Neo", Pretendard, "Malgun Gothic", sans-serif;
  --font-body: "IBM Plex Sans KR", "Apple SD Gothic Neo", Pretendard, "Malgun Gothic", sans-serif;
}

/* ---------- base ---------- */

*, *::before, *::after { box-sizing: border-box; }

html {
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--nav-h) + 1rem);
  -webkit-text-size-adjust: 100%;
}
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}

body {
  /* The per-site dials ds.css reads. They sit on body rather than on
     :root because ds.css loads AFTER this file and redeclares both on
     :root; a rule on body wins for every element inside it. Warm and
     unhurried, to match the motion dials on <html>. */
  --ds-lift: 2px;
  --ds-dur: 0.3s;

  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  font-size: 1rem;
  font-weight: 400;
  line-height: 1.9;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

/* An <img> carrying width and height attributes maps them to a used
   height, which overrides aspect-ratio unless it is released here.
   Without this line every banded photograph renders at its full file
   height and none of the crops below apply. */
img { max-width: 100%; height: auto; display: block; }

h1, h2, h3 {
  font-family: var(--font-display);
  font-weight: 600;
  line-height: 1.45;
  letter-spacing: 0.005em;
  margin: 0;
  text-wrap: balance;
}
p { margin: 0; }
ul, ol { margin: 0; padding: 0; list-style: none; }

a { color: var(--accent); text-underline-offset: 3px; }
a:hover { color: var(--text); }

/* The hours table and the rating are the two things people came for, so
   every figure on this page lines up in its column. */
.week-hours, .info-list, .rating-figure, .tel-link, .band-guide,
.hours-inline, time { font-variant-numeric: tabular-nums; }

.wrap {
  width: min(100% - (var(--gutter) * 2), var(--maxw));
  margin-inline: auto;
}

/* The centred text measure. One of the five layout families, and the
   thing the photographic bands alternate with. */
.measure {
  max-width: var(--measure);
  margin-inline: auto;
  text-align: center;
}
.measure h2 { margin-bottom: 1.1rem; }
.measure p { color: var(--muted); }
.measure p + p { margin-top: 1rem; }

/* The heading stays centred, the body does not. A centred heading is a
   title; four centred lines of ragged prose is a thing people stop
   reading, and this is the page whose whole argument is that it is easy
   to read. */
.measure.prose p { text-align: start; }

.sec { padding-block: clamp(3rem, 2rem + 5vw, 6rem); }
.sec-2 { background: var(--bg-2); border-block: 1px solid var(--line); }

.sec-head { margin-bottom: clamp(1.8rem, 1.2rem + 2vw, 3rem); }
.sec-head h2 {
  font-size: clamp(1.5rem, 1.25rem + 1.2vw, 2.1rem);
  margin-bottom: 0.9rem;
}
.sec-head p { color: var(--muted); }

.eyebrow {
  font-family: var(--font-display);
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  color: var(--brick);
  margin-bottom: 0.9rem;
}

/* ---------- buttons ---------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  min-height: 48px;
  padding: 0.7rem 1.4rem;
  font-family: var(--font-display);
  font-size: 0.98rem;
  font-weight: 600;
  line-height: 1.3;
  border-radius: var(--radius-sm);
  border: 1px solid transparent;
  text-decoration: none;
  cursor: pointer;
}
.btn-primary {
  background: var(--accent);
  color: var(--accent-ink);
  border-color: var(--accent);
}
.btn-primary:hover { color: var(--accent-ink); background: #173C46; }
.btn-ghost {
  background: transparent;
  color: var(--text);
  border-color: var(--line);
}
.btn-ghost:hover { color: var(--text); background: var(--bg-2); }
.btn:disabled { opacity: 0.6; cursor: default; }

.si { flex: none; }

/* ---------- reveal ----------
   The CSS half of the reveal. motion.js takes ownership when it runs and
   ds.css switches this transition off; if it never runs, media.js still
   adds .in and its four second failsafe still fires, so nothing here can
   leave content hidden. */
.rv {
  opacity: 0;
  transform: translateY(16px);
  transition: opacity 0.6s var(--ease), transform 0.6s var(--ease);
}
.rv.in { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  .rv { opacity: 1; transform: none; transition: none; }
}

/* ---------- header ---------- */

.nav {
  position: sticky;
  top: 0;
  z-index: 20;
  min-height: var(--nav-h);
  background: color-mix(in srgb, var(--bg) 92%, transparent);
  backdrop-filter: saturate(140%) blur(8px);
  border-bottom: 1px solid var(--line);
}
@supports not (background: color-mix(in srgb, red 50%, white)) {
  .nav { background: var(--bg); }
}
.nav .wrap {
  min-height: var(--nav-h);
  display: flex;
  align-items: center;
  gap: clamp(0.6rem, 0.3rem + 1.4vw, 1.8rem);
}
.brand {
  font-family: var(--font-display);
  font-size: 1.02rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  color: var(--text);
  text-decoration: none;
  white-space: nowrap;
}
/* Below 560px the full listing name, the four language links and the
   booking button cannot share one 358px row without the language links
   breaking to two lines each, which is what pushed the header past 80px.
   The short form is the name on the cafe's own canopy in g1, so nothing
   is invented by shortening it. */
.brand-short { display: none; }
.nav-links {
  display: flex;
  gap: 1.4rem;
  margin-inline-start: auto;
  font-size: 0.9rem;
}
.nav-links a {
  color: var(--muted);
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  min-height: 44px;
}
.nav-links a:hover { color: var(--text); }
.lang {
  display: flex;
  gap: 0.15rem;
  font-size: 0.82rem;
}
.lang a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding-inline: 0.5rem;
  color: var(--muted);
  text-decoration: none;
  border-radius: var(--radius-xs);
  /* Without this, 日本語 and 한국어 break one character per line inside a
     tight header and the nav grows to three rows. */
  white-space: nowrap;
}
.lang a:hover { color: var(--text); }
.lang a[aria-current="true"] {
  color: var(--text);
  font-weight: 600;
  box-shadow: inset 0 -2px 0 var(--brick);
}
.nav-cta { padding: 0.5rem 1rem; min-height: 44px; font-size: 0.9rem; }

@media (max-width: 860px) {
  .nav-links { display: none; }
  .lang { margin-inline-start: auto; }
}
@media (max-width: 560px) {
  .nav .wrap { gap: 0.35rem; }
  .brand-full { display: none; }
  .brand-short { display: inline; }
  .brand { font-size: 0.95rem; }
  .lang { font-size: 0.76rem; }
  .lang a { padding-inline: 0.28rem; }
  .nav-cta { padding: 0.5rem 0.7rem; font-size: 0.85rem; }
}

/* ---------- FAMILY 1: the terrace band ----------
   A wide photographic band with the centred measure directly beneath it,
   both inside the first screen. The section is deliberately NOT called
   .hero: motion.js attaches a scroll-linked drift to `.hero img`, and
   this page carries nothing scroll-linked. */

/* object-position is set high on purpose: the ERIC ROSE lettering sits in
   the upper third of this frame, and a centred crop cuts the one thing
   that makes this photograph provably this cafe. Checked at 1280x900 and
   390x844 by looking, not by arithmetic. The height cap keeps the
   booking CTA below it inside the first screen on a laptop. */
.lead-photo img {
  width: 100%;
  aspect-ratio: 3 / 2;
  object-fit: cover;
  object-position: 50% 24%;
  max-height: 44vh;
  max-height: 44svh;
}
.lead-copy {
  padding-block: clamp(1.8rem, 1.2rem + 3vw, 3.2rem);
}
.lead-copy h1 {
  font-size: clamp(1.75rem, 1.25rem + 2.4vw, 3rem);
  font-weight: 600;
  line-height: 1.35;
  margin-bottom: 1rem;
}
.lead-sub {
  color: var(--muted);
  font-size: clamp(1rem, 0.96rem + 0.2vw, 1.08rem);
  max-width: 34rem;
  margin-inline: auto;
}
.lead-ctas {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.8rem;
  margin-top: 1.6rem;
}

/* The caption under a band. Small, brick, and never a claim beyond what
   is in the frame. */
.band-cap {
  margin-top: 0.7rem;
  font-size: 0.82rem;
  line-height: 1.75;
  color: var(--muted);
}

/* ---------- FAMILY 3: the flat week ----------
   Seven rows, every one reading 09:00 to 20:00, no closed day and no
   exception. The sameness IS the answer, so nothing here dresses a row
   up or singles one out. .morning-grid is in motion.js GROUPS, so the
   seven rows arrive in sequence: seven identical rows landing together
   are a wall of text, and arriving one after another makes the sameness
   readable. */

.week {
  max-width: 34rem;
  margin-inline: auto;
  border-top: 2px solid var(--brick);
}
.week-row {
  display: grid;
  grid-template-columns: minmax(6.5rem, 0.6fr) minmax(0, 1fr);
  align-items: baseline;
  gap: 0.5rem 1rem;
  padding-block: 0.85rem;
  border-bottom: 1px solid var(--line);
}
.week-day {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 0.95rem;
}
.week-hours {
  font-family: var(--font-display);
  font-size: clamp(1.05rem, 0.98rem + 0.35vw, 1.2rem);
  font-weight: 500;
  letter-spacing: 0.01em;
  text-align: end;
}
.week-note {
  max-width: 34rem;
  margin: 1.3rem auto 0;
  font-size: 0.9rem;
  line-height: 1.8;
  color: var(--muted);
}

/* ---------- FAMILY 4: the plate pair ----------
   One 3:2 and one portrait, at two different heights on purpose, so the
   pair reads as an editorial spread rather than as two equal cards.

   NO REVEAL CLASS, DELIBERATELY. The design direction asks for a pair
   that fades WITHOUT the page's rise. motion.js is shared and exposes
   exactly one rise value for the whole document, so a per-element rise
   of zero is not expressible without forking it. Between the page's
   16px rise and no motion at all, no motion is the closer reading, and
   it also means the two photographs are never briefly hidden. */

.plate-pair {
  display: grid;
  grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
  gap: clamp(1rem, 0.6rem + 2vw, 2rem);
  align-items: start;
}
.plate figcaption {
  margin-top: 0.7rem;
  font-size: 0.82rem;
  line-height: 1.75;
  color: var(--muted);
}
.plate-a img { aspect-ratio: 3 / 2; object-fit: cover; width: 100%; border-radius: var(--radius-sm); }
.plate-b img { aspect-ratio: 3 / 4; object-fit: cover; width: 100%; border-radius: var(--radius-sm); }

/* The Google price band. A band, not a menu, and it is labelled as one
   in every language. Nothing on this page is transcribed from the
   photographed drink board. */
.guide {
  max-width: var(--measure);
  margin: clamp(2rem, 1.4rem + 2vw, 3rem) auto 0;
  padding: clamp(1.1rem, 0.9rem + 1vw, 1.6rem);
  background: var(--bg-2);
  border: 1px solid var(--line);
  border-inline-start: 3px solid var(--brick);
  border-radius: var(--radius-sm);
}
.guide h3 {
  font-size: 1rem;
  font-weight: 600;
  margin-bottom: 0.5rem;
}
.guide p { color: var(--muted); font-size: 0.92rem; line-height: 1.8; }
.band-guide {
  display: block;
  font-family: var(--font-display);
  font-size: clamp(1.3rem, 1.1rem + 1vw, 1.7rem);
  font-weight: 600;
  color: var(--text);
  margin-block: 0.7rem;
}

/* ---------- FAMILY 5: the information list ---------- */

.info-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.25fr) minmax(0, 1fr);
  gap: clamp(1.5rem, 1rem + 3vw, 3.5rem);
  align-items: start;
}
.info-list li {
  display: grid;
  grid-template-columns: 8rem minmax(0, 1fr);
  gap: 0.3rem 1rem;
  padding-block: 0.85rem;
  border-bottom: 1px solid var(--line);
}
.info-list li:first-child { border-top: 1px solid var(--line); }
.info-list .label {
  font-family: var(--font-display);
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.03em;
  color: var(--brick);
  padding-top: 0.2rem;
}
.info-list a {
  min-height: 44px;
  display: inline-flex;
  align-items: center;
}
.rating-figure { font-weight: 600; }
.info-side p { color: var(--muted); font-size: 0.93rem; line-height: 1.85; }
.info-actions { margin-top: 1.4rem; }

/* ---------- FAMILY 6: the booking block ---------- */

.reserve { background: var(--bg-2); border-top: 1px solid var(--line); }
.reserve-grid {
  display: grid;
  grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr);
  gap: clamp(1.6rem, 1rem + 3vw, 3.5rem);
  align-items: start;
}
.reserve-copy p { color: var(--muted); }
.reserve-copy h2 {
  font-size: clamp(1.45rem, 1.2rem + 1vw, 1.95rem);
  margin-bottom: 0.9rem;
}
.reserve-alt {
  margin-top: 1.4rem;
  padding-top: 1.2rem;
  border-top: 1px solid var(--line);
}
.tel-link {
  font-family: var(--font-display);
  font-size: 1.3rem;
  font-weight: 600;
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 4px;
  display: inline-flex;
  align-items: center;
  min-height: 44px;
}

.form {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1rem;
  background: var(--bg);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: clamp(1.2rem, 0.9rem + 1.5vw, 1.8rem);
}
.field { display: flex; flex-direction: column; gap: 0.35rem; min-width: 0; }
.field.full { grid-column: 1 / -1; }
.field label {
  font-family: var(--font-display);
  font-size: 0.85rem;
  font-weight: 600;
  line-height: 1.6;
}
.field input,
.field select {
  font: inherit;
  font-size: 1rem;
  min-height: 48px;
  padding: 0.6rem 0.8rem;
  color: var(--text);
  background: var(--bg-3);
  border: 1px solid var(--line);
  border-radius: var(--radius-sm);
  width: 100%;
}
/* The select keeps its native arrow. Stripping the appearance to match
   the paper ground would remove the one affordance that says "this
   opens". */
.field .hint {
  font-size: 0.78rem;
  line-height: 1.7;
  color: var(--muted);
}
/* booking.css already styles .form textarea and reads --bg-3 and --line
   from this file, so only the radius needs saying. */
.form textarea { border-radius: var(--radius-sm); }

/* OVERRIDE 1 and 2. booking.css hardcodes #f0a08c for the field error
   text and for a rejected input's border. On this paper ground that
   measures 1.88:1, so the one string a guest must be able to read would
   be effectively invisible. booking.css loads AFTER this file, so both
   rules are written one step more specific on purpose. On a page whose
   whole argument is that this cafe is clear about everything, an
   unreadable error message would be the one thing that undoes it. */
.form .field .field-msg { color: var(--error); font-weight: 600; }
.form .field.bad input,
.form .field.bad select,
.form .field.bad textarea { border-color: var(--error); border-width: 2px; }

.form-error, .form-ok {
  grid-column: 1 / -1;
  display: none;
  margin: 0;
  padding: 0.85rem 1rem;
  border-radius: var(--radius-sm);
  font-size: 0.95rem;
  line-height: 1.8;
}
.form-error.show, .form-ok.show { display: block; }
/* Status is never colour alone: each carries its own border weight and
   its own wording. */
.form-error {
  color: var(--error);
  background: #FBF0EC;
  border: 1px solid var(--error);
  font-weight: 600;
}
.form-error a { color: var(--error); text-decoration: underline; }
.form-ok {
  color: var(--success);
  background: #EDF4F1;
  border: 1px solid var(--success);
}

.book-result { border-radius: var(--radius); margin-top: 1.2rem; }
.ref-note {
  margin-top: 0.9rem;
  font-size: 0.86rem;
  line-height: 1.85;
  color: var(--muted);
}
.ref-note strong { color: var(--text); font-weight: 600; }

/* The confirmation panel and the note that explains it belong under the
   form, not under the left-hand column, which is where a plain two
   column grid puts the third and fourth children. */
@media (min-width: 861px) {
  .reserve-grid > .book-result,
  .reserve-grid > .ref-note { grid-column: 2; }
}

/* ---------- footer ---------- */

footer {
  background: var(--bg);
  border-top: 1px solid var(--line);
  padding-block: clamp(2.2rem, 1.6rem + 2vw, 3.4rem);
}
.foot-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 1.2rem 2rem;
  justify-content: space-between;
  align-items: start;
  padding-bottom: 1.4rem;
  border-bottom: 1px solid var(--line);
}
.foot-brand {
  font-family: var(--font-display);
  font-weight: 600;
  letter-spacing: 0.04em;
}
.foot-grid p { font-size: 0.9rem; color: var(--muted); }
.foot-links { display: flex; flex-wrap: wrap; gap: 0.2rem 0.4rem; }
.foot-links a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding-inline: 0.5rem;
  font-size: 0.9rem;
  color: var(--muted);
  text-decoration: none;
}
.foot-links a:hover { color: var(--text); }
.demo-note {
  margin-top: 0.9rem;
  font-size: 0.82rem;
  line-height: 1.8;
  color: var(--muted);
  max-width: 62rem;
}

/* ---------- narrow ----------
   Declared for every multi column layout in this file rather than left
   to work itself out. Checked at 390px and at 360px. */

@media (max-width: 860px) {
  .reserve-grid { grid-template-columns: 1fr; }
}
@media (max-width: 760px) {
  .plate-pair { grid-template-columns: 1fr; }
  .plate-b img { aspect-ratio: 4 / 5; }
  .info-grid { grid-template-columns: 1fr; }
}
@media (max-width: 620px) {
  .form { grid-template-columns: 1fr; }
  .info-list li { grid-template-columns: 1fr; row-gap: 0.1rem; }
  .week-row { grid-template-columns: minmax(4.5rem, auto) minmax(0, 1fr); }
  .lead-photo img { max-height: none; }
  .lead-ctas .btn { flex: 1 1 100%; }
}
