/* ============================================================
   HARCOURT - 東京都港区西麻布 - assets/site.css

   The only stylesheet written for this site. ds.css, booking.css
   and media.css are shared and load AFTER this file, so anything
   that has to beat them is written at a higher specificity rather
   than moved later in the cascade. Those overrides are marked.

   THE READ. One room in Nishi-Azabu with a tree in the window.
   The two usable frames are DAYLIGHT, so the page is about the
   room rather than the hour, and it refuses the reflex a listing
   categorised バー invites: a dark page with a gold accent. Cool
   greige ground, one green accent taken out of the street tree in
   g1, geometric sans throughout, and a great deal of white space.

   THE STRUCTURE. An asymmetric rail: a narrow persistent column of
   facts down the left against a much wider right column that
   carries one image or one paragraph at a time. The imbalance is
   the identity. Below 900px the rail becomes a short block that
   sits between the opening and the body of the page, which is why
   the opening, the rail and the stack are three separate grid
   items rather than two.
   ============================================================ */

/* ---------- Tokens ---------- */

:root {
  /* Palette. Measured against the ground they actually sit on:
       --text  on --bg   14.73:1      --text  on --bg-2  15.94:1
       --muted on --bg    6.29:1      --muted on --bg-2   6.81:1
       --accent on --bg   6.15:1   <- safe for small text, not only fills,
                                      which is why the accent is allowed to
                                      be typographic on this one site
       --error on --bg    7.29:1      --ok    on --bg     6.36:1
     No pure black, no pure white, one accent, one theme the whole
     way down. No section inverts. */
  --bg:         #F2F0EA;
  --bg-2:       #FAF9F5;
  --bg-3:       #EAE8E0;
  --text:       #1C1E1B;
  --muted:      #55594F;
  --line:       #D8D5CB;
  --accent:     #46603A;
  --accent-ink: #FAF9F5;
  --error:      #8E2C1C;
  --ok:         #35603F;

  /* One radius system. 2px: enough to stop a control looking like a
     rectangle cut out with scissors, not enough to read as a pill. */
  --radius: 2px;

  /* Type. Japanese leads. Zen Kaku Gothic Antique is a humanist
     gothic whose slightly softened terminals read as a considered
     room rather than a corporate one; the identity is carried by
     weight and space, so display and body are the same family and
     no second face fights it. Jost sits at the same x-height, so
     HARCOURT and 西麻布 share a line without a step. No serif: this
     shop has no documented heritage and a serif here would be the
     "it feels premium" reflex. */
  --font-display: "Zen Kaku Gothic Antique", "Hiragino Kaku Gothic ProN", "Hiragino Sans", "Yu Gothic", Meiryo, sans-serif;
  --font-body:    "Zen Kaku Gothic Antique", "Hiragino Kaku Gothic ProN", "Hiragino Sans", "Yu Gothic", Meiryo, sans-serif;
  --font-latin:   "Jost", "Helvetica Neue", Arial, sans-serif;

  /* The page is thin on content and the space is the design. */
  --lh: 1.9;

  --rail-w: clamp(10.5rem, 20vw, 15rem);
  --gutter: clamp(1.9rem, 6vw, 5rem);
  --pad-i: clamp(1.15rem, 4.5vw, 3rem);

  /* ds.css reads these. The mast does not stick, so nothing has to
     be cleared; --ds-lift is deliberately small because this is
     among the quietest pages in the set. */
  --nav-h: 0px;
  --ds-lift: 2px;
}

/* Latin pages take Jost for everything. zh-Hant and ko REPLACE the
   two font stacks wholesale rather than appending a CJK face after
   the Japanese one, which would render 繁體中文 and 한국어 in
   Japanese glyph shapes wherever the ranges overlap. */
html[lang="en"] {
  --font-display: var(--font-latin);
  --font-body:    var(--font-latin);
  --lh: 1.65;
}
html[lang="zh-Hant"] {
  --font-display: "Noto Sans TC", "PingFang TC", "Microsoft JhengHei", "Heiti TC", sans-serif;
  --font-body:    "Noto Sans TC", "PingFang TC", "Microsoft JhengHei", "Heiti TC", sans-serif;
}
html[lang="ko"] {
  --font-display: "Noto Sans KR", "Apple SD Gothic Neo", Pretendard, "Malgun Gothic", sans-serif;
  --font-body:    "Noto Sans KR", "Apple SD Gothic Neo", Pretendard, "Malgun Gothic", sans-serif;
}

/* ---------- Ground ---------- */

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

html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
}
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  font-weight: 400;
  font-size: clamp(0.98rem, 0.94rem + 0.18vw, 1.06rem);
  line-height: var(--lh);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

img { max-width: 100%; }

h1, h2, h3, p, ul, ol, dl, dt, dd, figure, blockquote { margin: 0; }
dd { margin-inline-start: 0; }
ul { padding: 0; list-style: none; }

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

::selection { background: var(--accent); color: var(--accent-ink); }

/* ---------- Shell ---------- */

.shell {
  max-width: 76rem;
  margin: 0 auto;
  padding-inline: var(--pad-i);
}

/* ---------- Masthead ----------
   Not sticky. A bar that follows the reader down would compete with
   the rail, which is the thing on this page that is meant to
   persist. */

.mast {
  border-block-end: 1px solid var(--line);
}
.mast-in {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.6rem 1.5rem;
  padding-block: clamp(1rem, 2.5vw, 1.6rem);
}
.mast-name {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  font-family: var(--font-latin);
  font-weight: 500;
  font-size: 1.05rem;
  letter-spacing: 0.16em;
  color: var(--text);
  text-decoration: none;
}
.mast-name:hover { color: var(--accent); }

.langsw {
  display: flex;
  flex-wrap: wrap;
  gap: 0.15rem;
}
.langsw a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding-inline: 0.65rem;
  font-size: 0.83rem;
  letter-spacing: 0.04em;
  color: var(--muted);
  text-decoration: none;
}
.langsw a:hover { color: var(--text); }
.langsw a[aria-current="true"] {
  color: var(--accent);
  box-shadow: inset 0 -1px 0 0 var(--accent);
}

/* ---------- The asymmetric rail ----------
   Three grid items: the opening (column 2, row 1), the rail
   (column 1, spanning both rows, sticky), and the stack of
   everything else (column 2, row 2). Three rather than two purely
   so that on a phone the source order can be opening, rail, stack:
   the name and the booking link stay at the top of the screen and
   the facts arrive as a short block before the body of the page. */

.spread {
  display: grid;
  grid-template-columns: var(--rail-w) minmax(0, 1fr);
  column-gap: var(--gutter);
  align-items: start;
}
.opening { grid-column: 2; grid-row: 1; }
.stack   { grid-column: 2; grid-row: 2; min-width: 0; }
.rail {
  grid-column: 1;
  grid-row: 1 / span 2;
  align-self: start;
  position: sticky;
  top: 2rem;
  min-width: 0;
  padding-block: clamp(2.4rem, 6vw, 4rem) 2rem;
  border-inline-end: 1px solid var(--line);
  padding-inline-end: clamp(0.9rem, 2vw, 1.6rem);
}

.rail-title {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 0.78rem;
  /* Tracking is set for the script actually being set. 0.18em on a run of
     kana reads as a gimmick; on small uppercase latin it is what makes the
     line legible. */
  letter-spacing: 0.1em;
  color: var(--muted);
  margin-block-end: 1.5rem;
}
html[lang="en"] .rail-title { text-transform: uppercase; letter-spacing: 0.18em; }

/* .info-grid is in motion.js GROUPS, so these rows stagger once on
   entry. Justification: they are a group, and the stagger is what
   shows they belong together. Nothing else on this page staggers. */
.info-grid { display: block; }
.fact + .fact {
  margin-block-start: 1.15rem;
  padding-block-start: 1.15rem;
  border-block-start: 1px solid var(--line);
}
.fact dt {
  font-size: 0.74rem;
  letter-spacing: 0.12em;
  color: var(--muted);
  margin-block-end: 0.3rem;
}
html[lang="en"] .fact dt { text-transform: uppercase; }
.fact dd {
  font-size: 0.93rem;
  line-height: 1.75;
  font-variant-numeric: tabular-nums;
}
.fact dd .nb { white-space: nowrap; }
.fact .sub {
  display: block;
  margin-block-start: 0.2rem;
  font-size: 0.78rem;
  line-height: 1.7;
  color: var(--muted);
  font-variant-numeric: normal;
}
.fact-closed dd { color: var(--accent); font-weight: 500; }

.rail .link,
.rail a {
  color: var(--accent);
  text-decoration: none;
  box-shadow: inset 0 -1px 0 0 var(--line);
}
/* The telephone number stands alone in its own row, so it is a target
   rather than a word in a sentence and gets a real one. The numbers
   inside the closing paragraphs stay inline: WCAG 2.5.8 exempts a link
   in a line of text, and padding one out would collide with the line
   above it. */
.fact dd a[data-tel] {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
}
.rail a:hover { color: var(--text); box-shadow: inset 0 -1px 0 0 currentColor; }

.maps-link {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  min-height: 44px;
  margin-block-start: 1.5rem;
  font-size: 0.85rem;
  box-shadow: none !important;
}
.maps-link svg { width: 1.05em; height: 1.05em; flex: none; }
.maps-link span { box-shadow: inset 0 -1px 0 0 var(--line); }

/* ---------- 1. The opening ----------
   Four text elements and no more: kicker, name, one sentence, the
   booking link. The photograph comes after them, at the top of the
   stack, so that on a phone the booking link is reachable without
   a scroll. */

.opening {
  padding-block: clamp(2.6rem, 8vw, 6rem) clamp(1.6rem, 4vw, 3rem);
}
.kicker {
  font-size: 0.78rem;
  letter-spacing: 0.1em;
  color: var(--muted);
  margin-block-end: clamp(1.1rem, 3vw, 1.8rem);
}
html[lang="en"] .kicker { text-transform: uppercase; letter-spacing: 0.16em; }

h1 { margin: 0; }
.wordmark {
  display: block;
  font-family: var(--font-latin);
  font-weight: 500;
  font-size: clamp(3rem, 11vw, 6.5rem);
  line-height: 1;
  letter-spacing: 0.055em;
  color: var(--text);
}

.lede {
  max-width: 34rem;
  margin-block-start: clamp(1.4rem, 3.5vw, 2.2rem);
  font-size: clamp(1rem, 0.96rem + 0.3vw, 1.15rem);
  color: var(--muted);
}
.cta-row { margin-block-start: clamp(1.8rem, 4vw, 2.6rem); }

/* ---------- Photographs ----------
   .m-figure gives min-width:0 inside a grid, which is the thing
   that blows a phone layout out when a real photograph replaces a
   placeholder. .m-fade fades it in once it has decoded.

   OVERRIDE (beats media.css on specificity, not on order):
   media.css pairs the fade with a scale(1.02) settle. The large
   image here fades and does nothing else. A room that drifts or
   zooms on arrival looks like a property listing. */
.photo.m-fade img {
  transform: none;
  transition: opacity 0.7s ease;
}
@media (prefers-reduced-motion: reduce) {
  .photo.m-fade img { transition: none; }
}

.photo { border-radius: var(--radius); background: var(--bg-3); }
.photo img { display: block; }

.shot {
  margin-block-end: clamp(2.6rem, 7vw, 5rem);
}
.shot .photo { aspect-ratio: 4 / 3; }

.cap {
  margin-block-start: 0.9rem;
  max-width: 34rem;
  font-size: 0.8rem;
  line-height: 1.8;
  color: var(--muted);
}

/* ---------- 2. One paragraph at a time ---------- */

.block {
  padding-block: clamp(2.6rem, 7vw, 5rem);
  border-block-start: 1px solid var(--line);
}

h2 {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(1.25rem, 1.1rem + 0.7vw, 1.7rem);
  line-height: 1.55;
  letter-spacing: 0.01em;
}
html[lang="en"] h2 { font-weight: 500; letter-spacing: 0.005em; }
html[lang="ko"] h2 { font-weight: 500; }

.prose {
  max-width: 36rem;
  margin-block-start: 1.4rem;
}
.prose p + p { margin-block-start: 1.3rem; }

/* ---------- 3. The statement ----------
   One centred line at pull-quote scale, and the only place the
   accent is asked to carry a whole line of type. It is the release
   in a page that is otherwise all left edge. */

.statement {
  padding-block: clamp(3.2rem, 10vw, 7rem);
  border-block-start: 1px solid var(--line);
  text-align: center;
}
.statement p {
  max-width: 42rem;
  margin-inline: auto;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: clamp(1.5rem, 1.15rem + 1.9vw, 2.75rem);
  line-height: 1.6;
  letter-spacing: 0.005em;
}
/* Japanese and Chinese break between any two characters, so a line at this
   size lands on 木が一本あり / ます。 unless the phrases are made unbreakable.
   Each clause is its own inline-block, so the break can only fall where the
   punctuation already puts one. */
.statement p > span { display: inline-block; }
.statement .under {
  margin-block-start: 1.4rem;
  max-width: 34rem;
  font-size: clamp(0.88rem, 0.85rem + 0.2vw, 1rem);
  font-weight: 400;
  line-height: 1.9;
  letter-spacing: 0.06em;
  color: var(--accent);
}

/* ---------- 4. The plate pair ---------- */

.plates {
  display: grid;
  grid-template-columns: minmax(0, 1.85fr) minmax(0, 1fr);
  gap: clamp(0.9rem, 2.5vw, 1.5rem);
  align-items: start;
  margin-block-start: clamp(1.6rem, 4vw, 2.4rem);
}
.plate-wide .photo  { aspect-ratio: 4 / 3; }
.plate-small .photo { aspect-ratio: 3 / 4; }

/* ---------- 5. Booking ---------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 48px;
  padding: 0.75rem 1.7rem;
  border: 1px solid var(--accent);
  border-radius: var(--radius);
  font: inherit;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 0.97rem;
  letter-spacing: 0.06em;
  line-height: 1.3;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
}
.btn-primary {
  background: var(--accent);
  color: var(--accent-ink);
}
.btn-primary:hover {
  background: #37502C;
  border-color: #37502C;
  color: var(--accent-ink);
}
.btn-primary:disabled { opacity: 0.72; cursor: default; }

.form {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 1.1rem 1.2rem;
  max-width: 40rem;
  margin-block-start: clamp(1.8rem, 4vw, 2.4rem);
}
.field {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  min-width: 0;
}
.field.full { grid-column: 1 / -1; }
.field label {
  font-size: 0.82rem;
  letter-spacing: 0.08em;
  color: var(--muted);
}
.field input,
.field select,
.field textarea {
  font: inherit;
  font-size: 1rem;
  min-height: 48px;
  padding: 0.6rem 0.8rem;
  background: var(--bg-3);
  color: var(--text);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}
/* The native select keeps its own caret. Stripping the appearance
   and not replacing the arrow is how a select stops looking like a
   select, and this form is filled in one-handed on a phone. */
.field input:hover,
.field select:hover,
.field textarea:hover { border-color: var(--muted); }
.field .hint {
  font-size: 0.79rem;
  line-height: 1.75;
  color: var(--muted);
}

/* OVERRIDE, and the brief calls it mandatory. booking.css hardcodes
   #f0a08c for the rejected-field border and the field message. On
   this ground that colour measures 1.82:1, which is not a readable
   error message, and the error is the one string a person has to be
   able to read. Restated at a higher specificity because site.css
   loads before booking.css. #8E2C1C measures 7.29:1 here. */
.form .field .field-msg { color: var(--error); font-size: 0.85rem; }
.form .field.bad input,
.form .field.bad select,
.form .field.bad textarea { border-color: var(--error); }

.form .field textarea {
  border-radius: var(--radius);
  min-height: 4.2em;
}

/* booking.css stretches the primary button across the whole form
   (flex: 1 1 14rem), which on a 40rem form is a 640px bar of accent
   and the loudest thing on a deliberately quiet page. Held to its
   own width and left aligned with the rest of the column; it goes
   back to full width on a phone, where a wide target is the point. */
.form .book-actions { justify-content: flex-start; }
.form .book-actions .btn { flex: 0 1 auto; min-width: 17rem; }

.form-error, .form-ok {
  grid-column: 1 / -1;
  display: none;
  margin: 0;
  padding: 0.85rem 1rem;
  border-radius: var(--radius);
  font-size: 0.93rem;
  line-height: 1.75;
}
.form-error.show, .form-ok.show { display: block; }
.form-error {
  color: var(--error);
  background: var(--bg-2);
  border: 1px solid var(--error);
}
.form-error a { color: var(--error); font-weight: 500; text-decoration: underline; }
.form-ok {
  color: var(--ok);
  background: var(--bg-2);
  border: 1px solid var(--ok);
}

/* The confirmation panel. booking.css supplies the structure and
   reads this site's own custom properties, so only the two things
   that belong to this page's type are set here. */
.book-result { border-radius: var(--radius); margin-block-start: 1.6rem; }
.book-result h3 { font-family: var(--font-display); font-weight: 500; }
.book-ref { border-radius: var(--radius); }

/* The note that explains, in the reader's own language, that the
   confirmation panel itself is written in Japanese. It exists only
   on zh.html and ko.html, because site.js carries ja, en, es, ar and
   ur strings and nothing else, and a reader deserves to know what
   the big characters on that panel are before they read them down a
   telephone. */
.panel-note {
  max-width: 40rem;
  margin-block-start: 1.1rem;
  padding: 0.9rem 1rem;
  border: 1px solid var(--line);
  border-inline-start: 3px solid var(--accent);
  border-radius: var(--radius);
  background: var(--bg-2);
  font-size: 0.85rem;
  line-height: 1.85;
  color: var(--text);
}

.after-form {
  max-width: 40rem;
  margin-block-start: 1.6rem;
  font-size: 0.87rem;
  line-height: 1.9;
  color: var(--muted);
}
.after-form a { font-weight: 500; }
.after-form strong { color: var(--text); font-weight: 500; }

/* ---------- Footer ---------- */

footer {
  border-block-start: 1px solid var(--line);
  padding-block: clamp(2.4rem, 6vw, 4rem) clamp(2.4rem, 6vw, 3.5rem);
  margin-block-start: clamp(2rem, 5vw, 3rem);
}
.foot-grid {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: 1.6rem 2.5rem;
}
.foot-name {
  font-family: var(--font-latin);
  font-weight: 500;
  font-size: 1rem;
  letter-spacing: 0.16em;
}
.addr {
  margin-block-start: 0.5rem;
  font-size: 0.85rem;
  line-height: 1.85;
  font-style: normal;
  color: var(--muted);
}
.addr .nb { white-space: nowrap; }
.foot-tel { margin-block-start: 0.5rem; font-size: 0.85rem; color: var(--muted); }
.foot-links { display: flex; flex-wrap: wrap; gap: 0.15rem 0.9rem; }
.foot-links a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  font-size: 0.83rem;
  color: var(--muted);
  text-decoration: none;
}
.foot-links a:hover { color: var(--accent); }

.demo-note {
  max-width: 44rem;
  margin-block-start: 1.5rem;
  font-size: 0.76rem;
  line-height: 1.85;
  color: var(--muted);
}
.demo-note + .demo-note { margin-block-start: 0.7rem; }

/* ---------- Skip link ---------- */

.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 20;
  padding: 0.8rem 1.2rem;
  background: var(--accent);
  color: var(--accent-ink);
  text-decoration: none;
}
.skip:focus { left: 0; }

/* ---------- Reveal ----------
   The CSS path. motion.js adds .ds-motion to <html> when it takes
   over and ds.css then switches this transition off, so the two
   never drive the same property at once. If no script runs at all
   the <noscript> block in the page head shows everything. */

.rv { opacity: 0; transform: translateY(12px); }
@media (prefers-reduced-motion: no-preference) {
  .rv { transition: opacity 0.6s ease, transform 0.6s cubic-bezier(0.22, 0.75, 0.3, 1); }
}
.rv.in { opacity: 1; transform: none; }
@media (prefers-reduced-motion: reduce) {
  .rv { opacity: 1; transform: none; }
}

/* ---------- Collapse ----------
   Declared here rather than left to work itself out. At 900px the
   rail stops being a margin and becomes a short block between the
   opening and the body of the page; below 620px the plate pair
   stacks and the small plate is held to a width that keeps a
   soft-focus photograph small, which is what it is for. */

@media (max-width: 900px) {
  .spread {
    display: block;
  }
  .rail {
    position: static;
    padding-block: clamp(1.6rem, 5vw, 2.2rem);
    padding-inline-end: 0;
    border-inline-end: 0;
    border-block-start: 1px solid var(--line);
    border-block-end: 1px solid var(--line);
  }
  .rail-title { margin-block-end: 1.1rem; }
  .info-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(13rem, 1fr));
    gap: 1.15rem 1.8rem;
  }
  .fact + .fact {
    margin-block-start: 0;
    padding-block-start: 0;
    border-block-start: 0;
  }
  .shot { margin-block-start: clamp(1.8rem, 6vw, 2.6rem); }
}

@media (max-width: 620px) {
  .plates { grid-template-columns: minmax(0, 1fr); }
  .plate-small { max-width: 17rem; }
  .form { grid-template-columns: minmax(0, 1fr); }
  .form .book-actions .btn { flex: 1 1 100%; min-width: 0; }
  .langsw a { padding-inline: 0.5rem; }
}

@media (max-width: 400px) {
  .wordmark { letter-spacing: 0.03em; }
}

/* ---------- Print ----------
   Somebody in a meeting prints this. The facts and the telephone
   number have to survive it. */

@media print {
  .skip, .langsw, .cta-row, .form, .foot-links { display: none; }
  body { background: #fff; color: #000; }
  .rv { opacity: 1; transform: none; }
  .spread { display: block; }
  .rail { position: static; border: 0; }
}
